> For the complete documentation index, see [llms.txt](https://noraent.gitbook.io/nora/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://noraent.gitbook.io/nora/documentation/customization/styling.md).

# 스타일링

노라 그리드는 css를 쉽게 덮어쓸 수 있습니다.

### 스타일 구성요소

Nora DataGrid는 Emotion 기반의 스타일 엔진을 사용하여, 프로젝트 전반에 걸쳐 일관된 스타일 관리와 유연한 테마 확장이 가능합니다.&#x20;

{% hint style="warning" %}
현재 그리드는 Emotion 기반의 스타일 엔진을 사용하고 있습니다.

React 17에서 React 18로 업데이트되면서 서버 컴포넌트(Server Components) 개념이 도입되어, App Router 및 Server Router 방식 간의 호환성 문제가 발생했습니다.

이에 따라 Nora DataGrid는 기존 엔진을 완전히 교체하기보다는, Tailwind와의 통합(Tailwind Integration) 방향으로 향후 지원을 확대할 예정입니다.

**🚧 논의 단계**
{% endhint %}

### 스타일링

각 구성 요소에는 고유한 CSS 클래스 네임이 내부적으로 정의되어 있어, Emotion 스타일 외에도 CSS 선택자를 활용한 세부 스타일 커스터마이징이 가능합니다.

{% hint style="info" %}
클래스명을 직접 지정해 사용할 경우, **`-root`**&#xAC00; 붙은 클래스명을 사용하는 것이 유지보수에 유리합니다.

-root 클래스명은 버전이 업데이트되더라도 대부분 유지되므로, 스타일 안정성을 확보할 수 있습니다.
{% endhint %}

```tsx
import { classes } from "@noraent/nora-datagrid";

import { columns, dataSource } from './constants';

function App() {
  return (
    <div style={{ height: 400, width: '100%' }}>
      <DataGrid
        columns={columns}
        dataSource={dataSource}
        style={{
            [`&.${classes.TableClasses.container.root}`]: {
              background: "red",
            },
            // OR
            ".NoraDataGrid-root": {
              background: "red",
            }
        }}
      />
    </div>
  );
}

export default App;
```

### CSS 네이밍 구조

개발자 도구를 사용하여 그리드 Element를 탐색할 수 있습니다. 수정하고자 하는 Element 스타일 중 -root로 끝나는 클래스명을 찾아 해당 이름으로 스타일을 지정하여 쉽게 적용할 수 있습니다.

아래는 css 네이밍 Viewer 입니다.  클래스명을 직접 사용하지 않는경우 참고해 주세요.

```
// Tree
준비중.
```

### 스타일 적용 예시

#### **css 네이밍 기준 스타일 적용**

```tsx
import { classes } from "@noraent/nora-datagrid";

import { columns, dataSource } from './constants';

function App() {
  return (
    <div style={{ height: 400, width: '100%' }}>
      <DataGrid
        columns={columns}
        dataSource={dataSource}
        style={{
          [`&.${classes.TableClasses.container.root}`]: {
              background: "#f7f7f7ff",
              [`& .${classes.TableClasses.title.header.root}`]: {
                [`& .${classes.TableClasses.title.header.row.cell.root}`]: {
                  background: "#fff",
                  borderBottomColor: "#b7decf",
                  [`& .${classes.TableClasses.title.header.row.cell.con.root}`]: {
                    color: "#3b4944ff",
                    ":hover": {
                      color: "#0c9762ff",
                    },
                  },
                },
              },
            },
        }}
        // OR
        "&.NoraDataGrid-root":{
          background: "#f7f7f7ff",
          "& .NoraDataGridHeader-root":{
            "& .NoraDataGridHeaderCell-root":{
              background: "#fff",
              borderBottomColor: "#b7decf",
              "& .NoraDataGridCon-root":{
                color: "#3b4944ff",
                ":hover": {
                  color: "#0c9762ff",
                },
              }
            }
          }
        }
      />
    </div>
  );
}

export default App;
```

***

#### **Provider**  :tada: <mark style="color:green;">new</mark>

ThemeProvider는 Nora DataGrid의 전체 테마 설정을 적용하는 컨텍스트 제공자입니다. 그리드의 색상, 폰트, 간격 등 공통 스타일을 한 번에 정의하고, 하위 그리드 컴포넌트들이 일관된 테마를 공유할 수 있습니다.

```tsx
import { ThemeProvider } from "@noraent/nora-datagrid";
```

```tsx

import { ThemeProvider as NoraDataGridThemeProvider } from '@noraent/nora-datagrid';
import { DataGrid } from '@noraent/nora-datagrid';

const theme:GridTheme = {
  mode: 'dark',
  ...
};
// or
const theme = createTheme({
  mode: 'dark',
});

function App() {
  return (
    <NoraDataGridThemeProvider theme={theme}>
      <DataGrid ... />
    </NoraDataGridThemeProvider>
  );
}
```

#### createTheme  :tada: <mark style="color:green;">new</mark>

사용자 정의 테마 객체를 안전하게 생성하는 유틸 함수입니다.  `createTheme`를 사용하면 기본 스타일은 유지하면서, 원하는 특정 스타일만 안전하게 수정할 수 있습니다.

{% hint style="danger" %}
**커스텀 컴포넌트 스타일 적용 시 주의사항**&#x20;

Row의 높이를 임의로 변경하지 마세요. Nora Data Grid는 대용량 데이터를 효율적으로 처리하기 위해 가상 스크롤(virtual scroll) 을 지원합니다. Row 높이를 변경하려면 별도의 전용 핸들링 이벤트를 통해 조정해야 합니다.
{% endhint %}

```tsx
import { createTheme } from "./types";
```

```tsx
const theme = createTheme({
  mode: "dark",
  ...
  // Nora DataGrid에서 지원하는 컴포넌트별 토큰 입니다. 그리드 색상, 간격 등 커스텀 하고싶을때 사용해주세요.
  components: {
    HeaderCell: {
      ...
    },
  },
  // `customVars`를 사용하면 사용자 정의 CSS 변수와 값을 정의할 수 있습니다. 
  // 기본 Nora DataGrid에서 사용하는 변수 값을 수정하거나, 새로운 규칙을 추가할 수 있습니다.
  customVars: {
    ":root": {
      "--noraDataGrid-skeleton-bg-1": "#3a3a3a",
      "--noraDataGrid-skeleton-bg-2": "red",
    },
  },
});
```

#### Custom Theme

커스텀 테마 예시 입니다.

{% tabs %}
{% tab title="Theme 1" %}
{% embed url="<https://stackblitz.com/edit/vitejs-vite-kaakk2dk?ctl=1&embed=1&file=src%2FApp.tsx&hideExplorer=1&hideNavigation=1&view=preview>" %}
{% endtab %}

{% tab title="Theme 2" %}
준비중.
{% endtab %}
{% endtabs %}

***

#### 셀 스타일링

셀에 사용자가 원하는 CSS 클래스를 적용할 수 있습니다.

cellClassName에서는 [GridCellPramsV2](/nora/api-reference/interfaces/gridcellpramsv2.md) 속성을 사용해주세요.

cellClassName은 초기 마운트시 또는 row 값이 변경 될때 마다 콜백 합니다.

```tsx

import { DataGridColDef, GridCellPrams, GridCellPramsV2 } from "@noraent/nora-datagrid";

export const columns: DataGridColDef = [
  {
    fieldId: "pnl",
    fieldName: "P&L",
    width: 90,
    textAlign: "right",
    cellClassName: (params: GridCellPramsV2) => {
      const [prev, current] = params.value;
      if (prev === undefined) return "custom-cell-border";
      if (current > prev) return "custom-cell-border super-up";
      if (current < prev) return "custom-cell-border super-down";
      return "";
    },
  },
];

// ========== OR ========== 

export const columns: DataGridColDef = [
  {
    fieldId: "pnl",
    fieldName: "P&L",
    width: 90,
    textAlign: "right",
    cellClassName: "custom-cell-border"
  },
];

```

{% tabs %}
{% tab title="응용 예제" %}
{% embed url="<https://stackblitz.com/edit/vitejs-vite-emkwpmst?ctl=1&embed=1&hideExplorer=1&hideNavigation=1&view=preview>" %}
{% endtab %}
{% endtabs %}
