@ihabdevteam/core 0.164.0 → 0.166.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.
- package/CHANGELOG.md +19 -0
- package/dist/components.cjs.js +11 -11
- package/dist/components.esm.css +1 -1
- package/dist/hooks.cjs.js +1 -1
- package/dist/i18n.cjs.js +1 -1
- package/dist/ihabdevteam-core.cjs.js +15 -15
- package/dist/ihabdevteam-core.d.ts +41 -5
- package/dist/packages/core/src/components/BarChart.d.ts +1 -1
- package/dist/packages/core/src/components/BarChart.js +4 -2
- package/dist/packages/core/src/components/ChartSection.css +24 -0
- package/dist/packages/core/src/components/ChartSection.d.ts +33 -4
- package/dist/packages/core/src/components/ChartSection.js +52 -2
- package/dist/packages/core/src/components/barChartTypes.d.ts +8 -0
- package/dist/packages/core/src/version.d.ts +1 -1
- package/dist/packages/core/src/version.js +1 -1
- package/dist/utils.cjs.js +1 -1
- package/package.json +1 -1
|
@@ -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, 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, detailSize, barGap, baseline, className, inGrid, }: BarChartProps): JSX.Element;
|
|
313
313
|
|
|
314
314
|
/** @public */
|
|
315
315
|
export declare interface BarChartControl {
|
|
@@ -410,6 +410,13 @@ export declare interface BarChartProps {
|
|
|
410
410
|
* 막대 수가 늘면 굵기는 `barWidth` 를 위 한계로 두고 줄어든다(계열 수만큼 센다).
|
|
411
411
|
*/
|
|
412
412
|
seriesMode?: 'stack' | 'group';
|
|
413
|
+
/** 머리의 보기 고르개 — 넓으면 세그먼트, 카드가 좁으면 '⋯' 한 단추로 접히고 그 메뉴에 칸들과 '상세보기' 가 함께 든다.
|
|
414
|
+
* `headExtra` 로 고르개를 손수 얹고 좁을 때를 따로 다루던 것을 대신한다(ChartSection 이 카드 제 폭으로 잰다). */
|
|
415
|
+
headSegment?: ChartHeadSegment;
|
|
416
|
+
/** 제목 왼쪽 아이콘 — Section·ChartSection 과 같은 자리·같은 색 */
|
|
417
|
+
icon?: string;
|
|
418
|
+
/** 제목 아래 설명 한 줄 */
|
|
419
|
+
disc?: ReactNode;
|
|
413
420
|
/** 0 선을 캔버스 가운데 두고 **음수는 아래로** 그린다(예: 변동률 %p). 주면 축은 위아래 대칭(±max|값|)이 되고,
|
|
414
421
|
* 눈금·격자선·이름표가 음수 구간까지 따라가며, 툴팁은 양수에 `+` 를 붙여 방향을 드러낸다.
|
|
415
422
|
* `series` + `seriesMode='group'` 과 함께 쓰면 갈래마다 0 선 위·아래로 자란다. 지금은 `0` 만 쓴다. */
|
|
@@ -992,6 +999,22 @@ export declare interface ChangeResult {
|
|
|
992
999
|
__ts: number;
|
|
993
1000
|
}
|
|
994
1001
|
|
|
1002
|
+
/** @public 카드 머리의 보기 고르개 — 넓으면 세그먼트, 좁으면 '⋯' 메뉴로 접힌다 */
|
|
1003
|
+
declare interface ChartHeadSegment {
|
|
1004
|
+
/** 지금 고른 칸의 열쇠 */
|
|
1005
|
+
value: string;
|
|
1006
|
+
onChange: (key: string) => void;
|
|
1007
|
+
/** 칸들. `icon` 은 접힌 메뉴에서만 쓰인다(고르개는 글자만). */
|
|
1008
|
+
options: {
|
|
1009
|
+
key: string;
|
|
1010
|
+
label: string;
|
|
1011
|
+
icon?: string;
|
|
1012
|
+
disabled?: boolean;
|
|
1013
|
+
}[];
|
|
1014
|
+
/** 고르개·메뉴의 이름(낭독기) */
|
|
1015
|
+
ariaLabel?: string;
|
|
1016
|
+
}
|
|
1017
|
+
|
|
995
1018
|
/** 차트 범례 — 색상 점 + 라벨 목록. BarChart/RingChart 섹션이 공유. @public */
|
|
996
1019
|
export declare function ChartLegend({ items, className }: {
|
|
997
1020
|
items: ChartLegendItem[];
|
|
@@ -1026,16 +1049,29 @@ export declare interface ChartPoint {
|
|
|
1026
1049
|
* 공유하도록 두 컴포넌트가 내부적으로 사용한다.
|
|
1027
1050
|
* @public
|
|
1028
1051
|
*/
|
|
1029
|
-
export declare function ChartSection({ title, titleClassName, headRight, subRow, className, inGrid, children }: ChartSectionProps): JSX.Element;
|
|
1052
|
+
export declare function ChartSection({ title, titleClassName, icon, disc, headRight, headSegment, headMenuItems, collapseBelow, subRow, className, inGrid, children }: ChartSectionProps): JSX.Element;
|
|
1030
1053
|
|
|
1031
1054
|
/** @public */
|
|
1032
1055
|
export declare interface ChartSectionProps {
|
|
1033
1056
|
/** 섹션 제목 */
|
|
1034
1057
|
title: ReactNode;
|
|
1058
|
+
/** 제목 왼쪽 아이콘 — `Section` 의 것과 같은 자리·같은 색 */
|
|
1059
|
+
icon?: string;
|
|
1060
|
+
/** 제목 아래 설명 한 줄 — `Section` 의 `disc` 와 같은 결 */
|
|
1061
|
+
disc?: ReactNode;
|
|
1035
1062
|
/** 제목 타이포그래피 클래스 (기본: 'h3') — 작은 카드(size='small')는 'h5' 등으로 축소 */
|
|
1036
1063
|
titleClassName?: string;
|
|
1037
|
-
/** 헤더 우측 영역 — 기간 네비게이션, 상세보기 버튼
|
|
1038
|
-
|
|
1064
|
+
/** 헤더 우측 영역 — 기간 네비게이션, 상세보기 버튼 등.
|
|
1065
|
+
* 함수로 주면 `collapsed`(머리가 좁아 고르개가 '⋯' 로 접혔는가)를 받는다 — 접혔을 때 단추를 메뉴로 옮기는 쪽이 쓴다. */
|
|
1066
|
+
headRight?: ReactNode | ((state: {
|
|
1067
|
+
collapsed: boolean;
|
|
1068
|
+
}) => ReactNode);
|
|
1069
|
+
/** 머리의 보기 고르개. 카드가 좁으면 '⋯' 한 단추로 접히고, 그 메뉴에 칸들이 들어간다. */
|
|
1070
|
+
headSegment?: ChartHeadSegment;
|
|
1071
|
+
/** 접힌 '⋯' 메뉴에서 칸들 **뒤** 에 구분선과 함께 붙는 항목(상세보기 등) */
|
|
1072
|
+
headMenuItems?: TooltipMenuColumnItem[];
|
|
1073
|
+
/** 고르개를 '⋯' 로 접는 카드 폭(px, 기본 420) */
|
|
1074
|
+
collapseBelow?: number;
|
|
1039
1075
|
/** 총계(ChartTotal) + 범례(ChartLegend)를 담는 서브로우 */
|
|
1040
1076
|
subRow?: ReactNode;
|
|
1041
1077
|
/** 섹션 루트에 추가할 클래스 */
|
|
@@ -1505,7 +1541,7 @@ export declare function copyText(text: string): Promise<boolean>;
|
|
|
1505
1541
|
*
|
|
1506
1542
|
* 값은 손으로 적고 `test/coreVersion.test.ts` 가 package.json 과 어긋나면 운다.
|
|
1507
1543
|
*/
|
|
1508
|
-
export declare const CORE_VERSION = "0.
|
|
1544
|
+
export declare const CORE_VERSION = "0.166.0";
|
|
1509
1545
|
|
|
1510
1546
|
/** @public */
|
|
1511
1547
|
declare const coreDefault: Record<string, unknown>;
|
|
@@ -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, 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, 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, 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, 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,9 @@ 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,
|
|
400
|
+
return (_jsx(ChartSection, { className: sectionClassName, inGrid: inGrid, icon: icon, disc: disc, headSegment: headSegment,
|
|
401
|
+
/* 좁아 고르개가 '⋯' 로 접히면 상세보기도 그 메뉴로 들어간다 — 머리에 단추 둘이 남지 않게 */
|
|
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)) ? (
|
|
401
403
|
// 진행률/평균 모드 또는 totalLabelKey+totalFormat 조합: 라벨(윗줄) + 값(아랫줄). size='small'은 라벨 생략
|
|
402
404
|
_jsx(ChartTotal, { label: isSmall ? undefined : `${t(control.period === 'week' ? 'manager.chart.weeklyPrefix' : 'manager.chart.monthlyPrefix')} ${t(totalLabelKey ?? labelAKey)}`, children: totalFormat ? (
|
|
403
405
|
// 숫자는 h0, 단위(시간/분/초 등)는 h5로 분리
|
|
@@ -31,6 +31,30 @@
|
|
|
31
31
|
.manager-section__title {
|
|
32
32
|
min-width: 0;
|
|
33
33
|
}
|
|
34
|
+
/* 아이콘 + (제목·설명) — Section 의 머리와 같은 결 */
|
|
35
|
+
.manager-section__title-row {
|
|
36
|
+
display: flex;
|
|
37
|
+
align-items: center;
|
|
38
|
+
gap: var(--spacing-s);
|
|
39
|
+
min-width: 0;
|
|
40
|
+
flex: 1 1 auto;
|
|
41
|
+
}
|
|
42
|
+
.manager-section__icon {
|
|
43
|
+
width: 20px;
|
|
44
|
+
height: 20px;
|
|
45
|
+
flex-shrink: 0;
|
|
46
|
+
display: flex;
|
|
47
|
+
align-items: center;
|
|
48
|
+
justify-content: center;
|
|
49
|
+
color: var(--t-item-fg, var(--color-main));
|
|
50
|
+
}
|
|
51
|
+
.manager-section__disc {
|
|
52
|
+
/* 제목 줄 **아래 한 줄** — flex 줄바꿈에서 통째로 한 줄을 차지한다(제목 옆에 서면 오른쪽 묶음을 밀어낸다) */
|
|
53
|
+
flex: 0 0 100%;
|
|
54
|
+
min-width: 0;
|
|
55
|
+
color: var(--color-gray);
|
|
56
|
+
margin: 0;
|
|
57
|
+
}
|
|
34
58
|
.manager-section__head-right {
|
|
35
59
|
display: flex;
|
|
36
60
|
align-items: center;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import './ChartSection.css';
|
|
2
|
-
import type
|
|
2
|
+
import { type ReactNode } from 'react';
|
|
3
|
+
import { type TooltipMenuColumnItem } from './Tooltip/MenuTooltip';
|
|
3
4
|
/** @public */
|
|
4
5
|
export interface ChartLegendItem {
|
|
5
6
|
color: string;
|
|
@@ -19,14 +20,42 @@ export interface ChartTotalProps {
|
|
|
19
20
|
}
|
|
20
21
|
/** 차트 총계 표시 — label이 있으면 라벨(윗줄)+값(아랫줄) stacked, 없으면 값만. @public */
|
|
21
22
|
export declare function ChartTotal({ label, children }: ChartTotalProps): import("react").JSX.Element;
|
|
23
|
+
/** @public 카드 머리의 보기 고르개 — 넓으면 세그먼트, 좁으면 '⋯' 메뉴로 접힌다 */
|
|
24
|
+
export interface ChartHeadSegment {
|
|
25
|
+
/** 지금 고른 칸의 열쇠 */
|
|
26
|
+
value: string;
|
|
27
|
+
onChange: (key: string) => void;
|
|
28
|
+
/** 칸들. `icon` 은 접힌 메뉴에서만 쓰인다(고르개는 글자만). */
|
|
29
|
+
options: {
|
|
30
|
+
key: string;
|
|
31
|
+
label: string;
|
|
32
|
+
icon?: string;
|
|
33
|
+
disabled?: boolean;
|
|
34
|
+
}[];
|
|
35
|
+
/** 고르개·메뉴의 이름(낭독기) */
|
|
36
|
+
ariaLabel?: string;
|
|
37
|
+
}
|
|
22
38
|
/** @public */
|
|
23
39
|
export interface ChartSectionProps {
|
|
24
40
|
/** 섹션 제목 */
|
|
25
41
|
title: ReactNode;
|
|
42
|
+
/** 제목 왼쪽 아이콘 — `Section` 의 것과 같은 자리·같은 색 */
|
|
43
|
+
icon?: string;
|
|
44
|
+
/** 제목 아래 설명 한 줄 — `Section` 의 `disc` 와 같은 결 */
|
|
45
|
+
disc?: ReactNode;
|
|
26
46
|
/** 제목 타이포그래피 클래스 (기본: 'h3') — 작은 카드(size='small')는 'h5' 등으로 축소 */
|
|
27
47
|
titleClassName?: string;
|
|
28
|
-
/** 헤더 우측 영역 — 기간 네비게이션, 상세보기 버튼
|
|
29
|
-
|
|
48
|
+
/** 헤더 우측 영역 — 기간 네비게이션, 상세보기 버튼 등.
|
|
49
|
+
* 함수로 주면 `collapsed`(머리가 좁아 고르개가 '⋯' 로 접혔는가)를 받는다 — 접혔을 때 단추를 메뉴로 옮기는 쪽이 쓴다. */
|
|
50
|
+
headRight?: ReactNode | ((state: {
|
|
51
|
+
collapsed: boolean;
|
|
52
|
+
}) => ReactNode);
|
|
53
|
+
/** 머리의 보기 고르개. 카드가 좁으면 '⋯' 한 단추로 접히고, 그 메뉴에 칸들이 들어간다. */
|
|
54
|
+
headSegment?: ChartHeadSegment;
|
|
55
|
+
/** 접힌 '⋯' 메뉴에서 칸들 **뒤** 에 구분선과 함께 붙는 항목(상세보기 등) */
|
|
56
|
+
headMenuItems?: TooltipMenuColumnItem[];
|
|
57
|
+
/** 고르개를 '⋯' 로 접는 카드 폭(px, 기본 420) */
|
|
58
|
+
collapseBelow?: number;
|
|
30
59
|
/** 총계(ChartTotal) + 범례(ChartLegend)를 담는 서브로우 */
|
|
31
60
|
subRow?: ReactNode;
|
|
32
61
|
/** 섹션 루트에 추가할 클래스 */
|
|
@@ -46,4 +75,4 @@ export interface ChartSectionProps {
|
|
|
46
75
|
* 공유하도록 두 컴포넌트가 내부적으로 사용한다.
|
|
47
76
|
* @public
|
|
48
77
|
*/
|
|
49
|
-
export default function ChartSection({ title, titleClassName, headRight, subRow, className, inGrid, children }: ChartSectionProps): import("react").JSX.Element;
|
|
78
|
+
export default function ChartSection({ title, titleClassName, icon, disc, headRight, headSegment, headMenuItems, collapseBelow, subRow, className, inGrid, children }: ChartSectionProps): import("react").JSX.Element;
|
|
@@ -1,5 +1,13 @@
|
|
|
1
|
+
'use client';
|
|
1
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
3
|
import './ChartSection.css';
|
|
4
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
5
|
+
import { useTranslation } from 'react-i18next';
|
|
6
|
+
import Icon from './Icon';
|
|
7
|
+
import Button from './Button';
|
|
8
|
+
import SegmentedControl from './SegmentedControl';
|
|
9
|
+
import Tooltip from './Tooltip/Tooltip';
|
|
10
|
+
import MenuTooltip from './Tooltip/MenuTooltip';
|
|
3
11
|
/** 차트 범례 — 색상 점 + 라벨 목록. BarChart/RingChart 섹션이 공유. @public */
|
|
4
12
|
export function ChartLegend({ items, className }) {
|
|
5
13
|
return (_jsx("div", { className: className ? `manager-bar-chart-legend ${className}` : 'manager-bar-chart-legend', children: items.map((it, i) => (_jsxs("span", { className: "manager-bar-chart-legend-item", children: [_jsx("span", { className: "manager-bar-chart-legend-dot", style: { background: it.color } }), it.label] }, i))) }));
|
|
@@ -17,6 +25,48 @@ export function ChartTotal({ label, children }) {
|
|
|
17
25
|
* 공유하도록 두 컴포넌트가 내부적으로 사용한다.
|
|
18
26
|
* @public
|
|
19
27
|
*/
|
|
20
|
-
export default function ChartSection({ title, titleClassName = 'h3', headRight, subRow, className, inGrid = false, children }) {
|
|
21
|
-
|
|
28
|
+
export default function ChartSection({ title, titleClassName = 'h3', icon, disc, headRight, headSegment, headMenuItems, collapseBelow = 420, subRow, className, inGrid = false, children }) {
|
|
29
|
+
const { t } = useTranslation();
|
|
30
|
+
const secRef = useRef(null);
|
|
31
|
+
/* 좁은지는 **카드 제 폭** 으로 잰다 — 부르는 쪽이 격자 칸 폭으로 대신 재면 두 칸을 차지하는 카드에서 틀린다.
|
|
32
|
+
ResizeObserver 가 없는 환경(구형·SSR)에서는 접지 않는다(넓은 쪽이 기본). */
|
|
33
|
+
const [좁음, set좁음] = useState(false);
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
const el = secRef.current;
|
|
36
|
+
if (!el || !headSegment)
|
|
37
|
+
return;
|
|
38
|
+
const 재기 = (w) => set좁음(w > 0 && w < collapseBelow);
|
|
39
|
+
재기(el.clientWidth);
|
|
40
|
+
if (typeof ResizeObserver === 'undefined')
|
|
41
|
+
return;
|
|
42
|
+
const ro = new ResizeObserver(entries => 재기(entries[0].contentRect.width));
|
|
43
|
+
ro.observe(el);
|
|
44
|
+
return () => ro.disconnect();
|
|
45
|
+
}, [headSegment, collapseBelow]);
|
|
46
|
+
const [메뉴자리, set메뉴자리] = useState(null);
|
|
47
|
+
const 메뉴닫기 = useCallback(() => set메뉴자리(null), []);
|
|
48
|
+
const 메뉴열기 = useCallback((e) => {
|
|
49
|
+
const r = e.currentTarget.getBoundingClientRect();
|
|
50
|
+
set메뉴자리(prev => (prev ? null : { left: r.left, right: r.right, top: r.top, bottom: r.bottom, width: r.width, height: r.height, x: r.x, y: r.y }));
|
|
51
|
+
}, []);
|
|
52
|
+
const 접힘 = !!headSegment && 좁음;
|
|
53
|
+
useEffect(() => { if (!접힘)
|
|
54
|
+
set메뉴자리(null); }, [접힘]);
|
|
55
|
+
const 메뉴항목 = headSegment
|
|
56
|
+
? [
|
|
57
|
+
...headSegment.options.map(o => ({
|
|
58
|
+
label: o.label,
|
|
59
|
+
icon: o.icon,
|
|
60
|
+
selected: o.key === headSegment.value,
|
|
61
|
+
disabled: o.disabled,
|
|
62
|
+
onClick: () => headSegment.onChange(o.key),
|
|
63
|
+
closeOnSelect: true,
|
|
64
|
+
})),
|
|
65
|
+
/* 성격이 다른 묶음 — 위는 무엇을 볼지, 아래는 창을 연다 */
|
|
66
|
+
...(headMenuItems ?? []).map((it, i) => (i === 0 ? { ...it, separatorBefore: true } : it)),
|
|
67
|
+
]
|
|
68
|
+
: [];
|
|
69
|
+
const 오른쪽 = typeof headRight === 'function' ? headRight({ collapsed: 접힘 }) : headRight;
|
|
70
|
+
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" }) }))] }));
|
|
22
72
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
|
+
import type { ChartHeadSegment } from './ChartSection';
|
|
2
3
|
import type { MonthBarData } from './barChartData';
|
|
3
4
|
/** @public */
|
|
4
5
|
export interface BarChartControl {
|
|
@@ -95,6 +96,13 @@ export interface BarChartProps {
|
|
|
95
96
|
* 막대 수가 늘면 굵기는 `barWidth` 를 위 한계로 두고 줄어든다(계열 수만큼 센다).
|
|
96
97
|
*/
|
|
97
98
|
seriesMode?: 'stack' | 'group';
|
|
99
|
+
/** 머리의 보기 고르개 — 넓으면 세그먼트, 카드가 좁으면 '⋯' 한 단추로 접히고 그 메뉴에 칸들과 '상세보기' 가 함께 든다.
|
|
100
|
+
* `headExtra` 로 고르개를 손수 얹고 좁을 때를 따로 다루던 것을 대신한다(ChartSection 이 카드 제 폭으로 잰다). */
|
|
101
|
+
headSegment?: ChartHeadSegment;
|
|
102
|
+
/** 제목 왼쪽 아이콘 — Section·ChartSection 과 같은 자리·같은 색 */
|
|
103
|
+
icon?: string;
|
|
104
|
+
/** 제목 아래 설명 한 줄 */
|
|
105
|
+
disc?: ReactNode;
|
|
98
106
|
/** 0 선을 캔버스 가운데 두고 **음수는 아래로** 그린다(예: 변동률 %p). 주면 축은 위아래 대칭(±max|값|)이 되고,
|
|
99
107
|
* 눈금·격자선·이름표가 음수 구간까지 따라가며, 툴팁은 양수에 `+` 를 붙여 방향을 드러낸다.
|
|
100
108
|
* `series` + `seriesMode='group'` 과 함께 쓰면 갈래마다 0 선 위·아래로 자란다. 지금은 `0` 만 쓴다. */
|