diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 11e4ad6b0..2c615ccd5 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -1817,8 +1817,17 @@ "subscribe_pitch_sign_in": { "message": "Already subscribed? Sign in" }, - "subscription_midnight_theme": { - "message": "Midnight Theme" + "subscription_default_theme": { + "message": "Default" + }, + "subscription_dark_blue_theme": { + "message": "Dark Blue Theme" + }, + "subscription_palm_theme": { + "message": "Palm Theme" + }, + "subscription_leaf_theme": { + "message": "Leaf Theme" }, "subscription_status": { "message": "Status" diff --git a/app/images/panel/allow.svg b/app/images/panel/allow.svg new file mode 100644 index 000000000..e4998171f --- /dev/null +++ b/app/images/panel/allow.svg @@ -0,0 +1,3 @@ + + + diff --git a/app/images/panel/icon-information-tooltip-blue.svg b/app/images/panel/icon-information-tooltip-blue.svg new file mode 100644 index 000000000..2b277cf22 --- /dev/null +++ b/app/images/panel/icon-information-tooltip-blue.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/images/panel/protected.svg b/app/images/panel/protected.svg new file mode 100644 index 000000000..73d901f4d --- /dev/null +++ b/app/images/panel/protected.svg @@ -0,0 +1,3 @@ + + + diff --git a/app/images/panel/restrict.svg b/app/images/panel/restrict.svg new file mode 100644 index 000000000..4769286af --- /dev/null +++ b/app/images/panel/restrict.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/images/panel/tracker-detail-cliqz-ads-icon.svg b/app/images/panel/tracker-detail-cliqz-ads-default-icon.svg similarity index 100% rename from app/images/panel/tracker-detail-cliqz-ads-icon.svg rename to app/images/panel/tracker-detail-cliqz-ads-default-icon.svg diff --git a/app/images/panel/tracker-detail-cliqz-ads-leaf-theme-icon.svg b/app/images/panel/tracker-detail-cliqz-ads-leaf-theme-icon.svg new file mode 100644 index 000000000..90929d493 --- /dev/null +++ b/app/images/panel/tracker-detail-cliqz-ads-leaf-theme-icon.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/app/images/panel/tracker-detail-cliqz-ads-palm-theme-icon.svg b/app/images/panel/tracker-detail-cliqz-ads-palm-theme-icon.svg new file mode 100644 index 000000000..afb953ed1 --- /dev/null +++ b/app/images/panel/tracker-detail-cliqz-ads-palm-theme-icon.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/app/images/panel/tracker-detail-cliqz-cookies-and-fingerprints-icon.svg b/app/images/panel/tracker-detail-cliqz-cookies-and-fingerprints-default-icon.svg similarity index 100% rename from app/images/panel/tracker-detail-cliqz-cookies-and-fingerprints-icon.svg rename to app/images/panel/tracker-detail-cliqz-cookies-and-fingerprints-default-icon.svg diff --git a/app/images/panel/tracker-detail-cliqz-cookies-and-fingerprints-leaf-theme-icon.svg b/app/images/panel/tracker-detail-cliqz-cookies-and-fingerprints-leaf-theme-icon.svg new file mode 100644 index 000000000..be051ccb1 --- /dev/null +++ b/app/images/panel/tracker-detail-cliqz-cookies-and-fingerprints-leaf-theme-icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/app/images/panel/tracker-detail-cliqz-cookies-and-fingerprints-palm-theme-icon.svg b/app/images/panel/tracker-detail-cliqz-cookies-and-fingerprints-palm-theme-icon.svg new file mode 100644 index 000000000..6e15fe156 --- /dev/null +++ b/app/images/panel/tracker-detail-cliqz-cookies-and-fingerprints-palm-theme-icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/app/panel/components/Blocking.jsx b/app/panel/components/Blocking.jsx index 0b6106099..cd430a761 100644 --- a/app/panel/components/Blocking.jsx +++ b/app/panel/components/Blocking.jsx @@ -294,7 +294,7 @@ class Blocking extends React.Component { show_tracker_urls, sitePolicy, smartBlock, - smartBlockActive + smartBlockActive, } = this.props; const { diff --git a/app/panel/components/Blocking/Tracker.jsx b/app/panel/components/Blocking/Tracker.jsx index a3f973f7c..ae0aa411e 100644 --- a/app/panel/components/Blocking/Tracker.jsx +++ b/app/panel/components/Blocking/Tracker.jsx @@ -17,6 +17,7 @@ import React from 'react'; import { ReactSVG } from 'react-svg'; import ClassNames from 'classnames'; +import { ThemeContext } from '../../contexts/ThemeContext'; import globals from '../../../../src/classes/Globals'; import { log } from '../../../../src/utils/common'; import { sendMessageInPromise } from '../../utils/msg'; @@ -27,6 +28,8 @@ import { renderKnownTrackerButtons, renderUnknownTrackerButtons } from './tracke * @memberOf BlockingComponents */ class Tracker extends React.Component { + static contextType = ThemeContext; + constructor(props) { super(props); this.state = { @@ -259,7 +262,7 @@ class Tracker extends React.Component { _renderCliqzAdsIcon() { return this._renderCliqzStatsIcon('ads'); } _renderCliqzStatsIcon(type) { - const path = `/app/images/panel/tracker-detail-cliqz-${type}-icon.svg`; + const path = `/app/images/panel/tracker-detail-cliqz-${type}-${this.context}-icon.svg`; return ( diff --git a/app/panel/components/BuildingBlocks/CliqzFeature.jsx b/app/panel/components/BuildingBlocks/CliqzFeature.jsx index b699e387a..d120a0607 100644 --- a/app/panel/components/BuildingBlocks/CliqzFeature.jsx +++ b/app/panel/components/BuildingBlocks/CliqzFeature.jsx @@ -51,7 +51,13 @@ class CliqzFeature extends React.Component { } _getStatus(active) { - return active ? t('on') : t('off'); + const { current_theme, trackerCount } = this.props; + switch (current_theme) { + case 'palm-theme': + return active ? ({trackerCount}) : (
); + default: + return active ? t('on') : t('off'); + } } _getTooltipBodyText(active, isTooltipBody, type) { diff --git a/app/panel/components/BuildingBlocks/RadioButton.jsx b/app/panel/components/BuildingBlocks/RadioButton.jsx new file mode 100644 index 000000000..12924cfb3 --- /dev/null +++ b/app/panel/components/BuildingBlocks/RadioButton.jsx @@ -0,0 +1,46 @@ +/** + * Radio Button Component + * + * Ghostery Browser Extension + * https://www.ghostery.com/ + * + * Copyright 2019 Ghostery, Inc. All rights reserved. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0 + */ + +import React from 'react'; +import PropTypes from 'prop-types'; +import ClassNames from 'classnames'; + +/** + * @class Implements a single radio button to be used inside the RadioButtonGroup component + * @memberof PanelBuildingBlocks + */ + +const RadioButton = (props) => { + const { checked, handleClick } = props; + const OuterCircleClassNames = ClassNames('RadioButton__outerCircle', { + checked, + }); + const InnerCircleClassNames = ClassNames('RadioButton__innerCircle', { + checked, + }); + return ( + + + + + + ); +}; + +// PropTypes ensure we pass required props of the correct type +RadioButton.propTypes = { + checked: PropTypes.bool.isRequired, + handleClick: PropTypes.func.isRequired, +}; + +export default RadioButton; diff --git a/app/panel/components/BuildingBlocks/RadioButtonGroup.jsx b/app/panel/components/BuildingBlocks/RadioButtonGroup.jsx new file mode 100644 index 000000000..e79cfe6d2 --- /dev/null +++ b/app/panel/components/BuildingBlocks/RadioButtonGroup.jsx @@ -0,0 +1,51 @@ +/** + * Radio Button Group Component + * + * Ghostery Browser Extension + * https://www.ghostery.com/ + * + * Copyright 2019 Ghostery, Inc. All rights reserved. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0 + */ + +/* eslint jsx-a11y/label-has-associated-control: 0 */ + +import React from 'react'; +import PropTypes from 'prop-types'; +import RadioButton from './RadioButton'; + +/** + * @class Implements a radio button group + * @memberof PanelBuildingBlocks + */ +const RadioButtonGroup = (props) => { + const { indexClicked, handleItemClick } = props; + return ( + props.labels.map((label, index) => ( +
+ + {t(label)} + +
+ handleItemClick(index)} + /> +
+
+ )) + ); +}; + +// PropTypes ensure we pass required props of the correct type +RadioButtonGroup.propTypes = { + labels: PropTypes.arrayOf(PropTypes.string).isRequired, + handleItemClick: PropTypes.func.isRequired, + indexClicked: PropTypes.number.isRequired +}; + + +export default RadioButtonGroup; diff --git a/app/panel/components/BuildingBlocks/StatsGraph.jsx b/app/panel/components/BuildingBlocks/StatsGraph.jsx index 0ae8ab68c..5bb4cc0f2 100644 --- a/app/panel/components/BuildingBlocks/StatsGraph.jsx +++ b/app/panel/components/BuildingBlocks/StatsGraph.jsx @@ -14,12 +14,14 @@ import { isEqual } from 'underscore'; import React from 'react'; import * as D3 from 'd3'; - +import { ThemeContext } from '../../contexts/ThemeContext'; /** * Generates an animated graph displaying locally stored stats * @memberof PanelBuildingBlocks */ class StatsGraph extends React.Component { + static contextType = ThemeContext; + /** * Lifecycle event */ @@ -161,6 +163,17 @@ class StatsGraph extends React.Component { .attrTween('stroke-dasharray', interpolator); } + function getThemeColor() { + switch (StatsGraph.context) { + case 'palm-theme': + return '#172a0b'; + case 'leaf-theme': + return '#173700'; + default: + return '#124559'; + } + } + pathGroup.append('path') .style('stroke', '#dddddd') .style('stroke-dasharray', '4,4') @@ -170,7 +183,7 @@ class StatsGraph extends React.Component { pathGroup.append('path') .attr('d', line) .attr('fill', 'none') - .attr('stroke', '#124559') + .attr('stroke', getThemeColor()) .attr('stroke-width', 1.5) .call(animator); // ---------------------------------------------------------------------- // @@ -187,7 +200,6 @@ class StatsGraph extends React.Component { .style('opacity', opacity); }, 1); } - // Add data points with event listeners for opening their respective tooltips canvas.append('g') .attr('class', 'point-group') @@ -196,7 +208,7 @@ class StatsGraph extends React.Component { .enter() .append('circle') .attr('class', (d, i) => `point point-${i}`) - .attr('fill', '#124559') + .attr('fill', getThemeColor()) .attr('cx', d => x(d.index)) .attr('cy', d => y(d.amount)) .attr('r', 0) diff --git a/app/panel/components/BuildingBlocks/index.js b/app/panel/components/BuildingBlocks/index.js index edc925cbc..8f73d6052 100644 --- a/app/panel/components/BuildingBlocks/index.js +++ b/app/panel/components/BuildingBlocks/index.js @@ -21,6 +21,8 @@ import GhosteryFeature from './GhosteryFeature'; import NotScanned from './NotScanned'; import PauseButton from './PauseButton'; import ToggleSlider from './ToggleSlider'; +import RadioButtonGroup from './RadioButtonGroup'; +import RadioButton from './RadioButton'; import ModalExitButton from './ModalExitButton'; export { @@ -31,5 +33,7 @@ export { NotScanned, PauseButton, ToggleSlider, + RadioButtonGroup, + RadioButton, ModalExitButton }; diff --git a/app/panel/components/Panel.jsx b/app/panel/components/Panel.jsx index c13fbb5da..6ed5e9517 100644 --- a/app/panel/components/Panel.jsx +++ b/app/panel/components/Panel.jsx @@ -16,6 +16,7 @@ import { NavLink } from 'react-router-dom'; import Header from '../containers/HeaderContainer'; import { PremiumPromoModal } from '../../shared-components'; import InsightsPromoModal from './InsightsPromoModal'; +import { ThemeContext } from '../contexts/ThemeContext'; import { DynamicUIPortContext } from '../contexts/DynamicUIPortContext'; import { sendMessage } from '../utils/msg'; import { setTheme } from '../utils/utils'; @@ -408,7 +409,7 @@ class Panel extends React.Component { } const notificationText = this.props.notificationShown && this.renderNotification(); - + const { current_theme } = this.props; return (
{this._renderPromoModal()} @@ -425,9 +426,11 @@ class Panel extends React.Component {
- - { this.props.children } - + + + { this.props.children } + + ); diff --git a/app/panel/components/Stats.jsx b/app/panel/components/Stats.jsx index 39aa829d2..8ec7ac7c7 100644 --- a/app/panel/components/Stats.jsx +++ b/app/panel/components/Stats.jsx @@ -524,13 +524,15 @@ class Stats extends React.Component { * @return {ReactComponent} StatsView instance */ render() { + const { user, loggedIn } = this.props; + const { showResetModal, selection } = this.state; return ( { - const newChecked = !this.state.isChecked; - this.setState({ isChecked: newChecked }); - const updated_theme = newChecked ? 'midnight-theme' : 'default'; + changeTheme = (updated_theme) => { + this.setState({ theme: updated_theme }); this.props.actions.getTheme(updated_theme).then(() => { sendMessage('ping', 'theme_change'); }); @@ -86,7 +86,7 @@ class Subscription extends React.Component { SubscriptionInfoComponent = () => (); - SubscriptionThemesComponent = () => (); + SubscriptionThemesComponent = () => (); PrioritySupportComponent = () => (); diff --git a/app/panel/components/Subscription/SubscriptionInfo.jsx b/app/panel/components/Subscription/SubscriptionInfo.jsx index 93c1161a4..8d115b17b 100644 --- a/app/panel/components/Subscription/SubscriptionInfo.jsx +++ b/app/panel/components/Subscription/SubscriptionInfo.jsx @@ -74,7 +74,7 @@ const SubscriptionInfo = (props) => {
    -
  • {t('subscription_midnight_theme')}
  • +
  • {t('subscription_dark_blue_theme')}
  • {t('historical_stats')}
  • {t('priority_support')}
diff --git a/app/panel/components/Subscription/SubscriptionThemes.jsx b/app/panel/components/Subscription/SubscriptionThemes.jsx index 3a00f0282..046d77445 100644 --- a/app/panel/components/Subscription/SubscriptionThemes.jsx +++ b/app/panel/components/Subscription/SubscriptionThemes.jsx @@ -12,36 +12,45 @@ */ import React from 'react'; -import { ToggleSlider } from '../BuildingBlocks'; +import PropTypes from 'prop-types'; +import { RadioButtonGroup } from '../BuildingBlocks'; /** * @class Implement Themes subview as a React component. * The view opens from the left-side menu of the main Subscription view. - * It allows to switch between available Ghostery themes. Right now it handles just one theme. Hence - slider. + * It allows to switch between available Ghostery themes. * @memberOf SettingsComponents - */ -const SubscriptionThemes = props => ( -
-
-
-

{ t('subscription_themes_title') }

-
- - - {t('subscription_midnight_theme')} - - -
- -
+*/ +const SubscriptionThemes = (props) => { + const themes = ['default', 'midnight-theme', 'palm-theme', 'leaf-theme']; + const themeLabels = ['subscription_default_theme', 'subscription_dark_blue_theme', 'subscription_palm_theme', 'subscription_leaf_theme']; + + const getIndexClicked = () => themes.indexOf(props.theme); + + const handleThemeClick = index => props.changeTheme(themes[index]); + + return ( +
+
+
+

{t('subscription_themes_title')}

+ + +
-
-); + ); +}; + +// PropTypes ensure we pass required props of the correct type +SubscriptionThemes.propTypes = { + changeTheme: PropTypes.func.isRequired, +}; + export default SubscriptionThemes; diff --git a/app/panel/components/Summary.jsx b/app/panel/components/Summary.jsx index cb5a679a5..35ba61ba9 100644 --- a/app/panel/components/Summary.jsx +++ b/app/panel/components/Summary.jsx @@ -623,6 +623,8 @@ class Summary extends React.Component { const { enable_anti_tracking, is_expert, + current_theme, + antiTracking, } = this.props; const isCondensed = this._isCondensed(); @@ -638,6 +640,8 @@ class Summary extends React.Component { isTooltipHeader={is_expert} isTooltipBody={!isCondensed} tooltipPosition={isCondensed ? 'right' : is_expert ? 'top top-right' : 'top'} + current_theme={current_theme} + trackerCount={antiTracking.trackerCount} />
); @@ -647,6 +651,8 @@ class Summary extends React.Component { const { enable_ad_block, is_expert, + current_theme, + adBlock, } = this.props; const isCondensed = this._isCondensed(); @@ -662,6 +668,8 @@ class Summary extends React.Component { isTooltipHeader={is_expert} isTooltipBody={!isCondensed} tooltipPosition={isCondensed ? 'right' : 'top'} + current_theme={current_theme} + trackerCount={adBlock.trackerCount} />
); @@ -671,6 +679,8 @@ class Summary extends React.Component { const { enable_smart_block, is_expert, + current_theme, + smartBlock } = this.props; const isCondensed = this._isCondensed(); @@ -686,6 +696,8 @@ class Summary extends React.Component { isTooltipHeader={is_expert} isTooltipBody={!isCondensed} tooltipPosition={isCondensed ? 'right' : is_expert ? 'top top-left' : 'top'} + current_theme={current_theme} + trackerCount={Object.keys(smartBlock.blocked).length} />
); @@ -779,6 +791,7 @@ class Summary extends React.Component { enable_offers, is_expert, is_expanded, + current_theme } = this.props; const { disableBlocking } = this.state; const isCondensed = this._isCondensed(); @@ -787,39 +800,46 @@ class Summary extends React.Component { 'Summary--expert': is_expert && !is_expanded, 'Summary--condensed': isCondensed, }); + const foregroundClassNames = ClassNames('Summary__foreground', { + active: current_theme === 'palm-theme' + || current_theme === 'leaf-theme', + }); return (
- {!isCondensed && disableBlocking && ()} - {!isCondensed && !disableBlocking && this._renderDonut()} - {!isCondensed && !disableBlocking && this._renderPageHostReadout()} - - {isCondensed && !disableBlocking && this._renderTotalTrackersFound()} +
+
+ {!isCondensed && disableBlocking && ()} + {!isCondensed && !disableBlocking && this._renderDonut()} + {!isCondensed && !disableBlocking && this._renderPageHostReadout()} + + {isCondensed && !disableBlocking && this._renderTotalTrackersFound()} + +
+ {!disableBlocking && this._renderTotalTrackersBlocked()} + {!disableBlocking && this._renderTotalRequestsModified()} + {!disableBlocking && this._renderPageLoadTime()} +
-
- {!disableBlocking && this._renderTotalTrackersBlocked()} - {!disableBlocking && this._renderTotalRequestsModified()} - {!disableBlocking && this._renderPageLoadTime()} -
+ {isCondensed && disableBlocking && ( +
+ )} - {isCondensed && disableBlocking && ( -
- )} +
+ {this._renderGhosteryFeature('trust')} + {this._renderGhosteryFeature('restrict', 'Summary__ghosteryFeatureContainer--middle')} + {this._renderPauseButton()} +
+
+ {this._renderCliqzAntiTracking()} + {this._renderCliqzAdBlock()} + {this._renderCliqzSmartBlock()} +
+ {this._renderStatsNavicon()} + {enable_offers && this._renderRewardsNavicon()} -
- {this._renderGhosteryFeature('trust')} - {this._renderGhosteryFeature('restrict', 'Summary__ghosteryFeatureContainer--middle')} - {this._renderPauseButton()} + {!isCondensed && this._renderPlusUpgradeBannerOrSubscriberIcon()}
-
- {this._renderCliqzAntiTracking()} - {this._renderCliqzAdBlock()} - {this._renderCliqzSmartBlock()} -
- {this._renderStatsNavicon()} - {enable_offers && this._renderRewardsNavicon()} - - {!isCondensed && this._renderPlusUpgradeBannerOrSubscriberIcon()}
); } diff --git a/app/panel/containers/StatsContainer.js b/app/panel/containers/StatsContainer.js index 5819bd7f7..2a9033a07 100644 --- a/app/panel/containers/StatsContainer.js +++ b/app/panel/containers/StatsContainer.js @@ -22,7 +22,7 @@ import Stats from '../components/Stats'; * @todo We are not using ownProps, so we better not specify it explicitly, * in this case it won't be passed by React (see https://github.com/reactjs/react-redux/blob/master/docs/api.md). */ -const mapStateToProps = state => Object.assign({}, state.account); +const mapStateToProps = state => Object.assign({}, state.account, {}); /** * Connects Subscription view component to the Redux store. Pass updated match, location, and history props to the wrapped component. diff --git a/app/panel/containers/SummaryContainer.js b/app/panel/containers/SummaryContainer.js index 826400617..fac24f3ba 100644 --- a/app/panel/containers/SummaryContainer.js +++ b/app/panel/containers/SummaryContainer.js @@ -29,7 +29,8 @@ const mapStateToProps = state => Object.assign({}, state.summary, state.panel, { is_expanded: state.panel.is_expanded, is_expert: state.panel.is_expert, tab_id: state.panel.tab_id, - user: state.account.user + user: state.account.user, + current_theme: state.panel.current_theme, }); /** * Bind Summary view component action creators using Redux's bindActionCreators diff --git a/app/panel/contexts/ThemeContext.js b/app/panel/contexts/ThemeContext.js new file mode 100644 index 000000000..f47652914 --- /dev/null +++ b/app/panel/contexts/ThemeContext.js @@ -0,0 +1,16 @@ +/** + * Theme Context + * + * Ghostery Browser Extension + * https://www.ghostery.com/ + * + * Copyright 2019 Ghostery, Inc. All rights reserved. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0 + */ + +import React from 'react'; + +export const ThemeContext = React.createContext(null); diff --git a/app/panel/utils/utils.js b/app/panel/utils/utils.js index a92dde970..b925d71d3 100644 --- a/app/panel/utils/utils.js +++ b/app/panel/utils/utils.js @@ -218,10 +218,11 @@ export function setTheme(doc, name, account) { // First remove all other style elements which may be there const styleList = doc.head.getElementsByTagName('style'); // Other kinds of loops are not supported equally across browsers + let themeStyle = null; for (let i = 0; i < styleList.length; i++) { const style = styleList[i]; if (style.title.startsWith(styleTitlePrefix)) { - doc.head.removeChild(style); + themeStyle = style; } } @@ -232,12 +233,21 @@ export function setTheme(doc, name, account) { const { css } = themeData[name]; // Create element for the theme being set, if it is not there - const themeStyle = doc.createElement('style'); - themeStyle.id = name; - themeStyle.title = `${styleTitlePrefix} ${name}`; - - // Set content of style element to the theme text. - themeStyle.textContent = css; - document.head.appendChild(themeStyle); + if (!themeStyle) { + themeStyle = doc.createElement('style'); + themeStyle.id = name; + themeStyle.title = `${styleTitlePrefix}`; + themeStyle.textContent = css; + doc.head.appendChild(themeStyle); + } else { + themeStyle.textContent = css; + } + } else { + for (let i = 0; i < styleList.length; i++) { + const style = styleList[i]; + if (style.title.startsWith(styleTitlePrefix)) { + doc.head.removeChild(style); + } + } } } diff --git a/app/scss/panel.scss b/app/scss/panel.scss index eaef66ef7..21ab2f760 100644 --- a/app/scss/panel.scss +++ b/app/scss/panel.scss @@ -65,6 +65,7 @@ html body { @import './partials/_account'; @import './partials/_drawer'; @import './partials/_toggle_slider'; +@import './partials/_radio_button'; @import './partials/_pause_button'; @import './partials/_donut_graph'; @import './partials/_ghostery_feature'; @@ -76,6 +77,7 @@ html body { @import './partials/_stats_graph'; @import './partials/_modal_exit_button'; @import './partials/insights_promo_modal.scss'; +// @import './themes/theme.scss'; // Imports from ../shared-components directory @import '../shared-components/Modal/Modal.scss'; diff --git a/app/scss/partials/_radio_button.scss b/app/scss/partials/_radio_button.scss new file mode 100644 index 000000000..51ddeb4bb --- /dev/null +++ b/app/scss/partials/_radio_button.scss @@ -0,0 +1,42 @@ +/** + * Radio Button Sass + * + * Ghostery Browser Extension + * https://www.ghostery.com/ + * + * Copyright 2019 Ghostery, Inc. All rights reserved. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0 + */ + +.RadioButtonGroup__label { + margin-right: 10px; + font-weight: bolder; +} +.RadioButtonGroup__container { + margin: 16px 0; + width: 138px; +} +.RadioButton__outerCircle { + border: 1px solid #4a4a4a; + height: 16px; + width: 16px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + box-sizing: border-box; + &.checked { + border: 2px solid #2092bf; + } +} +.RadioButton__innerCircle { + &.checked { + height: 8px; + width: 8px; + background-color: #2092bf; + border-radius: 50%; + } +} diff --git a/app/scss/partials/_settings.scss b/app/scss/partials/_settings.scss index dccf04282..96981e5aa 100644 --- a/app/scss/partials/_settings.scss +++ b/app/scss/partials/_settings.scss @@ -5,7 +5,7 @@ * https://www.ghostery.com/ * * Copyright 2019 Ghostery, Inc. All rights reserved. - * + * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0 @@ -58,7 +58,6 @@ text-align: left; } } - .s-tab-title { font-weight: 400; font-size: 18px; @@ -195,12 +194,11 @@ line-height: 1.4; } img.s-question { - top: -5px; - width: 14px; + width: 16px; height: auto; cursor: default; - vertical-align: top; opacity: 1.0; + margin: -6px 0 0 10px; } .s-option-group { margin-bottom: 12px; @@ -279,7 +277,7 @@ border-color: #CCCCCC; background-size: 8px 5px; -moz-appearance: none; - -webkit-appearance:none; + -webkit-appearance: none; } } #select-file { @@ -458,4 +456,4 @@ .blocking-trackers { margin-left: 25px; } -} \ No newline at end of file +} diff --git a/app/scss/partials/_subscribe.scss b/app/scss/partials/_subscribe.scss index 11e7375e4..c771b102d 100644 --- a/app/scss/partials/_subscribe.scss +++ b/app/scss/partials/_subscribe.scss @@ -83,17 +83,16 @@ -webkit-font-smoothing: antialiased; text-align: left; } - .themes-slider-label { - @extend .field-label; - padding-right: 20px !important; - } - .themes-slider-container { - padding-top: 10px !important; - } .column-subscription { padding-left: 30px !important; padding-right: 30px !important; } + .subscription-title { + display: inline; + } + .tooltip-icon { + margin-left: 5px !important; + } .status-label { @extend .field-label; padding-right: 7px !important; diff --git a/app/shared-components/Modal/Modal.scss b/app/shared-components/Modal/Modal.scss index 518bcb9fe..eeb0e48b9 100644 --- a/app/shared-components/Modal/Modal.scss +++ b/app/shared-components/Modal/Modal.scss @@ -19,8 +19,9 @@ right: 0; bottom: 0; left: 0; + z-index: 2147483647; } .Modal__background { background-color: rgba(#000000, 0.25); - z-index: 9; } + diff --git a/manifest.json b/manifest.json index fdc3ff517..af877af3d 100644 --- a/manifest.json +++ b/manifest.json @@ -103,4 +103,4 @@ "cliqz/offers-reminder/index.html", "cliqz/popup-notification/images/*" ] -} \ No newline at end of file +}