add increase-decrease font size buttons
This commit is contained in:
parent
e1ad90fc6f
commit
c92ae3a38d
11
.eslintrc.js
11
.eslintrc.js
@ -34,13 +34,14 @@ module.exports = {
|
|||||||
"import/prefer-default-export": "off",
|
"import/prefer-default-export": "off",
|
||||||
"linebreak-style": "off",
|
"linebreak-style": "off",
|
||||||
"max-len": "off",
|
"max-len": "off",
|
||||||
"no-console": "off",
|
|
||||||
"no-new": "off",
|
|
||||||
"no-continue": "off",
|
|
||||||
"no-plusplus": "off",
|
|
||||||
"object-curly-newline": "off",
|
|
||||||
"no-alert": "off",
|
"no-alert": "off",
|
||||||
|
"no-console": "off",
|
||||||
|
"no-continue": "off",
|
||||||
|
"no-new": "off",
|
||||||
|
"no-plusplus": "off",
|
||||||
"no-restricted-globals": "off",
|
"no-restricted-globals": "off",
|
||||||
|
"object-curly-newline": "off",
|
||||||
|
"prefer-destructuring": "off",
|
||||||
},
|
},
|
||||||
env: {
|
env: {
|
||||||
browser: true,
|
browser: true,
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { $, Dom } from 'core/Dom';
|
|||||||
import { ExcelComponentState } from 'core/ExcelComponentState';
|
import { ExcelComponentState } from 'core/ExcelComponentState';
|
||||||
import { ComponentOptionsType } from 'core/ExcelComponent';
|
import { ComponentOptionsType } from 'core/ExcelComponent';
|
||||||
import { createToolbar } from 'components/toolbar/toolbar.template';
|
import { createToolbar } from 'components/toolbar/toolbar.template';
|
||||||
import { initialStyleState } from 'src/constants';
|
import { fontSizes, initialStyleState } from 'src/constants';
|
||||||
|
|
||||||
export class Toolbar extends ExcelComponentState {
|
export class Toolbar extends ExcelComponentState {
|
||||||
static className = 'excel__toolbar';
|
static className = 'excel__toolbar';
|
||||||
@ -44,11 +44,41 @@ export class Toolbar extends ExcelComponentState {
|
|||||||
|
|
||||||
onClick(event: MouseEvent) {
|
onClick(event: MouseEvent) {
|
||||||
const target = $(event.target as HTMLElement);
|
const target = $(event.target as HTMLElement);
|
||||||
const stringValue = target?.data?.value;
|
|
||||||
|
let stringValue;
|
||||||
|
let value;
|
||||||
|
let key;
|
||||||
|
|
||||||
|
switch (true) {
|
||||||
|
case !!target.closest('[data-change-size]').$el: {
|
||||||
|
const el = target.closest('[data-change-size]');
|
||||||
|
|
||||||
|
if (el.hasClass('disable')) return;
|
||||||
|
|
||||||
|
const currentSize = this.store.getState().currentStyles.fontSize;
|
||||||
|
let idx = fontSizes.findIndex(font => font === currentSize);
|
||||||
|
let nextSize;
|
||||||
|
|
||||||
|
if (el.data.changeSize === 'increase') {
|
||||||
|
nextSize = fontSizes[++idx];
|
||||||
|
} else if (el.data.changeSize === 'decrease') {
|
||||||
|
nextSize = fontSizes[--idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
value = { fontSize: nextSize };
|
||||||
|
key = 'fontSize';
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
stringValue = target?.data?.value;
|
||||||
if (!stringValue) return;
|
if (!stringValue) return;
|
||||||
|
|
||||||
const value = JSON.parse(stringValue);
|
value = JSON.parse(stringValue);
|
||||||
const key = Object.keys(value)[0];
|
key = Object.keys(value)[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.$emitEventToObserver('toolbar:applyStyle', value);
|
this.$emitEventToObserver('toolbar:applyStyle', value);
|
||||||
this.setComponentState({ [key]: value[key] });
|
this.setComponentState({ [key]: value[key] });
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { ToolbarStateType } from 'components/toolbar/toolbar-types';
|
import { ToolbarStateType } from 'components/toolbar/toolbar-types';
|
||||||
import { initialStyleState } from 'src/constants';
|
import { isLargestFontSize, isSmallestFontSize } from 'core/utils';
|
||||||
|
import { fontFamilies, fontSizes, initialStyleState } from 'src/constants';
|
||||||
|
|
||||||
type ButtonConfigType = {
|
type ButtonConfigType = {
|
||||||
icon: string;
|
icon: string;
|
||||||
@ -80,22 +81,39 @@ 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) ? createButtonsFromConfigGroup(btn) : createButtonFromConfig(btn)));
|
||||||
|
|
||||||
const selectGroup = createGroup(createFontSizeButton(state.fontSize), createFontFamilyButton(state.fontFamily));
|
const selectGroup = createGroup(createFontSizeButton(state.fontSize), createFontFamilyButton(state.fontFamily));
|
||||||
|
const increaseDecreaseFontSize = createSizeUpDownButtons(state.fontSize);
|
||||||
|
|
||||||
|
buttons.push(increaseDecreaseFontSize);
|
||||||
buttons.push(selectGroup);
|
buttons.push(selectGroup);
|
||||||
|
|
||||||
return buttons.join('');
|
return buttons.join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
function createFontSizeButton(currentSize = initialStyleState.fontSize) {
|
function createSizeUpDownButtons(currentSize = initialStyleState.fontSize) {
|
||||||
const fontSizeInPixels = +currentSize.slice(0, -2);
|
const buttons = ['increase', 'decrease'];
|
||||||
const options = [];
|
|
||||||
|
|
||||||
for (let i = 8; i <= 24; i += 2) {
|
return buttons.map(btn => {
|
||||||
if (fontSizeInPixels === i) options.push(`<option value="${i}" selected>${i}</option>`);
|
const disable = btn === 'increase' ? isLargestFontSize(currentSize) : isSmallestFontSize(currentSize);
|
||||||
else options.push(`<option value="${i}">${i}</option>`);
|
return `
|
||||||
|
<div class="button${disable ? ' disable' : ''}" data-change-size="${btn}">
|
||||||
|
<i class="material-icons">text_${btn}</i>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}).join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createFontSizeButton(currentSize = initialStyleState.fontSize) {
|
||||||
|
const options = fontSizes.map(size => {
|
||||||
|
// remove 'px' part
|
||||||
|
const sizeValue = size.slice(0, -2);
|
||||||
|
return size === currentSize
|
||||||
|
? `<option value="${sizeValue}" selected>${sizeValue}</option>`
|
||||||
|
: `<option value="${sizeValue}">${sizeValue}</option>`;
|
||||||
|
});
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="button">
|
<div class="button">
|
||||||
<select class="button__size" id="button-size">
|
<select class="button__size" id="button-size">
|
||||||
@ -106,12 +124,11 @@ function createFontSizeButton(currentSize = initialStyleState.fontSize) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function createFontFamilyButton(font = initialStyleState.fontFamily) {
|
function createFontFamilyButton(font = initialStyleState.fontFamily) {
|
||||||
const fonts = ['Roboto', 'Cormorant SC', 'Kanit', 'Playfair Display'];
|
const options = fontFamilies.map(fontName => createFontFamilyOption(fontName, fontName === font));
|
||||||
const options = fonts.map(fontName => createFontFamilyOption(fontName, fontName === font));
|
|
||||||
|
|
||||||
function createFontFamilyOption(name: string, selected: boolean) {
|
function createFontFamilyOption(name: string, selected: boolean) {
|
||||||
return selected
|
return selected
|
||||||
? `<option value="${name}" selected style="font-family: ${name}">${name}</option>`
|
? `<option value="${name}" style="font-family: ${name}" selected >${name}</option>`
|
||||||
: `<option value="${name}" style="font-family: ${name}">${name}</option>`;
|
: `<option value="${name}" style="font-family: ${name}">${name}</option>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,22 +149,22 @@ function createGroup(...btns: string[]) {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function toButtonGroup(buttons: ButtonConfigType[]) {
|
function createButtonsFromConfigGroup(buttons: ButtonConfigType[]) {
|
||||||
if (buttons.length === 1) return toButton(buttons[0]);
|
if (buttons.length === 1) return createButtonFromConfig(buttons[0]);
|
||||||
const btns = buttons.map(btn => toButton(btn));
|
const btns = buttons.map(btn => createButtonFromConfig(btn));
|
||||||
|
|
||||||
return createGroup(...btns);
|
return createGroup(...btns);
|
||||||
}
|
}
|
||||||
|
|
||||||
function toButton(button: ButtonConfigType) {
|
function createButtonFromConfig(btnConfig: ButtonConfigType) {
|
||||||
const meta = `
|
const meta = `
|
||||||
data-type="button"
|
data-type="button"
|
||||||
data-value='${JSON.stringify(button.value)}'
|
data-value='${JSON.stringify(btnConfig.value)}'
|
||||||
`;
|
`;
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="button ${button.isActive ? 'active' : ''}"${meta}>
|
<div class="button ${btnConfig.isActive ? 'active' : ''}"${meta}>
|
||||||
<i class="material-icons" ${meta}>${button.icon}</i>
|
<i class="material-icons" ${meta}>${btnConfig.icon}</i>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,13 +4,27 @@ 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';
|
||||||
|
|
||||||
|
export const fontSizes = [
|
||||||
|
'12px',
|
||||||
|
'14px',
|
||||||
|
'16px',
|
||||||
|
'18px',
|
||||||
|
'20px',
|
||||||
|
'22px',
|
||||||
|
'24px',
|
||||||
|
'26px',
|
||||||
|
'28px',
|
||||||
|
'30px',
|
||||||
|
];
|
||||||
|
export const fontFamilies = ['Roboto', 'Cormorant SC', 'Kanit', 'Playfair Display'];
|
||||||
|
|
||||||
export const initialStyleState: ToolbarStateType = {
|
export const initialStyleState: ToolbarStateType = {
|
||||||
justifyContent: 'start',
|
justifyContent: 'start',
|
||||||
fontWeight: 'normal',
|
fontWeight: 'normal',
|
||||||
textDecoration: 'none',
|
textDecoration: 'none',
|
||||||
fontStyle: 'normal',
|
fontStyle: 'normal',
|
||||||
fontSize: '12px',
|
fontSize: fontSizes[0],
|
||||||
fontFamily: 'Roboto',
|
fontFamily: fontFamilies[0],
|
||||||
alignItems: 'start',
|
alignItems: 'start',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -105,6 +105,10 @@ export class Dom implements DomClass {
|
|||||||
this.$el?.classList.add(className);
|
this.$el?.classList.add(className);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hasClass(className: string) {
|
||||||
|
return Array.from(this.$el.classList).includes(className);
|
||||||
|
}
|
||||||
|
|
||||||
removeClass(className: string) {
|
removeClass(className: string) {
|
||||||
this.$el?.classList.remove(className);
|
this.$el?.classList.remove(className);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import { fontSizes } from 'src/constants';
|
||||||
|
|
||||||
export function capitalize(string: string): string {
|
export function capitalize(string: string): string {
|
||||||
if (!string) return '';
|
if (!string) return '';
|
||||||
|
|
||||||
@ -49,3 +51,13 @@ export function parse(value: string) {
|
|||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isLargestFontSize(fontSize?: string): number | boolean {
|
||||||
|
if (!fontSize) return false;
|
||||||
|
return fontSizes.length - 1 === fontSizes.findIndex(el => el === fontSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isSmallestFontSize(fontSize?: string): number | boolean {
|
||||||
|
if (!fontSize) return false;
|
||||||
|
return fontSizes.findIndex(el => el === fontSize) === 0;
|
||||||
|
}
|
||||||
|
|||||||
@ -16,6 +16,10 @@
|
|||||||
@include button(green)
|
@include button(green)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.button.disable {
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
.button__group {
|
.button__group {
|
||||||
border-right: 1px solid #c0c0c0;
|
border-right: 1px solid #c0c0c0;
|
||||||
&:last-child {
|
&:last-child {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user