Merged PR 169: Fix bugs with flex + Disable obnoxious swals + Add selector text + Sort SVG scss to different files
- Disable PushBehavior and set it in a different file - Fix behviors when parent === undefined - Fix flex behavrios when using anchors - Fix siblings not applying flex to theirs children on container delete - Fix flex behavior when using anchors - Enable flex by default - Disable obnoxious swals - Add selector text - Sort SVG scss to different files Others: Add some todos
This commit is contained in:
parent
a718268972
commit
3f58c5ba5e
15 changed files with 208 additions and 134 deletions
|
@ -1,77 +1,12 @@
|
|||
import Swal from 'sweetalert2';
|
||||
import { IContainerModel } from '../../../Interfaces/IContainerModel';
|
||||
import { reversePairwise } from '../../../utils/itertools';
|
||||
import { Simplex } from '../../../utils/simplex';
|
||||
import { ApplyWidthMargin, ApplyXMargin } from '../../../utils/svg';
|
||||
|
||||
/**
|
||||
* Try to push the siblings
|
||||
* @param container
|
||||
* @returns
|
||||
*/
|
||||
export function PushContainers(container: IContainerModel): IContainerModel {
|
||||
if (container.parent === null) {
|
||||
return container;
|
||||
}
|
||||
|
||||
if (container.parent.children.length <= 1) {
|
||||
return container;
|
||||
}
|
||||
|
||||
const prevIndex = container.parent.children.length - 2;
|
||||
const prev: IContainerModel = container.parent.children[prevIndex];
|
||||
const isOverlapping = prev.properties.x + prev.properties.width > container.properties.x;
|
||||
if (!isOverlapping) {
|
||||
return container;
|
||||
}
|
||||
|
||||
// find hole
|
||||
let lastContainer: IContainerModel | null = null;
|
||||
let space: number = 0;
|
||||
|
||||
while (space.toFixed(2) < container.properties.width.toFixed(2)) {
|
||||
// FIXME: possible infinite loop due to floating point
|
||||
// FIXME: A fix was applied using toFixed(2).
|
||||
// FIXME: A coverture check must be done to ensure that all scenarios are covered
|
||||
|
||||
const it = reversePairwise<IContainerModel>(container.parent.children.filter(child => child !== container));
|
||||
|
||||
for (const { cur, next } of it) {
|
||||
const hasSpaceBetween = next.properties.x + next.properties.width < cur.properties.x;
|
||||
if (hasSpaceBetween) {
|
||||
lastContainer = cur;
|
||||
space = cur.properties.x - (next.properties.x + next.properties.width);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (lastContainer === null) {
|
||||
// no space between
|
||||
break;
|
||||
}
|
||||
|
||||
const indexLastContainer = container.parent.children.indexOf(lastContainer);
|
||||
for (let i = indexLastContainer; i <= container.parent.children.length - 2; i++) {
|
||||
const sibling = container.parent.children[i];
|
||||
sibling.properties.x -= space;
|
||||
}
|
||||
}
|
||||
|
||||
const hasNoSpaceBetween = lastContainer === null;
|
||||
if (hasNoSpaceBetween) {
|
||||
// test gap between the left of the parent and the first container
|
||||
space = container.parent.children[0].properties.x;
|
||||
if (space > 0) {
|
||||
for (let i = 0; i <= container.parent.children.length - 2; i++) {
|
||||
const sibling = container.parent.children[i];
|
||||
sibling.properties.x -= space;
|
||||
}
|
||||
return container;
|
||||
}
|
||||
}
|
||||
|
||||
Flex(container);
|
||||
return container;
|
||||
interface IFlexibleGroup {
|
||||
group: IContainerModel[]
|
||||
offset: number
|
||||
size: number
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -83,26 +18,37 @@ export function Flex(container: IContainerModel): void {
|
|||
if (container.parent === null || container.parent === undefined) {
|
||||
return;
|
||||
}
|
||||
const flexibleContainers = container.parent.children
|
||||
|
||||
const flexibleGroups = GetFlexibleGroups(container.parent);
|
||||
|
||||
for (const flexibleGroup of flexibleGroups) {
|
||||
FlexGroup(flexibleGroup);
|
||||
}
|
||||
}
|
||||
|
||||
function FlexGroup(flexibleGroup: IFlexibleGroup): void {
|
||||
const children = flexibleGroup.group;
|
||||
const flexibleContainers = children
|
||||
.filter(sibling => sibling.properties.isFlex);
|
||||
|
||||
const minWidths = flexibleContainers
|
||||
.map(sibling => sibling.properties.minWidth);
|
||||
|
||||
const fixedWidth = container.parent.children
|
||||
const fixedWidth = children
|
||||
.filter(sibling => !sibling.properties.isFlex)
|
||||
.map(sibling => sibling.properties.width)
|
||||
.reduce((partialSum, a) => partialSum + a, 0);
|
||||
|
||||
const requiredMaxWidth = container.parent.properties.width - fixedWidth;
|
||||
const requiredMaxWidth = flexibleGroup.size - fixedWidth;
|
||||
|
||||
const minimumPossibleWidth = minWidths.reduce((partialSum, a) => partialSum + a, 0);
|
||||
if (minimumPossibleWidth > requiredMaxWidth) {
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: 'Cannot fit!',
|
||||
text: 'Cannot fit at all even when squeezing all flex containers to the minimum.'
|
||||
});
|
||||
// Swal.fire({
|
||||
// icon: 'error',
|
||||
// title: 'Cannot fit!',
|
||||
// text: 'Cannot fit at all even when squeezing all flex containers to the minimum.'
|
||||
// });
|
||||
console.error('[FlexBehavior] Cannot fit at all even when squeezing all flex containers to the minimum.');
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -110,8 +56,8 @@ export function Flex(container: IContainerModel): void {
|
|||
if (maxMinWidths * minWidths.length < requiredMaxWidth) {
|
||||
const wantedWidth = requiredMaxWidth / minWidths.length;
|
||||
// it fits, flex with maxMinWidths and fixed width
|
||||
let right = 0;
|
||||
for (const sibling of container.parent.children) {
|
||||
let right = flexibleGroup.offset;
|
||||
for (const sibling of children) {
|
||||
if (!sibling.properties.isFlex) {
|
||||
sibling.properties.x = right;
|
||||
right += sibling.properties.width;
|
||||
|
@ -132,13 +78,46 @@ export function Flex(container: IContainerModel): void {
|
|||
|
||||
// apply the solutions
|
||||
for (let i = 0; i < flexibleContainers.length; i++) {
|
||||
flexibleContainers[i].properties.width = ApplyWidthMargin(solutions[i], flexibleContainers[i].properties.margin.left, flexibleContainers[i].properties.margin.right)
|
||||
flexibleContainers[i].properties.width = ApplyWidthMargin(solutions[i], flexibleContainers[i].properties.margin.left, flexibleContainers[i].properties.margin.right);
|
||||
}
|
||||
|
||||
// move the containers
|
||||
let right = 0;
|
||||
for (const sibling of container.parent.children) {
|
||||
let right = flexibleGroup.offset;
|
||||
for (const sibling of children) {
|
||||
sibling.properties.x = ApplyXMargin(right, sibling.properties.margin.left);
|
||||
right += sibling.properties.width;
|
||||
}
|
||||
}
|
||||
|
||||
export function GetFlexibleGroups(parent: IContainerModel): IFlexibleGroup[] {
|
||||
const flexibleGroups: IFlexibleGroup[] = [];
|
||||
let group: IContainerModel[] = [];
|
||||
let offset = 0;
|
||||
let size = 0;
|
||||
for (const child of parent.children) {
|
||||
if (child.properties.isAnchor) {
|
||||
size = child.properties.x - offset;
|
||||
const flexibleGroup: IFlexibleGroup = {
|
||||
group,
|
||||
offset,
|
||||
size
|
||||
};
|
||||
|
||||
flexibleGroups.push(flexibleGroup);
|
||||
offset = child.properties.x + child.properties.width;
|
||||
group = [];
|
||||
continue;
|
||||
}
|
||||
|
||||
group.push(child);
|
||||
}
|
||||
size = parent.properties.width - offset;
|
||||
const flexibleGroup: IFlexibleGroup = {
|
||||
group,
|
||||
offset,
|
||||
size
|
||||
};
|
||||
|
||||
flexibleGroups.push(flexibleGroup);
|
||||
return flexibleGroups;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue