style(fe): standardize ModelList master-detail page with central width tokens, selection highlight, and viewport-fit bounds
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 80 KiB |
@@ -108,17 +108,17 @@ const handleRetry = () => {
|
||||
<section class="filters" aria-label="모델 검색 및 필터">
|
||||
<input
|
||||
v-model="filterModel.search"
|
||||
placeholder="Search models..."
|
||||
class="input"
|
||||
placeholder="모델명 검색..."
|
||||
class="input search-input"
|
||||
aria-label="모델 이름 검색"
|
||||
role="searchbox"
|
||||
/>
|
||||
<select
|
||||
v-model="filterModel.phase"
|
||||
class="input"
|
||||
class="input status-select"
|
||||
aria-label="모델 단계별 필터"
|
||||
>
|
||||
<option value="">All Phases</option>
|
||||
<option value="">전체 단계 (All Phases)</option>
|
||||
<option value="Mature">Mature</option>
|
||||
<option value="Validate">Validate</option>
|
||||
<option value="Review">Review</option>
|
||||
@@ -290,27 +290,38 @@ h3 {
|
||||
}
|
||||
|
||||
.filters {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 150px;
|
||||
gap: var(--spacing-4);
|
||||
margin-bottom: var(--spacing-5);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--ks-space-2);
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.input {
|
||||
padding: var(--spacing-2) var(--spacing-3);
|
||||
border: var(--border-width-1) solid var(--color-input-border);
|
||||
border-radius: var(--border-radius-base);
|
||||
background: var(--color-input-background);
|
||||
color: var(--color-text-primary);
|
||||
font-size: var(--font-size-sm);
|
||||
font-family: var(--font-sans);
|
||||
transition: all var(--transition-fast);
|
||||
height: var(--ks-control-height);
|
||||
padding: 0 var(--ks-space-2);
|
||||
border: 1px solid var(--ks-color-neutral-200);
|
||||
border-radius: var(--ks-radius-sm);
|
||||
background: var(--ks-color-surface);
|
||||
color: var(--ks-color-neutral-900);
|
||||
font-size: var(--ks-font-body);
|
||||
font-family: inherit;
|
||||
box-sizing: border-box;
|
||||
transition: all 0.15s ease;
|
||||
}
|
||||
|
||||
.input.search-input {
|
||||
width: var(--ks-control-width-search);
|
||||
}
|
||||
|
||||
.input.status-select {
|
||||
width: var(--ks-control-width-select);
|
||||
}
|
||||
|
||||
.input:focus {
|
||||
outline: none;
|
||||
border-color: var(--ks-color-action);
|
||||
box-shadow: 0 0 0 2px var(--ks-color-action);
|
||||
box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.15);
|
||||
}
|
||||
|
||||
.content-skeleton {
|
||||
@@ -331,46 +342,52 @@ h3 {
|
||||
}
|
||||
|
||||
.master-list {
|
||||
border: var(--border-width-1) solid var(--color-border-primary);
|
||||
border-radius: var(--border-radius-lg);
|
||||
border: 1px solid var(--ks-color-neutral-200);
|
||||
border-radius: var(--ks-radius-sm);
|
||||
overflow: hidden;
|
||||
background: var(--color-background-primary);
|
||||
background: var(--ks-color-surface);
|
||||
height: calc(100vh - 210px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.master-list h2 {
|
||||
padding: var(--spacing-4);
|
||||
background: var(--color-background-secondary);
|
||||
border-bottom: var(--border-width-1) solid var(--color-border-secondary);
|
||||
padding: var(--ks-space-2) var(--ks-space-3);
|
||||
background: #f1f5f9;
|
||||
border-bottom: 1px solid var(--ks-color-neutral-300);
|
||||
font-size: var(--ks-font-section);
|
||||
font-weight: 700;
|
||||
color: var(--ks-color-neutral-800);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.items {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--spacing-1);
|
||||
padding: var(--spacing-2);
|
||||
max-height: 600px;
|
||||
gap: var(--ks-space-2);
|
||||
padding: var(--ks-space-2);
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.model-item {
|
||||
padding: var(--spacing-3);
|
||||
background: var(--color-background-primary);
|
||||
border: var(--border-width-1) solid var(--color-border-secondary);
|
||||
border-radius: var(--border-radius-base);
|
||||
padding: var(--ks-space-2) var(--ks-space-3);
|
||||
background: var(--ks-color-surface);
|
||||
border: 1px solid var(--ks-color-neutral-200);
|
||||
border-radius: var(--ks-radius-sm);
|
||||
cursor: pointer;
|
||||
transition: all var(--transition-base);
|
||||
transition: all 0.15s ease;
|
||||
}
|
||||
|
||||
.model-item:hover {
|
||||
background: var(--color-background-hover);
|
||||
box-shadow: var(--shadow-sm);
|
||||
background: #e0f2fe;
|
||||
}
|
||||
|
||||
.model-item.is-selected {
|
||||
border-color: var(--color-primary-500);
|
||||
background: var(--color-primary-50);
|
||||
box-shadow: var(--shadow-sm);
|
||||
border-color: var(--ks-color-action);
|
||||
background: #eff6ff;
|
||||
color: #0f172a;
|
||||
box-shadow: 0 0 0 1px var(--ks-color-action);
|
||||
}
|
||||
|
||||
.item-header {
|
||||
@@ -442,24 +459,24 @@ h3 {
|
||||
}
|
||||
|
||||
.detail-panel {
|
||||
border: var(--border-width-1) solid var(--color-border-primary);
|
||||
border-radius: var(--border-radius-lg);
|
||||
padding: var(--spacing-4);
|
||||
background: var(--color-background-secondary);
|
||||
max-height: 700px;
|
||||
border: 1px solid var(--ks-color-neutral-200);
|
||||
border-radius: var(--ks-radius-sm);
|
||||
padding: var(--ks-space-3);
|
||||
background: var(--ks-color-surface);
|
||||
height: calc(100vh - 210px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.empty-detail {
|
||||
text-align: center;
|
||||
padding: var(--spacing-8);
|
||||
color: var(--color-text-tertiary);
|
||||
padding: var(--ks-space-8);
|
||||
color: var(--ks-color-neutral-500);
|
||||
}
|
||||
|
||||
.model-detail {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--spacing-4);
|
||||
gap: var(--ks-space-3);
|
||||
}
|
||||
|
||||
.section {
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
ClientSideRowModelModule,
|
||||
ColumnAutoSizeModule,
|
||||
CellStyleModule,
|
||||
ValidationModule,
|
||||
TextFilterModule,
|
||||
themeQuartz,
|
||||
ModuleRegistry,
|
||||
@@ -18,6 +19,7 @@ ModuleRegistry.registerModules([
|
||||
ClientSideRowModelModule,
|
||||
ColumnAutoSizeModule,
|
||||
CellStyleModule,
|
||||
ValidationModule,
|
||||
TextFilterModule,
|
||||
RowSelectionModule
|
||||
])
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { AgGridVue } from 'ag-grid-vue3'
|
||||
import { ClientSideRowModelModule, ColumnAutoSizeModule, CellStyleModule, ModuleRegistry, RowSelectionModule, TextFilterModule, themeQuartz, type ColDef, type RowClickedEvent } from 'ag-grid-community'
|
||||
import { ClientSideRowModelModule, ColumnAutoSizeModule, CellStyleModule, ValidationModule, ModuleRegistry, RowSelectionModule, TextFilterModule, themeQuartz, type ColDef, type RowClickedEvent } from 'ag-grid-community'
|
||||
import type { UiGridColumn } from '../adapter/contracts'
|
||||
|
||||
ModuleRegistry.registerModules([ClientSideRowModelModule, ColumnAutoSizeModule, CellStyleModule, TextFilterModule, RowSelectionModule])
|
||||
ModuleRegistry.registerModules([ClientSideRowModelModule, ColumnAutoSizeModule, CellStyleModule, ValidationModule, TextFilterModule, RowSelectionModule])
|
||||
|
||||
const emit = defineEmits<{ rowSelected: [row: unknown] }>()
|
||||
const props = withDefaults(defineProps<{ rows: unknown[]; columns: UiGridColumn[]; loading?: boolean; height?: string; rowSelection?: 'single' | 'multiple' | 'none'; showRowNumber?: boolean }>(), { loading: false, height: '32rem', rowSelection: 'single', showRowNumber: true })
|
||||
@@ -60,7 +60,6 @@ function onGridReady(params: { api: { sizeColumnsToFit: () => void } }): void {
|
||||
:column-defs="columnDefs"
|
||||
:row-selection="rowSelectionOptions"
|
||||
:loading="props.loading"
|
||||
:auto-size-strategy="{ type: 'fitGridWidth' }"
|
||||
overlay-no-rows-template="<div class='ks-ag-empty-overlay'><span style='font-size:2rem;'>📭</span><p style='margin-top:8px;font-weight:600;color:var(--ks-color-neutral-700);'>조회된 데이터가 없습니다</p><p style='font-size:12px;color:var(--ks-color-neutral-500);'>검색 조건을 변경하거나 신규 데이터를 수집하세요.</p></div>"
|
||||
@grid-ready="onGridReady"
|
||||
@first-data-rendered="onGridReady"
|
||||
|
||||
Reference in New Issue
Block a user