@ihabdevteam/core 0.213.0 → 0.214.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 +43 -0
- package/dist/components.cjs.js +184 -184
- package/dist/components.esm.css +1 -1
- package/dist/hooks.cjs.js +3 -3
- package/dist/i18n.cjs.js +3 -3
- package/dist/ihabdevteam-core.cjs.js +181 -181
- package/dist/ihabdevteam-core.d.ts +34 -2
- package/dist/packages/core/src/components/Word/TableFilterPanel.d.ts +4 -0
- package/dist/packages/core/src/components/Word/TableFilterPanel.js +5 -3
- package/dist/packages/core/src/components/Word/WordTableBlock.js +2 -2
- package/dist/packages/core/src/components/Word/useWordTableDisplaySettings.d.ts +10 -1
- package/dist/packages/core/src/components/Word/useWordTableDisplaySettings.js +18 -7
- package/dist/packages/core/src/components/Word/wordTableSettings.d.ts +8 -0
- package/dist/packages/core/src/components/Word/wordTableSettings.js +33 -0
- package/dist/packages/core/src/components/WordTable.css +85 -22
- package/dist/packages/core/src/components/WordTable.d.ts +17 -0
- package/dist/packages/core/src/components/WordTable.js +24 -7
- package/dist/packages/core/src/i18n/locales/en.json +2 -0
- package/dist/packages/core/src/i18n/locales/ko.json +2 -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
|
@@ -1626,7 +1626,7 @@ export declare function copyText(text: string): Promise<boolean>;
|
|
|
1626
1626
|
*
|
|
1627
1627
|
* 값은 손으로 적고 `test/coreVersion.test.ts` 가 package.json 과 어긋나면 운다.
|
|
1628
1628
|
*/
|
|
1629
|
-
export declare const CORE_VERSION = "0.
|
|
1629
|
+
export declare const CORE_VERSION = "0.214.0";
|
|
1630
1630
|
|
|
1631
1631
|
/** @public */
|
|
1632
1632
|
declare const coreDefault: Record<string, unknown>;
|
|
@@ -7332,6 +7332,10 @@ declare interface TableFilterPanelSmartProps extends TableFilterPanelBaseProps {
|
|
|
7332
7332
|
showCutLine?: boolean;
|
|
7333
7333
|
/** 구분선 섹션 노출 여부 — 대립쌍표 등 짝이 있는 표에서만(호출부가 판단). */
|
|
7334
7334
|
showDivLine2?: boolean;
|
|
7335
|
+
/** 상단·하단 정보(종이 머리·바닥 띠) 절을 세운다 — 띠를 쓰는 화면에서만(호출부가 판단). */
|
|
7336
|
+
showPaperBands?: boolean;
|
|
7337
|
+
showTopInfo?: boolean;
|
|
7338
|
+
showBottomInfo?: boolean;
|
|
7335
7339
|
/** 용지 방향과 외곽선 사이에 끼워 넣을 추가 섹션 — 칸 수/페이지당 개수/페이지 번호 등, 호출부 전용이라 직접 구성해 넘긴다. */
|
|
7336
7340
|
middleSections?: FilterPanelSection[];
|
|
7337
7341
|
/** middleSections의 현재 선택값. */
|
|
@@ -7458,6 +7462,8 @@ declare interface TableSettingsSetters {
|
|
|
7458
7462
|
setShowOutline: (v: boolean) => void;
|
|
7459
7463
|
setCutLine: (v: WordTableCutLine) => void;
|
|
7460
7464
|
setShowDivLine: (v: boolean) => void;
|
|
7465
|
+
setShowTopInfo?: (v: boolean) => void;
|
|
7466
|
+
setShowBottomInfo?: (v: boolean) => void;
|
|
7461
7467
|
}
|
|
7462
7468
|
|
|
7463
7469
|
/** `useTableSort` 의 선택 인자. @public */
|
|
@@ -9747,7 +9753,12 @@ export declare function useWordMeanings(rows: {
|
|
|
9747
9753
|
* WordTablePopup 등 표를 미리 보여주고 인쇄하는 곳에서 쓴다.
|
|
9748
9754
|
* @public
|
|
9749
9755
|
*/
|
|
9750
|
-
export declare function useWordTableDisplaySettings(items: WordSearchResultItem[]
|
|
9756
|
+
export declare function useWordTableDisplaySettings(items: WordSearchResultItem[],
|
|
9757
|
+
/** 종이 머리·바닥 띠를 쓰는 화면이면 참 — '상단 정보'·'하단 정보' 절이 함께 선다.
|
|
9758
|
+
* 안 쓰는 화면에 켜고 끌 것이 없는 절이 서면 안 되므로 기본은 거짓이다. */
|
|
9759
|
+
opts?: {
|
|
9760
|
+
paperBands?: boolean;
|
|
9761
|
+
}): UseWordTableDisplaySettingsResult;
|
|
9751
9762
|
|
|
9752
9763
|
/** @public */
|
|
9753
9764
|
export declare interface UseWordTableDisplaySettingsResult {
|
|
@@ -10585,6 +10596,10 @@ export declare interface WordTableDisplaySettings {
|
|
|
10585
10596
|
contentTypes: WordTableContentType[];
|
|
10586
10597
|
cutLine: WordTableCutLine;
|
|
10587
10598
|
showOutline: boolean;
|
|
10599
|
+
/** 종이 머리 띠(로고·표 번호)를 찍나 */
|
|
10600
|
+
showTopInfo: boolean;
|
|
10601
|
+
/** 종이 바닥 띠(만든 곳·주소·쪽 번호)를 찍나 */
|
|
10602
|
+
showBottomInfo: boolean;
|
|
10588
10603
|
showDivLine: boolean;
|
|
10589
10604
|
/** 표 칸 수(= 페이지당 개수, 최소 1). */
|
|
10590
10605
|
count: number;
|
|
@@ -10757,10 +10772,18 @@ export declare interface WordTableProps {
|
|
|
10757
10772
|
brand?: {
|
|
10758
10773
|
/** 로고와 저작권을 세운다. 나머지 자리는 각자 값이 있을 때만 선다. */
|
|
10759
10774
|
show?: boolean;
|
|
10775
|
+
/** 위 띠만 끈다(`show` 가 켜져 있을 때). 표 설정의 '상단 정보' 가 이것을 움직인다. */
|
|
10776
|
+
top?: boolean;
|
|
10777
|
+
/** 아래 띠만 끈다(`show` 가 켜져 있을 때). 표 설정의 '하단 정보' 가 이것을 움직인다. */
|
|
10778
|
+
bottom?: boolean;
|
|
10760
10779
|
/**
|
|
10761
10780
|
* 아래 오른쪽 — **이 표로 가는 주소**. 회사 홈 주소가 아니라 그 표의 공유 링크다
|
|
10762
10781
|
* (사용자 지시 2026-09-30). 종이를 든 사람이 이 주소로 같은 표를 화면에서 연다.
|
|
10763
10782
|
*
|
|
10783
|
+
* **`code` 와는 다른 것이다.** 표 번호는 기관 안에서 매긴 번호고 이 주소는 따로 난
|
|
10784
|
+
* 공유 링크다 — 번호에서 주소를 만들어 내지 않는다. 둘 다 이 표를 가리키지만 나오는
|
|
10785
|
+
* 데가 다르므로 각각 받는다.
|
|
10786
|
+
*
|
|
10764
10787
|
* 종이라 누를 수 없으니 글자 그대로 찍는다 — 그래서 **사람이 옮겨 칠 수 있는 길이**
|
|
10765
10788
|
* 여야 한다. 긴 주소를 그대로 주면 넘쳐 …로 잘리고, 잘린 주소는 옮겨 칠 수 없다.
|
|
10766
10789
|
* 짧은 주소를 쓰거나, 표 번호로 찾는 길을 함께 두는 편이 낫다.
|
|
@@ -10768,6 +10791,15 @@ export declare interface WordTableProps {
|
|
|
10768
10791
|
link?: string;
|
|
10769
10792
|
/** 저작권 글월 — 안 주면 `© IHAB, Inc. All rights reserved.` */
|
|
10770
10793
|
copyright?: string;
|
|
10794
|
+
/** 위 오른쪽 맨 앞 — **이 표의 이름**. `표 제목 · 기관 이름 · 표 번호` 로 선다. */
|
|
10795
|
+
title?: string;
|
|
10796
|
+
/**
|
|
10797
|
+
* 위 오른쪽 — **표 번호 앞에 붙는 기관 이름**(말귀매니저). 번호는 그 기관 안에서만
|
|
10798
|
+
* 고유하므로 이름과 함께여야 어느 곳의 몇 번인지가 정해진다(사용자 지시 2026-09-30).
|
|
10799
|
+
* `이름 · 번호` 로 선다. 이름이 길면 이름만 줄고 번호는 안 줄인다 — 번호가 잘리면
|
|
10800
|
+
* 확인 글자가 사라져 뜻이 없다.
|
|
10801
|
+
*/
|
|
10802
|
+
owner?: string;
|
|
10771
10803
|
};
|
|
10772
10804
|
/**
|
|
10773
10805
|
* **짧은 식별 글** — 표 번호(`1043-E`). `brand` 를 줬을 때 위 오른쪽에 선다.
|
|
@@ -45,6 +45,10 @@ export interface TableFilterPanelSmartProps extends TableFilterPanelBaseProps {
|
|
|
45
45
|
showCutLine?: boolean;
|
|
46
46
|
/** 구분선 섹션 노출 여부 — 대립쌍표 등 짝이 있는 표에서만(호출부가 판단). */
|
|
47
47
|
showDivLine2?: boolean;
|
|
48
|
+
/** 상단·하단 정보(종이 머리·바닥 띠) 절을 세운다 — 띠를 쓰는 화면에서만(호출부가 판단). */
|
|
49
|
+
showPaperBands?: boolean;
|
|
50
|
+
showTopInfo?: boolean;
|
|
51
|
+
showBottomInfo?: boolean;
|
|
48
52
|
/** 용지 방향과 외곽선 사이에 끼워 넣을 추가 섹션 — 칸 수/페이지당 개수/페이지 번호 등, 호출부 전용이라 직접 구성해 넘긴다. */
|
|
49
53
|
middleSections?: FilterPanelSection[];
|
|
50
54
|
/** middleSections의 현재 선택값. */
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import { useTranslation } from 'react-i18next';
|
|
4
4
|
import FilterPanel from '../FilterPanel';
|
|
5
|
-
import { buildCompositionSection, buildOrientationSection, buildBorderSection, buildCutLineSection, buildDivLineSection, buildTableSettingsSelected, applyTableSettingsSelect, } from './wordTableSettings';
|
|
5
|
+
import { buildCompositionSection, buildOrientationSection, buildBorderSection, buildCutLineSection, buildDivLineSection, buildTopInfoSection, buildBottomInfoSection, buildTableSettingsSelected, applyTableSettingsSelect, } from './wordTableSettings';
|
|
6
6
|
function isShellProps(props) {
|
|
7
7
|
return 'sections' in props;
|
|
8
8
|
}
|
|
@@ -22,7 +22,7 @@ export default function TableFilterPanel(props) {
|
|
|
22
22
|
if (isShellProps(props)) {
|
|
23
23
|
return (_jsx(FilterPanel, { className: className, title: title ?? t('wordTable.filterTitle', '표 설정'), sections: props.sections, selected: props.selected, onSelect: props.onSelect, ...접기, align: "inline" }));
|
|
24
24
|
}
|
|
25
|
-
const { hasImage, hasColloquial, contentTypes, orientation, showOutline, cutLine, showDivLine, setters, showCutLine = false, showDivLine2 = false, middleSections = [], extraSelected = {}, onExtraSelect, } = props;
|
|
25
|
+
const { hasImage, hasColloquial, contentTypes, orientation, showOutline, cutLine, showDivLine, setters, showCutLine = false, showDivLine2 = false, middleSections = [], extraSelected = {}, onExtraSelect, showPaperBands = false, showTopInfo = true, showBottomInfo = true, } = props;
|
|
26
26
|
const sections = [
|
|
27
27
|
buildCompositionSection(t, { hasImage, hasColloquial }),
|
|
28
28
|
buildOrientationSection(t),
|
|
@@ -30,9 +30,11 @@ export default function TableFilterPanel(props) {
|
|
|
30
30
|
buildBorderSection(t),
|
|
31
31
|
...(showCutLine ? [buildCutLineSection(t)] : []),
|
|
32
32
|
...(showDivLine2 ? [buildDivLineSection(t)] : []),
|
|
33
|
+
/* 띠를 쓰는 화면에서만 — 안 쓰는 표에 켜고 끌 것이 없는 절이 서면 안 된다 */
|
|
34
|
+
...(showPaperBands ? [buildTopInfoSection(t), buildBottomInfoSection(t)] : []),
|
|
33
35
|
];
|
|
34
36
|
const selected = {
|
|
35
|
-
...buildTableSettingsSelected(t, { contentTypes, orientation, showOutline, cutLine, showDivLine }),
|
|
37
|
+
...buildTableSettingsSelected(t, { contentTypes, orientation, showOutline, cutLine, showDivLine, showTopInfo, showBottomInfo }),
|
|
36
38
|
...extraSelected,
|
|
37
39
|
};
|
|
38
40
|
const onSelect = (value, sectionLabel) => {
|
|
@@ -12,7 +12,7 @@ import Popup from '../Popup/Popup';
|
|
|
12
12
|
import WordTable, { WORD_TABLE_PAPER } from '../WordTable';
|
|
13
13
|
import { chunkItems } from '../wordTableLayout';
|
|
14
14
|
import TableFilterPanel from './TableFilterPanel';
|
|
15
|
-
import { buildItemsPerPageSection,
|
|
15
|
+
import { buildItemsPerPageSection, PAGE_NUM_POSITION_VALUE, parsePageNumberPosition, itemsPerPageFromChoice } from './wordTableSettings';
|
|
16
16
|
import Toast from '../Toast';
|
|
17
17
|
import { useToastState } from '../../hooks/useToastState';
|
|
18
18
|
import { getImageResolver, checkImageExists } from '../../utils/imageConfig';
|
|
@@ -196,7 +196,7 @@ export default function WordTableBlock({ title, titleIcon, disc, filterTitle, fi
|
|
|
196
196
|
...((isEditable || showCellCount) ? [{ label: t('wordTable.filter.columns', '칸 수'), items: CELL_COUNTS.map(n => ({ value: `${n}칸`, displayLabel: t('wordTable.filter.column', { count: n }) })), display: 'segmented' }] : []),
|
|
197
197
|
// 내용이 있는(1개 이상) 표면 '페이지당 대립쌍/단어 수'를 항상 노출한다(표시 모드 한정).
|
|
198
198
|
...(pagesEnabled && (items?.length ?? 0) > 0 ? [buildItemsPerPageSection(t, { hasPairs, itemCount })] : []),
|
|
199
|
-
|
|
199
|
+
/* '페이지 번호' 자리 고르개는 걷었다 — 쪽 번호는 바닥 띠가 자리를 쥔다(사용자 지시 2026-09-30) */
|
|
200
200
|
], [t, isEditable, showCellCount, pagesEnabled, items?.length, hasPairs, itemCount, isPaginated]);
|
|
201
201
|
const middleSelected = {
|
|
202
202
|
...((isEditable || showCellCount) ? { [t('wordTable.filter.columns', '칸 수')]: `${count}칸` } : {}),
|
|
@@ -7,6 +7,10 @@ export interface WordTableDisplaySettings {
|
|
|
7
7
|
contentTypes: WordTableContentType[];
|
|
8
8
|
cutLine: WordTableCutLine;
|
|
9
9
|
showOutline: boolean;
|
|
10
|
+
/** 종이 머리 띠(로고·표 번호)를 찍나 */
|
|
11
|
+
showTopInfo: boolean;
|
|
12
|
+
/** 종이 바닥 띠(만든 곳·주소·쪽 번호)를 찍나 */
|
|
13
|
+
showBottomInfo: boolean;
|
|
10
14
|
showDivLine: boolean;
|
|
11
15
|
/** 표 칸 수(= 페이지당 개수, 최소 1). */
|
|
12
16
|
count: number;
|
|
@@ -32,4 +36,9 @@ export interface UseWordTableDisplaySettingsResult {
|
|
|
32
36
|
* WordTablePopup 등 표를 미리 보여주고 인쇄하는 곳에서 쓴다.
|
|
33
37
|
* @public
|
|
34
38
|
*/
|
|
35
|
-
export declare function useWordTableDisplaySettings(items: WordSearchResultItem[]
|
|
39
|
+
export declare function useWordTableDisplaySettings(items: WordSearchResultItem[],
|
|
40
|
+
/** 종이 머리·바닥 띠를 쓰는 화면이면 참 — '상단 정보'·'하단 정보' 절이 함께 선다.
|
|
41
|
+
* 안 쓰는 화면에 켜고 끌 것이 없는 절이 서면 안 되므로 기본은 거짓이다. */
|
|
42
|
+
opts?: {
|
|
43
|
+
paperBands?: boolean;
|
|
44
|
+
}): UseWordTableDisplaySettingsResult;
|
|
@@ -3,7 +3,7 @@ import { useMemo, useState, useCallback, useEffect } from 'react';
|
|
|
3
3
|
import { useTranslation } from 'react-i18next';
|
|
4
4
|
import { chunkItems } from '../wordTableLayout';
|
|
5
5
|
import { getImageResolver, checkImageExists } from '../../utils/imageConfig';
|
|
6
|
-
import { buildCompositionSection, buildOrientationSection, buildBorderSection, buildCutLineSection, buildDivLineSection,
|
|
6
|
+
import { buildCompositionSection, buildOrientationSection, buildBorderSection, buildCutLineSection, buildDivLineSection, buildTopInfoSection, buildBottomInfoSection, buildItemsPerPageSection, buildTableSettingsSelected, applyTableSettingsSelect, PAGE_NUM_POSITION_VALUE, parsePageNumberPosition, itemsPerPageFromChoice, } from './wordTableSettings';
|
|
7
7
|
/**
|
|
8
8
|
* 표시 전용 단어표(편집 없음)의 '표 설정' FilterPanel 상태·섹션을 제공하는 훅.
|
|
9
9
|
* 구성·용지 방향·외곽선, 내용이 있으면 페이지당 개수, 2페이지 이상이면 페이지 번호, 항목이 2개 이상이면
|
|
@@ -11,12 +11,19 @@ import { buildCompositionSection, buildOrientationSection, buildBorderSection, b
|
|
|
11
11
|
* WordTablePopup 등 표를 미리 보여주고 인쇄하는 곳에서 쓴다.
|
|
12
12
|
* @public
|
|
13
13
|
*/
|
|
14
|
-
export function useWordTableDisplaySettings(items
|
|
14
|
+
export function useWordTableDisplaySettings(items,
|
|
15
|
+
/** 종이 머리·바닥 띠를 쓰는 화면이면 참 — '상단 정보'·'하단 정보' 절이 함께 선다.
|
|
16
|
+
* 안 쓰는 화면에 켜고 끌 것이 없는 절이 서면 안 되므로 기본은 거짓이다. */
|
|
17
|
+
opts) {
|
|
15
18
|
const { t } = useTranslation();
|
|
19
|
+
const 띠쓰나 = opts?.paperBands === true;
|
|
16
20
|
const [orientation, setOrientation] = useState('landscape');
|
|
17
21
|
const [contentTypes, setContentTypes] = useState(['이미지', '단어', '표준 발음']);
|
|
18
22
|
const [cutLine, setCutLine] = useState('표시');
|
|
19
23
|
const [showOutline, setShowOutline] = useState(true);
|
|
24
|
+
/* 종이 머리·바닥 띠 — 기본은 켬(브랜드가 찍힌 종이가 기본값이다) */
|
|
25
|
+
const [showTopInfo, setShowTopInfo] = useState(true);
|
|
26
|
+
const [showBottomInfo, setShowBottomInfo] = useState(true);
|
|
20
27
|
const [showDivLine, setShowDivLine] = useState(true);
|
|
21
28
|
const [itemsPerPageSetting, setItemsPerPageSetting] = useState(8);
|
|
22
29
|
const [pageNumberPosition, setPageNumberPosition] = useState('right');
|
|
@@ -54,19 +61,23 @@ export function useWordTableDisplaySettings(items) {
|
|
|
54
61
|
buildOrientationSection(t),
|
|
55
62
|
// 내용이 있는(1개 이상) 표면 페이지당 개수를 항상 노출.
|
|
56
63
|
...(itemCount > 0 ? [buildItemsPerPageSection(t, { hasPairs, itemCount })] : []),
|
|
57
|
-
|
|
64
|
+
/* '페이지 번호' 자리 고르개는 걷었다(사용자 지시 2026-09-30) — 쪽 번호가 바닥 띠
|
|
65
|
+
오른쪽에 고정으로 서므로 고를 자리가 없다. `pageNumberPosition` 프롭은 남아 있어
|
|
66
|
+
띠를 안 쓰는 화면은 전처럼 자리를 정할 수 있다. */
|
|
58
67
|
buildBorderSection(t),
|
|
59
68
|
...(count > 1 ? [buildCutLineSection(t)] : []),
|
|
60
69
|
...(hasPairs ? [buildDivLineSection(t)] : []),
|
|
61
|
-
|
|
70
|
+
/* 띠를 쓰는 화면에서만 — 안 쓰는 표에 켜고 끌 것이 없는 절이 서면 안 된다 */
|
|
71
|
+
...(띠쓰나 ? [buildTopInfoSection(t), buildBottomInfoSection(t)] : []),
|
|
72
|
+
], [t, hasImage, hasColloquial, itemCount, hasPairs, isPaginated, count, 띠쓰나]);
|
|
62
73
|
const filterSelected = {
|
|
63
|
-
...buildTableSettingsSelected(t, { contentTypes, orientation, showOutline, cutLine, showDivLine }),
|
|
74
|
+
...buildTableSettingsSelected(t, { contentTypes, orientation, showOutline, cutLine, showDivLine, showTopInfo, showBottomInfo }),
|
|
64
75
|
...(itemCount > 0 ? { [t(hasPairs ? 'wordTable.filter.itemsPerPagePair' : 'wordTable.filter.itemsPerPageWord')]: `${effectiveItemsPerPage}개` } : {}),
|
|
65
76
|
...(isPaginated ? { [t('wordTable.filter.pageNumber', '페이지 번호')]: PAGE_NUM_POSITION_VALUE[pageNumberPosition] } : {}),
|
|
66
77
|
};
|
|
67
78
|
const handleSelect = useCallback((value, sectionLabel) => {
|
|
68
79
|
// 기본 5개 설정은 공용 헬퍼가 처리 — 처리했으면 종료. 나머지(페이지당 개수·페이지 번호)만 여기서.
|
|
69
|
-
if (applyTableSettingsSelect(t, value, sectionLabel, { setContentTypes, setOrientation, setShowOutline, setCutLine, setShowDivLine }))
|
|
80
|
+
if (applyTableSettingsSelect(t, value, sectionLabel, { setContentTypes, setOrientation, setShowOutline, setCutLine, setShowDivLine, setShowTopInfo, setShowBottomInfo }))
|
|
70
81
|
return;
|
|
71
82
|
if (sectionLabel === t('wordTable.filter.itemsPerPagePair', '페이지당 대립쌍 수') || sectionLabel === t('wordTable.filter.itemsPerPageWord', '페이지당 단어 수')) {
|
|
72
83
|
setItemsPerPageSetting(itemsPerPageFromChoice(parseInt(value), itemCount));
|
|
@@ -76,7 +87,7 @@ export function useWordTableDisplaySettings(items) {
|
|
|
76
87
|
}
|
|
77
88
|
}, [t, itemCount]);
|
|
78
89
|
return {
|
|
79
|
-
settings: { orientation, contentTypes, cutLine, showOutline, showDivLine, count },
|
|
90
|
+
settings: { orientation, contentTypes, cutLine, showOutline, showDivLine, count, showTopInfo, showBottomInfo },
|
|
80
91
|
filterSections, filterSelected, handleSelect,
|
|
81
92
|
pages, isPaginated, pageNumberPosition,
|
|
82
93
|
};
|
|
@@ -17,6 +17,10 @@ export declare function buildCompositionSection(t: TFunction, opts: {
|
|
|
17
17
|
export declare function buildOrientationSection(t: TFunction): FilterPanelSection;
|
|
18
18
|
/** @public 외곽선(표시/미표시) 세그먼트 섹션. */
|
|
19
19
|
export declare function buildBorderSection(t: TFunction): FilterPanelSection;
|
|
20
|
+
/** @public 상단 정보(표시/미표시) 세그먼트 섹션 — 종이 머리 띠(로고·표 번호)를 켜고 끈다. */
|
|
21
|
+
export declare function buildTopInfoSection(t: TFunction): FilterPanelSection;
|
|
22
|
+
/** @public 하단 정보(표시/미표시) 세그먼트 섹션 — 종이 바닥 띠(만든 곳·주소·쪽 번호)를 켜고 끈다. */
|
|
23
|
+
export declare function buildBottomInfoSection(t: TFunction): FilterPanelSection;
|
|
20
24
|
/** @public 절취선(표시/점선/코너/미표시) 세그먼트 섹션. */
|
|
21
25
|
export declare function buildCutLineSection(t: TFunction): FilterPanelSection;
|
|
22
26
|
/** @public 구분선(대립선, 표시/미표시) 세그먼트 섹션 — 대립쌍표에만 노출. */
|
|
@@ -48,6 +52,8 @@ export declare function buildTableSettingsSelected(t: TFunction, v: {
|
|
|
48
52
|
showOutline: boolean;
|
|
49
53
|
cutLine: WordTableCutLine;
|
|
50
54
|
showDivLine: boolean;
|
|
55
|
+
showTopInfo?: boolean;
|
|
56
|
+
showBottomInfo?: boolean;
|
|
51
57
|
}): Record<string, string | string[]>;
|
|
52
58
|
/** @public 기본 5개 설정 상태 setter 묶음. */
|
|
53
59
|
export interface TableSettingsSetters {
|
|
@@ -56,6 +62,8 @@ export interface TableSettingsSetters {
|
|
|
56
62
|
setShowOutline: (v: boolean) => void;
|
|
57
63
|
setCutLine: (v: WordTableCutLine) => void;
|
|
58
64
|
setShowDivLine: (v: boolean) => void;
|
|
65
|
+
setShowTopInfo?: (v: boolean) => void;
|
|
66
|
+
setShowBottomInfo?: (v: boolean) => void;
|
|
59
67
|
}
|
|
60
68
|
/**
|
|
61
69
|
* @public 기본 5개 설정 섹션의 FilterPanel select 처리. 처리했으면 true, 아니면(추가 섹션 라벨) false를
|
|
@@ -43,6 +43,28 @@ export function buildBorderSection(t) {
|
|
|
43
43
|
display: 'segmented',
|
|
44
44
|
};
|
|
45
45
|
}
|
|
46
|
+
/** @public 상단 정보(표시/미표시) 세그먼트 섹션 — 종이 머리 띠(로고·표 번호)를 켜고 끈다. */
|
|
47
|
+
export function buildTopInfoSection(t) {
|
|
48
|
+
return {
|
|
49
|
+
label: t('wordTable.filter.topInfo', '상단 정보'),
|
|
50
|
+
items: [
|
|
51
|
+
{ value: '표시', displayLabel: t('wordTable.filter.show', '표시') },
|
|
52
|
+
{ value: '미표시', displayLabel: t('wordTable.filter.hide', '미표시') },
|
|
53
|
+
],
|
|
54
|
+
display: 'segmented',
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/** @public 하단 정보(표시/미표시) 세그먼트 섹션 — 종이 바닥 띠(만든 곳·주소·쪽 번호)를 켜고 끈다. */
|
|
58
|
+
export function buildBottomInfoSection(t) {
|
|
59
|
+
return {
|
|
60
|
+
label: t('wordTable.filter.bottomInfo', '하단 정보'),
|
|
61
|
+
items: [
|
|
62
|
+
{ value: '표시', displayLabel: t('wordTable.filter.show', '표시') },
|
|
63
|
+
{ value: '미표시', displayLabel: t('wordTable.filter.hide', '미표시') },
|
|
64
|
+
],
|
|
65
|
+
display: 'segmented',
|
|
66
|
+
};
|
|
67
|
+
}
|
|
46
68
|
/** @public 절취선(표시/점선/코너/미표시) 세그먼트 섹션. */
|
|
47
69
|
export function buildCutLineSection(t) {
|
|
48
70
|
return {
|
|
@@ -115,6 +137,9 @@ export function buildTableSettingsSelected(t, v) {
|
|
|
115
137
|
[t('wordTable.filter.border', '외곽선')]: v.showOutline ? '표시' : '미표시',
|
|
116
138
|
[t('wordTable.filter.cutLine', '절취선')]: v.cutLine,
|
|
117
139
|
[t('wordPrint.divLine', '대립선')]: v.showDivLine ? '표시' : '미표시',
|
|
140
|
+
/* 띠를 안 쓰는 화면은 이 절을 아예 안 세우므로 값이 있어도 안 보인다 */
|
|
141
|
+
[t('wordTable.filter.topInfo', '상단 정보')]: v.showTopInfo === false ? '미표시' : '표시',
|
|
142
|
+
[t('wordTable.filter.bottomInfo', '하단 정보')]: v.showBottomInfo === false ? '미표시' : '표시',
|
|
118
143
|
};
|
|
119
144
|
}
|
|
120
145
|
/**
|
|
@@ -147,5 +172,13 @@ export function applyTableSettingsSelect(t, value, sectionLabel, s) {
|
|
|
147
172
|
s.setShowDivLine(value === '표시');
|
|
148
173
|
return true;
|
|
149
174
|
}
|
|
175
|
+
if (sectionLabel === t('wordTable.filter.topInfo', '상단 정보')) {
|
|
176
|
+
s.setShowTopInfo?.(value === '표시');
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
if (sectionLabel === t('wordTable.filter.bottomInfo', '하단 정보')) {
|
|
180
|
+
s.setShowBottomInfo?.(value === '표시');
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
150
183
|
return false;
|
|
151
184
|
}
|
|
@@ -66,20 +66,22 @@
|
|
|
66
66
|
/* ── 종이 머리·바닥 띠 ────────────────────────────────────────────────
|
|
67
67
|
쪽 번호가 쓰던 수를 위아래로 넓힌 것이다. 격자가 그만큼 비우고 띠는 그 빈 자리에
|
|
68
68
|
절대 배치로 선다 — **격자 안**이라 인쇄가 격자만 복사해 가도 함께 간다. */
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
69
|
+
/* 띠 높이에 딱 붙인다 — 남는 틈은 4px 뿐이다(사용자 지시 2026-09-30: 여백이 많다).
|
|
70
|
+
비운 자리가 띠보다 크면 로고와 칸 사이가 벌어져 종이가 헐거워 보인다.
|
|
71
|
+
**위아래를 따로 비운다** — 표 설정에서 한쪽만 끌 수 있다. */
|
|
72
|
+
.word-table-block__content--brand-top { padding-top: calc(32px * var(--wt-unscale, 1)); }
|
|
73
|
+
.word-table-block__content--brand-bottom { padding-bottom: calc(26px * var(--wt-unscale, 1)); }
|
|
75
74
|
/* 절취선 바탕·외곽선은 칸이 있는 데까지만 — 띠까지 두르면 로고가 표 안에 든 것처럼 보인다
|
|
76
75
|
(쪽 번호 때와 같은 까닭). 아래는 쪽 번호 규칙과 겹치므로 여기서 다시 적어 이긴다. */
|
|
77
|
-
.word-table-block__content--brand.word-table-block__content--cut-show
|
|
76
|
+
.word-table-block__content--brand-top.word-table-block__content--cut-show,
|
|
77
|
+
.word-table-block__content--brand-bottom.word-table-block__content--cut-show {
|
|
78
78
|
background-clip: content-box;
|
|
79
79
|
}
|
|
80
|
-
.word-table-block__content--brand.word-table-block__content--outline::after {
|
|
80
|
+
.word-table-block__content--brand-top.word-table-block__content--outline::after {
|
|
81
81
|
top: calc(32px * var(--wt-unscale, 1));
|
|
82
|
-
|
|
82
|
+
}
|
|
83
|
+
.word-table-block__content--brand-bottom.word-table-block__content--outline::after {
|
|
84
|
+
bottom: calc(26px * var(--wt-unscale, 1));
|
|
83
85
|
}
|
|
84
86
|
|
|
85
87
|
.word-table__band {
|
|
@@ -93,18 +95,34 @@
|
|
|
93
95
|
z-index: 2;
|
|
94
96
|
pointer-events: none;
|
|
95
97
|
color: var(--color-gray);
|
|
96
|
-
/*
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
font-size: calc(var(--text-body-3-size, 14px) * var(--wt-unscale, 1));
|
|
102
|
-
line-height: calc(var(--text-body-3-line, 22px) * var(--wt-unscale, 1));
|
|
103
|
-
font-weight: var(--text-body-3-weight, 400);
|
|
98
|
+
/* 글꼴 크기는 띠마다 다르다 — 위는 caption-1, 아래는 caption-2(사용자 지시 2026-09-30).
|
|
99
|
+
클래스(`.caption-1`)를 그냥 붙이면 크기가 고정돼 배율 되돌림이 안 먹으므로 같은
|
|
100
|
+
토큰에 되돌림만 곱한다. 그 토큰은 보는 사람 쪽 설정(좁은 화면 · 큰 글씨)을 타므로
|
|
101
|
+
종이 글씨도 그만큼 달라진다 — 화면과 종이를 한 급으로 맞추기로 한 값이다. */
|
|
102
|
+
font-weight: var(--text-caption-1-weight, 400);
|
|
104
103
|
}
|
|
105
104
|
/* 비워 둔 44px 안에 든다 */
|
|
106
|
-
|
|
107
|
-
.
|
|
105
|
+
/* 위는 **11px**, 아래는 **8px** — 둘 다 종이 전용 값이라 토큰에서 벗어난다
|
|
106
|
+
(사용자 지시 2026-09-30). 화면 글씨는 읽는 거리에 맞추지만 이 줄들은 종이에 찍혀
|
|
107
|
+
필요할 때만 들여다본다. 배율 되돌림은 그대로 받는다. */
|
|
108
|
+
.word-table__band--top {
|
|
109
|
+
top: 0;
|
|
110
|
+
height: calc(28px * var(--wt-unscale, 1));
|
|
111
|
+
font-size: calc(11px * var(--wt-unscale, 1));
|
|
112
|
+
line-height: calc(15px * var(--wt-unscale, 1));
|
|
113
|
+
}
|
|
114
|
+
/* 아래는 **8px** 이다(사용자 지시 2026-09-30) — 만든 곳 · 주소 · 쪽 번호는 찾을 때만 읽는
|
|
115
|
+
잔글이라 디자인 시스템의 가장 작은 급(caption-2, 11px)보다 더 내린다. 토큰을 안 쓰는
|
|
116
|
+
유일한 자리이고, **종이 전용 값**이라 그렇다: 화면 글씨는 사람이 읽는 거리에 맞추지만
|
|
117
|
+
이 줄은 종이에 인쇄돼 필요할 때만 들여다본다. 배율 되돌림은 그대로 받는다. */
|
|
118
|
+
.word-table__band--bottom {
|
|
119
|
+
/* 로고까지 이 색을 받는다 — 마스크를 `currentColor` 로 칠하므로 글씨와 늘 같은 색이다 */
|
|
120
|
+
color: var(--color-gray);
|
|
121
|
+
bottom: 0;
|
|
122
|
+
height: calc(22px * var(--wt-unscale, 1));
|
|
123
|
+
font-size: calc(8px * var(--wt-unscale, 1));
|
|
124
|
+
line-height: calc(12px * var(--wt-unscale, 1));
|
|
125
|
+
}
|
|
108
126
|
|
|
109
127
|
.word-table__brand-logo {
|
|
110
128
|
height: calc(28px * var(--wt-unscale, 1));
|
|
@@ -115,8 +133,30 @@
|
|
|
115
133
|
print-color-adjust: exact;
|
|
116
134
|
-webkit-print-color-adjust: exact;
|
|
117
135
|
}
|
|
118
|
-
/* 만든 곳 로고 —
|
|
119
|
-
|
|
136
|
+
/* 만든 곳(ihab) 로고 — **그림이 아니라 꼴**이다. 흰 판 SVG 를 마스크로 오려 그 자리를
|
|
137
|
+
`currentColor` 로 칠하므로 곁의 글씨와 **같은 색**이 된다(사용자 지시 2026-09-30).
|
|
138
|
+
파일에 `fill` 이 박혀 있어 `<img>` 로는 색을 못 바꾼다. 가로세로비는 파일 그대로(264:100).
|
|
139
|
+
인쇄에서도 색이 빠지지 않게 말귀 로고와 같은 수를 쓴다. */
|
|
140
|
+
.word-table__brand-logo--ihab {
|
|
141
|
+
display: block;
|
|
142
|
+
height: calc(17px * var(--wt-unscale, 1));
|
|
143
|
+
width: calc(17px * 2.64 * var(--wt-unscale, 1));
|
|
144
|
+
flex-shrink: 0;
|
|
145
|
+
background-color: currentColor;
|
|
146
|
+
/* 이 파일이 로고를 **직접** 가리킨다 — 묶개가 주소를 풀어 준다. 마디에 인라인으로
|
|
147
|
+
주던 때는 그 값이 화면에 안 실리는 일이 있었고, 무엇보다 여기 적어야 인쇄 문서로
|
|
148
|
+
(스타일시트를 통째로 베껴 가므로) 함께 간다. */
|
|
149
|
+
-webkit-mask-image: url('../logo/Logo_IHAB_en_white.svg');
|
|
150
|
+
mask-image: url('../logo/Logo_IHAB_en_white.svg');
|
|
151
|
+
-webkit-mask-repeat: no-repeat;
|
|
152
|
+
mask-repeat: no-repeat;
|
|
153
|
+
-webkit-mask-size: contain;
|
|
154
|
+
mask-size: contain;
|
|
155
|
+
-webkit-mask-position: center;
|
|
156
|
+
mask-position: center;
|
|
157
|
+
print-color-adjust: exact;
|
|
158
|
+
-webkit-print-color-adjust: exact;
|
|
159
|
+
}
|
|
120
160
|
|
|
121
161
|
/* 만든 곳 — 로고와 저작권이 한 줄로 붙는다 */
|
|
122
162
|
.word-table__brand-by {
|
|
@@ -142,11 +182,34 @@
|
|
|
142
182
|
/* 표 번호·주소 — **종이 글씨는 전부 한 글꼴이다**(사용자 지시 2026-09-30). 고정폭으로
|
|
143
183
|
찍어 봤는데 한 장 안에 글꼴이 둘 섞여 보였다. 종이가 한 벌로 읽히는 쪽을 골랐다 —
|
|
144
184
|
목록 카드(`WordTableButton`)의 번호는 청한 대로 고정폭 그대로다. */
|
|
185
|
+
/* 기관 이름 · 표 번호 — 번호만 진하게 둔다(찾는 눈이 번호에 먼저 닿게) */
|
|
186
|
+
.word-table__ident {
|
|
187
|
+
display: flex;
|
|
188
|
+
align-items: center;
|
|
189
|
+
gap: calc(6px * var(--wt-unscale, 1));
|
|
190
|
+
min-width: 0;
|
|
191
|
+
}
|
|
192
|
+
/* 이름이 길면 이름만 줄어든다 — 번호는 잘리면 확인 글자가 사라져 뜻이 없다 */
|
|
193
|
+
.word-table__owner {
|
|
194
|
+
min-width: 0;
|
|
195
|
+
overflow: hidden;
|
|
196
|
+
text-overflow: ellipsis;
|
|
197
|
+
white-space: nowrap;
|
|
198
|
+
}
|
|
199
|
+
.word-table__ident-dot { flex-shrink: 0; }
|
|
200
|
+
/* 표 번호 — **띠와 같은 회색**이다(사용자 지시 2026-09-30). 한때 번호만 진하게 뒀는데,
|
|
201
|
+
머리 줄 전체가 종이를 식별하는 잔글이라 한 무게로 읽히는 편이 낫다. */
|
|
145
202
|
.word-table__code {
|
|
146
|
-
color: var(--color-text-primary);
|
|
147
203
|
flex-shrink: 0;
|
|
148
204
|
white-space: nowrap;
|
|
149
205
|
}
|
|
206
|
+
/* 표 제목 — 셋 중 제일 먼저 줄어든다(기관 이름·번호가 이 종이를 가리키는 값이다) */
|
|
207
|
+
.word-table__paper-title {
|
|
208
|
+
min-width: 0;
|
|
209
|
+
overflow: hidden;
|
|
210
|
+
text-overflow: ellipsis;
|
|
211
|
+
white-space: nowrap;
|
|
212
|
+
}
|
|
150
213
|
/* 이 표로 가는 주소 — 길 수 있으므로 넘치면 …로 자른다(쪽 번호는 안 밀린다) */
|
|
151
214
|
.word-table__link {
|
|
152
215
|
color: var(--color-gray);
|
|
@@ -99,10 +99,18 @@ export interface WordTableProps {
|
|
|
99
99
|
brand?: {
|
|
100
100
|
/** 로고와 저작권을 세운다. 나머지 자리는 각자 값이 있을 때만 선다. */
|
|
101
101
|
show?: boolean;
|
|
102
|
+
/** 위 띠만 끈다(`show` 가 켜져 있을 때). 표 설정의 '상단 정보' 가 이것을 움직인다. */
|
|
103
|
+
top?: boolean;
|
|
104
|
+
/** 아래 띠만 끈다(`show` 가 켜져 있을 때). 표 설정의 '하단 정보' 가 이것을 움직인다. */
|
|
105
|
+
bottom?: boolean;
|
|
102
106
|
/**
|
|
103
107
|
* 아래 오른쪽 — **이 표로 가는 주소**. 회사 홈 주소가 아니라 그 표의 공유 링크다
|
|
104
108
|
* (사용자 지시 2026-09-30). 종이를 든 사람이 이 주소로 같은 표를 화면에서 연다.
|
|
105
109
|
*
|
|
110
|
+
* **`code` 와는 다른 것이다.** 표 번호는 기관 안에서 매긴 번호고 이 주소는 따로 난
|
|
111
|
+
* 공유 링크다 — 번호에서 주소를 만들어 내지 않는다. 둘 다 이 표를 가리키지만 나오는
|
|
112
|
+
* 데가 다르므로 각각 받는다.
|
|
113
|
+
*
|
|
106
114
|
* 종이라 누를 수 없으니 글자 그대로 찍는다 — 그래서 **사람이 옮겨 칠 수 있는 길이**
|
|
107
115
|
* 여야 한다. 긴 주소를 그대로 주면 넘쳐 …로 잘리고, 잘린 주소는 옮겨 칠 수 없다.
|
|
108
116
|
* 짧은 주소를 쓰거나, 표 번호로 찾는 길을 함께 두는 편이 낫다.
|
|
@@ -110,6 +118,15 @@ export interface WordTableProps {
|
|
|
110
118
|
link?: string;
|
|
111
119
|
/** 저작권 글월 — 안 주면 `© IHAB, Inc. All rights reserved.` */
|
|
112
120
|
copyright?: string;
|
|
121
|
+
/** 위 오른쪽 맨 앞 — **이 표의 이름**. `표 제목 · 기관 이름 · 표 번호` 로 선다. */
|
|
122
|
+
title?: string;
|
|
123
|
+
/**
|
|
124
|
+
* 위 오른쪽 — **표 번호 앞에 붙는 기관 이름**(말귀매니저). 번호는 그 기관 안에서만
|
|
125
|
+
* 고유하므로 이름과 함께여야 어느 곳의 몇 번인지가 정해진다(사용자 지시 2026-09-30).
|
|
126
|
+
* `이름 · 번호` 로 선다. 이름이 길면 이름만 줄고 번호는 안 줄인다 — 번호가 잘리면
|
|
127
|
+
* 확인 글자가 사라져 뜻이 없다.
|
|
128
|
+
*/
|
|
129
|
+
owner?: string;
|
|
113
130
|
};
|
|
114
131
|
/**
|
|
115
132
|
* **짧은 식별 글** — 표 번호(`1043-E`). `brand` 를 줬을 때 위 오른쪽에 선다.
|
|
@@ -16,10 +16,11 @@ import useMediaQuery from '../hooks/useMediaQuery';
|
|
|
16
16
|
import { isTouchPointer, recentlyTouched, useTouchToggle } from '../hooks/touchToggle';
|
|
17
17
|
/* `Footer` 가 하듯 곧장 가져온다 — 묶개가 알아서 옮겨 주고, 인쇄 창은 `<img>` 가 다 받아진
|
|
18
18
|
뒤에 인쇄한다. 말귀는 **컬러 판**이다(사용자 지시 2026-09-30) — 종이에서도 색으로 나가야
|
|
19
|
-
하므로 아래 CSS 가 `print-color-adjust: exact` 를 준다.
|
|
20
|
-
|
|
19
|
+
하므로 아래 CSS 가 `print-color-adjust: exact` 를 준다.
|
|
20
|
+
|
|
21
|
+
ihab 은 **흰 판을 마스크로 쓴다**(사용자 지시 2026-09-30: 글자색을 입힌다) — 그쪽은
|
|
22
|
+
`WordTable.css` 가 제 곁의 파일을 직접 가리키므로 여기서 안 들여온다. */
|
|
21
23
|
import 말귀로고 from '../logo/Logo_speechear_kr.svg';
|
|
22
|
-
import ihab로고 from '../logo/Logo_IHAB_en_black.svg';
|
|
23
24
|
import { WORD_TABLE_PAPER, gridFor, CUT_CLASS, POS_LABEL, WORD_TYPE_LABEL, expandSlashLabel, dotDashStyle, REF_W_BOTH, REF_W_TEXT_ONLY, REF_W_IMAGE_ONLY, REF_H_BOTH, REF_H_TEXT_ONLY, REF_H_IMAGE_ONLY, } from './wordTableLayout';
|
|
24
25
|
import { useFitScale } from './useFitScale';
|
|
25
26
|
import { claimSound } from './Training/currentSound';
|
|
@@ -371,14 +372,19 @@ export default function WordTable({ title, titleIcon, disc, className, orientati
|
|
|
371
372
|
: (items ?? []).some(item => (item.words ?? []).length > 1);
|
|
372
373
|
/* 로고를 세우기로 한 때만 띠를 두른다. `code`·`link` 만 주고 `show` 를 안 주면 띠가 없으니
|
|
373
374
|
그 값들도 설 자리가 없다 — 켜는 스위치를 하나로 둔다. */
|
|
374
|
-
|
|
375
|
+
/* 띠를 쓰기로 한 종이인가 — 한쪽을 꺼도 이 종이는 '띠를 쓰는 꼴'이다.
|
|
376
|
+
쪽 번호가 어디에 서는지를 이 값이 가른다(아래를 보라). */
|
|
377
|
+
const 브랜드쓰나 = Boolean(brand?.show);
|
|
378
|
+
const 띠쓰나 = 브랜드쓰나 && (brand?.top !== false || brand?.bottom !== false);
|
|
379
|
+
const 위띠쓰나 = Boolean(brand?.show) && brand?.top !== false;
|
|
380
|
+
const 아래띠쓰나 = Boolean(brand?.show) && brand?.bottom !== false;
|
|
375
381
|
const 저작권 = brand?.copyright ?? '© IHAB, Inc. All rights reserved.';
|
|
376
382
|
const contentClass = cx('word-table-block__content', CUT_CLASS[cutLine], showOutline && 'word-table-block__content--outline', showDivLine && hasPairs && 'word-table-block__content--div-line',
|
|
377
383
|
/* 번호가 설 자리를 비운다 — 번호가 없으면 비우지 않는다(표가 공연히 낮아지지 않게) */
|
|
378
|
-
pageNumber && pageNumberPosition !== 'none' && 'word-table-block__content--page-number',
|
|
384
|
+
!브랜드쓰나 && pageNumber && pageNumberPosition !== 'none' && 'word-table-block__content--page-number',
|
|
379
385
|
/* 띠가 설 자리를 위아래로 비운다 — 같은 까닭으로 띠가 없으면 안 비운다.
|
|
380
386
|
바닥 띠가 쪽 번호 자리를 겸하므로 둘이 겹쳐도 아래는 한 번만 비운다(CSS 가 덮어쓴다). */
|
|
381
|
-
|
|
387
|
+
위띠쓰나 && 'word-table-block__content--brand-top', 아래띠쓰나 && 'word-table-block__content--brand-bottom');
|
|
382
388
|
// 빈칸(추가버튼)은 스케일 역보정으로 실제 크기 유지
|
|
383
389
|
const counterScale = { transform: `scale(${1 / scale})`, transformOrigin: 'center center' };
|
|
384
390
|
/* **채점 단추는 표와 함께 줄어들면 안 된다.**
|
|
@@ -419,7 +425,18 @@ export default function WordTable({ title, titleIcon, disc, className, orientati
|
|
|
419
425
|
_jsxs("div", { className: "word-table-block__card-actions", children: [renderCellAction?.(index, item), onRemoveItem && (_jsx("div", { className: "word-table-block__card-close", children: _jsx(Button, { htmlType: "button", size: buttonSize, type: "dot", icon: "x", variant: "transparent-lightGray", useBorder: false, showTooltipInfo: (item.words ?? []).length > 1 ? t('wordPrint.removePair', '대립쌍 빼기') : t('wordPrint.removeWord', '단어 빼기'), ariaLabel: (item.words ?? []).length > 1 ? t('wordPrint.removePair', '대립쌍 빼기') : t('wordPrint.removeWord', '단어 빼기'), onClick: () => onRemoveItem(item.id) }) }))] }))] }, item.id))), Array.from({ length: Math.max(0, cols * rows - (items?.length ?? 0)) }).map((_, i) => {
|
|
420
426
|
const isWithinCount = (items?.length ?? 0) + i < cellCount;
|
|
421
427
|
return (_jsx("div", { className: "word-table-block__card word-table-block__card--filler", children: showFillerAdd && onActivateCell && isWithinCount && (_jsx("div", { style: counterScale, children: _jsx(Button, { htmlType: "button", size: buttonSize, type: "bar", icon: "plus", label: t('wordTable.addWord', '추가하기'), onClick: () => onActivateCell((items?.length ?? 0) + i) }) })) }, `filler-${i}`));
|
|
422
|
-
})] })),
|
|
428
|
+
})] })), 위띠쓰나 && (_jsx(_Fragment, { children: _jsxs("div", { className: "word-table__band word-table__band--top", children: [_jsx("img", { className: "word-table__brand-logo", src: 말귀로고, alt: "\uB9D0\uADC0" }), (() => {
|
|
429
|
+
/* 표 제목 · 기관 이름 · 표 번호 — 있는 것끼리만 가운뎃점으로 잇는다
|
|
430
|
+
(사용자 지시 2026-09-30). 없는 것 자리에 점이 남으면 안 된다. */
|
|
431
|
+
const 조각들 = [
|
|
432
|
+
brand?.title && _jsx("span", { className: "word-table__paper-title", children: brand.title }, "t"),
|
|
433
|
+
brand?.owner && _jsx("span", { className: "word-table__owner", children: brand.owner }, "o"),
|
|
434
|
+
code && _jsx("span", { className: "word-table__code", children: code }, "c"),
|
|
435
|
+
].filter(Boolean);
|
|
436
|
+
if (조각들.length === 0)
|
|
437
|
+
return null;
|
|
438
|
+
return (_jsx("span", { className: "word-table__ident", children: 조각들.map((조각, i) => (_jsxs(Fragment, { children: [i > 0 && _jsx("span", { className: "word-table__ident-dot", "aria-hidden": "true", children: "\u00B7" }), 조각] }, i))) }));
|
|
439
|
+
})()] }) })), 아래띠쓰나 && (_jsx(_Fragment, { children: _jsxs("div", { className: "word-table__band word-table__band--bottom", children: [_jsxs("span", { className: "word-table__brand-by", children: [_jsx("span", { className: "word-table__brand-logo--ihab", role: "img", "aria-label": "IHAB" }), _jsx("span", { className: "word-table__copyright", children: 저작권 })] }), _jsxs("span", { className: "word-table__band-end", children: [brand?.link && _jsx("span", { className: "word-table__link", children: brand.link }), pageNumber && pageNumberPosition !== 'none' && (_jsx("span", { className: "word-table__page-count", children: t('wordTable.filter.pageIndicator', { current: pageNumber.current, total: pageNumber.total }) }))] })] }) })), !브랜드쓰나 && pageNumber && pageNumberPosition !== 'none' && (_jsx("span", { className: `word-table__page-number body-3 word-table__page-number--${pageNumberPosition}`, children: t('wordTable.filter.pageIndicator', { current: pageNumber.current, total: pageNumber.total }) }))] }) }), onReorder && _jsx("span", { role: "status", style: 보이지않게, children: 옮김알림 })] }));
|
|
423
440
|
/* 담는 틀 — 높이를 받은 자리에서만 두른다. `useFitScale` 은 **스케일러의 부모**를 재므로
|
|
424
441
|
이 틀이 곧 그 자(척도)가 된다. 가운데 맞춤은 남는 세로를 위아래로 나눈다 — 표가 상자보다
|
|
425
442
|
납작할 때 아래로만 쏠려 보이지 않게. */
|