add fontFamily select, some fixes

This commit is contained in:
Sergey Krylov 2022-07-11 12:57:49 +05:00
parent f2ee7b8469
commit e1ad90fc6f
13 changed files with 101 additions and 37 deletions

View File

@ -3,7 +3,7 @@ import * as actions from 'redux/action-creators';
import { $, Dom } from 'core/Dom'; import { $, Dom } from 'core/Dom';
import { ComponentOptionsType, ExcelComponent } from 'core/ExcelComponent'; import { ComponentOptionsType, ExcelComponent } from 'core/ExcelComponent';
import { TableSelection } from 'components/table/TableSelection'; import { TableSelection } from 'components/table/TableSelection';
import { changeCurrentStyles } from 'redux/action-creators'; import { changeCurrentStyles, changeCurrentText } from 'redux/action-creators';
import { createTable } from 'components/table/table.template'; import { createTable } from 'components/table/table.template';
import { initialStyleState } from 'src/constants'; import { initialStyleState } from 'src/constants';
import { parse } from 'core/utils'; import { parse } from 'core/utils';
@ -90,7 +90,9 @@ export class Table extends ExcelComponent {
this.$emitEventToObserver('table:select-cell', this.selection.current); this.$emitEventToObserver('table:select-cell', this.selection.current);
const styles = this.selection.current?.getStyles(Object.keys(initialStyleState)); const styles = this.selection.current?.getStyles(Object.keys(initialStyleState));
this.dispatchToStore(changeCurrentStyles(styles)); this.dispatchToStore(changeCurrentStyles(styles));
this.dispatchToStore(changeCurrentText(this.selection.current.text));
} }
async resizeTable(event: MouseEvent) { async resizeTable(event: MouseEvent) {

View File

@ -55,9 +55,27 @@ export class Toolbar extends ExcelComponentState {
} }
onChange(e: any) { onChange(e: any) {
const value = `${e.target.value.toString()}px`; const target = $(e.target);
let value = '';
let key = '';
this.$emitEventToObserver('toolbar:applyStyle', { fontSize: value }); switch (true) {
this.setComponentState({ fontSize: value }); case !!target.closest('#button-size').$el:
value = `${e.target.value.toString()}px`;
key = 'fontSize';
break;
case !!target.closest('#button-font').$el:
value = e.target.value;
key = 'fontFamily';
break;
default: break;
}
if (key && value) {
this.$emitEventToObserver('toolbar:applyStyle', { [key]: value });
this.setComponentState({ [key]: value });
}
} }
} }

View File

@ -5,4 +5,5 @@ export type ToolbarStateType = {
justifyContent?: 'start' | 'center' | 'end'; justifyContent?: 'start' | 'center' | 'end';
alignItems?: 'start' | 'center' | 'end'; alignItems?: 'start' | 'center' | 'end';
fontSize?: string; fontSize?: string;
fontFamily?: string
}; };

View File

@ -81,11 +81,13 @@ export function createToolbar(state: ToolbarStateType): string {
]; ];
const buttons = btns.map(btn => (Array.isArray(btn) ? toButtonGroup(btn) : toButton(btn))); const buttons = btns.map(btn => (Array.isArray(btn) ? toButtonGroup(btn) : toButton(btn)));
buttons.push(createFontSizeButton(state.fontSize));
const selectGroup = createGroup(createFontSizeButton(state.fontSize), createFontFamilyButton(state.fontFamily));
buttons.push(selectGroup);
return buttons.join(' '); return buttons.join(' ');
} }
function createFontSizeButton(currentSize = '12px') { function createFontSizeButton(currentSize = initialStyleState.fontSize) {
const fontSizeInPixels = +currentSize.slice(0, -2); const fontSizeInPixels = +currentSize.slice(0, -2);
const options = []; const options = [];
@ -103,10 +105,26 @@ function createFontSizeButton(currentSize = '12px') {
`; `;
} }
function toButtonGroup(buttons: ButtonConfigType[]) { function createFontFamilyButton(font = initialStyleState.fontFamily) {
if (buttons.length === 1) return toButton(buttons[0]); const fonts = ['Roboto', 'Cormorant SC', 'Kanit', 'Playfair Display'];
const btns = buttons.map(btn => toButton(btn)); const options = fonts.map(fontName => createFontFamilyOption(fontName, fontName === font));
function createFontFamilyOption(name: string, selected: boolean) {
return selected
? `<option value="${name}" selected style="font-family: ${name}">${name}</option>`
: `<option value="${name}" style="font-family: ${name}">${name}</option>`;
}
return `
<div class="button">
<select class="button__font" id="button-font">
${options.join('')}
</select>
</div>
`;
}
function createGroup(...btns: string[]) {
return ` return `
<div class="button__group"> <div class="button__group">
${btns.join('')} ${btns.join('')}
@ -114,6 +132,13 @@ function toButtonGroup(buttons: ButtonConfigType[]) {
`; `;
} }
function toButtonGroup(buttons: ButtonConfigType[]) {
if (buttons.length === 1) return toButton(buttons[0]);
const btns = buttons.map(btn => toButton(btn));
return createGroup(...btns);
}
function toButton(button: ButtonConfigType) { function toButton(button: ButtonConfigType) {
const meta = ` const meta = `
data-type="button" data-type="button"

View File

@ -1,5 +1,6 @@
import { startCellId } from 'components/table/table.functions'; import { startCellId } from 'components/table/table.functions';
import { ToolbarStateType } from 'components/toolbar/toolbar-types'; import { ToolbarStateType } from 'components/toolbar/toolbar-types';
import { storageName } from 'pages/ExcelPage';
import { StateType } from 'redux/types'; import { StateType } from 'redux/types';
import { storage } from 'core/utils'; import { storage } from 'core/utils';
@ -9,19 +10,29 @@ export const initialStyleState: ToolbarStateType = {
textDecoration: 'none', textDecoration: 'none',
fontStyle: 'normal', fontStyle: 'normal',
fontSize: '12px', fontSize: '12px',
fontFamily: 'Roboto',
alignItems: 'start',
}; };
export function getNormalizeInitialState(params: string): StateType { export const initialState: StateType = {
return {
colState: {}, colState: {},
rowState: {}, rowState: {},
dataState: {}, dataState: {},
stylesState: {}, stylesState: {},
title: 'New excel table', title: 'New excel table',
id: params,
openDate: Date.now(), openDate: Date.now(),
...storage(`excel:${params}`), currentStyles: initialStyleState,
currentStyles: { ...storage(`excel:${params}`)?.stylesState?.[startCellId] }, currentText: 'huy',
currentText: { ...storage(`excel:${params}`)?.dataState?.[startCellId] }, };
export function getNormalizeInitialState(params: string): StateType {
const state = storage(storageName(params));
if (!state) return initialState;
return {
...state,
id: params,
currentStyles: state?.stylesState?.[startCellId] || initialStyleState,
currentText: state?.dataState?.[startCellId],
}; };
} }

View File

@ -1,4 +1,3 @@
import { startCellId } from 'components/table/table.functions';
import { storage } from 'core/utils'; import { storage } from 'core/utils';
import { storageName } from 'pages/ExcelPage'; import { storageName } from 'pages/ExcelPage';
import { StateType } from 'redux/types'; import { StateType } from 'redux/types';
@ -22,20 +21,10 @@ export class LocalStorageClient implements ClientDataType {
} }
get() { get() {
const data = this.norm(storage(storageName(this.name))) || getNormalizeInitialState(this.name);
return new Promise(resolve => { return new Promise(resolve => {
setTimeout(() => { setTimeout(() => {
resolve(data); resolve(getNormalizeInitialState(this.name));
}, 1500); }, 1500);
}); });
} }
norm(state: StateType) {
return {
...state,
currentStyles: { ...state.stylesState?.[startCellId] },
currentText: state.dataState?.[startCellId],
};
}
} }

View File

@ -111,7 +111,9 @@ export class Dom implements DomClass {
getStyles(styles: any[]) { getStyles(styles: any[]) {
return styles.reduce((res, s) => { return styles.reduce((res, s) => {
res[s] = this.$el.style[s] || initialStyleState[s as keyof ToolbarStateType]; // replace all need if case style value have 2 or more word, this.$el.style[s] return ""word value""
// for example font-family
res[s] = this.$el.style[s].replaceAll('"', '') || initialStyleState[s as keyof ToolbarStateType];
return res; return res;
}, {}); }, {});
} }

View File

@ -5,3 +5,4 @@ export const CHANGE_TITLE = 'CHANGE_TITLE';
export const DELETE_TABLE = 'DELETE_TABLE'; export const DELETE_TABLE = 'DELETE_TABLE';
export const TABLE_RESIZE = 'TABLE_RESIZE'; export const TABLE_RESIZE = 'TABLE_RESIZE';
export const UPDATE_DATE = 'UPDATE_DATE'; export const UPDATE_DATE = 'UPDATE_DATE';
export const CHANGE_CURRENT_TEXT = 'CHANGE_CURRENT_TEXT';

View File

@ -6,7 +6,7 @@ import {
APPLY_STYLES, APPLY_STYLES,
CHANGE_TITLE, CHANGE_TITLE,
DELETE_TABLE, DELETE_TABLE,
UPDATE_DATE, UPDATE_DATE, CHANGE_CURRENT_TEXT,
} from 'redux/action-constants'; } from 'redux/action-constants';
export function tableResize(resizeData: any) { export function tableResize(resizeData: any) {
@ -57,3 +57,10 @@ export function updateOpenDate(data: string): ActionType {
data, data,
}; };
} }
export function changeCurrentText(data: string): ActionType {
return {
type: CHANGE_CURRENT_TEXT,
data,
};
}

View File

@ -8,7 +8,7 @@ import {
APPLY_STYLES, APPLY_STYLES,
CHANGE_TITLE, CHANGE_TITLE,
DELETE_TABLE, DELETE_TABLE,
UPDATE_DATE, UPDATE_DATE, CHANGE_CURRENT_TEXT,
} from 'redux/action-constants'; } from 'redux/action-constants';
export function rootReducer(state: StateType, action: ActionType) { export function rootReducer(state: StateType, action: ActionType) {
@ -63,7 +63,11 @@ export function rootReducer(state: StateType, action: ActionType) {
} }
case UPDATE_DATE: { case UPDATE_DATE: {
return { ...this.state, openDate: action.data }; return { ...state, openDate: action.data };
}
case CHANGE_CURRENT_TEXT: {
return { ...state, currentText: action.data };
} }
default: return state; default: return state;

View File

@ -10,8 +10,8 @@ export type StateType = {
rowState: { [k: number]: number }; rowState: { [k: number]: number };
currentStyles: ToolbarStateType; currentStyles: ToolbarStateType;
dataState: { [k: string]: string }; dataState: { [k: string]: string };
id: string; id?: string;
openDate: string; openDate: number;
stylesState: { [k: string]: ToolbarStateType }; stylesState: { [k: string]: ToolbarStateType };
title: string; title: string;
currentText: string; currentText: string;

View File

@ -26,4 +26,8 @@
.button__size { .button__size {
width: 50px; width: 50px;
} }
.button__font {
width: 100px;
}
} }

View File

@ -1,4 +1,4 @@
@import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Cormorant+SC&family=Kanit&family=Playfair+Display&family=Roboto&display=swap');;
@import "~normalize.css"; @import "~normalize.css";
@import './components/header'; @import './components/header';