FIX: [App]: Borders done right
This commit is contained in:
committed by
Nicolás Hatcher Andrés
parent
494a315cbd
commit
2c2228c2c2
@@ -51,6 +51,84 @@ fn borders_all() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// let's check the borders around
|
||||||
|
{
|
||||||
|
let row = 4;
|
||||||
|
for column in 6..9 {
|
||||||
|
let style = model.get_cell_style(0, row, column).unwrap();
|
||||||
|
let border_item = BorderItem {
|
||||||
|
style: BorderStyle::Thin,
|
||||||
|
color: Some("#FF5566".to_string()),
|
||||||
|
};
|
||||||
|
let expected_border = Border {
|
||||||
|
diagonal_up: false,
|
||||||
|
diagonal_down: false,
|
||||||
|
left: None,
|
||||||
|
right: None,
|
||||||
|
top: None,
|
||||||
|
bottom: Some(border_item.clone()),
|
||||||
|
diagonal: None,
|
||||||
|
};
|
||||||
|
assert_eq!(style.border, expected_border);
|
||||||
|
}
|
||||||
|
let row = 9;
|
||||||
|
for column in 6..9 {
|
||||||
|
let style = model.get_cell_style(0, row, column).unwrap();
|
||||||
|
let border_item = BorderItem {
|
||||||
|
style: BorderStyle::Thin,
|
||||||
|
color: Some("#FF5566".to_string()),
|
||||||
|
};
|
||||||
|
let expected_border = Border {
|
||||||
|
diagonal_up: false,
|
||||||
|
diagonal_down: false,
|
||||||
|
left: None,
|
||||||
|
right: None,
|
||||||
|
top: Some(border_item.clone()),
|
||||||
|
bottom: None,
|
||||||
|
diagonal: None,
|
||||||
|
};
|
||||||
|
assert_eq!(style.border, expected_border);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let column = 5;
|
||||||
|
for row in 5..9 {
|
||||||
|
let style = model.get_cell_style(0, row, column).unwrap();
|
||||||
|
let border_item = BorderItem {
|
||||||
|
style: BorderStyle::Thin,
|
||||||
|
color: Some("#FF5566".to_string()),
|
||||||
|
};
|
||||||
|
let expected_border = Border {
|
||||||
|
diagonal_up: false,
|
||||||
|
diagonal_down: false,
|
||||||
|
left: None,
|
||||||
|
right: Some(border_item.clone()),
|
||||||
|
top: None,
|
||||||
|
bottom: None,
|
||||||
|
diagonal: None,
|
||||||
|
};
|
||||||
|
assert_eq!(style.border, expected_border);
|
||||||
|
}
|
||||||
|
let column = 9;
|
||||||
|
for row in 5..9 {
|
||||||
|
let style = model.get_cell_style(0, row, column).unwrap();
|
||||||
|
let border_item = BorderItem {
|
||||||
|
style: BorderStyle::Thin,
|
||||||
|
color: Some("#FF5566".to_string()),
|
||||||
|
};
|
||||||
|
let expected_border = Border {
|
||||||
|
diagonal_up: false,
|
||||||
|
diagonal_down: false,
|
||||||
|
left: Some(border_item.clone()),
|
||||||
|
right: None,
|
||||||
|
top: None,
|
||||||
|
bottom: None,
|
||||||
|
diagonal: None,
|
||||||
|
};
|
||||||
|
assert_eq!(style.border, expected_border);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Lets remove all of them:
|
// Lets remove all of them:
|
||||||
let border_area: BorderArea = serde_json::from_str(
|
let border_area: BorderArea = serde_json::from_str(
|
||||||
r##"{
|
r##"{
|
||||||
@@ -63,8 +141,8 @@ fn borders_all() {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
model.set_area_with_border(range, &border_area).unwrap();
|
model.set_area_with_border(range, &border_area).unwrap();
|
||||||
for row in 5..9 {
|
for row in 4..10 {
|
||||||
for column in 6..9 {
|
for column in 5..10 {
|
||||||
let style = model.get_cell_style(0, row, column).unwrap();
|
let style = model.get_cell_style(0, row, column).unwrap();
|
||||||
let expected_border = Border {
|
let expected_border = Border {
|
||||||
diagonal_up: false,
|
diagonal_up: false,
|
||||||
@@ -229,6 +307,84 @@ fn borders_outer() {
|
|||||||
};
|
};
|
||||||
assert_eq!(style.border, expected_border);
|
assert_eq!(style.border, expected_border);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// let's check the borders around
|
||||||
|
{
|
||||||
|
let row = 4;
|
||||||
|
for column in 6..9 {
|
||||||
|
let style = model.get_cell_style(0, row, column).unwrap();
|
||||||
|
let border_item = BorderItem {
|
||||||
|
style: BorderStyle::Thin,
|
||||||
|
color: Some("#FF5566".to_string()),
|
||||||
|
};
|
||||||
|
let expected_border = Border {
|
||||||
|
diagonal_up: false,
|
||||||
|
diagonal_down: false,
|
||||||
|
left: None,
|
||||||
|
right: None,
|
||||||
|
top: None,
|
||||||
|
bottom: Some(border_item.clone()),
|
||||||
|
diagonal: None,
|
||||||
|
};
|
||||||
|
assert_eq!(style.border, expected_border);
|
||||||
|
}
|
||||||
|
let row = 9;
|
||||||
|
for column in 6..9 {
|
||||||
|
let style = model.get_cell_style(0, row, column).unwrap();
|
||||||
|
let border_item = BorderItem {
|
||||||
|
style: BorderStyle::Thin,
|
||||||
|
color: Some("#FF5566".to_string()),
|
||||||
|
};
|
||||||
|
let expected_border = Border {
|
||||||
|
diagonal_up: false,
|
||||||
|
diagonal_down: false,
|
||||||
|
left: None,
|
||||||
|
right: None,
|
||||||
|
top: Some(border_item.clone()),
|
||||||
|
bottom: None,
|
||||||
|
diagonal: None,
|
||||||
|
};
|
||||||
|
assert_eq!(style.border, expected_border);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let column = 5;
|
||||||
|
for row in 5..9 {
|
||||||
|
let style = model.get_cell_style(0, row, column).unwrap();
|
||||||
|
let border_item = BorderItem {
|
||||||
|
style: BorderStyle::Thin,
|
||||||
|
color: Some("#FF5566".to_string()),
|
||||||
|
};
|
||||||
|
let expected_border = Border {
|
||||||
|
diagonal_up: false,
|
||||||
|
diagonal_down: false,
|
||||||
|
left: None,
|
||||||
|
right: Some(border_item.clone()),
|
||||||
|
top: None,
|
||||||
|
bottom: None,
|
||||||
|
diagonal: None,
|
||||||
|
};
|
||||||
|
assert_eq!(style.border, expected_border);
|
||||||
|
}
|
||||||
|
let column = 9;
|
||||||
|
for row in 5..9 {
|
||||||
|
let style = model.get_cell_style(0, row, column).unwrap();
|
||||||
|
let border_item = BorderItem {
|
||||||
|
style: BorderStyle::Thin,
|
||||||
|
color: Some("#FF5566".to_string()),
|
||||||
|
};
|
||||||
|
let expected_border = Border {
|
||||||
|
diagonal_up: false,
|
||||||
|
diagonal_down: false,
|
||||||
|
left: Some(border_item.clone()),
|
||||||
|
right: None,
|
||||||
|
top: None,
|
||||||
|
bottom: None,
|
||||||
|
diagonal: None,
|
||||||
|
};
|
||||||
|
assert_eq!(style.border, expected_border);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -275,6 +431,72 @@ fn borders_top() {
|
|||||||
assert_eq!(style.border, expected_border);
|
assert_eq!(style.border, expected_border);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// let's check the borders around
|
||||||
|
{
|
||||||
|
let row = 4;
|
||||||
|
for column in 6..9 {
|
||||||
|
let style = model.get_cell_style(0, row, column).unwrap();
|
||||||
|
let border_item = BorderItem {
|
||||||
|
style: BorderStyle::Thin,
|
||||||
|
color: Some("#FF5566".to_string()),
|
||||||
|
};
|
||||||
|
let expected_border = Border {
|
||||||
|
diagonal_up: false,
|
||||||
|
diagonal_down: false,
|
||||||
|
left: None,
|
||||||
|
right: None,
|
||||||
|
top: None,
|
||||||
|
bottom: Some(border_item.clone()),
|
||||||
|
diagonal: None,
|
||||||
|
};
|
||||||
|
assert_eq!(style.border, expected_border);
|
||||||
|
}
|
||||||
|
let row = 9;
|
||||||
|
for column in 6..9 {
|
||||||
|
let style = model.get_cell_style(0, row, column).unwrap();
|
||||||
|
let expected_border = Border {
|
||||||
|
diagonal_up: false,
|
||||||
|
diagonal_down: false,
|
||||||
|
left: None,
|
||||||
|
right: None,
|
||||||
|
top: None,
|
||||||
|
bottom: None,
|
||||||
|
diagonal: None,
|
||||||
|
};
|
||||||
|
assert_eq!(style.border, expected_border);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let column = 5;
|
||||||
|
for row in 5..9 {
|
||||||
|
let style = model.get_cell_style(0, row, column).unwrap();
|
||||||
|
let expected_border = Border {
|
||||||
|
diagonal_up: false,
|
||||||
|
diagonal_down: false,
|
||||||
|
left: None,
|
||||||
|
right: None,
|
||||||
|
top: None,
|
||||||
|
bottom: None,
|
||||||
|
diagonal: None,
|
||||||
|
};
|
||||||
|
assert_eq!(style.border, expected_border);
|
||||||
|
}
|
||||||
|
let column = 9;
|
||||||
|
for row in 5..9 {
|
||||||
|
let style = model.get_cell_style(0, row, column).unwrap();
|
||||||
|
let expected_border = Border {
|
||||||
|
diagonal_up: false,
|
||||||
|
diagonal_down: false,
|
||||||
|
left: None,
|
||||||
|
right: None,
|
||||||
|
top: None,
|
||||||
|
bottom: None,
|
||||||
|
diagonal: None,
|
||||||
|
};
|
||||||
|
assert_eq!(style.border, expected_border);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@@ -48,6 +48,54 @@ fn tsv_crlf_paste() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn cut_paste() {
|
||||||
|
let mut model = UserModel::new_empty("model", "en", "UTC").unwrap();
|
||||||
|
model.set_user_input(0, 1, 1, "42").unwrap();
|
||||||
|
model.set_user_input(0, 1, 2, "=A1*3+1").unwrap();
|
||||||
|
|
||||||
|
// set A1 bold
|
||||||
|
let range = Area {
|
||||||
|
sheet: 0,
|
||||||
|
row: 1,
|
||||||
|
column: 1,
|
||||||
|
width: 1,
|
||||||
|
height: 1,
|
||||||
|
};
|
||||||
|
model.update_range_style(&range, "font.b", "true").unwrap();
|
||||||
|
|
||||||
|
model
|
||||||
|
.set_user_input(0, 2, 1, "A season of faith, \"perfection\"")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// Select A1:B2 and copy
|
||||||
|
model.set_selected_range(1, 1, 2, 2).unwrap();
|
||||||
|
let copy = model.copy_to_clipboard().unwrap();
|
||||||
|
|
||||||
|
model.set_selected_cell(4, 4).unwrap();
|
||||||
|
|
||||||
|
// paste in cell D4 (4, 4)
|
||||||
|
model
|
||||||
|
.paste_from_clipboard((1, 1, 2, 2), ©.data, true)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(model.get_cell_content(0, 4, 4), Ok("42".to_string()));
|
||||||
|
assert_eq!(model.get_cell_content(0, 4, 5), Ok("=D4*3+1".to_string()));
|
||||||
|
assert_eq!(
|
||||||
|
model.get_formatted_cell_value(0, 4, 5),
|
||||||
|
Ok("127".to_string())
|
||||||
|
);
|
||||||
|
// cell D4 must be bold
|
||||||
|
let style_d4 = model.get_cell_style(0, 4, 4).unwrap();
|
||||||
|
assert!(style_d4.font.b);
|
||||||
|
|
||||||
|
// range A1:B2 must be empty
|
||||||
|
assert_eq!(model.get_cell_content(0, 1, 1), Ok("".to_string()));
|
||||||
|
assert_eq!(model.get_cell_content(0, 1, 2), Ok("".to_string()));
|
||||||
|
assert_eq!(model.get_cell_content(0, 2, 1), Ok("".to_string()));
|
||||||
|
assert_eq!(model.get_cell_content(0, 2, 2), Ok("".to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn copy_paste_internal() {
|
fn copy_paste_internal() {
|
||||||
let mut model = UserModel::new_empty("model", "en", "UTC").unwrap();
|
let mut model = UserModel::new_empty("model", "en", "UTC").unwrap();
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use csv_sniffer::Sniffer;
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
constants::{self, DEFAULT_ROW_HEIGHT},
|
constants::{self, DEFAULT_ROW_HEIGHT, LAST_COLUMN, LAST_ROW},
|
||||||
expressions::{
|
expressions::{
|
||||||
types::{Area, CellReferenceIndex},
|
types::{Area, CellReferenceIndex},
|
||||||
utils::{is_valid_column_number, is_valid_row},
|
utils::{is_valid_column_number, is_valid_row},
|
||||||
@@ -41,7 +41,7 @@ pub struct Clipboard {
|
|||||||
pub(crate) range: (i32, i32, i32, i32),
|
pub(crate) range: (i32, i32, i32, i32),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize, PartialEq)]
|
||||||
pub enum BorderType {
|
pub enum BorderType {
|
||||||
All,
|
All,
|
||||||
Inner,
|
Inner,
|
||||||
@@ -796,7 +796,6 @@ impl UserModel {
|
|||||||
range: &Area,
|
range: &Area,
|
||||||
border_area: &BorderArea,
|
border_area: &BorderArea,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
// FIXME: We need to set the border also in neighbouring cells.
|
|
||||||
let sheet = range.sheet;
|
let sheet = range.sheet;
|
||||||
let mut diff_list = Vec::new();
|
let mut diff_list = Vec::new();
|
||||||
let last_row = range.row + range.height - 1;
|
let last_row = range.row + range.height - 1;
|
||||||
@@ -806,12 +805,6 @@ impl UserModel {
|
|||||||
let old_value = self.model.get_style_for_cell(sheet, row, column)?;
|
let old_value = self.model.get_style_for_cell(sheet, row, column)?;
|
||||||
let mut style = old_value.clone();
|
let mut style = old_value.clone();
|
||||||
|
|
||||||
// First remove all existing borders
|
|
||||||
style.border.top = None;
|
|
||||||
style.border.right = None;
|
|
||||||
style.border.bottom = None;
|
|
||||||
style.border.left = None;
|
|
||||||
|
|
||||||
match border_area.r#type {
|
match border_area.r#type {
|
||||||
BorderType::All => {
|
BorderType::All => {
|
||||||
style.border.top = Some(border_area.item.clone());
|
style.border.top = Some(border_area.item.clone());
|
||||||
@@ -868,7 +861,10 @@ impl UserModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
BorderType::None => {
|
BorderType::None => {
|
||||||
// noop, we already removed all the borders
|
style.border.top = None;
|
||||||
|
style.border.right = None;
|
||||||
|
style.border.bottom = None;
|
||||||
|
style.border.left = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -882,6 +878,122 @@ impl UserModel {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// bottom of the cells above the first
|
||||||
|
if range.row > 1
|
||||||
|
&& [
|
||||||
|
BorderType::Top,
|
||||||
|
BorderType::All,
|
||||||
|
BorderType::None,
|
||||||
|
BorderType::Outer,
|
||||||
|
]
|
||||||
|
.contains(&border_area.r#type)
|
||||||
|
{
|
||||||
|
let row = range.row - 1;
|
||||||
|
for column in range.column..=last_column {
|
||||||
|
let old_value = self.model.get_style_for_cell(sheet, row, column)?;
|
||||||
|
let mut style = old_value.clone();
|
||||||
|
if border_area.r#type == BorderType::None {
|
||||||
|
style.border.bottom = None;
|
||||||
|
} else {
|
||||||
|
style.border.bottom = Some(border_area.item.clone());
|
||||||
|
}
|
||||||
|
self.model.set_cell_style(sheet, row, column, &style)?;
|
||||||
|
diff_list.push(Diff::SetCellStyle {
|
||||||
|
sheet,
|
||||||
|
row,
|
||||||
|
column,
|
||||||
|
old_value: Box::new(old_value),
|
||||||
|
new_value: Box::new(style),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Cells to the right
|
||||||
|
if last_column < LAST_COLUMN
|
||||||
|
&& [
|
||||||
|
BorderType::Right,
|
||||||
|
BorderType::All,
|
||||||
|
BorderType::None,
|
||||||
|
BorderType::Outer,
|
||||||
|
]
|
||||||
|
.contains(&border_area.r#type)
|
||||||
|
{
|
||||||
|
let column = last_column + 1;
|
||||||
|
for row in range.row..=last_row {
|
||||||
|
let old_value = self.model.get_style_for_cell(sheet, row, column)?;
|
||||||
|
let mut style = old_value.clone();
|
||||||
|
if border_area.r#type == BorderType::None {
|
||||||
|
style.border.left = None;
|
||||||
|
} else {
|
||||||
|
style.border.left = Some(border_area.item.clone());
|
||||||
|
}
|
||||||
|
self.model.set_cell_style(sheet, row, column, &style)?;
|
||||||
|
diff_list.push(Diff::SetCellStyle {
|
||||||
|
sheet,
|
||||||
|
row,
|
||||||
|
column,
|
||||||
|
old_value: Box::new(old_value),
|
||||||
|
new_value: Box::new(style),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Cells bellow
|
||||||
|
if last_row < LAST_ROW
|
||||||
|
&& [
|
||||||
|
BorderType::Bottom,
|
||||||
|
BorderType::All,
|
||||||
|
BorderType::None,
|
||||||
|
BorderType::Outer,
|
||||||
|
]
|
||||||
|
.contains(&border_area.r#type)
|
||||||
|
{
|
||||||
|
let row = last_row + 1;
|
||||||
|
for column in range.column..=last_column {
|
||||||
|
let old_value = self.model.get_style_for_cell(sheet, row, column)?;
|
||||||
|
let mut style = old_value.clone();
|
||||||
|
if border_area.r#type == BorderType::None {
|
||||||
|
style.border.top = None;
|
||||||
|
} else {
|
||||||
|
style.border.top = Some(border_area.item.clone());
|
||||||
|
}
|
||||||
|
self.model.set_cell_style(sheet, row, column, &style)?;
|
||||||
|
diff_list.push(Diff::SetCellStyle {
|
||||||
|
sheet,
|
||||||
|
row,
|
||||||
|
column,
|
||||||
|
old_value: Box::new(old_value),
|
||||||
|
new_value: Box::new(style),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Cells to the left
|
||||||
|
if range.column > 1
|
||||||
|
&& [
|
||||||
|
BorderType::Left,
|
||||||
|
BorderType::All,
|
||||||
|
BorderType::None,
|
||||||
|
BorderType::Outer,
|
||||||
|
]
|
||||||
|
.contains(&border_area.r#type)
|
||||||
|
{
|
||||||
|
let column = range.column - 1;
|
||||||
|
for row in range.row..=last_row {
|
||||||
|
let old_value = self.model.get_style_for_cell(sheet, row, column)?;
|
||||||
|
let mut style = old_value.clone();
|
||||||
|
if border_area.r#type == BorderType::None {
|
||||||
|
style.border.right = None;
|
||||||
|
} else {
|
||||||
|
style.border.right = Some(border_area.item.clone());
|
||||||
|
}
|
||||||
|
self.model.set_cell_style(sheet, row, column, &style)?;
|
||||||
|
diff_list.push(Diff::SetCellStyle {
|
||||||
|
sheet,
|
||||||
|
row,
|
||||||
|
column,
|
||||||
|
old_value: Box::new(old_value),
|
||||||
|
new_value: Box::new(style),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.push_diff_list(diff_list);
|
self.push_diff_list(diff_list);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
PencilLine,
|
PencilLine,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import type React from "react";
|
import type React from "react";
|
||||||
import { useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import {
|
import {
|
||||||
BorderBottomIcon,
|
BorderBottomIcon,
|
||||||
@@ -27,6 +27,7 @@ import ColorPicker from "./colorPicker";
|
|||||||
type BorderPickerProps = {
|
type BorderPickerProps = {
|
||||||
className?: string;
|
className?: string;
|
||||||
onChange: (border: BorderOptions) => void;
|
onChange: (border: BorderOptions) => void;
|
||||||
|
onClose: () => void;
|
||||||
anchorEl: React.RefObject<HTMLElement>;
|
anchorEl: React.RefObject<HTMLElement>;
|
||||||
anchorOrigin?: PopoverOrigin;
|
anchorOrigin?: PopoverOrigin;
|
||||||
transformOrigin?: PopoverOrigin;
|
transformOrigin?: PopoverOrigin;
|
||||||
@@ -36,25 +37,33 @@ type BorderPickerProps = {
|
|||||||
const BorderPicker = (properties: BorderPickerProps) => {
|
const BorderPicker = (properties: BorderPickerProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const [borderSelected, setBorderSelected] = useState(BorderType.None);
|
const [borderSelected, setBorderSelected] = useState<BorderType | null>(null);
|
||||||
const [borderColor, setBorderColor] = useState("#000000");
|
const [borderColor, setBorderColor] = useState("#000000");
|
||||||
const [borderStyle, setBorderStyle] = useState(BorderStyle.Thin);
|
const [borderStyle, setBorderStyle] = useState(BorderStyle.Thin);
|
||||||
const [colorPickerOpen, setColorPickerOpen] = useState(false);
|
const [colorPickerOpen, setColorPickerOpen] = useState(false);
|
||||||
const [stylePickerOpen, setStylePickerOpen] = useState(false);
|
const [stylePickerOpen, setStylePickerOpen] = useState(false);
|
||||||
const closePicker = (): void => {
|
|
||||||
|
// biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
|
||||||
|
useEffect(() => {
|
||||||
|
if (!borderSelected) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
properties.onChange({
|
properties.onChange({
|
||||||
color: borderColor,
|
color: borderColor,
|
||||||
style: borderStyle,
|
style: borderStyle,
|
||||||
border: borderSelected,
|
border: borderSelected,
|
||||||
});
|
});
|
||||||
};
|
}, [borderColor, borderStyle, borderSelected]);
|
||||||
|
|
||||||
|
const onClose = properties.onClose;
|
||||||
|
|
||||||
const borderColorButton = useRef(null);
|
const borderColorButton = useRef(null);
|
||||||
const borderStyleButton = useRef(null);
|
const borderStyleButton = useRef(null);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<StyledPopover
|
<StyledPopover
|
||||||
open={properties.open}
|
open={properties.open}
|
||||||
onClose={(): void => closePicker()}
|
onClose={onClose}
|
||||||
anchorEl={properties.anchorEl.current}
|
anchorEl={properties.anchorEl.current}
|
||||||
anchorOrigin={
|
anchorOrigin={
|
||||||
properties.anchorOrigin || { vertical: "bottom", horizontal: "left" }
|
properties.anchorOrigin || { vertical: "bottom", horizontal: "left" }
|
||||||
@@ -71,13 +80,13 @@ const BorderPicker = (properties: BorderPickerProps) => {
|
|||||||
$pressed={borderSelected === BorderType.All}
|
$pressed={borderSelected === BorderType.All}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (borderSelected === BorderType.All) {
|
if (borderSelected === BorderType.All) {
|
||||||
setBorderSelected(BorderType.None);
|
setBorderSelected(null);
|
||||||
} else {
|
} else {
|
||||||
setBorderSelected(BorderType.All);
|
setBorderSelected(BorderType.All);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
disabled={false}
|
disabled={false}
|
||||||
title={t("workbook.toolbar.borders_button_title")}
|
title={t("toolbar.borders.all")}
|
||||||
>
|
>
|
||||||
<BorderAllIcon />
|
<BorderAllIcon />
|
||||||
</Button>
|
</Button>
|
||||||
@@ -86,13 +95,13 @@ const BorderPicker = (properties: BorderPickerProps) => {
|
|||||||
$pressed={borderSelected === BorderType.Inner}
|
$pressed={borderSelected === BorderType.Inner}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (borderSelected === BorderType.Inner) {
|
if (borderSelected === BorderType.Inner) {
|
||||||
setBorderSelected(BorderType.None);
|
setBorderSelected(null);
|
||||||
} else {
|
} else {
|
||||||
setBorderSelected(BorderType.Inner);
|
setBorderSelected(BorderType.Inner);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
disabled={false}
|
disabled={false}
|
||||||
title={t("workbook.toolbar.borders_button_title")}
|
title={t("toolbar.borders.inner")}
|
||||||
>
|
>
|
||||||
<BorderInnerIcon />
|
<BorderInnerIcon />
|
||||||
</Button>
|
</Button>
|
||||||
@@ -101,13 +110,13 @@ const BorderPicker = (properties: BorderPickerProps) => {
|
|||||||
$pressed={borderSelected === BorderType.CenterH}
|
$pressed={borderSelected === BorderType.CenterH}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (borderSelected === BorderType.CenterH) {
|
if (borderSelected === BorderType.CenterH) {
|
||||||
setBorderSelected(BorderType.None);
|
setBorderSelected(null);
|
||||||
} else {
|
} else {
|
||||||
setBorderSelected(BorderType.CenterH);
|
setBorderSelected(BorderType.CenterH);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
disabled={false}
|
disabled={false}
|
||||||
title={t("workbook.toolbar.borders_button_title")}
|
title={t("toolbar.borders.horizontal")}
|
||||||
>
|
>
|
||||||
<BorderCenterHIcon />
|
<BorderCenterHIcon />
|
||||||
</Button>
|
</Button>
|
||||||
@@ -116,13 +125,13 @@ const BorderPicker = (properties: BorderPickerProps) => {
|
|||||||
$pressed={borderSelected === BorderType.CenterV}
|
$pressed={borderSelected === BorderType.CenterV}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (borderSelected === BorderType.CenterV) {
|
if (borderSelected === BorderType.CenterV) {
|
||||||
setBorderSelected(BorderType.None);
|
setBorderSelected(null);
|
||||||
} else {
|
} else {
|
||||||
setBorderSelected(BorderType.CenterV);
|
setBorderSelected(BorderType.CenterV);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
disabled={false}
|
disabled={false}
|
||||||
title={t("workbook.toolbar.borders_button_title")}
|
title={t("toolbar.borders.vertical")}
|
||||||
>
|
>
|
||||||
<BorderCenterVIcon />
|
<BorderCenterVIcon />
|
||||||
</Button>
|
</Button>
|
||||||
@@ -137,7 +146,7 @@ const BorderPicker = (properties: BorderPickerProps) => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
disabled={false}
|
disabled={false}
|
||||||
title={t("workbook.toolbar.borders_button_title")}
|
title={t("toolbar.borders.outer")}
|
||||||
>
|
>
|
||||||
<BorderOuterIcon />
|
<BorderOuterIcon />
|
||||||
</Button>
|
</Button>
|
||||||
@@ -154,7 +163,7 @@ const BorderPicker = (properties: BorderPickerProps) => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
disabled={false}
|
disabled={false}
|
||||||
title={t("workbook.toolbar.borders_button_title")}
|
title={t("toolbar.borders.clear")}
|
||||||
>
|
>
|
||||||
<BorderNoneIcon />
|
<BorderNoneIcon />
|
||||||
</Button>
|
</Button>
|
||||||
@@ -169,7 +178,7 @@ const BorderPicker = (properties: BorderPickerProps) => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
disabled={false}
|
disabled={false}
|
||||||
title={t("workbook.toolbar.borders_button_title")}
|
title={t("toolbar.borders.top")}
|
||||||
>
|
>
|
||||||
<BorderTopIcon />
|
<BorderTopIcon />
|
||||||
</Button>
|
</Button>
|
||||||
@@ -184,7 +193,7 @@ const BorderPicker = (properties: BorderPickerProps) => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
disabled={false}
|
disabled={false}
|
||||||
title={t("workbook.toolbar.borders_button_title")}
|
title={t("toolbar.borders.right")}
|
||||||
>
|
>
|
||||||
<BorderRightIcon />
|
<BorderRightIcon />
|
||||||
</Button>
|
</Button>
|
||||||
@@ -199,7 +208,7 @@ const BorderPicker = (properties: BorderPickerProps) => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
disabled={false}
|
disabled={false}
|
||||||
title={t("workbook.toolbar.borders_button_title")}
|
title={t("toolbar.borders.bottom")}
|
||||||
>
|
>
|
||||||
<BorderBottomIcon />
|
<BorderBottomIcon />
|
||||||
</Button>
|
</Button>
|
||||||
@@ -214,7 +223,7 @@ const BorderPicker = (properties: BorderPickerProps) => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
disabled={false}
|
disabled={false}
|
||||||
title={t("workbook.toolbar.borders_button_title")}
|
title={t("toolbar.borders.left")}
|
||||||
>
|
>
|
||||||
<BorderLeftIcon />
|
<BorderLeftIcon />
|
||||||
</Button>
|
</Button>
|
||||||
@@ -228,7 +237,7 @@ const BorderPicker = (properties: BorderPickerProps) => {
|
|||||||
$pressed={false}
|
$pressed={false}
|
||||||
disabled={false}
|
disabled={false}
|
||||||
ref={borderColorButton}
|
ref={borderColorButton}
|
||||||
title={t("workbook.toolbar.borders_button_title")}
|
title={t("toolbar.borders.color")}
|
||||||
>
|
>
|
||||||
<PencilLine />
|
<PencilLine />
|
||||||
</Button>
|
</Button>
|
||||||
@@ -243,7 +252,7 @@ const BorderPicker = (properties: BorderPickerProps) => {
|
|||||||
type="button"
|
type="button"
|
||||||
$pressed={false}
|
$pressed={false}
|
||||||
disabled={false}
|
disabled={false}
|
||||||
title={t("workbook.toolbar.borders_button_title")}
|
title={t("toolbar.borders.style")}
|
||||||
>
|
>
|
||||||
<BorderStyleIcon />
|
<BorderStyleIcon />
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -325,7 +325,7 @@ function Toolbar(properties: ToolbarProperties) {
|
|||||||
onClick={() => setBorderPickerOpen(true)}
|
onClick={() => setBorderPickerOpen(true)}
|
||||||
ref={borderButton}
|
ref={borderButton}
|
||||||
disabled={!canEdit}
|
disabled={!canEdit}
|
||||||
title={t("toolbar.borders")}
|
title={t("toolbar.borders.title")}
|
||||||
>
|
>
|
||||||
<Grid2X2 />
|
<Grid2X2 />
|
||||||
</StyledButton>
|
</StyledButton>
|
||||||
@@ -369,6 +369,8 @@ function Toolbar(properties: ToolbarProperties) {
|
|||||||
<BorderPicker
|
<BorderPicker
|
||||||
onChange={(border): void => {
|
onChange={(border): void => {
|
||||||
properties.onBorderChanged(border);
|
properties.onBorderChanged(border);
|
||||||
|
}}
|
||||||
|
onClose={() => {
|
||||||
setBorderPickerOpen(false);
|
setBorderPickerOpen(false);
|
||||||
}}
|
}}
|
||||||
anchorEl={borderButton}
|
anchorEl={borderButton}
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
"format_number": "Format number",
|
"format_number": "Format number",
|
||||||
"font_color": "Font color",
|
"font_color": "Font color",
|
||||||
"fill_color": "Fill color",
|
"fill_color": "Fill color",
|
||||||
"borders": "Borders",
|
|
||||||
"decimal_places_increase": "Increase decimal places",
|
"decimal_places_increase": "Increase decimal places",
|
||||||
"decimal_places_decrease": "Decrease decimal places",
|
"decimal_places_decrease": "Decrease decimal places",
|
||||||
"show_hide_grid_lines": "Show/hide grid lines",
|
"show_hide_grid_lines": "Show/hide grid lines",
|
||||||
@@ -39,6 +38,21 @@
|
|||||||
"currency_gbp_example": "£",
|
"currency_gbp_example": "£",
|
||||||
"date_short_example": "09/24/2024",
|
"date_short_example": "09/24/2024",
|
||||||
"date_long_example": "Tuesday, September 24, 2024"
|
"date_long_example": "Tuesday, September 24, 2024"
|
||||||
|
},
|
||||||
|
"borders": {
|
||||||
|
"title": "Borders",
|
||||||
|
"all": "All borders",
|
||||||
|
"inner": "Inner borders",
|
||||||
|
"outer": "Outer borders",
|
||||||
|
"top": "Top borders",
|
||||||
|
"bottom": "Bottom borders",
|
||||||
|
"clear": "Clear borders",
|
||||||
|
"left": "Left borders",
|
||||||
|
"right": "Right borders",
|
||||||
|
"horizontal": "Horizontal borders",
|
||||||
|
"vertical": "Vertical borders",
|
||||||
|
"color": "Border color",
|
||||||
|
"style": "Border style"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"num_fmt": {
|
"num_fmt": {
|
||||||
|
|||||||
Reference in New Issue
Block a user