mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-08 02:24:11 +00:00
94233: applied feedback for css variables
This commit is contained in:
@@ -48,7 +48,6 @@ import { BreadcrumbsService } from './breadcrumbs/breadcrumbs.service';
|
|||||||
import { IdleModalComponent } from './shared/idle-modal/idle-modal.component';
|
import { IdleModalComponent } from './shared/idle-modal/idle-modal.component';
|
||||||
import { getDefaultThemeConfig } from '../config/config.util';
|
import { getDefaultThemeConfig } from '../config/config.util';
|
||||||
import { AppConfig, APP_CONFIG } from 'src/config/app-config.interface';
|
import { AppConfig, APP_CONFIG } from 'src/config/app-config.interface';
|
||||||
import { getCSSCustomPropIndex } from './shared/sass-helper/css-variable.utils';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-app',
|
selector: 'ds-app',
|
||||||
@@ -181,9 +180,8 @@ export class AppComponent implements OnInit, AfterViewInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private storeCSSVariables() {
|
private storeCSSVariables() {
|
||||||
getCSSCustomPropIndex(this.document).forEach(([prop, val]) => {
|
this.cssService.clearCSSVariables();
|
||||||
this.cssService.addCSSVariable(prop, val);
|
this.cssService.addCSSVariables(this.cssService.getCSSVariablesFromStylesheets(this.document));
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngAfterViewInit() {
|
ngAfterViewInit() {
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
import { Action } from '@ngrx/store';
|
import { Action } from '@ngrx/store';
|
||||||
import { type } from '../ngrx/type';
|
import { type } from '../ngrx/type';
|
||||||
|
import { KeyValuePair } from '../key-value-pair.model';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For each action type in an action group, make a simple
|
* For each action type in an action group, make a simple
|
||||||
@@ -11,6 +12,8 @@ import { type } from '../ngrx/type';
|
|||||||
*/
|
*/
|
||||||
export const CSSVariableActionTypes = {
|
export const CSSVariableActionTypes = {
|
||||||
ADD: type('dspace/css-variables/ADD'),
|
ADD: type('dspace/css-variables/ADD'),
|
||||||
|
ADD_ALL: type('dspace/css-variables/ADD_ALL'),
|
||||||
|
CLEAR: type('dspace/css-variables/CLEAR'),
|
||||||
};
|
};
|
||||||
|
|
||||||
export class AddCSSVariableAction implements Action {
|
export class AddCSSVariableAction implements Action {
|
||||||
@@ -24,5 +27,20 @@ export class AddCSSVariableAction implements Action {
|
|||||||
this.payload = {name, value};
|
this.payload = {name, value};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
export class AddAllCSSVariablesAction implements Action {
|
||||||
|
type = CSSVariableActionTypes.ADD_ALL;
|
||||||
|
payload: KeyValuePair<string, string>[];
|
||||||
|
|
||||||
export type CSSVariableAction = AddCSSVariableAction;
|
constructor(variables: KeyValuePair<string, string>[]) {
|
||||||
|
this.payload = variables;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ClearCSSVariablesAction implements Action {
|
||||||
|
type = CSSVariableActionTypes.CLEAR;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CSSVariableAction = AddCSSVariableAction | AddAllCSSVariablesAction | ClearCSSVariablesAction;
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
import { CSSVariableAction, CSSVariableActionTypes } from './css-variable.actions';
|
import { CSSVariableAction, CSSVariableActionTypes } from './css-variable.actions';
|
||||||
|
import { KeyValuePair } from '../key-value-pair.model';
|
||||||
|
|
||||||
export interface CSSVariablesState {
|
export interface CSSVariablesState {
|
||||||
[name: string]: string;
|
[name: string]: string;
|
||||||
@@ -16,6 +17,11 @@ export function cssVariablesReducer(state = initialState, action: CSSVariableAct
|
|||||||
case CSSVariableActionTypes.ADD: {
|
case CSSVariableActionTypes.ADD: {
|
||||||
const variable = action.payload;
|
const variable = action.payload;
|
||||||
return Object.assign({}, state, { [variable.name]: variable.value });
|
return Object.assign({}, state, { [variable.name]: variable.value });
|
||||||
|
} case CSSVariableActionTypes.ADD_ALL: {
|
||||||
|
const variables = action.payload;
|
||||||
|
return Object.assign({}, state, ...variables.map(({ key, value }: KeyValuePair<string, string>) => {return {[key]: value}}));
|
||||||
|
} case CSSVariableActionTypes.CLEAR: {
|
||||||
|
return initialState;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
return state;
|
return state;
|
||||||
|
@@ -1,19 +1,35 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { AppState, keySelector } from '../../app.reducer';
|
import { AppState, keySelector } from '../../app.reducer';
|
||||||
import { createSelector, MemoizedSelector, select, Store } from '@ngrx/store';
|
import { createSelector, MemoizedSelector, select, Store } from '@ngrx/store';
|
||||||
import { AddCSSVariableAction } from './css-variable.actions';
|
import { AddAllCSSVariablesAction, AddCSSVariableAction, ClearCSSVariablesAction } from './css-variable.actions';
|
||||||
import { PaginationComponentOptions } from '../pagination/pagination-component-options.model';
|
import { PaginationComponentOptions } from '../pagination/pagination-component-options.model';
|
||||||
import { buildPaginatedList, PaginatedList } from '../../core/data/paginated-list.model';
|
import { buildPaginatedList, PaginatedList } from '../../core/data/paginated-list.model';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { hasValue } from '../empty.util';
|
import { hasValue } from '../empty.util';
|
||||||
import { KeyValuePair } from '../key-value-pair.model';
|
import { KeyValuePair } from '../key-value-pair.model';
|
||||||
import { PageInfo } from '../../core/shared/page-info.model';
|
import { PageInfo } from '../../core/shared/page-info.model';
|
||||||
|
import { CSSVariablesState } from './css-variable.reducer';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This service deals with adding and retrieving CSS variables to and from the store
|
* This service deals with adding and retrieving CSS variables to and from the store
|
||||||
*/
|
*/
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CSSVariableService {
|
export class CSSVariableService {
|
||||||
|
isSameDomain = (styleSheet) => {
|
||||||
|
// Internal style blocks won't have an href value
|
||||||
|
if (!styleSheet.href) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return styleSheet.href.indexOf(window.location.origin) === 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Determine if the given rule is a CSSStyleRule
|
||||||
|
See: https://developer.mozilla.org/en-US/docs/Web/API/CSSRule#Type_constants
|
||||||
|
*/
|
||||||
|
isStyleRule = (rule) => rule.type === 1;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
protected store: Store<AppState>) {
|
protected store: Store<AppState>) {
|
||||||
}
|
}
|
||||||
@@ -27,18 +43,33 @@ export class CSSVariableService {
|
|||||||
this.store.dispatch(new AddCSSVariableAction(name, value));
|
this.store.dispatch(new AddCSSVariableAction(name, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds multiples CSS variables to the store
|
||||||
|
* @param variables The key-value pairs with the CSS variables to be added
|
||||||
|
*/
|
||||||
|
addCSSVariables(variables: KeyValuePair<string, string>[]) {
|
||||||
|
this.store.dispatch(new AddAllCSSVariablesAction(variables));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears all CSS variables ƒrom the store
|
||||||
|
*/
|
||||||
|
clearCSSVariables() {
|
||||||
|
this.store.dispatch(new ClearCSSVariablesAction());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the value of a specific CSS key
|
* Returns the value of a specific CSS key
|
||||||
* @param name The name/key of the CSS value
|
* @param name The name/key of the CSS value
|
||||||
*/
|
*/
|
||||||
getVariable(name: string) {
|
getVariable(name: string): Observable<string> {
|
||||||
return this.store.pipe(select(themeVariableByNameSelector(name)));
|
return this.store.pipe(select(themeVariableByNameSelector(name)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the CSSVariablesState of the store containing all variables
|
* Returns the CSSVariablesState of the store containing all variables
|
||||||
*/
|
*/
|
||||||
getAllVariables() {
|
getAllVariables(): Observable<CSSVariablesState> {
|
||||||
return this.store.pipe(select(themeVariablesSelector));
|
return this.store.pipe(select(themeVariablesSelector));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,6 +81,40 @@ export class CSSVariableService {
|
|||||||
searchVariable(query: string, paginationOptions: PaginationComponentOptions): Observable<PaginatedList<KeyValuePair<string, string>>> {
|
searchVariable(query: string, paginationOptions: PaginationComponentOptions): Observable<PaginatedList<KeyValuePair<string, string>>> {
|
||||||
return this.store.pipe(select(themePaginatedVariablesByQuery(query, paginationOptions)));
|
return this.store.pipe(select(themePaginatedVariablesByQuery(query, paginationOptions)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all custom properties on a page
|
||||||
|
* @return array<KeyValuePair<string, string>>
|
||||||
|
* ex; [{key: "--color-accent", value: "#b9f500"}, {key: "--color-text", value: "#252525"}, ...]
|
||||||
|
*/
|
||||||
|
getCSSVariablesFromStylesheets(document: Document): KeyValuePair<string, string>[]
|
||||||
|
{
|
||||||
|
// styleSheets is array-like, so we convert it to an array.
|
||||||
|
// Filter out any stylesheets not on this domain
|
||||||
|
return [...document.styleSheets]
|
||||||
|
.filter(this.isSameDomain)
|
||||||
|
.reduce(
|
||||||
|
(finalArr, sheet) =>
|
||||||
|
finalArr.concat(
|
||||||
|
// cssRules is array-like, so we convert it to an array
|
||||||
|
[...sheet.cssRules].filter(this.isStyleRule).reduce((propValArr, rule: any) => {
|
||||||
|
const props = [...rule.style]
|
||||||
|
.map((propName) => {
|
||||||
|
return {
|
||||||
|
key: propName.trim(),
|
||||||
|
value: rule.style.getPropertyValue(propName).trim()
|
||||||
|
} as KeyValuePair<string, string>;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
// Discard any props that don't start with "--". Custom props are required to.
|
||||||
|
.filter(({ key }: KeyValuePair<string, string>) => key.indexOf('--') === 0);
|
||||||
|
|
||||||
|
return [...propValArr, ...props];
|
||||||
|
}, [])
|
||||||
|
),
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const themeVariablesSelector = (state: AppState) => state.cssVariables;
|
const themeVariablesSelector = (state: AppState) => state.cssVariables;
|
||||||
|
@@ -1,46 +1,4 @@
|
|||||||
// Uses code from https://css-tricks.com/how-to-get-all-custom-properties-on-a-page-in-javascript/
|
// Uses code from https://css-tricks.com/how-to-get-all-custom-properties-on-a-page-in-javascript/
|
||||||
|
|
||||||
const isSameDomain = (styleSheet) => {
|
import { KeyValuePair } from '../key-value-pair.model';
|
||||||
// Internal style blocks won't have an href value
|
|
||||||
if (!styleSheet.href) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return styleSheet.href.indexOf(window.location.origin) === 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Determine if the given rule is a CSSStyleRule
|
|
||||||
See: https://developer.mozilla.org/en-US/docs/Web/API/CSSRule#Type_constants
|
|
||||||
*/
|
|
||||||
const isStyleRule = (rule) => rule.type === 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all custom properties on a page
|
|
||||||
* @return array<array[string, string]>
|
|
||||||
* ex; [["--color-accent", "#b9f500"], ["--color-text", "#252525"], ...]
|
|
||||||
*/
|
|
||||||
export const getCSSCustomPropIndex = (document: Document) =>
|
|
||||||
// styleSheets is array-like, so we convert it to an array.
|
|
||||||
// Filter out any stylesheets not on this domain
|
|
||||||
[...document.styleSheets]
|
|
||||||
.filter(isSameDomain)
|
|
||||||
.reduce(
|
|
||||||
(finalArr, sheet) =>
|
|
||||||
finalArr.concat(
|
|
||||||
// cssRules is array-like, so we convert it to an array
|
|
||||||
[...sheet.cssRules].filter(isStyleRule).reduce((propValArr, rule: any) => {
|
|
||||||
const props = [...rule.style]
|
|
||||||
.map((propName) => [
|
|
||||||
propName.trim(),
|
|
||||||
rule.style.getPropertyValue(propName).trim()
|
|
||||||
])
|
|
||||||
// Discard any props that don't start with "--". Custom props are required to.
|
|
||||||
.filter(([propName]) => propName.indexOf('--') === 0);
|
|
||||||
|
|
||||||
return [...propValArr, ...props];
|
|
||||||
}, [])
|
|
||||||
),
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user