@ihabdevteam/core 0.168.0 → 0.170.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.
@@ -309,7 +309,7 @@ export declare type BadgeType = 'bar' | 'dot';
309
309
  * - 주(week): 'YYYY년 M월 N째주' 드롭다운 + 그 주의 요일(월~일) 막대
310
310
  * 원시 렌더링은 내부 BarChartCanvas가 담당한다.
311
311
  */
312
- export declare function BarChart({ size, barWidth, titleKey, data, colorA, colorB, labelAKey, labelBKey, showTotal, totalUnitKey, totalLabelKey, control: controlProp, hideControls, rate, rateAgg, tightMax, avgMode, totalFormat, series, seriesMode, loading, onDetail, headExtra, headSegment, icon, disc, detailSize, barGap, baseline, className, inGrid, }: BarChartProps): JSX.Element;
312
+ export declare function BarChart({ size, barWidth, titleKey, data, colorA, colorB, labelAKey, labelBKey, showTotal, totalUnitKey, totalLabelKey, control: controlProp, hideControls, rate, rateAgg, tightMax, avgMode, totalFormat, series, seriesMode, loading, onDetail, headExtra, headSegment, icon, disc, onClick, cardAriaLabel, cardTooltip, detailSize, barGap, baseline, className, inGrid, }: BarChartProps): JSX.Element;
313
313
 
314
314
  /** @public */
315
315
  export declare interface BarChartControl {
@@ -413,6 +413,12 @@ export declare interface BarChartProps {
413
413
  /** 머리의 보기 고르개 — 넓으면 세그먼트, 카드가 좁으면 '⋯' 한 단추로 접히고 그 메뉴에 칸들과 '상세보기' 가 함께 든다.
414
414
  * `headExtra` 로 고르개를 손수 얹고 좁을 때를 따로 다루던 것을 대신한다(ChartSection 이 카드 제 폭으로 잰다). */
415
415
  headSegment?: ChartHeadSegment;
416
+ /** 카드 자체를 누를 수 있게 — 커서·hover 테두리·키보드까지 ChartSection 이 한 결로 붙인다(머리의 단추·고르개 누름은 카드를 열지 않는다) */
417
+ onClick?: () => void;
418
+ /** 누르는 카드의 이름(낭독기) — 안 주면 제목 */
419
+ cardAriaLabel?: string;
420
+ /** 카드에 포인터가 닿을 때(키보드는 초점) 뜨는 설명 — StatChart tooltip 과 같은 뜻 */
421
+ cardTooltip?: string;
416
422
  /** 제목 왼쪽 아이콘 — Section·ChartSection 과 같은 자리·같은 색 */
417
423
  icon?: string;
418
424
  /** 제목 아래 설명 한 줄 */
@@ -1049,7 +1055,7 @@ export declare interface ChartPoint {
1049
1055
  * 공유하도록 두 컴포넌트가 내부적으로 사용한다.
1050
1056
  * @public
1051
1057
  */
1052
- export declare function ChartSection({ title, titleClassName, icon, disc, headRight, headSegment, headMenuItems, collapseBelow, subRow, className, inGrid, children }: ChartSectionProps): JSX.Element;
1058
+ export declare function ChartSection({ title, titleClassName, icon, disc, headRight, headSegment, headMenuItems, collapseBelow, onClick, ariaLabel, tooltip, subRow, className, inGrid, children }: ChartSectionProps): JSX.Element;
1053
1059
 
1054
1060
  /** @public */
1055
1061
  export declare interface ChartSectionProps {
@@ -1072,6 +1078,14 @@ export declare interface ChartSectionProps {
1072
1078
  headMenuItems?: TooltipMenuColumnItem[];
1073
1079
  /** 고르개를 '⋯' 로 접는 카드 폭(px, 기본 420) */
1074
1080
  collapseBelow?: number;
1081
+ /** 카드 자체를 누를 수 있게 한다 — 커서·hover 테두리·키보드(Enter·Space)·role·tabIndex 를 한 결로 붙인다.
1082
+ * `StatChart onClick` 과 같은 모양이다(소비자가 감싸개를 만들어 흉내 내던 것). */
1083
+ onClick?: () => void;
1084
+ /** 누르는 카드의 이름(낭독기) — 안 주면 제목이 글자일 때 그것을 쓴다 */
1085
+ ariaLabel?: string;
1086
+ /** 카드에 포인터가 닿을 때(키보드는 초점이 들어올 때) 뜨는 설명 — `StatChart tooltip` 과 같은 뜻.
1087
+ * 같은 줄에 선 StatChart 카드들만 설명이 뜨고 이 카드만 안 뜨던 것을 메운다. */
1088
+ tooltip?: string;
1075
1089
  /** 총계(ChartTotal) + 범례(ChartLegend)를 담는 서브로우 */
1076
1090
  subRow?: ReactNode;
1077
1091
  /** 섹션 루트에 추가할 클래스 */
@@ -1541,7 +1555,7 @@ export declare function copyText(text: string): Promise<boolean>;
1541
1555
  *
1542
1556
  * 값은 손으로 적고 `test/coreVersion.test.ts` 가 package.json 과 어긋나면 운다.
1543
1557
  */
1544
- export declare const CORE_VERSION = "0.168.0";
1558
+ export declare const CORE_VERSION = "0.170.0";
1545
1559
 
1546
1560
  /** @public */
1547
1561
  declare const coreDefault: Record<string, unknown>;
@@ -5332,7 +5346,7 @@ export declare function reviewTableName(original: string | ReviewSource, today:
5332
5346
  * 미지정 시에는 헤더 없는 순수 링만 렌더된다(크기/색상 데모 등).
5333
5347
  * @public
5334
5348
  */
5335
- export declare function RingChart({ titleKey, headRight, icon, showTotal, totalLabelKey, legend, loading, className, inGrid, ...ringProps }: RingChartProps): JSX.Element;
5349
+ export declare function RingChart({ titleKey, headRight, icon, showTotal, totalLabelKey, legend, loading, className, inGrid, onClick, ariaLabel, tooltip, ...ringProps }: RingChartProps): JSX.Element;
5336
5350
 
5337
5351
  /** @public */
5338
5352
  export declare interface RingChartProps {
@@ -5385,6 +5399,12 @@ export declare interface RingChartProps {
5385
5399
  className?: string;
5386
5400
  /** CSS 격자 칸 안에 세운다 — 아래 여백·최소 폭을 풀고 링을 카드 바닥에 맞춘다. ChartSection `inGrid` 참고(titleKey 지정 시에만 사용) */
5387
5401
  inGrid?: boolean;
5402
+ /** 카드 자체를 누를 수 있게 — 커서·hover 테두리·키보드까지 ChartSection 이 한 결로 붙인다(titleKey 지정 시에만) */
5403
+ onClick?: () => void;
5404
+ /** 누르는 카드의 이름(낭독기) — 안 주면 제목 */
5405
+ ariaLabel?: string;
5406
+ /** 카드에 포인터가 닿을 때(키보드는 초점) 뜨는 설명 — StatChart tooltip 과 같은 뜻(titleKey 지정 시에만) */
5407
+ tooltip?: string;
5388
5408
  }
5389
5409
 
5390
5410
  /** @public */
@@ -6200,7 +6220,7 @@ export declare function splitTrainingVariants(value: unknown): string[];
6200
6220
  * (도넛 breakdown은 RingChart segments 모드, 리스트는 페이지에서 직접 구성).
6201
6221
  * @public
6202
6222
  */
6203
- export declare function StatChart({ label, value, change, changeType, icon, tooltip, onClick }: StatChartProps): JSX.Element;
6223
+ export declare function StatChart({ label, value, change, changeType, icon, tooltip, onClick, children }: StatChartProps): JSX.Element;
6204
6224
 
6205
6225
  /** @public */
6206
6226
  export declare type StatChartChangeType = 'up' | 'down' | 'neutral';
@@ -6220,6 +6240,9 @@ export declare interface StatChartProps {
6220
6240
  /** 호버 시 표시할 툴팁 텍스트 */
6221
6241
  tooltip?: string;
6222
6242
  onClick?: () => void;
6243
+ /** 값 **아래** 에 붙는 자리 — 목록 몇 줄, "외 n건" 단추처럼 값을 풀어 보이는 것.
6244
+ * 이 자리가 없어 소비자가 카드 마크업(`manager-stat-card__*` 여덟 이름)을 통째로 베끼고 있었다(말귀 매니저 '금일 방문 예정'). */
6245
+ children?: ReactNode;
6223
6246
  }
6224
6247
 
6225
6248
  /**
@@ -13,4 +13,4 @@ import type { BarChartProps } from './barChartTypes';
13
13
  * - 주(week): 'YYYY년 M월 N째주' 드롭다운 + 그 주의 요일(월~일) 막대
14
14
  * 원시 렌더링은 내부 BarChartCanvas가 담당한다.
15
15
  */
16
- export default function BarChart({ size, barWidth, titleKey, data, colorA, colorB, labelAKey, labelBKey, showTotal, totalUnitKey, totalLabelKey, control: controlProp, hideControls, rate, rateAgg, tightMax, avgMode, totalFormat, series, seriesMode, loading, onDetail, headExtra, headSegment, icon, disc, detailSize, barGap, baseline, className, inGrid, }: BarChartProps): import("react").JSX.Element;
16
+ export default function BarChart({ size, barWidth, titleKey, data, colorA, colorB, labelAKey, labelBKey, showTotal, totalUnitKey, totalLabelKey, control: controlProp, hideControls, rate, rateAgg, tightMax, avgMode, totalFormat, series, seriesMode, loading, onDetail, headExtra, headSegment, icon, disc, onClick, cardAriaLabel, cardTooltip, detailSize, barGap, baseline, className, inGrid, }: BarChartProps): import("react").JSX.Element;
@@ -261,7 +261,7 @@ const BAR_SIZE_PRESET = {
261
261
  * - 주(week): 'YYYY년 M월 N째주' 드롭다운 + 그 주의 요일(월~일) 막대
262
262
  * 원시 렌더링은 내부 BarChartCanvas가 담당한다.
263
263
  */
264
- export default function BarChart({ size = 'medium', barWidth, titleKey, data, colorA, colorB, labelAKey, labelBKey, showTotal = false, totalUnitKey, totalLabelKey, control: controlProp, hideControls = false, rate = false, rateAgg = 'dayMean', tightMax = false, avgMode = false, totalFormat, series, seriesMode = 'stack', loading = false, onDetail, headExtra, headSegment, icon, disc, detailSize = 32, barGap, baseline, className, inGrid = false, }) {
264
+ export default function BarChart({ size = 'medium', barWidth, titleKey, data, colorA, colorB, labelAKey, labelBKey, showTotal = false, totalUnitKey, totalLabelKey, control: controlProp, hideControls = false, rate = false, rateAgg = 'dayMean', tightMax = false, avgMode = false, totalFormat, series, seriesMode = 'stack', loading = false, onDetail, headExtra, headSegment, icon, disc, onClick, cardAriaLabel, cardTooltip, detailSize = 32, barGap, baseline, className, inGrid = false, }) {
265
265
  const { t, i18n } = useTranslation();
266
266
  const sizePreset = BAR_SIZE_PRESET[size];
267
267
  // 외부 control 미지정 시 내부 컨트롤 사용 (단독 차트 하위 호환)
@@ -397,7 +397,7 @@ export default function BarChart({ size = 'medium', barWidth, titleKey, data, co
397
397
  const isLarge = size === 'large';
398
398
  const sectionClassName = [isSmall ? 'manager-section--compact' : isLarge ? 'manager-section--full' : undefined, className]
399
399
  .filter(Boolean).join(' ') || undefined;
400
- return (_jsx(ChartSection, { className: sectionClassName, inGrid: inGrid, icon: icon, disc: disc, headSegment: headSegment,
400
+ return (_jsx(ChartSection, { className: sectionClassName, inGrid: inGrid, icon: icon, disc: disc, onClick: onClick, ariaLabel: cardAriaLabel, tooltip: cardTooltip, headSegment: headSegment,
401
401
  /* 좁아 고르개가 '⋯' 로 접히면 상세보기도 그 메뉴로 들어간다 — 머리에 단추 둘이 남지 않게 */
402
402
  headMenuItems: onDetail ? [{ label: t('trainingStatus.detail', '상세보기'), icon: 'list', onClick: onDetail, closeOnSelect: true }] : undefined, title: t(titleKey), titleClassName: isSmall ? 'h5 chart-section-title--small' : undefined, headRight: isSmall ? (headExtra ?? undefined) : ({ collapsed }) => _jsxs(_Fragment, { children: [!hideControls && _jsx(BarChartControls, { control: control }), headExtra, onDetail && !collapsed && (_jsx("span", { className: "manager-bar-chart-detail-btn", children: _jsx(Button, { htmlType: "button", size: detailSize, type: "dot", icon: "list", ariaLabel: t('trainingStatus.detail', '상세보기'), showTooltipInfo: t('trainingStatus.detail', '상세보기'), onClick: onDetail }) }))] }), subRow: _jsxs(_Fragment, { children: [showTotal ? ((rate || avgMode || (!!totalLabelKey && !!totalFormat)) ? (
403
403
  // 진행률/평균 모드 또는 totalLabelKey+totalFormat 조합: 라벨(윗줄) + 값(아랫줄). size='small'은 라벨 생략
@@ -17,6 +17,16 @@
17
17
  /* 차트 카드 — inline 나열 가능하도록 최소 폭만 지정(최대 폭 제한 없음) */
18
18
  min-width: 320px;
19
19
  }
20
+ /* 누르는 카드 — StatChart 의 누르는 카드와 같은 결(커서·hover 테두리). 소비자가 감싸개로 흉내 내던 것 */
21
+ .manager-section--clickable {
22
+ cursor: pointer;
23
+ transition: box-shadow 120ms ease, border-color 120ms ease;
24
+ }
25
+ .manager-section--clickable:hover {
26
+ border-color: var(--color-main);
27
+ box-shadow: var(--shadow-dropdown);
28
+ }
29
+
20
30
  .manager-section__head {
21
31
  display: flex;
22
32
  justify-content: space-between;
@@ -56,6 +56,14 @@ export interface ChartSectionProps {
56
56
  headMenuItems?: TooltipMenuColumnItem[];
57
57
  /** 고르개를 '⋯' 로 접는 카드 폭(px, 기본 420) */
58
58
  collapseBelow?: number;
59
+ /** 카드 자체를 누를 수 있게 한다 — 커서·hover 테두리·키보드(Enter·Space)·role·tabIndex 를 한 결로 붙인다.
60
+ * `StatChart onClick` 과 같은 모양이다(소비자가 감싸개를 만들어 흉내 내던 것). */
61
+ onClick?: () => void;
62
+ /** 누르는 카드의 이름(낭독기) — 안 주면 제목이 글자일 때 그것을 쓴다 */
63
+ ariaLabel?: string;
64
+ /** 카드에 포인터가 닿을 때(키보드는 초점이 들어올 때) 뜨는 설명 — `StatChart tooltip` 과 같은 뜻.
65
+ * 같은 줄에 선 StatChart 카드들만 설명이 뜨고 이 카드만 안 뜨던 것을 메운다. */
66
+ tooltip?: string;
59
67
  /** 총계(ChartTotal) + 범례(ChartLegend)를 담는 서브로우 */
60
68
  subRow?: ReactNode;
61
69
  /** 섹션 루트에 추가할 클래스 */
@@ -75,4 +83,4 @@ export interface ChartSectionProps {
75
83
  * 공유하도록 두 컴포넌트가 내부적으로 사용한다.
76
84
  * @public
77
85
  */
78
- export default function ChartSection({ title, titleClassName, icon, disc, headRight, headSegment, headMenuItems, collapseBelow, subRow, className, inGrid, children }: ChartSectionProps): import("react").JSX.Element;
86
+ export default function ChartSection({ title, titleClassName, icon, disc, headRight, headSegment, headMenuItems, collapseBelow, onClick, ariaLabel, tooltip, subRow, className, inGrid, children }: ChartSectionProps): import("react").JSX.Element;
@@ -7,6 +7,8 @@ import Icon from './Icon';
7
7
  import Button from './Button';
8
8
  import SegmentedControl from './SegmentedControl';
9
9
  import Tooltip from './Tooltip/Tooltip';
10
+ import TooltipInfo from './Tooltip/InfoTooltip';
11
+ import { useHoverAnchor } from '../hooks/useHoverAnchor';
10
12
  import MenuTooltip from './Tooltip/MenuTooltip';
11
13
  /** 차트 범례 — 색상 점 + 라벨 목록. BarChart/RingChart 섹션이 공유. @public */
12
14
  export function ChartLegend({ items, className }) {
@@ -25,9 +27,14 @@ export function ChartTotal({ label, children }) {
25
27
  * 공유하도록 두 컴포넌트가 내부적으로 사용한다.
26
28
  * @public
27
29
  */
28
- export default function ChartSection({ title, titleClassName = 'h3', icon, disc, headRight, headSegment, headMenuItems, collapseBelow = 420, subRow, className, inGrid = false, children }) {
30
+ export default function ChartSection({ title, titleClassName = 'h3', icon, disc, headRight, headSegment, headMenuItems, collapseBelow = 420, onClick, ariaLabel, tooltip, subRow, className, inGrid = false, children }) {
29
31
  const { t } = useTranslation();
30
32
  const secRef = useRef(null);
33
+ /* 설명 툴팁 — StatChart 와 같은 결(카드 사각형 기준, 포인터가 나가거나 초점이 빠지면 닫힘).
34
+ hover 전용이면 키보드로는 볼 수 없어 초점에도 연다. */
35
+ const { anchorRect: 설명자리, openAt: 설명열기, close: 설명닫기 } = useHoverAnchor();
36
+ const 설명보이기 = useCallback(() => { if (tooltip && secRef.current)
37
+ 설명열기(secRef.current); }, [tooltip, 설명열기]);
31
38
  /* 좁은지는 **카드 제 폭** 으로 잰다 — 부르는 쪽이 격자 칸 폭으로 대신 재면 두 칸을 차지하는 카드에서 틀린다.
32
39
  ResizeObserver 가 없는 환경(구형·SSR)에서는 접지 않는다(넓은 쪽이 기본). */
33
40
  const [좁음, set좁음] = useState(false);
@@ -66,7 +73,33 @@ export default function ChartSection({ title, titleClassName = 'h3', icon, disc,
66
73
  ...(headMenuItems ?? []).map((it, i) => (i === 0 ? { ...it, separatorBefore: true } : it)),
67
74
  ]
68
75
  : [];
76
+ /* 누르는 카드 — 머리의 단추·고르개를 눌렀을 때까지 카드가 열리면 안 된다(그 누름은 제 일을 한다) */
77
+ const 카드누름 = useCallback((e) => {
78
+ if (!onClick)
79
+ return;
80
+ const t = e.target;
81
+ if (t && typeof t.closest === 'function' && t.closest('button, a, input, select, textarea, [role="radiogroup"]'))
82
+ return;
83
+ onClick();
84
+ }, [onClick]);
85
+ const 카드키 = useCallback((e) => {
86
+ if (!onClick)
87
+ return;
88
+ if (e.target !== e.currentTarget)
89
+ return; // 안쪽 단추의 Enter·Space 는 그 단추 것
90
+ if (e.key === 'Enter' || e.key === ' ') {
91
+ e.preventDefault();
92
+ onClick();
93
+ }
94
+ }, [onClick]);
69
95
  const 오른쪽 = typeof headRight === 'function' ? headRight({ collapsed: 접힘 }) : headRight;
70
96
  const 머리오른쪽 = (오른쪽 || headSegment) ? (_jsxs("div", { className: "manager-section__head-right", children: [오른쪽, headSegment && (접힘 ? (_jsx(Button, { htmlType: "button", size: 32, type: "dot", icon: "ellipsis", ariaLabel: headSegment.ariaLabel ?? t('common.more', '더보기'), showTooltipInfo: headSegment.ariaLabel ?? t('common.more', '더보기'), "aria-haspopup": "menu", "aria-expanded": !!메뉴자리, onClick: 메뉴열기 })) : (_jsx(SegmentedControl, { size: 32, ariaLabel: headSegment.ariaLabel, options: headSegment.options.map(o => ({ key: o.key, label: o.label, disabled: o.disabled })), value: headSegment.value, onChange: headSegment.onChange })))] })) : null;
71
- return (_jsxs("section", { ref: secRef, className: ['manager-section', inGrid && 'manager-section--grid', className].filter(Boolean).join(' '), children: [_jsxs("div", { className: "manager-section__head", children: [_jsxs("div", { className: "manager-section__title-row", children: [icon && _jsx(Icon, { icon: icon, label: typeof title === 'string' ? title : undefined, className: "manager-section__icon" }), _jsx("div", { className: ['manager-section__title', titleClassName].filter(Boolean).join(' '), children: title })] }), 머리오른쪽, disc && _jsx("div", { className: "manager-section__disc body-3", children: disc })] }), subRow && _jsx("div", { className: "barchart-sub-row", children: subRow }), children, 메뉴자리 && (_jsx(Tooltip, { anchorRect: 메뉴자리, onClose: 메뉴닫기, ariaLabel: headSegment?.ariaLabel ?? t('tooltip.menu', '메뉴'), children: _jsx(MenuTooltip, { columns: [{ items: 메뉴항목 }], onClose: 메뉴닫기, size: "small" }) }))] }));
97
+ return (_jsxs("section", { ref: secRef, className: ['manager-section', inGrid && 'manager-section--grid', onClick && 'manager-section--clickable', className].filter(Boolean).join(' '), onClick: onClick ? 카드누름 : undefined, onKeyDown: onClick ? 카드키 : undefined, onPointerEnter: tooltip ? 설명보이기 : undefined, onPointerLeave: tooltip ? 설명닫기 : undefined, onFocus: tooltip ? 설명보이기 : undefined, onBlur: tooltip ? 설명닫기 : undefined, role: onClick ? 'button' : undefined, tabIndex: onClick ? 0 : undefined, "aria-label": onClick ? (ariaLabel ?? (typeof title === 'string' ? title : undefined)) : undefined, children: [tooltip && 설명자리 && (_jsx(TooltipInfo, { anchorRect: {
98
+ left: 설명자리.left,
99
+ top: 설명자리.top + 21,
100
+ right: 설명자리.right,
101
+ bottom: 설명자리.bottom,
102
+ width: 설명자리.width,
103
+ height: 설명자리.height,
104
+ }, text: tooltip })), _jsxs("div", { className: "manager-section__head", children: [_jsxs("div", { className: "manager-section__title-row", children: [icon && _jsx(Icon, { icon: icon, label: typeof title === 'string' ? title : undefined, className: "manager-section__icon" }), _jsx("div", { className: ['manager-section__title', titleClassName].filter(Boolean).join(' '), children: title })] }), 머리오른쪽, disc && _jsx("div", { className: "manager-section__disc body-3", children: disc })] }), subRow && _jsx("div", { className: "barchart-sub-row", children: subRow }), children, 메뉴자리 && (_jsx(Tooltip, { anchorRect: 메뉴자리, onClose: 메뉴닫기, ariaLabel: headSegment?.ariaLabel ?? t('tooltip.menu', '메뉴'), children: _jsx(MenuTooltip, { columns: [{ items: 메뉴항목 }], onClose: 메뉴닫기, size: "small" }) }))] }));
72
105
  }
@@ -60,6 +60,12 @@ export interface RingChartProps {
60
60
  className?: string;
61
61
  /** CSS 격자 칸 안에 세운다 — 아래 여백·최소 폭을 풀고 링을 카드 바닥에 맞춘다. ChartSection `inGrid` 참고(titleKey 지정 시에만 사용) */
62
62
  inGrid?: boolean;
63
+ /** 카드 자체를 누를 수 있게 — 커서·hover 테두리·키보드까지 ChartSection 이 한 결로 붙인다(titleKey 지정 시에만) */
64
+ onClick?: () => void;
65
+ /** 누르는 카드의 이름(낭독기) — 안 주면 제목 */
66
+ ariaLabel?: string;
67
+ /** 카드에 포인터가 닿을 때(키보드는 초점) 뜨는 설명 — StatChart tooltip 과 같은 뜻(titleKey 지정 시에만) */
68
+ tooltip?: string;
63
69
  }
64
70
  /**
65
71
  * 도넛 링 차트 — 전체 대비 완료 비율을 원형 호로 표현.
@@ -67,4 +73,4 @@ export interface RingChartProps {
67
73
  * 미지정 시에는 헤더 없는 순수 링만 렌더된다(크기/색상 데모 등).
68
74
  * @public
69
75
  */
70
- export default function RingChart({ titleKey, headRight, icon, showTotal, totalLabelKey, legend, loading, className, inGrid, ...ringProps }: RingChartProps): import("react").JSX.Element;
76
+ export default function RingChart({ titleKey, headRight, icon, showTotal, totalLabelKey, legend, loading, className, inGrid, onClick, ariaLabel, tooltip, ...ringProps }: RingChartProps): import("react").JSX.Element;
@@ -51,7 +51,7 @@ function RingChartCanvas({ done, total, segments, color = 'var(--color-main)', s
51
51
  * 미지정 시에는 헤더 없는 순수 링만 렌더된다(크기/색상 데모 등).
52
52
  * @public
53
53
  */
54
- export default function RingChart({ titleKey, headRight, icon, showTotal, totalLabelKey, legend, loading, className, inGrid = false, ...ringProps }) {
54
+ export default function RingChart({ titleKey, headRight, icon, showTotal, totalLabelKey, legend, loading, className, inGrid = false, onClick, ariaLabel, tooltip, ...ringProps }) {
55
55
  const { t } = useTranslation();
56
56
  if (!titleKey)
57
57
  return _jsx(RingChartCanvas, { ...ringProps });
@@ -64,5 +64,5 @@ export default function RingChart({ titleKey, headRight, icon, showTotal, totalL
64
64
  .filter(Boolean).join(' ') || undefined;
65
65
  // StatChart(.manager-stat-card__icon)와 동일한 톤 — headRight 자리에 렌더(둘 중 하나만 사용)
66
66
  const iconNode = icon && (_jsx("span", { className: "chart-section-icon", children: _jsx(Icon, { icon: icon, className: "chart-section-icon-inner" }) }));
67
- return (_jsx(ChartSection, { className: sectionClassName, inGrid: inGrid, title: t(titleKey), titleClassName: isSmall ? 'h5 chart-section-title--small' : undefined, headRight: iconNode || (isSmall ? undefined : headRight), subRow: (showTotal || legend) && _jsxs(_Fragment, { children: [showTotal ? (_jsxs(ChartTotal, { label: !isSmall && totalLabelKey ? t(totalLabelKey) : undefined, children: [_jsx("span", { className: "barchart-total__num h0", children: pct }), _jsx("span", { className: "barchart-total__unit h5", children: "%" })] })) : _jsx("span", {}), legend && _jsx(ChartLegend, { items: legend })] }), children: loading ? (_jsx("div", { className: "manager-bar-chart-loading", children: _jsx(Loader, { size: 32 }) })) : (_jsx("div", { className: "ring-chart-section-body ring-chart-section-body--offset", children: _jsx(RingChartCanvas, { ...ringProps, hideCenter: ringProps.hideCenter ?? isSmall }) })) }));
67
+ return (_jsx(ChartSection, { className: sectionClassName, inGrid: inGrid, onClick: onClick, ariaLabel: ariaLabel, tooltip: tooltip, title: t(titleKey), titleClassName: isSmall ? 'h5 chart-section-title--small' : undefined, headRight: iconNode || (isSmall ? undefined : headRight), subRow: (showTotal || legend) && _jsxs(_Fragment, { children: [showTotal ? (_jsxs(ChartTotal, { label: !isSmall && totalLabelKey ? t(totalLabelKey) : undefined, children: [_jsx("span", { className: "barchart-total__num h0", children: pct }), _jsx("span", { className: "barchart-total__unit h5", children: "%" })] })) : _jsx("span", {}), legend && _jsx(ChartLegend, { items: legend })] }), children: loading ? (_jsx("div", { className: "manager-bar-chart-loading", children: _jsx(Loader, { size: 32 }) })) : (_jsx("div", { className: "ring-chart-section-body ring-chart-section-body--offset", children: _jsx(RingChartCanvas, { ...ringProps, hideCenter: ringProps.hideCenter ?? isSmall }) })) }));
68
68
  }
@@ -48,6 +48,16 @@
48
48
  flex: 1;
49
49
  justify-content: space-between;
50
50
  }
51
+ /* 값 아래 자리 — 목록·단추 등 카드가 값을 풀어 보이는 것 */
52
+ .manager-stat-card__body {
53
+ display: flex;
54
+ flex-direction: column;
55
+ align-items: stretch;
56
+ gap: 4px;
57
+ width: 100%;
58
+ text-align: left;
59
+ }
60
+
51
61
  .manager-stat-card__left {
52
62
  display: flex;
53
63
  flex-direction: row;
@@ -1,4 +1,5 @@
1
1
  import './StatChart.css';
2
+ import { type ReactNode } from 'react';
2
3
  /** @public */
3
4
  export type StatChartChangeType = 'up' | 'down' | 'neutral';
4
5
  /** @public */
@@ -16,6 +17,9 @@ export interface StatChartProps {
16
17
  /** 호버 시 표시할 툴팁 텍스트 */
17
18
  tooltip?: string;
18
19
  onClick?: () => void;
20
+ /** 값 **아래** 에 붙는 자리 — 목록 몇 줄, "외 n건" 단추처럼 값을 풀어 보이는 것.
21
+ * 이 자리가 없어 소비자가 카드 마크업(`manager-stat-card__*` 여덟 이름)을 통째로 베끼고 있었다(말귀 매니저 '금일 방문 예정'). */
22
+ children?: ReactNode;
19
23
  }
20
24
  /**
21
25
  * 순수 카운트 스탯 카드 — 제목+아이콘, 큰 숫자, 증감(선택) 만 보여준다.
@@ -23,4 +27,4 @@ export interface StatChartProps {
23
27
  * (도넛 breakdown은 RingChart segments 모드, 리스트는 페이지에서 직접 구성).
24
28
  * @public
25
29
  */
26
- export default function StatChart({ label, value, change, changeType, icon, tooltip, onClick }: StatChartProps): import("react").JSX.Element;
30
+ export default function StatChart({ label, value, change, changeType, icon, tooltip, onClick, children }: StatChartProps): import("react").JSX.Element;
@@ -11,7 +11,7 @@ import TooltipInfo from './Tooltip/InfoTooltip';
11
11
  * (도넛 breakdown은 RingChart segments 모드, 리스트는 페이지에서 직접 구성).
12
12
  * @public
13
13
  */
14
- export default function StatChart({ label, value, change, changeType, icon, tooltip, onClick }) {
14
+ export default function StatChart({ label, value, change, changeType, icon, tooltip, onClick, children }) {
15
15
  const cardRef = useRef(null);
16
16
  /* 앵커 상태는 공용 훅이 갖는다 — ManagerPage 의 VisitListCard 가 같은 것을 손으로
17
17
  한 벌 더 적고 있었다. 여는 조건(tooltip 이 있을 때만)만 여기 남긴다. */
@@ -37,5 +37,5 @@ export default function StatChart({ label, value, change, changeType, icon, tool
37
37
  bottom: anchorRect.bottom,
38
38
  width: anchorRect.width,
39
39
  height: anchorRect.height,
40
- }, text: tooltip })), _jsxs("div", { className: "manager-stat-card__label-row", children: [_jsx("span", { className: "manager-stat-card__label h5", children: label }), icon && (_jsx("span", { className: "manager-stat-card__icon", children: _jsx(Icon, { icon: icon, className: "manager-stat-card__icon-inner" }) }))] }), _jsx("div", { className: "manager-stat-card__content", children: _jsxs("div", { className: "manager-stat-card__left", children: [_jsx("div", { className: "manager-stat-card__value h2", children: value }), changeText && (_jsx("div", { className: `manager-stat-card__change manager-stat-card__change--${resolvedChangeType ?? 'neutral'} caption-1`, children: changeText }))] }) })] }));
40
+ }, text: tooltip })), _jsxs("div", { className: "manager-stat-card__label-row", children: [_jsx("span", { className: "manager-stat-card__label h5", children: label }), icon && (_jsx("span", { className: "manager-stat-card__icon", children: _jsx(Icon, { icon: icon, className: "manager-stat-card__icon-inner" }) }))] }), _jsxs("div", { className: "manager-stat-card__content", children: [_jsxs("div", { className: "manager-stat-card__left", children: [_jsx("div", { className: "manager-stat-card__value h2", children: value }), changeText && (_jsx("div", { className: `manager-stat-card__change manager-stat-card__change--${resolvedChangeType ?? 'neutral'} caption-1`, children: changeText }))] }), children && _jsx("div", { className: "manager-stat-card__body", children: children })] })] }));
41
41
  }
@@ -99,6 +99,12 @@ export interface BarChartProps {
99
99
  /** 머리의 보기 고르개 — 넓으면 세그먼트, 카드가 좁으면 '⋯' 한 단추로 접히고 그 메뉴에 칸들과 '상세보기' 가 함께 든다.
100
100
  * `headExtra` 로 고르개를 손수 얹고 좁을 때를 따로 다루던 것을 대신한다(ChartSection 이 카드 제 폭으로 잰다). */
101
101
  headSegment?: ChartHeadSegment;
102
+ /** 카드 자체를 누를 수 있게 — 커서·hover 테두리·키보드까지 ChartSection 이 한 결로 붙인다(머리의 단추·고르개 누름은 카드를 열지 않는다) */
103
+ onClick?: () => void;
104
+ /** 누르는 카드의 이름(낭독기) — 안 주면 제목 */
105
+ cardAriaLabel?: string;
106
+ /** 카드에 포인터가 닿을 때(키보드는 초점) 뜨는 설명 — StatChart tooltip 과 같은 뜻 */
107
+ cardTooltip?: string;
102
108
  /** 제목 왼쪽 아이콘 — Section·ChartSection 과 같은 자리·같은 색 */
103
109
  icon?: string;
104
110
  /** 제목 아래 설명 한 줄 */
@@ -46,4 +46,4 @@
46
46
  *
47
47
  * 값은 손으로 적고 `test/coreVersion.test.ts` 가 package.json 과 어긋나면 운다.
48
48
  */
49
- export declare const CORE_VERSION = "0.168.0";
49
+ export declare const CORE_VERSION = "0.170.0";
@@ -46,4 +46,4 @@
46
46
  *
47
47
  * 값은 손으로 적고 `test/coreVersion.test.ts` 가 package.json 과 어긋나면 운다.
48
48
  */
49
- export const CORE_VERSION = '0.168.0';
49
+ export const CORE_VERSION = '0.170.0';