mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 23:01:09 +02:00
feat(todo): inline column editing in board headers, remove separate editor
Move column editing (color, name, reorder, delete) directly into each column/sheet header. In edit mode, ViewColumnHeader shows color dots, name input, and action buttons inline. Add column button in toolbar. - ViewColumnHeader: edit mode with color picker, name input, move/delete - Props flow: page → BoardViewRenderer → Layout → ViewColumn → Header - Remove separate column-editor bar from page - Narrower Fokus sheet widths (360/480/640/840px) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
3b54d4d48e
commit
1926c6b1f2
7 changed files with 336 additions and 186 deletions
|
|
@ -11,9 +11,20 @@
|
|||
interface Props {
|
||||
view: LocalBoardView;
|
||||
layoutOverride?: 'kanban' | 'grid' | 'fokus';
|
||||
onColumnRename?: (colIdx: number, name: string) => void;
|
||||
onColumnColorChange?: (colIdx: number, color: string) => void;
|
||||
onColumnMove?: (colIdx: number, dir: -1 | 1) => void;
|
||||
onColumnDelete?: (colIdx: number) => void;
|
||||
}
|
||||
|
||||
let { view, layoutOverride }: Props = $props();
|
||||
let {
|
||||
view,
|
||||
layoutOverride,
|
||||
onColumnRename,
|
||||
onColumnColorChange,
|
||||
onColumnMove,
|
||||
onColumnDelete,
|
||||
}: Props = $props();
|
||||
|
||||
let activeLayout = $derived(layoutOverride || view.layout);
|
||||
|
||||
|
|
@ -74,6 +85,10 @@
|
|||
onTaskToggle={handleTaskToggle}
|
||||
onTaskDelete={handleTaskDelete}
|
||||
onTaskUpdate={handleTaskUpdate}
|
||||
{onColumnRename}
|
||||
{onColumnColorChange}
|
||||
{onColumnMove}
|
||||
{onColumnDelete}
|
||||
/>
|
||||
{:else if activeLayout === 'grid'}
|
||||
<GridLayout
|
||||
|
|
@ -82,6 +97,10 @@
|
|||
onTaskToggle={handleTaskToggle}
|
||||
onTaskDelete={handleTaskDelete}
|
||||
onTaskUpdate={handleTaskUpdate}
|
||||
{onColumnRename}
|
||||
{onColumnColorChange}
|
||||
{onColumnMove}
|
||||
{onColumnDelete}
|
||||
/>
|
||||
{:else}
|
||||
<KanbanLayout
|
||||
|
|
@ -90,5 +109,9 @@
|
|||
onTaskToggle={handleTaskToggle}
|
||||
onTaskDelete={handleTaskDelete}
|
||||
onTaskUpdate={handleTaskUpdate}
|
||||
{onColumnRename}
|
||||
{onColumnColorChange}
|
||||
{onColumnMove}
|
||||
{onColumnDelete}
|
||||
/>
|
||||
{/if}
|
||||
|
|
|
|||
|
|
@ -14,15 +14,29 @@
|
|||
onTaskToggle: (task: Task) => void;
|
||||
onTaskDelete: (taskId: string) => void;
|
||||
onTaskUpdate: (taskId: string, data: Partial<Task>) => void;
|
||||
onColumnRename?: (colIdx: number, name: string) => void;
|
||||
onColumnColorChange?: (colIdx: number, color: string) => void;
|
||||
onColumnMove?: (colIdx: number, dir: -1 | 1) => void;
|
||||
onColumnDelete?: (colIdx: number) => void;
|
||||
}
|
||||
|
||||
let { columns, onTaskDrop, onTaskToggle, onTaskDelete, onTaskUpdate }: Props = $props();
|
||||
let {
|
||||
columns,
|
||||
onTaskDrop,
|
||||
onTaskToggle,
|
||||
onTaskDelete,
|
||||
onTaskUpdate,
|
||||
onColumnRename,
|
||||
onColumnColorChange,
|
||||
onColumnMove,
|
||||
onColumnDelete,
|
||||
}: Props = $props();
|
||||
|
||||
const PAGE_WIDTH_MAP: Record<string, string> = {
|
||||
narrow: 'min(640px, 85vw)',
|
||||
medium: 'min(840px, 85vw)',
|
||||
wide: 'min(1024px, 92vw)',
|
||||
full: '92vw',
|
||||
narrow: 'min(360px, 85vw)',
|
||||
medium: 'min(480px, 85vw)',
|
||||
wide: 'min(640px, 90vw)',
|
||||
full: 'min(840px, 95vw)',
|
||||
};
|
||||
|
||||
let sheetWidth = $derived(PAGE_WIDTH_MAP[todoSettings.pageWidth] || PAGE_WIDTH_MAP.medium);
|
||||
|
|
@ -106,10 +120,20 @@
|
|||
bind:this={scrollContainer}
|
||||
onscroll={handleScroll}
|
||||
>
|
||||
{#each columns as column (column.id)}
|
||||
{#each columns as column, i (column.id)}
|
||||
{@const tasks = localTasksByColumn[column.id] || column.tasks}
|
||||
<div class="fokus-sheet" class:sheet-completed={column.name === 'Erledigt'}>
|
||||
<ViewColumnHeader name={column.name} color={column.color} taskCount={tasks.length} />
|
||||
<ViewColumnHeader
|
||||
name={column.name}
|
||||
color={column.color}
|
||||
taskCount={tasks.length}
|
||||
columnIndex={i}
|
||||
totalColumns={columns.length}
|
||||
onRename={onColumnRename ? (name) => onColumnRename(i, name) : undefined}
|
||||
onColorChange={onColumnColorChange ? (c) => onColumnColorChange(i, c) : undefined}
|
||||
onMove={onColumnMove ? (dir) => onColumnMove(i, dir) : undefined}
|
||||
onDelete={onColumnDelete ? () => onColumnDelete(i) : undefined}
|
||||
/>
|
||||
|
||||
<div
|
||||
class="sheet-content"
|
||||
|
|
|
|||
|
|
@ -9,20 +9,40 @@
|
|||
onTaskToggle: (task: Task) => void;
|
||||
onTaskDelete: (taskId: string) => void;
|
||||
onTaskUpdate: (taskId: string, data: Partial<Task>) => void;
|
||||
onColumnRename?: (colIdx: number, name: string) => void;
|
||||
onColumnColorChange?: (colIdx: number, color: string) => void;
|
||||
onColumnMove?: (colIdx: number, dir: -1 | 1) => void;
|
||||
onColumnDelete?: (colIdx: number) => void;
|
||||
}
|
||||
|
||||
let { columns, onTaskDrop, onTaskToggle, onTaskDelete, onTaskUpdate }: Props = $props();
|
||||
let {
|
||||
columns,
|
||||
onTaskDrop,
|
||||
onTaskToggle,
|
||||
onTaskDelete,
|
||||
onTaskUpdate,
|
||||
onColumnRename,
|
||||
onColumnColorChange,
|
||||
onColumnMove,
|
||||
onColumnDelete,
|
||||
}: Props = $props();
|
||||
</script>
|
||||
|
||||
<div class="grid-layout">
|
||||
{#each columns as column (column.id)}
|
||||
{#each columns as column, i (column.id)}
|
||||
<div class="grid-cell">
|
||||
<ViewColumn
|
||||
{column}
|
||||
columnIndex={i}
|
||||
totalColumns={columns.length}
|
||||
{onTaskDrop}
|
||||
{onTaskToggle}
|
||||
{onTaskDelete}
|
||||
{onTaskUpdate}
|
||||
onColumnRename={onColumnRename ? (name) => onColumnRename(i, name) : undefined}
|
||||
onColumnColorChange={onColumnColorChange ? (c) => onColumnColorChange(i, c) : undefined}
|
||||
onColumnMove={onColumnMove ? (dir) => onColumnMove(i, dir) : undefined}
|
||||
onColumnDelete={onColumnDelete ? () => onColumnDelete(i) : undefined}
|
||||
/>
|
||||
</div>
|
||||
{/each}
|
||||
|
|
|
|||
|
|
@ -9,20 +9,40 @@
|
|||
onTaskToggle: (task: Task) => void;
|
||||
onTaskDelete: (taskId: string) => void;
|
||||
onTaskUpdate: (taskId: string, data: Partial<Task>) => void;
|
||||
onColumnRename?: (colIdx: number, name: string) => void;
|
||||
onColumnColorChange?: (colIdx: number, color: string) => void;
|
||||
onColumnMove?: (colIdx: number, dir: -1 | 1) => void;
|
||||
onColumnDelete?: (colIdx: number) => void;
|
||||
}
|
||||
|
||||
let { columns, onTaskDrop, onTaskToggle, onTaskDelete, onTaskUpdate }: Props = $props();
|
||||
let {
|
||||
columns,
|
||||
onTaskDrop,
|
||||
onTaskToggle,
|
||||
onTaskDelete,
|
||||
onTaskUpdate,
|
||||
onColumnRename,
|
||||
onColumnColorChange,
|
||||
onColumnMove,
|
||||
onColumnDelete,
|
||||
}: Props = $props();
|
||||
</script>
|
||||
|
||||
<div class="kanban-layout">
|
||||
{#each columns as column (column.id)}
|
||||
{#each columns as column, i (column.id)}
|
||||
<div class="kanban-column-wrapper">
|
||||
<ViewColumn
|
||||
{column}
|
||||
columnIndex={i}
|
||||
totalColumns={columns.length}
|
||||
{onTaskDrop}
|
||||
{onTaskToggle}
|
||||
{onTaskDelete}
|
||||
{onTaskUpdate}
|
||||
onColumnRename={onColumnRename ? (name) => onColumnRename(i, name) : undefined}
|
||||
onColumnColorChange={onColumnColorChange ? (c) => onColumnColorChange(i, c) : undefined}
|
||||
onColumnMove={onColumnMove ? (dir) => onColumnMove(i, dir) : undefined}
|
||||
onColumnDelete={onColumnDelete ? () => onColumnDelete(i) : undefined}
|
||||
/>
|
||||
</div>
|
||||
{/each}
|
||||
|
|
|
|||
|
|
@ -9,13 +9,31 @@
|
|||
|
||||
interface Props {
|
||||
column: GroupedColumn;
|
||||
columnIndex?: number;
|
||||
totalColumns?: number;
|
||||
onTaskDrop: (taskId: string, columnId: string) => void;
|
||||
onTaskToggle: (task: Task) => void;
|
||||
onTaskDelete: (taskId: string) => void;
|
||||
onTaskUpdate: (taskId: string, data: Partial<Task>) => void;
|
||||
onColumnRename?: (name: string) => void;
|
||||
onColumnColorChange?: (color: string) => void;
|
||||
onColumnMove?: (dir: -1 | 1) => void;
|
||||
onColumnDelete?: () => void;
|
||||
}
|
||||
|
||||
let { column, onTaskDrop, onTaskToggle, onTaskDelete, onTaskUpdate }: Props = $props();
|
||||
let {
|
||||
column,
|
||||
columnIndex = 0,
|
||||
totalColumns = 1,
|
||||
onTaskDrop,
|
||||
onTaskToggle,
|
||||
onTaskDelete,
|
||||
onTaskUpdate,
|
||||
onColumnRename,
|
||||
onColumnColorChange,
|
||||
onColumnMove,
|
||||
onColumnDelete,
|
||||
}: Props = $props();
|
||||
|
||||
// Local tasks state for drag and drop
|
||||
let localTasks = $state<Task[]>([]);
|
||||
|
|
@ -102,7 +120,17 @@
|
|||
|
||||
<div class="view-column flex flex-col">
|
||||
<!-- Header -->
|
||||
<ViewColumnHeader name={column.name} color={column.color} taskCount={localTasks.length} />
|
||||
<ViewColumnHeader
|
||||
name={column.name}
|
||||
color={column.color}
|
||||
taskCount={localTasks.length}
|
||||
{columnIndex}
|
||||
{totalColumns}
|
||||
onRename={onColumnRename}
|
||||
onColorChange={onColumnColorChange}
|
||||
onMove={onColumnMove}
|
||||
onDelete={onColumnDelete}
|
||||
/>
|
||||
|
||||
<!-- Tasks list with drag and drop -->
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -1,19 +1,105 @@
|
|||
<script lang="ts">
|
||||
import { getContext } from 'svelte';
|
||||
import { ArrowLeft, ArrowRight, Trash } from '@manacore/shared-icons';
|
||||
|
||||
interface Props {
|
||||
name: string;
|
||||
color: string;
|
||||
taskCount: number;
|
||||
columnIndex?: number;
|
||||
totalColumns?: number;
|
||||
onRename?: (name: string) => void;
|
||||
onColorChange?: (color: string) => void;
|
||||
onMove?: (dir: -1 | 1) => void;
|
||||
onDelete?: () => void;
|
||||
}
|
||||
|
||||
let { name, color, taskCount }: Props = $props();
|
||||
let {
|
||||
name,
|
||||
color,
|
||||
taskCount,
|
||||
columnIndex = 0,
|
||||
totalColumns = 1,
|
||||
onRename,
|
||||
onColorChange,
|
||||
onMove,
|
||||
onDelete,
|
||||
}: Props = $props();
|
||||
|
||||
const editModeCtx: { readonly active: boolean } | undefined = getContext('editMode');
|
||||
let editMode = $derived(editModeCtx?.active ?? false);
|
||||
let editable = $derived(editMode && !!onRename);
|
||||
|
||||
const COLORS = [
|
||||
'#EF4444',
|
||||
'#F59E0B',
|
||||
'#22C55E',
|
||||
'#3B82F6',
|
||||
'#8B5CF6',
|
||||
'#EC4899',
|
||||
'#14B8A6',
|
||||
'#F97316',
|
||||
'#6B7280',
|
||||
];
|
||||
</script>
|
||||
|
||||
<div class="column-header">
|
||||
<div class="header-left">
|
||||
<span class="color-dot" style="background-color: {color}"></span>
|
||||
<span class="column-name">{name}</span>
|
||||
</div>
|
||||
<span class="task-count">{taskCount}</span>
|
||||
<div class="column-header" class:editing={editable}>
|
||||
{#if editable}
|
||||
<!-- Edit mode: color dots + name input + actions -->
|
||||
<div class="edit-header">
|
||||
<div class="color-row">
|
||||
{#each COLORS as c}
|
||||
<button
|
||||
class="color-pick"
|
||||
class:active={color === c}
|
||||
style="background-color: {c}"
|
||||
onclick={() => onColorChange?.(c)}
|
||||
></button>
|
||||
{/each}
|
||||
</div>
|
||||
<div class="edit-row">
|
||||
<input
|
||||
class="name-input"
|
||||
type="text"
|
||||
value={name}
|
||||
oninput={(e) => onRename?.(e.currentTarget.value)}
|
||||
/>
|
||||
<div class="edit-actions">
|
||||
<button
|
||||
class="act-btn"
|
||||
onclick={() => onMove?.(-1)}
|
||||
disabled={columnIndex === 0}
|
||||
title="Nach links"
|
||||
>
|
||||
<ArrowLeft size={12} />
|
||||
</button>
|
||||
<button
|
||||
class="act-btn"
|
||||
onclick={() => onMove?.(1)}
|
||||
disabled={columnIndex >= totalColumns - 1}
|
||||
title="Nach rechts"
|
||||
>
|
||||
<ArrowRight size={12} />
|
||||
</button>
|
||||
<button
|
||||
class="act-btn del-btn"
|
||||
onclick={() => onDelete?.()}
|
||||
disabled={totalColumns <= 1}
|
||||
title="Spalte löschen"
|
||||
>
|
||||
<Trash size={12} />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<!-- Normal mode -->
|
||||
<div class="header-left">
|
||||
<span class="color-dot" style="background-color: {color}"></span>
|
||||
<span class="column-name">{name}</span>
|
||||
</div>
|
||||
<span class="task-count">{taskCount}</span>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
|
@ -24,6 +110,10 @@
|
|||
padding: 0.75rem 1rem;
|
||||
}
|
||||
|
||||
.column-header.editing {
|
||||
padding: 0.5rem 0.75rem;
|
||||
}
|
||||
|
||||
.header-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
@ -65,4 +155,93 @@
|
|||
background: rgba(255, 255, 255, 0.1);
|
||||
color: #6b7280;
|
||||
}
|
||||
|
||||
/* ── Edit mode ────────────────────────────────────────── */
|
||||
.edit-header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.375rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.color-row {
|
||||
display: flex;
|
||||
gap: 0.2rem;
|
||||
}
|
||||
|
||||
.color-pick {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid transparent;
|
||||
cursor: pointer;
|
||||
transition: all 0.15s;
|
||||
padding: 0;
|
||||
}
|
||||
.color-pick:hover {
|
||||
transform: scale(1.25);
|
||||
}
|
||||
.color-pick.active {
|
||||
border-color: white;
|
||||
box-shadow: 0 0 0 1.5px currentColor;
|
||||
transform: scale(1.15);
|
||||
}
|
||||
|
||||
.edit-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.375rem;
|
||||
}
|
||||
|
||||
.name-input {
|
||||
flex: 1;
|
||||
font-size: 0.8125rem;
|
||||
font-weight: 600;
|
||||
color: #374151;
|
||||
background: transparent;
|
||||
border: none;
|
||||
border-bottom: 1px solid rgba(139, 92, 246, 0.3);
|
||||
padding: 0.125rem 0;
|
||||
outline: none;
|
||||
min-width: 0;
|
||||
}
|
||||
.name-input:focus {
|
||||
border-bottom-color: #8b5cf6;
|
||||
}
|
||||
:global(.dark) .name-input {
|
||||
color: #f3f4f6;
|
||||
}
|
||||
|
||||
.edit-actions {
|
||||
display: flex;
|
||||
gap: 0.125rem;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.act-btn {
|
||||
padding: 0.2rem;
|
||||
border-radius: 0.25rem;
|
||||
color: #9ca3af;
|
||||
cursor: pointer;
|
||||
transition: all 0.15s;
|
||||
background: transparent;
|
||||
border: none;
|
||||
line-height: 0;
|
||||
}
|
||||
.act-btn:hover:not(:disabled) {
|
||||
color: #374151;
|
||||
background: rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
.act-btn:disabled {
|
||||
opacity: 0.25;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
:global(.dark) .act-btn:hover:not(:disabled) {
|
||||
color: #f3f4f6;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
.del-btn:hover:not(:disabled) {
|
||||
color: #ef4444 !important;
|
||||
background: rgba(239, 68, 68, 0.1) !important;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
import { BoardViewRenderer } from '$lib/components/board-views';
|
||||
import { todoSettings, type PageWidth } from '$lib/stores/settings.svelte';
|
||||
import { boardViewsStore } from '$lib/stores/board-views.svelte';
|
||||
import { ArrowLeft, ArrowRight, Plus, Trash } from '@manacore/shared-icons';
|
||||
import { Plus } from '@manacore/shared-icons';
|
||||
|
||||
// Get active view + edit mode from layout context
|
||||
const activeViewCtx: { readonly value: LocalBoardView | null } = getContext('activeView');
|
||||
|
|
@ -148,57 +148,11 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Column Editor -->
|
||||
{#if columnsEditable}
|
||||
<div class="column-editor">
|
||||
{#each activeView.columns as col, i (col.id)}
|
||||
<div class="col-edit-card">
|
||||
<div class="col-colors">
|
||||
{#each COLUMN_COLORS as c}
|
||||
<button
|
||||
class="col-color-dot"
|
||||
class:active={col.color === c}
|
||||
style="background-color: {c}"
|
||||
onclick={() => updateColumn(i, { color: c })}
|
||||
></button>
|
||||
{/each}
|
||||
</div>
|
||||
<input
|
||||
class="col-name-input"
|
||||
type="text"
|
||||
value={col.name}
|
||||
oninput={(e) => updateColumn(i, { name: e.currentTarget.value })}
|
||||
/>
|
||||
<div class="col-actions">
|
||||
<button
|
||||
class="col-action-btn"
|
||||
onclick={() => moveColumn(i, -1)}
|
||||
disabled={i === 0}
|
||||
title="Nach links"
|
||||
>
|
||||
<ArrowLeft size={14} />
|
||||
</button>
|
||||
<button
|
||||
class="col-action-btn"
|
||||
onclick={() => moveColumn(i, 1)}
|
||||
disabled={i === activeView.columns.length - 1}
|
||||
title="Nach rechts"
|
||||
>
|
||||
<ArrowRight size={14} />
|
||||
</button>
|
||||
<button
|
||||
class="col-action-btn col-delete-btn"
|
||||
onclick={() => removeColumn(i)}
|
||||
disabled={activeView.columns.length <= 1}
|
||||
title="Spalte löschen"
|
||||
>
|
||||
<Trash size={14} />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
<div class="add-col-bar">
|
||||
<button class="col-add-btn" onclick={addColumn} title="Spalte hinzufügen">
|
||||
<Plus size={16} />
|
||||
<Plus size={14} />
|
||||
<span>Spalte</span>
|
||||
</button>
|
||||
</div>
|
||||
{:else}
|
||||
|
|
@ -208,7 +162,14 @@
|
|||
|
||||
<!-- Board Content -->
|
||||
{#if activeView}
|
||||
<BoardViewRenderer view={activeView} {layoutOverride} />
|
||||
<BoardViewRenderer
|
||||
view={activeView}
|
||||
{layoutOverride}
|
||||
onColumnRename={columnsEditable ? (i, name) => updateColumn(i, { name }) : undefined}
|
||||
onColumnColorChange={columnsEditable ? (i, color) => updateColumn(i, { color }) : undefined}
|
||||
onColumnMove={columnsEditable ? moveColumn : undefined}
|
||||
onColumnDelete={columnsEditable ? removeColumn : undefined}
|
||||
/>
|
||||
{:else}
|
||||
<div class="empty-state">
|
||||
<p class="text-muted-foreground">Views werden geladen...</p>
|
||||
|
|
@ -319,132 +280,27 @@
|
|||
color: white;
|
||||
}
|
||||
|
||||
/* ── Column Editor ────────────────────────────────────── */
|
||||
.column-editor {
|
||||
/* ── Add Column Bar ───────────────────────────────────── */
|
||||
.add-col-bar {
|
||||
display: flex;
|
||||
gap: 0.75rem;
|
||||
padding: 0.75rem 1.5rem;
|
||||
overflow-x: auto;
|
||||
scrollbar-width: none;
|
||||
padding: 0.5rem 1.5rem;
|
||||
flex-shrink: 0;
|
||||
background: rgba(139, 92, 246, 0.03);
|
||||
border-bottom: 1px solid rgba(139, 92, 246, 0.08);
|
||||
}
|
||||
.column-editor::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
:global(.dark) .column-editor {
|
||||
background: rgba(139, 92, 246, 0.05);
|
||||
border-bottom-color: rgba(139, 92, 246, 0.12);
|
||||
}
|
||||
|
||||
.col-edit-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.375rem;
|
||||
padding: 0.5rem 0.75rem;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
border: 1px solid rgba(0, 0, 0, 0.08);
|
||||
border-radius: 0.5rem;
|
||||
min-width: 140px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
:global(.dark) .col-edit-card {
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
border-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.col-colors {
|
||||
display: flex;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.col-color-dot {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid transparent;
|
||||
cursor: pointer;
|
||||
transition: all 0.15s;
|
||||
}
|
||||
.col-color-dot:hover {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
.col-color-dot.active {
|
||||
border-color: white;
|
||||
box-shadow: 0 0 0 2px currentColor;
|
||||
transform: scale(1.15);
|
||||
}
|
||||
|
||||
.col-name-input {
|
||||
font-size: 0.8125rem;
|
||||
font-weight: 600;
|
||||
color: #374151;
|
||||
background: transparent;
|
||||
border: none;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
||||
padding: 0.125rem 0;
|
||||
outline: none;
|
||||
width: 100%;
|
||||
}
|
||||
.col-name-input:focus {
|
||||
border-bottom-color: #8b5cf6;
|
||||
}
|
||||
:global(.dark) .col-name-input {
|
||||
color: #f3f4f6;
|
||||
border-bottom-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.col-actions {
|
||||
display: flex;
|
||||
gap: 0.25rem;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.col-action-btn {
|
||||
padding: 0.25rem;
|
||||
border-radius: 0.25rem;
|
||||
color: #6b7280;
|
||||
cursor: pointer;
|
||||
transition: all 0.15s;
|
||||
background: transparent;
|
||||
border: none;
|
||||
}
|
||||
.col-action-btn:hover:not(:disabled) {
|
||||
color: #374151;
|
||||
background: rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
.col-action-btn:disabled {
|
||||
opacity: 0.3;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
:global(.dark) .col-action-btn {
|
||||
color: #9ca3af;
|
||||
}
|
||||
:global(.dark) .col-action-btn:hover:not(:disabled) {
|
||||
color: #f3f4f6;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.col-delete-btn:hover:not(:disabled) {
|
||||
color: #ef4444 !important;
|
||||
background: rgba(239, 68, 68, 0.1) !important;
|
||||
}
|
||||
|
||||
.col-add-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 0.5rem;
|
||||
border: 2px dashed rgba(139, 92, 246, 0.3);
|
||||
gap: 0.375rem;
|
||||
padding: 0.25rem 0.75rem;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
border-radius: 9999px;
|
||||
border: 1px dashed rgba(139, 92, 246, 0.4);
|
||||
color: #8b5cf6;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
transition: all 0.15s;
|
||||
flex-shrink: 0;
|
||||
align-self: center;
|
||||
}
|
||||
.col-add-btn:hover {
|
||||
border-color: #8b5cf6;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue