@ihabdevteam/core 0.11.0 → 0.12.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.
@@ -3001,7 +3001,7 @@ export declare interface PairStats {
3001
3001
  total: number;
3002
3002
  }
3003
3003
 
3004
- export declare function Panel({ title, actions, size, minHeight, maxWidth, className, scrollable, useBorder, useBg, useRowBorder, labelWidth, form, loading, empty, children }: PanelProps): JSX.Element;
3004
+ export declare function Panel({ title, disc, actions, size, minHeight, maxWidth, className, scrollable, useBorder, useBg, useRowBorder, labelWidth, form, loading, empty, children }: PanelProps): JSX.Element;
3005
3005
 
3006
3006
  /** @public */
3007
3007
  export declare type PanelElement = HTMLDivElement & {
@@ -3017,6 +3017,16 @@ export declare function PanelGrid({ cols, children }: {
3017
3017
 
3018
3018
  declare interface PanelProps {
3019
3019
  title?: ReactNode;
3020
+ /**
3021
+ * 제목 아래 한 줄 설명. Section 의 `disc` 와 같은 자리다.
3022
+ *
3023
+ * 머리가 제목 한 줄뿐이면, 칸이 무엇을 하는 자리인지 적을 곳이 없어 부르는
3024
+ * 쪽이 설명을 첫 행(`PanelRow variant="description"`)으로 내리게 된다 —
3025
+ * 고르는 것이 없는 행이 하나 늘고, 행 높이(56px)까지 차지한다.
3026
+ * 설명을 `title` 에 끼워 넣는 것도 답이 아니다: 제목은 `<h2>` 안에 그려지므로
3027
+ * 스크린리더가 설명까지 제목으로 읽는다.
3028
+ */
3029
+ disc?: ReactNode;
3020
3030
  actions?: ReactNode;
3021
3031
  /** 행 높이 스케일 — small 48 / medium 56 / large 64. 기본 medium */
3022
3032
  size?: PanelSize;
@@ -39,10 +39,27 @@
39
39
  .panel--small .panel__header { min-height: 48px; }
40
40
  .panel--medium .panel__header { min-height: 56px; }
41
41
  .panel--large .panel__header { min-height: 64px; }
42
+ /* 제목 + 설명 한 덩이. 설명이 없으면 한 줄짜리라 예전과 같은 모양이다. */
43
+ .panel__title-group {
44
+ display: flex;
45
+ flex-direction: column;
46
+ gap: 4px;
47
+ min-width: 0;
48
+ }
42
49
  .panel__title {
43
50
  color: var(--color-darkGray);
44
51
  margin: 0;
45
52
  }
53
+ /* Section 의 disc 와 같은 색·같은 급 */
54
+ .panel__disc {
55
+ color: var(--color-gray);
56
+ margin: 0;
57
+ }
58
+ /* 설명이 붙은 머리는 두 줄이라 size 의 min-height 를 넘어선다 —
59
+ 위아래 여백을 줘서 글이 테두리에 붙지 않게 한다. */
60
+ .panel__header--with-disc {
61
+ padding-block: var(--spacing-s);
62
+ }
46
63
  .panel__actions {
47
64
  display: flex;
48
65
  gap: 6px;
@@ -4,6 +4,16 @@ import './Panel.css';
4
4
  type PanelSize = 'small' | 'medium' | 'large';
5
5
  interface PanelProps {
6
6
  title?: ReactNode;
7
+ /**
8
+ * 제목 아래 한 줄 설명. Section 의 `disc` 와 같은 자리다.
9
+ *
10
+ * 머리가 제목 한 줄뿐이면, 칸이 무엇을 하는 자리인지 적을 곳이 없어 부르는
11
+ * 쪽이 설명을 첫 행(`PanelRow variant="description"`)으로 내리게 된다 —
12
+ * 고르는 것이 없는 행이 하나 늘고, 행 높이(56px)까지 차지한다.
13
+ * 설명을 `title` 에 끼워 넣는 것도 답이 아니다: 제목은 `<h2>` 안에 그려지므로
14
+ * 스크린리더가 설명까지 제목으로 읽는다.
15
+ */
16
+ disc?: ReactNode;
7
17
  actions?: ReactNode;
8
18
  /** 행 높이 스케일 — small 48 / medium 56 / large 64. 기본 medium */
9
19
  size?: PanelSize;
@@ -27,7 +37,7 @@ interface PanelProps {
27
37
  empty?: ReactNode;
28
38
  children?: ReactNode;
29
39
  }
30
- export default function Panel({ title, actions, size, minHeight, maxWidth, className, scrollable, useBorder, useBg, useRowBorder, labelWidth, form, loading, empty, children }: PanelProps): import("react").JSX.Element;
40
+ export default function Panel({ title, disc, actions, size, minHeight, maxWidth, className, scrollable, useBorder, useBg, useRowBorder, labelWidth, form, loading, empty, children }: PanelProps): import("react").JSX.Element;
31
41
  /** @public */
32
42
  export declare function PanelGrid({ cols, children }: {
33
43
  cols?: number;
@@ -13,7 +13,7 @@ import TextField from './TextField';
13
13
  import Loader from './Loader';
14
14
  import './Panel.css';
15
15
  const noop = () => { };
16
- export default function Panel({ title, actions, size = 'medium', minHeight, maxWidth, className, scrollable, useBorder = true, useBg = true, useRowBorder = true, labelWidth, form = false, loading, empty, children }) {
16
+ export default function Panel({ title, disc, actions, size = 'medium', minHeight, maxWidth, className, scrollable, useBorder = true, useBg = true, useRowBorder = true, labelWidth, form = false, loading, empty, children }) {
17
17
  const cls = cx('panel', `panel--${size}`, form ? 'panel--form' : '',
18
18
  /* minHeight 패널은 마지막 행 아래 빈 공간이 생길 수 있으므로 행 하단 구분선 사용 */
19
19
  minHeight !== undefined ? 'panel--fill' : '', !useBorder ? 'panel--no-border' : '', !useBg ? 'panel--no-bg' : '', !useRowBorder ? 'panel--no-row-border' : '', className);
@@ -24,7 +24,7 @@ export default function Panel({ title, actions, size = 'medium', minHeight, maxW
24
24
  style.maxWidth = typeof maxWidth === 'number' ? `${maxWidth}px` : maxWidth;
25
25
  if (labelWidth !== undefined)
26
26
  style['--panel-label-width'] = typeof labelWidth === 'number' ? `${labelWidth}px` : labelWidth;
27
- return (_jsxs("div", { className: cls, style: Object.keys(style).length ? style : undefined, children: [title != null && (_jsxs("div", { className: "panel__header", children: [_jsx("h2", { className: "panel__title h5b", children: title }), actions && _jsx("div", { className: "panel__actions", children: actions })] })), loading ? (_jsx(PanelRow, { variant: "loading" })) : empty != null && (children == null || (Array.isArray(children) && children.length === 0)) ? (_jsx(PanelRow, { variant: "empty", children: empty })) : scrollable ? (_jsx("div", { className: "panel__body--scroll", children: children })) : children] }));
27
+ return (_jsxs("div", { className: cls, style: Object.keys(style).length ? style : undefined, children: [(title != null || disc != null) && (_jsxs("div", { className: cx('panel__header', disc != null ? 'panel__header--with-disc' : ''), children: [_jsxs("div", { className: "panel__title-group", children: [title != null && _jsx("h2", { className: "panel__title h5b", children: title }), disc != null && _jsx("p", { className: "panel__disc body-3", children: disc })] }), actions && _jsx("div", { className: "panel__actions", children: actions })] })), loading ? (_jsx(PanelRow, { variant: "loading" })) : empty != null && (children == null || (Array.isArray(children) && children.length === 0)) ? (_jsx(PanelRow, { variant: "empty", children: empty })) : scrollable ? (_jsx("div", { className: "panel__body--scroll", children: children })) : children] }));
28
28
  }
29
29
  // ── PanelGrid ──────────────────────────────────────────────────────────────
30
30
  /** @public */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ihabdevteam/core",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "private": false,
5
5
  "main": "dist/ihabdevteam-core.cjs.js",
6
6
  "module": "dist/ihabdevteam-core.esm.js",