@ihabdevteam/core 0.172.0 → 0.174.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -543,7 +543,7 @@ export declare interface BoardProps<T> {
543
543
  }
544
544
 
545
545
  /** @public */
546
- export declare function BottomNav({ items, activeKey, onChange, appMode, onAppModeChange, moreItems, }: {
546
+ export declare function BottomNav({ items, activeKey, onChange, appMode, onAppModeChange, moreItems, scrollContainer, }: {
547
547
  items?: NavItem[];
548
548
  activeKey?: string;
549
549
  onChange?: (key: string) => void;
@@ -551,6 +551,13 @@ export declare function BottomNav({ items, activeKey, onChange, appMode, onAppMo
551
551
  onAppModeChange?: (mode: 'malgwi' | 'manager') => void;
552
552
  /** nav 항목과 별개로 항상 더보기 메뉴에 노출되는 유틸(알림·설정·계정 등) */
553
553
  moreItems?: BottomNavMoreItem[];
554
+ /**
555
+ * 갈래를 고를 때 **맨 위로 되돌릴 본문 스크롤 통** — CSS 고르개나 ref. `SideNav` 와 같은 뜻이다.
556
+ *
557
+ * 모바일에서도 갈래를 바꾸면 본문이 위에서 시작해야 한다 — 전에는 데스크톱(SideNav)만 되돌려, 같은 앱에서
558
+ * 큰 화면은 위로 가고 작은 화면은 앞 화면의 스크롤 자리에 남았다. 유틸(더보기 메뉴의 알림·설정 등)은 갈래가 아니라 되돌리지 않는다.
559
+ */
560
+ scrollContainer?: string | RefObject<HTMLElement | null>;
554
561
  }): JSX.Element;
555
562
 
556
563
  /**
@@ -1556,7 +1563,7 @@ export declare function copyText(text: string): Promise<boolean>;
1556
1563
  *
1557
1564
  * 값은 손으로 적고 `test/coreVersion.test.ts` 가 package.json 과 어긋나면 운다.
1558
1565
  */
1559
- export declare const CORE_VERSION = "0.172.0";
1566
+ export declare const CORE_VERSION = "0.174.0";
1560
1567
 
1561
1568
  /** @public */
1562
1569
  declare const coreDefault: Record<string, unknown>;
@@ -2682,7 +2689,7 @@ export declare function hasStructureContrast(A: Decomp, B: Decomp): boolean;
2682
2689
  *
2683
2690
  * @public
2684
2691
  */
2685
- export declare function Header({ activeKey, onChange, items, malgwiItems: _malgwiItems, managerItems: _managerItems, unreadCount, onDebug, onNotification, onAccount, onSetting, onHelp, appMode, onAppModeChange }: {
2692
+ export declare function Header({ activeKey, onChange, items, malgwiItems: _malgwiItems, managerItems: _managerItems, unreadCount, onDebug, onNotification, onAccount, onSetting, onHelp, appMode, onAppModeChange, scrollContainer }: {
2686
2693
  activeKey?: string | null;
2687
2694
  onChange?: (key?: string) => void;
2688
2695
  /** 지금 모드의 내비 항목. 데스크톱은 SideNav, 모바일은 BottomNav 가 이 목록을 그린다. */
@@ -2702,6 +2709,13 @@ export declare function Header({ activeKey, onChange, items, malgwiItems: _malgw
2702
2709
  onHelp?: () => void;
2703
2710
  appMode?: 'malgwi' | 'manager';
2704
2711
  onAppModeChange?: (mode: 'malgwi' | 'manager') => void;
2712
+ /**
2713
+ * 갈래를 고를 때 **맨 위로 되돌릴 본문 스크롤 통** — CSS 고르개나 ref. 안쪽 `SideNav`·`BottomNav` 에 그대로 넘긴다.
2714
+ *
2715
+ * 본문이 `body` 가 아니라 제 통에서 구르는 셸(`body { overflow: hidden }`)이면 **반드시 준다** — 창 굴리기는 그 앱에서 아무 일도 하지 않는다.
2716
+ * **ref 로 주는 것이 가장 낫다**: 고르개 글자로 주면 코어가 소비자 클래스 이름을 다시 붙잡는 꼴이고, ref 면 그 얽힘이 아예 없다.
2717
+ */
2718
+ scrollContainer?: string | RefObject<HTMLElement | null>;
2705
2719
  }): JSX.Element;
2706
2720
 
2707
2721
  /** @public */
@@ -5957,6 +5971,14 @@ export declare interface SideNavProps {
5957
5971
  appMode?: 'malgwi' | 'manager';
5958
5972
  /** 앱 모드 전환 콜백 */
5959
5973
  onAppModeChange?: (mode: 'malgwi' | 'manager') => void;
5974
+ /**
5975
+ * 갈래를 고를 때 **맨 위로 되돌릴 본문 스크롤 통** — CSS 고르개나 ref.
5976
+ *
5977
+ * 안 주면 `.content-area` 를 찾고(코어가 **소비자 클래스 이름을 붙잡고 있던 자리** 다 — 말귀가 그 이름을 바꾸는 날
5978
+ * 화면은 멀쩡한데 내비를 눌러도 스크롤이 안 돌아갔다), 그것도 없으면 창을 굴린다.
5979
+ * 본문이 `body` 가 아니라 제 통에서 구르는 셸(body 가 `overflow: hidden`)이면 **반드시 준다** — 창 굴리기는 그 앱에서 아무 일도 하지 않는다.
5980
+ */
5981
+ scrollContainer?: string | RefObject<HTMLElement | null>;
5960
5982
  }
5961
5983
 
5962
5984
  /**
@@ -1,3 +1,4 @@
1
+ import { type RefObject } from 'react';
1
2
  import './BottomNav.css';
2
3
  import './Tooltip/Tooltip.css';
3
4
  /** @public */
@@ -27,7 +28,7 @@ export type BottomNavMoreItem = {
27
28
  onClick?: () => void;
28
29
  };
29
30
  /** @public */
30
- export default function BottomNav({ items, activeKey, onChange, appMode, onAppModeChange, moreItems, }: {
31
+ export default function BottomNav({ items, activeKey, onChange, appMode, onAppModeChange, moreItems, scrollContainer, }: {
31
32
  items?: NavItem[];
32
33
  activeKey?: string;
33
34
  onChange?: (key: string) => void;
@@ -35,4 +36,11 @@ export default function BottomNav({ items, activeKey, onChange, appMode, onAppMo
35
36
  onAppModeChange?: (mode: 'malgwi' | 'manager') => void;
36
37
  /** nav 항목과 별개로 항상 더보기 메뉴에 노출되는 유틸(알림·설정·계정 등) */
37
38
  moreItems?: BottomNavMoreItem[];
39
+ /**
40
+ * 갈래를 고를 때 **맨 위로 되돌릴 본문 스크롤 통** — CSS 고르개나 ref. `SideNav` 와 같은 뜻이다.
41
+ *
42
+ * 모바일에서도 갈래를 바꾸면 본문이 위에서 시작해야 한다 — 전에는 데스크톱(SideNav)만 되돌려, 같은 앱에서
43
+ * 큰 화면은 위로 가고 작은 화면은 앞 화면의 스크롤 자리에 남았다. 유틸(더보기 메뉴의 알림·설정 등)은 갈래가 아니라 되돌리지 않는다.
44
+ */
45
+ scrollContainer?: string | RefObject<HTMLElement | null>;
38
46
  }): import("react").JSX.Element;
@@ -12,12 +12,13 @@ import MenuTooltip from './Tooltip/MenuTooltip';
12
12
  import './Tooltip/Tooltip.css';
13
13
  import { useAnchoredMenu, anchoredMenuZIndex } from '../hooks/useAnchoredMenu';
14
14
  import { useTranslation } from 'react-i18next';
15
+ import { scrollNavTargetToTop } from '../utils/navScroll';
15
16
  const BTN_SIZE = 52;
16
17
  const BTN_GAP = 10;
17
18
  /** 배지 숫자 — SideNav·MenuTooltip 과 같이 99 에서 자른다. 0 이하·없음은 0. */
18
19
  const badgeOf = (n) => (n && n > 0 ? n : 0);
19
20
  /** @public */
20
- export default function BottomNav({ items = [], activeKey, onChange, appMode, onAppModeChange, moreItems = [], }) {
21
+ export default function BottomNav({ items = [], activeKey, onChange, appMode, onAppModeChange, moreItems = [], scrollContainer, }) {
21
22
  const { t } = useTranslation();
22
23
  const nextMode = appMode === 'manager' ? 'malgwi' : 'manager';
23
24
  const modeIcon = appMode === 'manager' ? 'arrow-left' : 'arrow-right';
@@ -91,8 +92,10 @@ export default function BottomNav({ items = [], activeKey, onChange, appMode, on
91
92
  onClick: () => {
92
93
  if (it.state === 'disabled')
93
94
  return;
94
- if (it.key && onChange)
95
+ if (it.key && onChange) {
95
96
  onChange(it.key);
97
+ scrollNavTargetToTop(scrollContainer, 'BottomNav');
98
+ }
96
99
  handleCloseMore();
97
100
  },
98
101
  })),
@@ -115,6 +118,9 @@ export default function BottomNav({ items = [], activeKey, onChange, appMode, on
115
118
  const count = badgeOf(it.badgeCount);
116
119
  return (
117
120
  // key 는 선택 prop 이다 — 없으면 자리 번호로(형제 key 가 모두 undefined 가 되던 것)
118
- _jsxs("span", { className: "bottom-nav__slot", children: [_jsx(Button, { htmlType: "button", size: 52, type: "dot", icon: it.icon, ariaLabel: nameWithCount(it.label, count), selected: !!it.key && it.key === activeKey, disabled: it.state === 'disabled', className: "bottom-nav-item", onClick: () => it.key && onChange?.(it.key) }), count > 0 && (_jsx("span", { "aria-hidden": "true", children: _jsx(Badge, { type: "dot", position: "top-right", number: Math.min(count, 99), size: 24 }) }))] }, it.key ?? `__slot-${i}`));
121
+ _jsxs("span", { className: "bottom-nav__slot", children: [_jsx(Button, { htmlType: "button", size: 52, type: "dot", icon: it.icon, ariaLabel: nameWithCount(it.label, count), selected: !!it.key && it.key === activeKey, disabled: it.state === 'disabled', className: "bottom-nav-item", onClick: () => { if (it.key) {
122
+ onChange?.(it.key);
123
+ scrollNavTargetToTop(scrollContainer, 'BottomNav');
124
+ } } }), count > 0 && (_jsx("span", { "aria-hidden": "true", children: _jsx(Badge, { type: "dot", position: "top-right", number: Math.min(count, 99), size: 24 }) }))] }, it.key ?? `__slot-${i}`));
119
125
  }) }), showMore && (_jsxs(_Fragment, { children: [_jsx("div", { className: "bottom-nav__divider", "aria-hidden": "true" }), _jsx("div", { className: "bottom-nav__right", children: _jsxs("div", { ref: moreRef, className: "bottom-nav__slot", children: [_jsx(Button, { htmlType: "button", size: 52, type: "dot", icon: activeMore?.icon ?? 'ellipsis', ariaLabel: nameWithCount(activeMore?.label ?? t('nav.more', '더보기'), moreBadge), selected: !!activeMore, className: "bottom-nav-item", onClick: handleToggleMore, "aria-expanded": moreOpen, "aria-controls": moreOpen ? moreMenuId : undefined }), moreBadge > 0 && (_jsx("span", { "aria-hidden": "true", children: _jsx(Badge, { type: "dot", position: "top-right", number: Math.min(moreBadge, 99), size: 24 }) })), moreOpen && createPortal(_jsx("div", { id: moreMenuId, role: "group", "aria-label": t('nav.moreMenu', '더보기 메뉴'), className: "tooltip-content", style: menuStyle, ref: menuRef, children: _jsx(MenuTooltip, { columns: moreColumns, onClose: handleCloseMore }) }), document.body)] }) })] }))] }));
120
126
  }
@@ -1,3 +1,4 @@
1
+ import { type RefObject } from 'react';
1
2
  import './Tooltip/Tooltip.css';
2
3
  import { type SideNavItem } from './SideNav';
3
4
  import './Header.css';
@@ -18,7 +19,7 @@ export declare function BrandIdentity({ appMode }: {
18
19
  *
19
20
  * @public
20
21
  */
21
- export default function Header({ activeKey, onChange, items, malgwiItems: _malgwiItems, managerItems: _managerItems, unreadCount, onDebug, onNotification, onAccount, onSetting, onHelp, appMode, onAppModeChange }: {
22
+ export default function Header({ activeKey, onChange, items, malgwiItems: _malgwiItems, managerItems: _managerItems, unreadCount, onDebug, onNotification, onAccount, onSetting, onHelp, appMode, onAppModeChange, scrollContainer }: {
22
23
  activeKey?: string | null;
23
24
  onChange?: (key?: string) => void;
24
25
  /** 지금 모드의 내비 항목. 데스크톱은 SideNav, 모바일은 BottomNav 가 이 목록을 그린다. */
@@ -38,6 +39,13 @@ export default function Header({ activeKey, onChange, items, malgwiItems: _malgw
38
39
  onHelp?: () => void;
39
40
  appMode?: 'malgwi' | 'manager';
40
41
  onAppModeChange?: (mode: 'malgwi' | 'manager') => void;
42
+ /**
43
+ * 갈래를 고를 때 **맨 위로 되돌릴 본문 스크롤 통** — CSS 고르개나 ref. 안쪽 `SideNav`·`BottomNav` 에 그대로 넘긴다.
44
+ *
45
+ * 본문이 `body` 가 아니라 제 통에서 구르는 셸(`body { overflow: hidden }`)이면 **반드시 준다** — 창 굴리기는 그 앱에서 아무 일도 하지 않는다.
46
+ * **ref 로 주는 것이 가장 낫다**: 고르개 글자로 주면 코어가 소비자 클래스 이름을 다시 붙잡는 꼴이고, ref 면 그 얽힘이 아예 없다.
47
+ */
48
+ scrollContainer?: string | RefObject<HTMLElement | null>;
41
49
  }): import("react").JSX.Element;
42
50
  /**
43
51
  * `Header`의 alias입니다. 프로젝트 내 `Header`라는 이름이 이미 사용 중일 때 충돌 없이 임포트할 수 있습니다.
@@ -42,7 +42,7 @@ export function BrandIdentity({ appMode }) {
42
42
  *
43
43
  * @public
44
44
  */
45
- export default function Header({ activeKey, onChange, items, malgwiItems: _malgwiItems, managerItems: _managerItems, unreadCount, onDebug, onNotification, onAccount, onSetting, onHelp, appMode, onAppModeChange }) {
45
+ export default function Header({ activeKey, onChange, items, malgwiItems: _malgwiItems, managerItems: _managerItems, unreadCount, onDebug, onNotification, onAccount, onSetting, onHelp, appMode, onAppModeChange, scrollContainer }) {
46
46
  const { t } = useTranslation();
47
47
  const isMobile = useMediaQuery("(max-width: 767px)");
48
48
  /* **모바일 하단 내비에 SideNav 항목을 옮겨 적는다.** 예전에는 `SideNavItem` 을 `NavItem` 으로
@@ -118,7 +118,7 @@ export default function Header({ activeKey, onChange, items, malgwiItems: _malgw
118
118
  }], [bottomMoreItems, activeKey, closeUtilMenu]);
119
119
  return (_jsxs("aside", { className: `header${appMode === 'manager' ? ' header--manager' : ''}`, children: [_jsxs("div", { className: "header__bi", children: [_jsx(BrandIdentity, { appMode: appMode }), _jsxs("div", { className: "header__menu-button", ref: utilTriggerRef, children: [_jsx(Button, { htmlType: "button", size: 48, type: "dot", shape: "pill", variant: "default", icon: 'menu', ariaLabel: onNotification && unreadCount && unreadCount > 0
120
120
  ? t('nav.badgeLabel', { label: t('header.menuOpen', '메뉴 열기'), count: unreadCount, defaultValue: '{{label}}, {{count}}개' })
121
- : t('header.menuOpen', '메뉴 열기'), onClick: toggleUtilMenu, "aria-expanded": utilOpen, "aria-controls": utilOpen ? utilMenuId : undefined }), !!onNotification && !!unreadCount && unreadCount > 0 && (_jsx(Badge, { type: "dot", number: Math.min(unreadCount, 99), size: 24, "aria-hidden": true })), utilOpen && createPortal(_jsx("div", { id: utilMenuId, role: "group", "aria-label": t('header.utilMenu', '유틸리티 메뉴'), className: "tooltip-content", style: utilMenuStyle, ref: utilMenuRef, children: _jsx(MenuTooltip, { columns: utilColumns, onClose: closeUtilMenu }) }), document.body)] })] }), _jsx(SideNav, { items: items, activeKey: activeKey ?? undefined, onChange: onChange, unreadCount: unreadCount, onDebug: onDebug, onNotification: onNotification, onAccount: onAccount, onSetting: onSetting, onHelp: onHelp, appMode: appMode, onAppModeChange: onAppModeChange }), isMobile && _jsx(BottomNav, { items: bottomItems, activeKey: activeKey ?? undefined, onChange: handleBottomChange, appMode: appMode, onAppModeChange: onAppModeChange })] }));
121
+ : t('header.menuOpen', '메뉴 열기'), onClick: toggleUtilMenu, "aria-expanded": utilOpen, "aria-controls": utilOpen ? utilMenuId : undefined }), !!onNotification && !!unreadCount && unreadCount > 0 && (_jsx(Badge, { type: "dot", number: Math.min(unreadCount, 99), size: 24, "aria-hidden": true })), utilOpen && createPortal(_jsx("div", { id: utilMenuId, role: "group", "aria-label": t('header.utilMenu', '유틸리티 메뉴'), className: "tooltip-content", style: utilMenuStyle, ref: utilMenuRef, children: _jsx(MenuTooltip, { columns: utilColumns, onClose: closeUtilMenu }) }), document.body)] })] }), _jsx(SideNav, { scrollContainer: scrollContainer, items: items, activeKey: activeKey ?? undefined, onChange: onChange, unreadCount: unreadCount, onDebug: onDebug, onNotification: onNotification, onAccount: onAccount, onSetting: onSetting, onHelp: onHelp, appMode: appMode, onAppModeChange: onAppModeChange }), isMobile && _jsx(BottomNav, { items: bottomItems, activeKey: activeKey ?? undefined, onChange: handleBottomChange, scrollContainer: scrollContainer, appMode: appMode, onAppModeChange: onAppModeChange })] }));
122
122
  }
123
123
  /**
124
124
  * `Header`의 alias입니다. 프로젝트 내 `Header`라는 이름이 이미 사용 중일 때 충돌 없이 임포트할 수 있습니다.
@@ -1,5 +1,5 @@
1
1
  import './SideNav.css';
2
- import React, { type ReactNode } from 'react';
2
+ import React, { type ReactNode, type RefObject } from 'react';
3
3
  /** @public */
4
4
  export interface SideNavItem {
5
5
  key?: string;
@@ -27,6 +27,14 @@ export interface SideNavProps {
27
27
  appMode?: 'malgwi' | 'manager';
28
28
  /** 앱 모드 전환 콜백 */
29
29
  onAppModeChange?: (mode: 'malgwi' | 'manager') => void;
30
+ /**
31
+ * 갈래를 고를 때 **맨 위로 되돌릴 본문 스크롤 통** — CSS 고르개나 ref.
32
+ *
33
+ * 안 주면 `.content-area` 를 찾고(코어가 **소비자 클래스 이름을 붙잡고 있던 자리** 다 — 말귀가 그 이름을 바꾸는 날
34
+ * 화면은 멀쩡한데 내비를 눌러도 스크롤이 안 돌아갔다), 그것도 없으면 창을 굴린다.
35
+ * 본문이 `body` 가 아니라 제 통에서 구르는 셸(body 가 `overflow: hidden`)이면 **반드시 준다** — 창 굴리기는 그 앱에서 아무 일도 하지 않는다.
36
+ */
37
+ scrollContainer?: string | RefObject<HTMLElement | null>;
30
38
  }
31
39
  /** @public */
32
40
  export default function SideNav(props: SideNavProps): React.JSX.Element;
@@ -7,6 +7,7 @@ import Badge from './Badge';
7
7
  import React, { useCallback } from 'react';
8
8
  import { useTranslation } from 'react-i18next';
9
9
  import { isSafeOpenHref } from '../utils/safeHref';
10
+ import { scrollNavTargetToTop } from '../utils/navScroll';
10
11
  /** 단추 이름에 개수를 붙인다 — 뱃지는 aria-hidden 이라 개수는 이름으로만 전해진다(BottomNav 와 같은 문구). */
11
12
  function nameWithCount(t, label, count) {
12
13
  return count && count > 0 ? t('nav.badgeLabel', { label, count, defaultValue: '{{label}}, {{count}}개' }) : label;
@@ -57,7 +58,7 @@ function SideNavButton(props) {
57
58
  /** @public */
58
59
  export default function SideNav(props) {
59
60
  const { t } = useTranslation();
60
- const { items = [], activeKey, onChange, unreadCount, onDebug, onNotification, onAccount, onSetting, onHelp, appMode, onAppModeChange } = props || {};
61
+ const { items = [], activeKey, onChange, unreadCount, onDebug, onNotification, onAccount, onSetting, onHelp, appMode, onAppModeChange, scrollContainer } = props || {};
61
62
  /* 모드를 안 주면 말귀로 본다 — Header(브랜드)·BottomNav 와 같게. 전에는 여기만 매니저로 봐 같은 화면에서
62
63
  데스크톱은 '말귀로 이동', 모바일은 '말귀 매니저' 로 서로 반대를 가리켰다. */
63
64
  const isManager = appMode === 'manager';
@@ -80,14 +81,7 @@ export default function SideNav(props) {
80
81
  return;
81
82
  }
82
83
  onChange?.(it.key);
83
- try {
84
- const contentEl = document.querySelector('.content-area');
85
- if (contentEl)
86
- contentEl.scrollTop = 0;
87
- else
88
- window.scrollTo({ top: 0 });
89
- }
90
- catch (_) { }
84
+ scrollNavTargetToTop(scrollContainer, 'SideNav');
91
85
  /* 키보드로 고르면 포커스가 레일 안에 남으므로 태블릿 레일도 펼친 채 둔다(:focus-within) —
92
86
  아래 강제 접힘은 마우스가 들어와야 풀리므로 키보드 사용자에게 걸면 레일이 닫힌 채 포커스만 남는다. */
93
87
  if (!fromPointer)
@@ -0,0 +1,11 @@
1
+ import type { RefObject } from 'react';
2
+ /** 소비자가 통을 안 알려 줄 때 찾아 보는 이름 — 옛 동작 유지(말귀 셸의 본문). @internal */
3
+ export declare const 기본통고르개 = ".content-area";
4
+ /**
5
+ * 갈래를 고른 뒤 본문을 맨 위로 — 내비(SideNav·BottomNav)가 함께 쓴다. @internal
6
+ *
7
+ * 통을 못 찾으면 창을 굴리는데, 본문이 제 통에서 구르는 셸(`body { overflow: hidden }`)에서는
8
+ * 그것이 **아무 일도 하지 않는다** — 그때는 조용히 죽는 대신 개발 모드에 한 번 알린다.
9
+ * 코어가 `.content-area`(소비자 클래스 이름)를 붙잡고 있던 자리라, 부르는 쪽이 통을 알려 주는 것이 정본이다.
10
+ */
11
+ export declare function scrollNavTargetToTop(scrollContainer?: string | RefObject<HTMLElement | null>, 어디서?: string): void;
@@ -0,0 +1,27 @@
1
+ import { devWarnOnce } from './devWarn';
2
+ /** 소비자가 통을 안 알려 줄 때 찾아 보는 이름 — 옛 동작 유지(말귀 셸의 본문). @internal */
3
+ export const 기본통고르개 = '.content-area';
4
+ /**
5
+ * 갈래를 고른 뒤 본문을 맨 위로 — 내비(SideNav·BottomNav)가 함께 쓴다. @internal
6
+ *
7
+ * 통을 못 찾으면 창을 굴리는데, 본문이 제 통에서 구르는 셸(`body { overflow: hidden }`)에서는
8
+ * 그것이 **아무 일도 하지 않는다** — 그때는 조용히 죽는 대신 개발 모드에 한 번 알린다.
9
+ * 코어가 `.content-area`(소비자 클래스 이름)를 붙잡고 있던 자리라, 부르는 쪽이 통을 알려 주는 것이 정본이다.
10
+ */
11
+ export function scrollNavTargetToTop(scrollContainer, 어디서 = 'Nav') {
12
+ try {
13
+ const el = typeof scrollContainer === 'string'
14
+ ? document.querySelector(scrollContainer)
15
+ : scrollContainer?.current ?? document.querySelector(기본통고르개);
16
+ if (el) {
17
+ el.scrollTop = 0;
18
+ return;
19
+ }
20
+ const 문서 = document.scrollingElement ?? document.documentElement;
21
+ if (문서 && 문서.scrollHeight <= 문서.clientHeight) {
22
+ devWarnOnce('nav-scroll-container', `[${어디서}] 본문을 맨 위로 되돌릴 통을 못 찾았다(기본 ${기본통고르개}) — 창도 구를 수 없어 아무 일도 하지 않는다. scrollContainer 로 통을 알려 준다.`);
23
+ }
24
+ window.scrollTo({ top: 0 });
25
+ }
26
+ catch (_) { }
27
+ }
@@ -46,4 +46,4 @@
46
46
  *
47
47
  * 값은 손으로 적고 `test/coreVersion.test.ts` 가 package.json 과 어긋나면 운다.
48
48
  */
49
- export declare const CORE_VERSION = "0.172.0";
49
+ export declare const CORE_VERSION = "0.174.0";
@@ -46,4 +46,4 @@
46
46
  *
47
47
  * 값은 손으로 적고 `test/coreVersion.test.ts` 가 package.json 과 어긋나면 운다.
48
48
  */
49
- export const CORE_VERSION = '0.172.0';
49
+ export const CORE_VERSION = '0.174.0';