feat(fe): Add form field navigation - Enter key moves to next field

- Create useFormFieldNavigation composable for Tab-like Enter behavior
- KsTextField: Enter -> next field
- KsTextArea: Ctrl+Enter for newline, Enter -> next field
- KsSelect: Enter -> next field after selection
- Implements standard form navigation pattern across input components
This commit is contained in:
2026-08-16 21:50:50 +09:00
parent 5213ea142b
commit b12fc7411d
25 changed files with 1105 additions and 85 deletions
+114 -5
View File
@@ -7,9 +7,45 @@ body {
background: var(--ks-color-canvas);
color: var(--ks-color-text);
font-family: Inter, Pretendard, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
font-size: var(--ks-font-body);
line-height: var(--ks-line-body);
font-size: var(--ks-font-body, 12px);
line-height: var(--ks-line-body, 16px);
}
/* KBX v60 Global Typography Token Scale Standard (표준 폰트 크기 계층 규격) */
h1, .ks-title {
font-size: var(--ks-font-page, 16px) !important;
line-height: var(--ks-line-page, 22px) !important;
font-weight: 700 !important;
}
h2, .ks-section-title {
font-size: var(--ks-font-section, 14px) !important;
line-height: var(--ks-line-section, 18px) !important;
font-weight: 700 !important;
}
h3, h4, dt, legend {
font-size: var(--ks-font-section, 14px) !important;
line-height: var(--ks-line-section, 18px) !important;
font-weight: 600 !important;
}
p, span, li, td, input, select, button, label, .ks-font-body {
font-size: var(--ks-font-body, 12px);
line-height: var(--ks-line-body, 16px);
}
th, .ag-header-cell-text {
font-size: var(--ks-font-grid, 12px) !important;
line-height: var(--ks-line-grid, 16px) !important;
font-weight: 700 !important;
}
caption, .hint, .note, .ks-caption, small, .help-text, .ks-font-caption {
font-size: var(--ks-font-caption, 11px) !important;
line-height: var(--ks-line-caption, 14px) !important;
}
button, input, select, textarea { font: inherit; }
a { color: var(--ks-color-action); }
:focus-visible { outline: var(--ks-focus-ring-width) solid color-mix(in srgb, var(--ks-color-focus) 55%, transparent); outline-offset: var(--ks-focus-ring-offset); }
@@ -56,7 +92,79 @@ input[type="text"], input[type="number"], input[type="date"], select, textarea,
box-sizing: border-box;
}
/* Default Width Standards for Form & Filter Controls (기본 넓이 표준 규격) */
/* Automatic Global Inline Rule for Filter Container Slots */
.ks-page__filters .ks-text-field,
.ks-page__filters .ks-select,
.ks-page__filters .ks-date-field {
display: flex !important;
flex-direction: row !important;
align-items: center !important;
gap: var(--ks-space-2, 6px) !important;
}
.ks-page__filters:empty,
.ks-page__command-bar:empty,
.ks-page__summary:empty {
display: none !important;
min-height: 0 !important;
padding: 0 !important;
margin: 0 !important;
border: none !important;
}
.ks-page__filters .ks-text-field__label,
.ks-page__filters .ks-select__label,
.ks-page__filters .ks-date-field__label,
.ks-text-field--inline .ks-text-field__label,
.ks-select--inline .ks-select__label,
.ks-date-field--inline .ks-date-field__label {
width: var(--ks-field-label-width, 72px) !important;
min-width: var(--ks-field-label-width, 72px) !important;
max-width: var(--ks-field-label-width, 72px) !important;
text-align: left !important;
white-space: nowrap !important;
flex-shrink: 0 !important;
margin-bottom: 0 !important;
font-size: var(--ks-font-body) !important;
}
.ks-page__filters .ks-text-field__container,
.ks-page__filters .ks-select__container,
.ks-page__filters .ks-date-field__container,
.ks-text-field--inline .ks-text-field__container,
.ks-select--inline .ks-select__container,
.ks-date-field--inline .ks-date-field__container {
flex: 1 1 auto !important;
min-width: 0 !important;
max-width: 100% !important;
width: 100% !important;
}
.ks-set-sm, .ks-filter-sm {
width: var(--ks-set-width-sm, 200px) !important;
min-width: var(--ks-set-width-sm, 200px) !important;
max-width: var(--ks-set-width-sm, 200px) !important;
flex-shrink: 0 !important;
}
.ks-set-md, .ks-filter-md {
width: var(--ks-set-width-md, 260px) !important;
min-width: var(--ks-set-width-md, 260px) !important;
max-width: var(--ks-set-width-md, 260px) !important;
flex-shrink: 0 !important;
}
.ks-set-lg, .ks-filter-lg {
width: var(--ks-set-width-lg, 340px) !important;
min-width: var(--ks-set-width-lg, 340px) !important;
max-width: var(--ks-set-width-lg, 340px) !important;
flex-shrink: 0 !important;
}
select, .p-select, .p-dropdown, .ks-select, .status-select {
width: var(--ks-control-width-select);
max-width: 100%;
@@ -75,10 +183,11 @@ input[type="date"] {
.filters, .ks-page__filters form, .ks-page__filters section {
display: flex;
align-items: center;
gap: var(--ks-space-2);
flex-wrap: wrap;
gap: var(--ks-space-3);
flex-wrap: nowrap;
}
button, .p-button, .ks-button {
height: var(--ks-control-height) !important;
font-size: var(--ks-font-body) !important;
+75 -14
View File
@@ -59,9 +59,14 @@
/* KBX v60 ERP/OMS/WMS Ultra-Dense Control & Layout Heights & Default Widths */
--ks-control-height: 28px; /* ERP/OMS Input Control 28px */
--ks-field-label-width: 72px; /* Standardized Inline Field Label Fixed Width 72px */
--ks-set-width-sm: 200px; /* Standardized Compact Field Set Width 200px */
--ks-set-width-md: 260px; /* Standardized Default Field Set Width 260px */
--ks-set-width-lg: 340px; /* Standardized Wide Field Set Width 340px */
--ks-control-width-select: 160px; /* Standard Select/Dropdown Default Width 160px */
--ks-control-width-search: 220px; /* Standard Search Input Default Width 220px */
--ks-control-width-date: 140px; /* Standard Date Field Default Width 140px */
--ks-grid-row-height: 28px; /* Ultra-Dense Grid Row 28px */
--ks-grid-header-height: 30px; /* Grid Header 30px */
--ks-content-max: 100%; /* Full Screen Utilization */
@@ -266,34 +271,90 @@
}
/* Raw Table Standard Grid Class for legacy fallback tables */
.grid-table, .kbx-grid-table, .models-table, .shadow-runs-table {
.grid-table, .kbx-grid-table, .models-table, .shadow-runs-table, .ks-grid-table {
width: 100%;
border-collapse: collapse;
font-size: var(--ks-font-grid);
background: var(--ks-color-surface);
border: 1px solid var(--ks-color-border);
border: 1px solid var(--ks-color-border-strong);
border-radius: var(--ks-radius-sm);
}
.grid-table th, .kbx-grid-table th, .models-table th, .shadow-runs-table th {
height: 30px;
.grid-table th, .kbx-grid-table th, .models-table th, .shadow-runs-table th, .ks-grid-table th {
height: var(--ks-grid-header-height, 30px);
padding: 0 10px;
background-color: var(--ks-color-canvas);
border-bottom: 1px solid var(--ks-color-border);
font-weight: 600;
background-color: #f1f5f9;
border-bottom: 2px solid var(--ks-color-border-strong);
font-weight: 700;
text-align: left;
color: var(--ks-color-text-muted);
color: var(--ks-color-neutral-900);
}
.grid-table td, .kbx-grid-table td, .models-table td, .shadow-runs-table td {
height: 28px;
[data-theme='dark'] .grid-table th,
[data-theme='dark'] .kbx-grid-table th,
[data-theme='dark'] .models-table th,
[data-theme='dark'] .shadow-runs-table th,
[data-theme='dark'] .ks-grid-table th {
background-color: #1e293b;
color: #f8fafc;
border-bottom: 2px solid #475569;
}
.grid-table td, .kbx-grid-table td, .models-table td, .shadow-runs-table td, .ks-grid-table td {
height: var(--ks-grid-row-height, 28px);
padding: 0 10px;
border-bottom: 1px solid var(--ks-color-border);
color: var(--ks-color-text);
box-sizing: border-box;
color: var(--ks-color-neutral-950);
box-sizing: border-border-box;
}
.grid-table tr:hover, .kbx-grid-table tr:hover, .models-table tr:hover, .shadow-runs-table tr:hover {
background-color: var(--ks-color-neutral-100);
[data-theme='dark'] .grid-table td,
[data-theme='dark'] .kbx-grid-table td,
[data-theme='dark'] .models-table td,
[data-theme='dark'] .shadow-runs-table td,
[data-theme='dark'] .ks-grid-table td {
color: #f8fafc;
border-bottom: 1px solid #334155;
}
/* Zebra Stripes & Hover & Selection Rules */
.grid-table tr:nth-child(even), .kbx-grid-table tr:nth-child(even), .ks-grid-table tr:nth-child(even) {
background-color: #ffffff;
}
.grid-table tr:nth-child(odd), .kbx-grid-table tr:nth-child(odd), .ks-grid-table tr:nth-child(odd) {
background-color: #f8fafc;
}
[data-theme='dark'] .grid-table tr:nth-child(even),
[data-theme='dark'] .kbx-grid-table tr:nth-child(even),
[data-theme='dark'] .ks-grid-table tr:nth-child(even) {
background-color: #0f172a;
}
[data-theme='dark'] .grid-table tr:nth-child(odd),
[data-theme='dark'] .kbx-grid-table tr:nth-child(odd),
[data-theme='dark'] .ks-grid-table tr:nth-child(odd) {
background-color: #090d16;
}
.grid-table tr:hover, .kbx-grid-table tr:hover, .models-table tr:hover, .shadow-runs-table tr:hover, .ks-grid-table tr:hover, .ks-grid-row:hover {
background-color: #e0f2fe !important;
}
[data-theme='dark'] .grid-table tr:hover,
[data-theme='dark'] .kbx-grid-table tr:hover,
[data-theme='dark'] .models-table tr:hover,
[data-theme='dark'] .shadow-runs-table tr:hover,
[data-theme='dark'] .ks-grid-table tr:hover,
[data-theme='dark'] .ks-grid-row:hover {
background-color: #334155 !important;
}
.grid-table tr.selected, .ks-grid-table tr.selected, .ks-grid-row.selected {
background-color: #dbeafe !important;
color: #1e3a8a !important;
font-weight: 700;
}