phase 12
All checks were successful
CI/CD Pipeline / VM Test - backend-integration (push) Successful in 8s
CI/CD Pipeline / VM Test - full-stack (push) Successful in 7s
CI/CD Pipeline / VM Test - performance (push) Successful in 7s
CI/CD Pipeline / VM Test - security (push) Successful in 7s
CI/CD Pipeline / Backend Linting (push) Successful in 2s
CI/CD Pipeline / Frontend Linting (push) Successful in 16s
CI/CD Pipeline / Nix Flake Check (push) Successful in 38s
CI/CD Pipeline / CI Summary (push) Successful in 0s
All checks were successful
CI/CD Pipeline / VM Test - backend-integration (push) Successful in 8s
CI/CD Pipeline / VM Test - full-stack (push) Successful in 7s
CI/CD Pipeline / VM Test - performance (push) Successful in 7s
CI/CD Pipeline / VM Test - security (push) Successful in 7s
CI/CD Pipeline / Backend Linting (push) Successful in 2s
CI/CD Pipeline / Frontend Linting (push) Successful in 16s
CI/CD Pipeline / Nix Flake Check (push) Successful in 38s
CI/CD Pipeline / CI Summary (push) Successful in 0s
This commit is contained in:
268
frontend/src/lib/components/canvas/AlignmentToolbar.svelte
Normal file
268
frontend/src/lib/components/canvas/AlignmentToolbar.svelte
Normal file
@@ -0,0 +1,268 @@
|
||||
<script lang="ts">
|
||||
/**
|
||||
* Alignment toolbar component
|
||||
* Provides UI buttons for alignment and distribution operations
|
||||
*/
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { selectionCount } from '$lib/stores/selection';
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
$: disabled = $selectionCount < 2;
|
||||
$: distributeDisabled = $selectionCount < 3;
|
||||
</script>
|
||||
|
||||
<div class="alignment-toolbar">
|
||||
<div class="toolbar-section">
|
||||
<div class="section-label">Align</div>
|
||||
<div class="button-group">
|
||||
<button
|
||||
class="toolbar-button"
|
||||
on:click={() => dispatch('align-left')}
|
||||
{disabled}
|
||||
title="Align Left"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
>
|
||||
<line x1="3" y1="6" x2="3" y2="18" />
|
||||
<rect x="7" y="8" width="10" height="3" />
|
||||
<rect x="7" y="13" width="7" height="3" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="toolbar-button"
|
||||
on:click={() => dispatch('align-center-h')}
|
||||
{disabled}
|
||||
title="Center Horizontal"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
>
|
||||
<line x1="12" y1="6" x2="12" y2="18" />
|
||||
<rect x="7" y="8" width="10" height="3" />
|
||||
<rect x="9" y="13" width="6" height="3" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="toolbar-button"
|
||||
on:click={() => dispatch('align-right')}
|
||||
{disabled}
|
||||
title="Align Right"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
>
|
||||
<line x1="21" y1="6" x2="21" y2="18" />
|
||||
<rect x="7" y="8" width="10" height="3" />
|
||||
<rect x="10" y="13" width="7" height="3" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<div class="separator" />
|
||||
|
||||
<button
|
||||
class="toolbar-button"
|
||||
on:click={() => dispatch('align-top')}
|
||||
{disabled}
|
||||
title="Align Top"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
>
|
||||
<line x1="6" y1="3" x2="18" y2="3" />
|
||||
<rect x="8" y="7" width="3" height="10" />
|
||||
<rect x="13" y="7" width="3" height="7" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="toolbar-button"
|
||||
on:click={() => dispatch('align-center-v')}
|
||||
{disabled}
|
||||
title="Center Vertical"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
>
|
||||
<line x1="6" y1="12" x2="18" y2="12" />
|
||||
<rect x="8" y="7" width="3" height="10" />
|
||||
<rect x="13" y="9" width="3" height="6" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="toolbar-button"
|
||||
on:click={() => dispatch('align-bottom')}
|
||||
{disabled}
|
||||
title="Align Bottom"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
>
|
||||
<line x1="6" y1="21" x2="18" y2="21" />
|
||||
<rect x="8" y="7" width="3" height="10" />
|
||||
<rect x="13" y="10" width="3" height="7" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="toolbar-section">
|
||||
<div class="section-label">Distribute</div>
|
||||
<div class="button-group">
|
||||
<button
|
||||
class="toolbar-button"
|
||||
on:click={() => dispatch('distribute-h')}
|
||||
disabled={distributeDisabled}
|
||||
title="Distribute Horizontal"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
>
|
||||
<rect x="5" y="8" width="3" height="8" />
|
||||
<rect x="11" y="8" width="3" height="8" />
|
||||
<rect x="17" y="8" width="3" height="8" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="toolbar-button"
|
||||
on:click={() => dispatch('distribute-v')}
|
||||
disabled={distributeDisabled}
|
||||
title="Distribute Vertical"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
>
|
||||
<rect x="8" y="5" width="8" height="3" />
|
||||
<rect x="8" y="11" width="8" height="3" />
|
||||
<rect x="8" y="17" width="8" height="3" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.alignment-toolbar {
|
||||
display: flex;
|
||||
gap: 1.5rem;
|
||||
padding: 0.75rem;
|
||||
background-color: var(--color-bg, #ffffff);
|
||||
border: 1px solid var(--color-border, #e5e7eb);
|
||||
border-radius: 0.5rem;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.toolbar-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.section-label {
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
color: var(--color-text-secondary, #6b7280);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
gap: 0.25rem;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.toolbar-button {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
padding: 0;
|
||||
background-color: var(--color-bg-secondary, #f9fafb);
|
||||
border: 1px solid var(--color-border, #d1d5db);
|
||||
border-radius: 0.375rem;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--color-text, #374151);
|
||||
}
|
||||
|
||||
.toolbar-button:hover:not(:disabled) {
|
||||
background-color: var(--color-bg-hover, #f3f4f6);
|
||||
border-color: var(--color-primary, #3b82f6);
|
||||
}
|
||||
|
||||
.toolbar-button:active:not(:disabled) {
|
||||
background-color: var(--color-bg-active, #e5e7eb);
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
.toolbar-button:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.separator {
|
||||
width: 1px;
|
||||
height: 24px;
|
||||
background-color: var(--color-border, #d1d5db);
|
||||
margin: 0 0.25rem;
|
||||
}
|
||||
|
||||
svg {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user