add fontFamily select, some fixes
This commit is contained in:
parent
f2ee7b8469
commit
e1ad90fc6f
@ -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) {
|
||||||
|
|||||||
@ -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 });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
};
|
};
|
||||||
|
|||||||
@ -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"
|
||||||
|
|||||||
@ -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 const initialState: StateType = {
|
||||||
|
colState: {},
|
||||||
|
rowState: {},
|
||||||
|
dataState: {},
|
||||||
|
stylesState: {},
|
||||||
|
title: 'New excel table',
|
||||||
|
openDate: Date.now(),
|
||||||
|
currentStyles: initialStyleState,
|
||||||
|
currentText: 'huy',
|
||||||
};
|
};
|
||||||
|
|
||||||
export function getNormalizeInitialState(params: string): StateType {
|
export function getNormalizeInitialState(params: string): StateType {
|
||||||
|
const state = storage(storageName(params));
|
||||||
|
if (!state) return initialState;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
colState: {},
|
...state,
|
||||||
rowState: {},
|
|
||||||
dataState: {},
|
|
||||||
stylesState: {},
|
|
||||||
title: 'New excel table',
|
|
||||||
id: params,
|
id: params,
|
||||||
openDate: Date.now(),
|
currentStyles: state?.stylesState?.[startCellId] || initialStyleState,
|
||||||
...storage(`excel:${params}`),
|
currentText: state?.dataState?.[startCellId],
|
||||||
currentStyles: { ...storage(`excel:${params}`)?.stylesState?.[startCellId] },
|
|
||||||
currentText: { ...storage(`excel:${params}`)?.dataState?.[startCellId] },
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
}, {});
|
}, {});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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';
|
||||||
|
|||||||
@ -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,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
4
src/redux/types.d.ts
vendored
4
src/redux/types.d.ts
vendored
@ -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;
|
||||||
|
|||||||
@ -26,4 +26,8 @@
|
|||||||
.button__size {
|
.button__size {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.button__font {
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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';
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user