๊ธ์ตยท๊ณต๊ณต SI ํ๋ก์ ํธ๋ฅผ ๋ชฉํ๋ก ์ค๊ณ ์ค์ธ ์ํฐํ๋ผ์ด์ฆ ํ๋ก ํธ์๋ ๋ฐ์ดํฐ ๊ทธ๋ฆฌ๋
OneGrid๋ ๋จ์ ํ ์ด๋ธ ์ปดํฌ๋ํธ๊ฐ ์๋๋ผ, ๋์ฉ๋ ๋ฐ์ดํฐ ์กฐํยทํธ์งยท๋ณด์ยท์ ๊ทผ์ฑยท๋ฌธ์ํยทํ๋ ์์ํฌ ๋ํผ๊น์ง ํฌํจํ๋ ์์ฉ ๊ทธ๋ฆฌ๋ 1.0์ ๋ชฉํ๋ก ๊ฐ๋ฐ๋๊ณ ์์ต๋๋ค.
ํ์ฌ ๋ฒ์ ์
0.0.0ํ๋ฆฌ ๋ฆด๋ฆฌ์ฆ ๋จ๊ณ์ ๋๋ค. API๋ 1.0 ์์ ํ ์ ๊น์ง ๋ณ๊ฒฝ๋ ์ ์์ผ๋ฉฐ, ๋ณ๊ฒฝ ์ฌํญ์API_CHANGELOG.md์ ๊ธฐ๋กํฉ๋๋ค.
| ์์ญ | ์ํ |
|---|---|
| ํจํค์ง ๊ตฌ์กฐ | core, dom, react, vue, themes, pagination, adapters, testing ๋ถ๋ฆฌ |
| ๋ฐ์ดํฐ ๋ชจ๋ธ | Client, Infinite, Server, Viewport, Tree row model baseline |
| ๋์ฉ๋ ์ ๋ต | 10M/100M rows๋ ์ ์ฒด ๋ฐฐ์ด/DOM์ด ์๋๋ผ Server/Viewport/Segmented virtual scroll ๊ธฐ๋ฐ |
| ๋ ์ด์์ | pinned pane, frozen rows/columns, row/column virtualization, header/cell merge |
| ํต์ฌ ๊ธฐ๋ฅ | sort, filter, edit, selection, clipboard, menu, summary, grouping, tree, pivot, pagination |
| ๋ณด์ | CSP nonce, text-only ๊ธฐ๋ณธ ๋ ๋๋ง, sanitizer hook, URL protocol allowlist |
| ๋ํผ | Vanilla DOM, React, Vue API parity baseline |
| ๋ฌธ์/์์ | Docusaurus ๋ฌธ์์ Vanilla/React/Vue ์์ ์นดํ๋ก๊ทธ ์ด์ |
| Column Virtualization | Pivot | Pagination |
|---|---|---|
![]() |
![]() |
![]() |
- ๐ฆ SI ์นํ ๊ตฌ์กฐ: ๊ธ์ตยท๊ณต๊ณต ํ๋ก์ ํธ์์ ์๊ตฌํ๋ ๊ณ ์ ์ปฌ๋ผ, ๋ณํฉ, ์๋ฒ ๋ฐ์ดํฐ, ํธ์ง ์ด๋ ฅ, ๋ณด์ ์ ์ฑ ์ ์ฒ์๋ถํฐ ๊ณ ๋ คํฉ๋๋ค.
- ๐งฑ ๋ถ๋ฆฌ๋ ์ํคํ
์ฒ:
@onegrid/core๋ DOM์ ์์กดํ์ง ์๊ณ ,@onegrid/dom,@onegrid/react,@onegrid/vue๊ฐ ๋์ผํ ๊ณ์ฝ์ ์๋นํฉ๋๋ค. - ๐ ๋์ฉ๋ ๊ธฐ์ค์ ์ค๊ณ: 10M ~ 100M rows๋ client array๊ฐ ์๋๋ผ row model๊ณผ segmented viewport mapping์ผ๋ก ๋ค๋ฃน๋๋ค.
- ๐ ์์ ํ ๊ธฐ๋ณธ๊ฐ: ๋ฌธ์์ด ๋ ๋๋ง์ ๊ธฐ๋ณธ์ ์ผ๋ก text ์ฒ๋ฆฌ๋๊ณ , HTML ๋ ๋๋ง์ sanitizer๊ฐ ์๋ ๋ช ์์ opt-in์ผ๋ก ์ ํํฉ๋๋ค.
- โฟ ์ค์ฌ์ฉ ์ ๊ทผ์ฑ: ํค๋ณด๋ ํฌ์ปค์ค, ARIA grid semantics, header/menu interaction์ E2E๋ก ๊ฒ์ฆํฉ๋๋ค.
- ๐จ ํ ๋ง ํ์ฅ์ฑ: CSS variable ๊ธฐ๋ฐ theme foundation๊ณผ SI tenant palette๋ฅผ ์ ๊ณตํฉ๋๋ค.
| ํจํค์ง | ์ญํ |
|---|---|
@onegrid/core |
public type, column/row/state/event/plugin contract, ์์ ๋ก์ง |
@onegrid/dom |
DOM renderer, virtualization, focus, editor/menu/export runtime |
@onegrid/react |
React wrapper, ref ๊ธฐ๋ฐ GridApi, React renderer slot bridge |
@onegrid/vue |
Vue wrapper, expose ๊ธฐ๋ฐ GridApi, Vue slot bridge |
@onegrid/themes |
default theme, SI theme token, runtime theme helper |
@onegrid/pagination |
pagination contract/package baseline |
@onegrid/adapters |
import/export and external adapter boundary |
@onegrid/testing |
test helpers and shared verification utilities |
pnpm add @onegrid/core @onegrid/dom @onegrid/themesimport { OneGrid } from "@onegrid/dom";
import type { ColumnDef } from "@onegrid/core";
import "@onegrid/themes/default.css";
interface OrderRow {
readonly id: string;
readonly customer: string;
readonly amount: number;
readonly status: "Draft" | "Approved" | "Rejected";
}
const columns: readonly ColumnDef<OrderRow>[] = [
{ field: "id", headerName: "ID", pinned: "left" },
{ field: "customer", headerName: "Customer" },
{ field: "amount", headerName: "Amount", type: "number" },
{ field: "status", headerName: "Status", filter: "set" }
];
const rows: readonly OrderRow[] = [
{ id: "ORD-1001", customer: "Han Public Office", amount: 1200000, status: "Approved" },
{ id: "ORD-1002", customer: "Korea Finance", amount: 450000, status: "Draft" },
{ id: "ORD-1003", customer: "Metro Audit Team", amount: 780000, status: "Rejected" }
];
const grid = new OneGrid<OrderRow>({
el: document.querySelector("#grid") as HTMLElement,
columns,
data: rows,
rowModel: "client",
accessibility: { label: "Orders grid" }
});
grid.selectRows(["ORD-1001"]);pnpm add @onegrid/react @onegrid/core @onegrid/dom @onegrid/themesimport { useRef } from "react";
import { OneGrid, type OneGridHandle } from "@onegrid/react";
import "@onegrid/themes/default.css";
export function OrdersGrid() {
const gridRef = useRef<OneGridHandle<OrderRow>>(null);
return (
<OneGrid<OrderRow>
ref={gridRef}
columns={columns}
data={rows}
rowKey="id"
rowModel="client"
accessibility={{ label: "Orders grid" }}
onSelectionChanged={(event) => console.log(event.rowKeys)}
/>
);
}pnpm add @onegrid/vue @onegrid/core @onegrid/dom @onegrid/themes<script setup lang="ts">
import { ref } from "vue";
import { OneGrid, type OneGridExpose } from "@onegrid/vue";
import "@onegrid/themes/default.css";
const grid = ref<OneGridExpose>();
</script>
<template>
<OneGrid
ref="grid"
:columns="columns"
:data="rows"
row-key="id"
row-model="client"
:accessibility="{ label: 'Orders grid' }"
/>
</template>field๊ธฐ๋ฐ ์ปฌ๋ผ๊ณผcolumnId๊ธฐ๋ฐ fieldless column์ ๋ชจ๋ ์ง์ํฉ๋๋ค.defaultColumnDef,columnTypes,columnState,getColumnState,setColumnState,resetColumnState๋ฅผ ์ ๊ณตํฉ๋๋ค.- group header, header merge, pinned column, column resize/move/hide UI๋ฅผ ์์ ์ E2E ๊ธฐ์ค์ผ๋ก ๊ด๋ฆฌํฉ๋๋ค.
client: ๋ธ๋ผ์ฐ์ ๋ฉ๋ชจ๋ฆฌ์ ์ ํฉํ ๋ฐ์ดํฐ์ ์ฉ์ ๋๋ค.infinite: block request์ lazy loading ๊ธฐ๋ฐ์ ๋๋ค.server: ์๋ฒ ์ ๋ ฌ/ํํฐ/๊ทธ๋ฃน ํ์ฅ ์์ฒญ์ ๋ถ๋ฆฌํฉ๋๋ค.viewport: ๋ ผ๋ฆฌ row index์ visible range ๊ธฐ๋ฐ ๋์ฉ๋ ํ์์ฉ์ ๋๋ค.tree: hierarchical row ํ์์ expand/collapse baseline์ ์ ๊ณตํฉ๋๋ค.
- cell editing, batch edit session, pending edit history, commit/cancel, undo/redo edit stack์ ์ ๊ณตํฉ๋๋ค.
Tab,Enter,Escape,Backspaceํธ์ง ์ ์ฑ ์ ๋ฌธ์ํํ๊ณ ํค๋ณด๋ ์ด๋๊ณผ ์คํฌ๋กค ๋๊ธฐํ๋ฅผ ๋ณด๊ฐํ์ต๋๋ค.- read-only edit / external state integration์ ํตํด wrapper controlled state์ ์ฐ๋ํ ์ ์์ต๋๋ค.
- CSV, XLSX, PDF, print layout export๋ฅผ ์ ๊ณตํฉ๋๋ค.
- import๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๊ธฐ์กด ๋ฐ์ดํฐ๋ฅผ ๊ต์ฒดํ๋ฉฐ, append ๋ฐฉ์์ ๋ณ๋ ์ต์ ์ผ๋ก ๋ถ๋ฆฌํฉ๋๋ค.
- merge layout, grouped header, paged data, wide columns๋ฅผ ์์ฉ ์ฐ์ถ๋ฌผ ํ์ง ๊ธฐ์ค์ผ๋ก ๊ณ์ ๊ฒ์ฆํฉ๋๋ค.
OneGrid์ 10M ~ 100M rows ์ง์์ ์๋๋ฅผ ์๋ฏธํฉ๋๋ค.
- ์ ์ฒด row ๋ฐฐ์ด์ ๋ธ๋ผ์ฐ์ ์ ์ฌ๋ฆฌ์ง ์์ต๋๋ค.
- ์ ์ฒด row DOM์ ๋ง๋ค์ง ์์ต๋๋ค.
ServerRowModel,InfiniteRowModel,ViewportRowModel, segmented virtual scroll mapping์ผ๋ก ํ์ํฉ๋๋ค.- request dedupe, cancellation, cache window, logical row index๋ฅผ ์กฐํฉํฉ๋๋ค.
๊ธ์ง๋๋ ๋ฐฉ์:
// ๊ธ์ง: 100M rows ์ ์ฒด ๋ฐฐ์ด ์์ฑ
const rows = Array.from({ length: 100_000_000 }, createRow);๊ถ์ฅ ๋ฐฉ์:
const grid = new OneGrid({
el,
columns,
rowModel: "viewport",
dataSource: {
async getRows({ startRow, endRow }) {
return {
rows: await fetchRows(startRow, endRow),
rowCount: 100_000_000
};
}
},
viewport: {
initialRowCount: 100_000_000,
viewportSize: 60,
overscan: 24
},
virtualization: {
segmented: true,
rowHeight: 30
}
});eval,new Function, inline event handler๋ฅผ ์ฌ์ฉํ์ง ์์ต๋๋ค.- ๊ธฐ๋ณธ cell/header renderer๋ ๋ฌธ์์ด์ HTML์ด ์๋๋ผ text๋ก ์ฒ๋ฆฌํฉ๋๋ค.
- HTML renderer๋ ๋ช ์์ opt-in์ด๋ฉฐ sanitizer๋ฅผ ์ฃผ์ ํด์ผ ํฉ๋๋ค.
- CSP nonce ๊ธฐ๋ฐ style injection์ ์ง์ํฉ๋๋ค.
- URL formatter๋
http:,https:,mailto:,tel:๋ฑ ํ์ฉ protocol๋ง ํต๊ณผ์ํต๋๋ค.
๊ด๋ จ ๋ฌธ์:
@onegrid/themes๋ CSS variable ๊ธฐ๋ฐ์ผ๋ก ๊ตฌ์ฑ๋์ด ์๊ณ , tenant ๋จ์ ํ
๋ง๋ฅผ ๋ฐํ์์ ์ ์ฉํ ์ ์์ต๋๋ค.
import { createSiTheme } from "@onegrid/themes";
const theme = createSiTheme({
name: "bnk-red",
density: "compact",
tokens: {
colors: {
accent: "rgb(215 25 31)",
accentHover: "rgb(139 3 4)",
border: "rgb(183 169 151)",
header: "rgb(248 250 252)",
selected: "rgb(255 238 238)",
muted: "rgb(101 92 79)"
}
}
});์์ ์นดํ๋ก๊ทธ์๋ BNK CI ์์์ ๊ธฐ์ค์ผ๋ก ์๋ ๊ณ์ด์ ๊ตฌ์ฑํด ๋ SI ํ๋ ํธ ์์ ๊ฐ ํฌํจ๋์ด ์์ต๋๋ค.
si-bnk-redsi-bnk-goldsi-bnk-gray
pnpm install
pnpm --filter @onegrid/examples dev --host 127.0.0.1 --port 4174๋ธ๋ผ์ฐ์ ์์ ์๋ ์ฃผ์๋ฅผ ์ฝ๋๋ค.
http://127.0.0.1:4174
์์ฃผ ๋ณด๋ ์์ :
| ๊ฒฝ๋ก | ํ์ธ ํฌ์ธํธ |
|---|---|
/#COL-003 |
์ปฌ๋ผ UI, ๋ฉ๋ด, resize, pin/hide/move |
/#ROW-003 |
Server row model๊ณผ group expand request |
/#LAY-003 |
Column virtualization๊ณผ pinned pane scroll sync |
/#LAY-004 |
Cell merge layout๊ณผ range selection |
/#F-EDIT |
Batch edit, pending edits, undo/redo |
/#F-EXPORT |
CSV/XLSX/PDF/print/import |
/#F-I18N |
๋ฐํ์ locale ๋ณ๊ฒฝ |
/#SEC-001 |
CSP nonce ์์ |
/#THEME-002 |
SI theme customization |
/#EX-005-006 |
100M viewport rows setup |
pnpm lint
pnpm typecheck
pnpm test:unit
pnpm test:e2e
pnpm test:a11y
pnpm test:perf:smoke
pnpm build
pnpm docs:build์๊ฐ ํ๊ท smoke:
pnpm test:e2e:visual| ๋ฌธ์ | ์ฉ๋ |
|---|---|
AGENTS.md |
๊ฐ๋ฐ ์์ด์ ํธ ์ด์ ๊ท์น๊ณผ ํ์ง ๊ธฐ์ค |
ARCHITECT.md |
์ํคํ ์ฒ ์์น, ํจํค์ง ๊ฒฝ๊ณ, ๋์ฉ๋ ์ ๋ต |
CHECKLIST.md |
๋ก๋๋งต, ์๋ฃ ์ฆ๋น, ๋ฆฌ์คํฌ/๊ฒฐ์ ๊ธฐ๋ก |
API_CHANGELOG.md |
public API ๋ณ๊ฒฝ ์ด๋ ฅ |
SECURITY.md |
๋ณด์ ์ ์ฑ ๊ณผ ๊ธฐ๋ณธ๊ฐ |
apps/docs/docs/api |
GridOptions, ColumnDef, GridApi, Events, Plugins |
apps/docs/docs/features |
๊ธฐ๋ฅ๋ณ ๊ฐ์ด๋ |
apps/docs/docs/frameworks |
React, Vue, API parity |
apps/docs/docs/quick-start |
Vanilla, React, Vue ๋น ๋ฅธ ์์ |
OneGrid 1.0 ์ ๊น์ง ํนํ ์๋ ํญ๋ชฉ์ ๊ณ์ ๊ฐํํฉ๋๋ค.
- ๋์ฉ๋ viewport/server row model์ ๋ธ๋ผ์ฐ์ ๋ณ ์คํฌ๋กค ํ์ง
- cell/header merge์ pinned/virtualization ์กฐํฉ์ ํ๊ท ํ ์คํธ
- export/import ์ฐ์ถ๋ฌผ์ Excel/PDF/print fidelity
- framework wrapper API parity์ controlled state integration
- CSP/XSS/a11y/performance ํ์ง ๊ฒ์ดํธ ์๋ํ
๋ผ์ด์ ์ค๋ ์์ง ํ์ ๋์ง ์์์ต๋๋ค. npm/CDN ๋ฐฐํฌ ๋๋ ์ธ๋ถ ๋ฐฐํฌ ์ ํ๋ก์ ํธ ๋ผ์ด์ ์ค๋ฅผ ํ์ ํด์ผ ํฉ๋๋ค.


