import { type HTMLAttributes } from 'react';
import type { SGnbHeader, SGnbType } from '../SGnb/gnb.config';
/** 메뉴 스타일: box(라운드) / belt(풀폭 행) — 자식 SGnb 의 메뉴 모양 */
export type SLayoutType = SGnbType;
/** 레이아웃 구조: fix(좌측 GNB + 페이지 가로 분할) / full(풀폭 상단바 + 아래에 메뉴|페이지) */
export type SLayoutHeader = SGnbHeader;
/**
* 자식 GNB 가 SLayout 에 올리는 자기 치수·요구사항.
*
* SLayout 은 GNB 의 내부 상수(레일·메뉴 폭, 상단바 높이, 전환 길이)도 items·activeRail 도 모른다 —
* 치수를 아는 쪽이 올리고 프레임은 받아 쓰기만 한다. GNB 내부 치수가 바뀌어도 프레임은 따라온다.
*/
export interface SLayoutNavState {
/**
* 펼친 GNB 컬럼 폭(px). 레일·메뉴 유무를 반영한 합이다.
* 접힘은 SLayout 이 folded 로 따로 접으므로 여기엔 펼친 폭만 담는다.
*/
columnWidth: number;
/** 상단바 높이(CSS 길이) — header="full" 그리드의 1행 높이가 된다. */
topHeight: string;
/** 접힘 전환 길이(ms) — 페이지 열이 메뉴와 같은 길이로 미끄러지도록 맞춘다. */
foldMs: number;
/**
* 상단바가 레이아웃 전폭이어야 하는지.
* 레일에 리프 아이템이 있으면 메뉴 폭이 출렁여 fix 상단바가 함께 흔들리므로 GNB 가 true 로 올린다.
* true 면 header prop 과 무관하게 full 로 선다.
*/
requireFullHeader: boolean;
/**
* GNB 폭을 지금 드래그로 조절하는 중인지.
* 참이면 메뉴 열의 폭 전환을 끈다 — 접힘용 전환(foldMs)이 그대로 걸려 있으면
* 열이 손보다 그 길이만큼 늦게 따라와 끌리는 느낌이 사라진다.
*/
resizing?: boolean;
}
export interface SLayoutContextValue {
/** 메뉴 스타일 — 자식 SGnb 가 스타일을 맞추는 기준 */
type: SLayoutType;
/**
* 상단바 구조 — 자식 SGnb·SPage 가 배치를 맞추는 기준(유효 header).
* 등록된 GNB 가 requireFullHeader 를 올리면 여기에도 full 로 반영된다.
*/
header: SLayoutHeader;
/** GNB 좌측 레일 사용 여부 — 자식 SGnb 가 따른다 */
useRail: boolean;
/** GNB 접힘 상태 */
folded: boolean;
/** 접힘 상태 변경 */
setFolded: (folded: boolean) => void;
/**
* 자식 GNB 가 자기 치수·요구사항을 등록한다. 언마운트하거나 SLayout 밖으로 나가면 null 로 해제한다.
* 페인트 전에 반영돼야 하므로 GNB 쪽에서 layout effect 로 호출한다.
*/
registerNav: (nav: SLayoutNavState | null) => void;
}
export declare const SLayoutContext: import("react").Context;
/**
* 레이아웃이 보장하는 최소 가로 폭(px). GNB 를 포함한 전체 기준이다.
* 전용 토큰이 없어 상수로 둔다(GNB_MENU_WIDTH 와 같은 이유).
*
* 창이 이보다 좁아져도 프레임 자체는 창을 넘지 않는다 — 모자란 몫은 SPage 가 가로 스크롤로 삼킨다.
* 그래서 GNB·상단바는 제자리에 남고 문서(창)에는 스크롤이 생기지 않는다.
*/
export declare const SLAYOUT_MIN_WIDTH = 1366;
/**
* SPage 가 자기 콘텐츠의 최소 폭을 계산할 때 읽는 변수. SLayout 이 프레임에 심는다.
* SLayout 밖의 SPage 는 이 변수가 없어(폴백 0) 최소 폭 규칙이 걸리지 않는다.
*/
export declare const SLAYOUT_MIN_WIDTH_VAR = "--s-layout-min-width";
/**
* SLayout 의 상태를 읽고 제어한다. `` 밖에서 호출하면 throw.
* 외부 버튼으로 GNB 를 접거나, 현재 구조(header)·메뉴 스타일(type)에 따라 분기할 때 사용한다.
*/
export declare function useSLayout(): SLayoutContextValue;
export interface SLayoutProps extends HTMLAttributes {
/** 메뉴 스타일: box(라운드) / belt(풀폭 행). 자식 SGnb 가 이 값을 따른다. */
type?: SLayoutType;
/** 레이아웃 구조: fix(가로 분할) / full(풀폭 상단바). 자식 SGnb·SPage 가 이 값을 따른다. */
header?: SLayoutHeader;
/**
* GNB 좌측 레일 사용 여부. 자식 SGnb 가 이 값을 따르고, 그만큼 넓어진 컬럼 폭을 되올린다.
* 레일에 children 없는 아이템이 있으면 SGnb 가 full 상단바를 요구하고, 이 레이아웃도 그에 맞춰 full 그리드로 선다.
*/
useRail?: boolean;
/** GNB 접힘 상태 (controlled) */
folded?: boolean;
/** GNB 초기 접힘 상태 (uncontrolled) */
defaultFolded?: boolean;
/** 접힘 상태 변경 */
onFoldedChange?: (folded: boolean) => void;
}
/**
* SLayout — 앱 셸 프레임 겸 context provider.
* header 가 배치를 결정하고 overflow:hidden 으로 스크롤 경계를 만든다.
* 자식 SGnb·SPage 는 context 에서 type·header·folded 를 읽으므로 앱은 이 값들을 여기 한 곳에만 쓴다.
* 높이는 기본 100%(부모를 채움) — 앱 루트로 쓸 땐 부모를 뷰포트 높이로 잡는다.
*
* 가로는 SLAYOUT_MIN_WIDTH 를 최소 폭으로 보장한다. 창이 그보다 좁아도 프레임은 창 폭을 그대로 받고,
* 모자란 몫은 SPage 가 가로 스크롤로 삼킨다 — GNB·상단바는 제자리에 남고 문서엔 스크롤이 생기지 않는다.
*
* 치수는 자식이 소유한다: GNB 가 registerNav 로 컬럼 폭·상단바 높이·전환 길이를 올리고
* 이 프레임은 그 값으로 그리드를 깐다(SLayout 은 GNB 내부 상수를 import 하지 않는다).
*
* - header="fix": [GNB(자기 폭 소유) | 페이지] 가로 flex. 프레임이 폭에 관여하지 않는다.
* - header="full": 이름 있는 영역으로 깐 그리드다.
* "header header" ← 전폭 상단바 (1행, 높이 = 등록된 topHeight)
* "nav page" ← 메뉴 열(등록된 columnWidth) | 페이지
* 접으면 nav 열을 0 으로 접어 페이지가 전폭을 쓴다.
*/
export declare const SLayout: import("react").ForwardRefExoticComponent>;