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",
|
||||
"linebreak-style": "off",
|
||||
"max-len": "off",
|
||||
"no-console": "off",
|
||||
"no-new": "off",
|
||||
"no-continue": "off",
|
||||
"no-plusplus": "off",
|
||||
"object-curly-newline": "off",
|
||||
"no-alert": "off",
|
||||
"no-console": "off",
|
||||
"no-continue": "off",
|
||||
"no-new": "off",
|
||||
"no-plusplus": "off",
|
||||
"no-restricted-globals": "off",
|
||||
"object-curly-newline": "off",
|
||||
"prefer-destructuring": "off",
|
||||
},
|
||||
env: {
|
||||
browser: true,
|
||||
|
||||
@ -3,7 +3,7 @@ import { $, Dom } from 'core/Dom';
|
||||
import { ExcelComponentState } from 'core/ExcelComponentState';
|
||||
import { ComponentOptionsType } from 'core/ExcelComponent';
|
||||
import { createToolbar } from 'components/toolbar/toolbar.template';
|
||||
import { initialStyleState } from 'src/constants';
|
||||
import { fontSizes, initialStyleState } from 'src/constants';
|
||||
|
||||
export class Toolbar extends ExcelComponentState {
|
||||
static className = 'excel__toolbar';
|
||||
@ -44,11 +44,41 @@ export class Toolbar extends ExcelComponentState {
|
||||
|
||||
onClick(event: MouseEvent) {
|
||||
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;
|
||||
|
||||
const value = JSON.parse(stringValue);
|
||||
const key = Object.keys(value)[0];
|
||||
value = JSON.parse(stringValue);
|
||||
key = Object.keys(value)[0];
|
||||
}
|
||||
}
|
||||
|
||||
this.$emitEventToObserver('toolbar:applyStyle', value);
|
||||
this.setComponentState({ [key]: value[key] });
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
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 = {
|
||||
icon: string;
|
||||
@ -80,21 +81,38 @@ 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 increaseDecreaseFontSize = createSizeUpDownButtons(state.fontSize);
|
||||
|
||||
buttons.push(increaseDecreaseFontSize);
|
||||
buttons.push(selectGroup);
|
||||
return buttons.join(' ');
|
||||
|
||||
return buttons.join('');
|
||||
}
|
||||
|
||||
function createSizeUpDownButtons(currentSize = initialStyleState.fontSize) {
|
||||
const buttons = ['increase', 'decrease'];
|
||||
|
||||
return buttons.map(btn => {
|
||||
const disable = btn === 'increase' ? isLargestFontSize(currentSize) : isSmallestFontSize(currentSize);
|
||||
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 fontSizeInPixels = +currentSize.slice(0, -2);
|
||||
const options = [];
|
||||
|
||||
for (let i = 8; i <= 24; i += 2) {
|
||||
if (fontSizeInPixels === i) options.push(`<option value="${i}" selected>${i}</option>`);
|
||||
else options.push(`<option value="${i}">${i}</option>`);
|
||||
}
|
||||
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 `
|
||||
<div class="button">
|
||||
@ -106,12 +124,11 @@ function createFontSizeButton(currentSize = initialStyleState.fontSize) {
|
||||
}
|
||||
|
||||
function createFontFamilyButton(font = initialStyleState.fontFamily) {
|
||||
const fonts = ['Roboto', 'Cormorant SC', 'Kanit', 'Playfair Display'];
|
||||
const options = fonts.map(fontName => createFontFamilyOption(fontName, fontName === font));
|
||||
const options = fontFamilies.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}" selected >${name}</option>`
|
||||
: `<option value="${name}" style="font-family: ${name}">${name}</option>`;
|
||||
}
|
||||
|
||||
@ -132,22 +149,22 @@ function createGroup(...btns: string[]) {
|
||||
`;
|
||||
}
|
||||
|
||||
function toButtonGroup(buttons: ButtonConfigType[]) {
|
||||
if (buttons.length === 1) return toButton(buttons[0]);
|
||||
const btns = buttons.map(btn => toButton(btn));
|
||||
function createButtonsFromConfigGroup(buttons: ButtonConfigType[]) {
|
||||
if (buttons.length === 1) return createButtonFromConfig(buttons[0]);
|
||||
const btns = buttons.map(btn => createButtonFromConfig(btn));
|
||||
|
||||
return createGroup(...btns);
|
||||
}
|
||||
|
||||
function toButton(button: ButtonConfigType) {
|
||||
function createButtonFromConfig(btnConfig: ButtonConfigType) {
|
||||
const meta = `
|
||||
data-type="button"
|
||||
data-value='${JSON.stringify(button.value)}'
|
||||
data-value='${JSON.stringify(btnConfig.value)}'
|
||||
`;
|
||||
|
||||
return `
|
||||
<div class="button ${button.isActive ? 'active' : ''}"${meta}>
|
||||
<i class="material-icons" ${meta}>${button.icon}</i>
|
||||
<div class="button ${btnConfig.isActive ? 'active' : ''}"${meta}>
|
||||
<i class="material-icons" ${meta}>${btnConfig.icon}</i>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
@ -4,13 +4,27 @@ import { storageName } from 'pages/ExcelPage';
|
||||
import { StateType } from 'redux/types';
|
||||
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 = {
|
||||
justifyContent: 'start',
|
||||
fontWeight: 'normal',
|
||||
textDecoration: 'none',
|
||||
fontStyle: 'normal',
|
||||
fontSize: '12px',
|
||||
fontFamily: 'Roboto',
|
||||
fontSize: fontSizes[0],
|
||||
fontFamily: fontFamilies[0],
|
||||
alignItems: 'start',
|
||||
};
|
||||
|
||||
|
||||
@ -105,6 +105,10 @@ export class Dom implements DomClass {
|
||||
this.$el?.classList.add(className);
|
||||
}
|
||||
|
||||
hasClass(className: string) {
|
||||
return Array.from(this.$el.classList).includes(className);
|
||||
}
|
||||
|
||||
removeClass(className: string) {
|
||||
this.$el?.classList.remove(className);
|
||||
}
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import { fontSizes } from 'src/constants';
|
||||
|
||||
export function capitalize(string: string): string {
|
||||
if (!string) return '';
|
||||
|
||||
@ -49,3 +51,13 @@ export function parse(value: string) {
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
.button.disable {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.button__group {
|
||||
border-right: 1px solid #c0c0c0;
|
||||
&:last-child {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user