전체 글 115

ExtJS 사용자를 위한 다음 단계: VanillaFront

시작하며ExtJS는 훌륭한 프레임워크였고, 지금도 많은 한국 기업의 사내 시스템·관리자 페이지·대시보드를 돌리고 있습니다. 그리드·폼·레이아웃이 한 세트로 제공되는 "batteries included" 철학은 사내 시스템처럼 화면 수가 많고 시각적 통일성이 중요한 프로젝트에 정확히 맞았습니다.하지만 2020년대 중반, ExtJS를 유지하는 개발팀은 몇 가지 무거운 질문에 직면합니다.Sencha가 Idera에 인수된 후 라이선스 정책·가격이 강화되었고,ExtJS 4/5는 사실상 EOL, 모던 브라우저 대응·보안 패치가 부담이 되며,모던 개발 워크플로우 (AI 코드 생성, VSCode 통합) 와 거리가 멀어졌습니다.이 글은 그런 팀들에게 VanillaFront가 왜 자연스러운 다음 단계가 되는지 — 익숙한 ..

GridDiv (그리드 디비전)

Va.GridDiv — CSS Grid 기반 격자 레이아웃 컨테이너CSS Grid를 이용해 셀 단위 격자 레이아웃을 만드는 컨테이너입니다. Va.Component를 직접 상속받으며 display: grid가 자동 적용되어, 실제 데이터 그리드(Va.Grid)와는 다른 목적의 정적 격자 레이아웃(카드 나열, 폼 격자 배치, 스프레드시트 스타일 표 등)에 사용됩니다.클래스 정보Va.GridDiv extends Va.ComponenttagName: 'gridDiv' (실제 렌더링은 )isContainer: trueisEnableRoot: true파일: va_griddiv.js (별도 모듈)짝을 이루는 3형제va_griddiv.js 하나에 세 컴포넌트가 함께 정의되어 있으며, 함께 사용하는 것이 표준 패턴입니다..

SearchPanel (조회패널)

Va.SearchPanel — 조회 조건 전용 패널 컨테이너목록/그리드 화면 상단의 "조회 조건 입력 영역"을 위한 전용 패널입니다. Va.Semantic을 상속받아 태그로 렌더링되며, va-search-panel 클래스가 부여되어 테두리·상단 강조선·hover 그림자 등 검색 폼 전용 시각 스타일이 자동 적용됩니다.클래스 정보Va.SearchPanel extends Va.Semantic extends Va.ComponenttagName: 'searchPanel' (실제 렌더링은 )isContainer: true기본 사용법{ tagName: 'searchPanel', layout: 'ds-flex fd-row ai-center gap-s', tags: [ { tagName:..

TitleBar (타이틀바)

Va.TitleBar — 제목과 액션을 함께 놓는 상단 바 컨테이너제목 텍스트와 액션 버튼을 한 줄에 나란히 배치하는 상단 바 전용 컨테이너입니다. Va.Div를 상속받으며 va-title-bar 클래스가 부여되어 flex row 레이아웃 + 타이틀 바 전용 padding이 자동 적용됩니다.클래스 정보Va.TitleBar extends Va.Div extends Va.ComponenttagName: 'titleBar' (실제 렌더링은 )isContainer: true기본 사용법{ tagName: 'titleBar', tags: [ { tagName: 'title', innerHTML: '사용자 목록' }, { tagName: 'div', style: { flex: 1 ..

SubTitle (서브타이틀)

Va.SubTitle — Title 아래의 보조 제목 컴포넌트Title 아래에 오는 보조/부제목을 표시하는 전용 컨테이너입니다. Va.Div를 상속받으며 va-sub-title 클래스가 부여되어 테마별 보조 제목 스타일(작은 폰트, 옅은 색상 등)이 자동 적용됩니다. 클래스 정보Va.SubTitle extends Va.Div extends Va.ComponenttagName: 'subTitle' (실제 렌더링은 )isContainer: true기본 사용법{ tagName: 'subTitle', innerHTML: '2026년 3월 기준'}또는 코드로:let subTitle = new Va.SubTitle({ text: '(선택 사항)'});parent.append(subTitle);Tit..