diff --git a/src/components/table/Table.ts b/src/components/table/Table.ts index 41e13d8..bd486db 100644 --- a/src/components/table/Table.ts +++ b/src/components/table/Table.ts @@ -3,7 +3,7 @@ import * as actions from 'redux/action-creators'; import { $, Dom } from 'core/Dom'; import { ComponentOptionsType, ExcelComponent } from 'core/ExcelComponent'; 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 { initialStyleState } from 'src/constants'; import { parse } from 'core/utils'; @@ -90,7 +90,9 @@ export class Table extends ExcelComponent { this.$emitEventToObserver('table:select-cell', this.selection.current); const styles = this.selection.current?.getStyles(Object.keys(initialStyleState)); + this.dispatchToStore(changeCurrentStyles(styles)); + this.dispatchToStore(changeCurrentText(this.selection.current.text)); } async resizeTable(event: MouseEvent) { diff --git a/src/components/toolbar/Toolbar.ts b/src/components/toolbar/Toolbar.ts index 61566a6..de77049 100644 --- a/src/components/toolbar/Toolbar.ts +++ b/src/components/toolbar/Toolbar.ts @@ -55,9 +55,27 @@ export class Toolbar extends ExcelComponentState { } onChange(e: any) { - const value = `${e.target.value.toString()}px`; + const target = $(e.target); + let value = ''; + let key = ''; - this.$emitEventToObserver('toolbar:applyStyle', { fontSize: value }); - this.setComponentState({ fontSize: value }); + switch (true) { + 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 }); + } } } diff --git a/src/components/toolbar/toolbar-types.ts b/src/components/toolbar/toolbar-types.ts index 44b6013..53e7d60 100644 --- a/src/components/toolbar/toolbar-types.ts +++ b/src/components/toolbar/toolbar-types.ts @@ -5,4 +5,5 @@ export type ToolbarStateType = { justifyContent?: 'start' | 'center' | 'end'; alignItems?: 'start' | 'center' | 'end'; fontSize?: string; + fontFamily?: string }; diff --git a/src/components/toolbar/toolbar.template.ts b/src/components/toolbar/toolbar.template.ts index 223eeb5..43763c7 100644 --- a/src/components/toolbar/toolbar.template.ts +++ b/src/components/toolbar/toolbar.template.ts @@ -81,11 +81,13 @@ export function createToolbar(state: ToolbarStateType): string { ]; 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(' '); } -function createFontSizeButton(currentSize = '12px') { +function createFontSizeButton(currentSize = initialStyleState.fontSize) { const fontSizeInPixels = +currentSize.slice(0, -2); const options = []; @@ -103,10 +105,26 @@ function createFontSizeButton(currentSize = '12px') { `; } -function toButtonGroup(buttons: ButtonConfigType[]) { - if (buttons.length === 1) return toButton(buttons[0]); - const btns = buttons.map(btn => toButton(btn)); +function createFontFamilyButton(font = initialStyleState.fontFamily) { + const fonts = ['Roboto', 'Cormorant SC', 'Kanit', 'Playfair Display']; + const options = fonts.map(fontName => createFontFamilyOption(fontName, fontName === font)); + function createFontFamilyOption(name: string, selected: boolean) { + return selected + ? `` + : ``; + } + + return ` +
+ +
+ `; +} + +function createGroup(...btns: string[]) { return `
${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) { const meta = ` data-type="button" diff --git a/src/constants.ts b/src/constants.ts index cc34f29..fe2b788 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,5 +1,6 @@ import { startCellId } from 'components/table/table.functions'; import { ToolbarStateType } from 'components/toolbar/toolbar-types'; +import { storageName } from 'pages/ExcelPage'; import { StateType } from 'redux/types'; import { storage } from 'core/utils'; @@ -9,19 +10,29 @@ export const initialStyleState: ToolbarStateType = { textDecoration: 'none', fontStyle: 'normal', fontSize: '12px', + fontFamily: 'Roboto', + alignItems: 'start', +}; + +export const initialState: StateType = { + colState: {}, + rowState: {}, + dataState: {}, + stylesState: {}, + title: 'New excel table', + openDate: Date.now(), + currentStyles: initialStyleState, + currentText: 'huy', }; export function getNormalizeInitialState(params: string): StateType { + const state = storage(storageName(params)); + if (!state) return initialState; + return { - colState: {}, - rowState: {}, - dataState: {}, - stylesState: {}, - title: 'New excel table', + ...state, id: params, - openDate: Date.now(), - ...storage(`excel:${params}`), - currentStyles: { ...storage(`excel:${params}`)?.stylesState?.[startCellId] }, - currentText: { ...storage(`excel:${params}`)?.dataState?.[startCellId] }, + currentStyles: state?.stylesState?.[startCellId] || initialStyleState, + currentText: state?.dataState?.[startCellId], }; } diff --git a/src/core/Clients.ts b/src/core/Clients.ts index b69277e..70e102a 100644 --- a/src/core/Clients.ts +++ b/src/core/Clients.ts @@ -1,4 +1,3 @@ -import { startCellId } from 'components/table/table.functions'; import { storage } from 'core/utils'; import { storageName } from 'pages/ExcelPage'; import { StateType } from 'redux/types'; @@ -22,20 +21,10 @@ export class LocalStorageClient implements ClientDataType { } get() { - const data = this.norm(storage(storageName(this.name))) || getNormalizeInitialState(this.name); - return new Promise(resolve => { setTimeout(() => { - resolve(data); + resolve(getNormalizeInitialState(this.name)); }, 1500); }); } - - norm(state: StateType) { - return { - ...state, - currentStyles: { ...state.stylesState?.[startCellId] }, - currentText: state.dataState?.[startCellId], - }; - } } diff --git a/src/core/Dom.ts b/src/core/Dom.ts index 82b466f..9b2ff2e 100644 --- a/src/core/Dom.ts +++ b/src/core/Dom.ts @@ -111,7 +111,9 @@ export class Dom implements DomClass { getStyles(styles: any[]) { 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; }, {}); } diff --git a/src/redux/action-constants.ts b/src/redux/action-constants.ts index fc016a6..a201e07 100644 --- a/src/redux/action-constants.ts +++ b/src/redux/action-constants.ts @@ -5,3 +5,4 @@ export const CHANGE_TITLE = 'CHANGE_TITLE'; export const DELETE_TABLE = 'DELETE_TABLE'; export const TABLE_RESIZE = 'TABLE_RESIZE'; export const UPDATE_DATE = 'UPDATE_DATE'; +export const CHANGE_CURRENT_TEXT = 'CHANGE_CURRENT_TEXT'; diff --git a/src/redux/action-creators.ts b/src/redux/action-creators.ts index cf15f20..c307e1e 100644 --- a/src/redux/action-creators.ts +++ b/src/redux/action-creators.ts @@ -6,7 +6,7 @@ import { APPLY_STYLES, CHANGE_TITLE, DELETE_TABLE, - UPDATE_DATE, + UPDATE_DATE, CHANGE_CURRENT_TEXT, } from 'redux/action-constants'; export function tableResize(resizeData: any) { @@ -57,3 +57,10 @@ export function updateOpenDate(data: string): ActionType { data, }; } + +export function changeCurrentText(data: string): ActionType { + return { + type: CHANGE_CURRENT_TEXT, + data, + }; +} diff --git a/src/redux/rootReducer.ts b/src/redux/rootReducer.ts index a9f2c32..6d54d7c 100644 --- a/src/redux/rootReducer.ts +++ b/src/redux/rootReducer.ts @@ -8,7 +8,7 @@ import { APPLY_STYLES, CHANGE_TITLE, DELETE_TABLE, - UPDATE_DATE, + UPDATE_DATE, CHANGE_CURRENT_TEXT, } from 'redux/action-constants'; export function rootReducer(state: StateType, action: ActionType) { @@ -63,7 +63,11 @@ export function rootReducer(state: StateType, action: ActionType) { } 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; diff --git a/src/redux/types.d.ts b/src/redux/types.d.ts index 807a307..7dadd6d 100644 --- a/src/redux/types.d.ts +++ b/src/redux/types.d.ts @@ -10,8 +10,8 @@ export type StateType = { rowState: { [k: number]: number }; currentStyles: ToolbarStateType; dataState: { [k: string]: string }; - id: string; - openDate: string; + id?: string; + openDate: number; stylesState: { [k: string]: ToolbarStateType }; title: string; currentText: string; diff --git a/src/styles/components/toolbar.scss b/src/styles/components/toolbar.scss index 3ef0348..88c459e 100644 --- a/src/styles/components/toolbar.scss +++ b/src/styles/components/toolbar.scss @@ -26,4 +26,8 @@ .button__size { width: 50px; } + + .button__font { + width: 100px; + } } diff --git a/src/styles/index.scss b/src/styles/index.scss index f6a19c9..27e87bf 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -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 './components/header';