@ncds/ui-admin 1.8.26 → 1.8.28-alpha.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.
Files changed (24) hide show
  1. package/dist/cjs/src/components/feedback-and-status/badge/Badge.js +1 -1
  2. package/dist/cjs/src/components/layout/page-title/__tests__/pageTitleStyle.test.js +94 -0
  3. package/dist/cjs/src/components/navigation/pagination/Pagination.js +14 -14
  4. package/dist/cjs/src/components/navigation/pagination/__tests__/Pagination.test.js +17 -0
  5. package/dist/cjs/src/generated/scoped-css.js +1 -1
  6. package/dist/cjs/vitest.config.js +12 -1
  7. package/dist/esm/src/components/feedback-and-status/badge/Badge.js +1 -1
  8. package/dist/esm/src/components/layout/page-title/__tests__/pageTitleStyle.test.js +91 -0
  9. package/dist/esm/src/components/navigation/pagination/Pagination.js +14 -14
  10. package/dist/esm/src/components/navigation/pagination/__tests__/Pagination.test.js +17 -0
  11. package/dist/esm/src/generated/scoped-css.js +1 -1
  12. package/dist/esm/vitest.config.js +12 -1
  13. package/dist/temp/src/components/feedback-and-status/badge/Badge.d.ts +1 -1
  14. package/dist/temp/src/components/feedback-and-status/badge/Badge.js +1 -1
  15. package/dist/temp/src/components/layout/page-title/__tests__/pageTitleStyle.test.d.ts +1 -0
  16. package/dist/temp/src/components/layout/page-title/__tests__/pageTitleStyle.test.js +94 -0
  17. package/dist/temp/src/components/navigation/pagination/Pagination.js +14 -14
  18. package/dist/temp/src/components/navigation/pagination/__tests__/Pagination.test.js +7 -0
  19. package/dist/temp/src/generated/scoped-css.js +1 -1
  20. package/dist/temp/vitest.config.js +11 -0
  21. package/dist/types/src/components/feedback-and-status/badge/Badge.d.ts +1 -1
  22. package/dist/types/src/components/layout/page-title/__tests__/pageTitleStyle.test.d.ts +1 -0
  23. package/dist/ui-admin/assets/styles/style.css +15 -18
  24. package/package.json +1 -1
@@ -16,7 +16,7 @@ const BADGE_ICON_SIZE = 12;
16
16
  /** new-badge 박스 안에 들어가는 'N' 아이콘 크기. 박스는 sm 16px / md 20px 이며 아이콘은 그보다 작다(패딩 포함). */
17
17
  const NEW_BADGE_ICON_SIZE = {
18
18
  sm: 12,
19
- md: 16
19
+ md: 14
20
20
  };
21
21
  const Badge = _ref => {
22
22
  let {
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+
3
+ var _nodePath = _interopRequireDefault(require("node:path"));
4
+ var _sass = require("sass");
5
+ var _vitest = require("vitest");
6
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
7
+ // 배경·그림자·패딩은 jsdom 에서 계산되지 않으므로, 컴파일된 CSS 에서 variant 별 규칙을 검사한다.
8
+ // (input-base/__tests__/inputAutofill.test.ts 와 같은 방식 — 컴포넌트 SCSS 엔트리를 직접 컴파일)
9
+ const PAGE_TITLE_SCSS_PATH = _nodePath.default.resolve(__dirname, '../../../../../assets/styles/components/page-title/_index.scss');
10
+ const compiledPageTitleCss = (0, _sass.compile)(PAGE_TITLE_SCSS_PATH).css;
11
+ /** 선택자 → 선언 목록. 같은 선택자가 여러 규칙에 나오면 선언을 이어 붙인다. */
12
+ const parseRules = css => {
13
+ const rules = new Map();
14
+ for (const [, selectorList, body] of css.matchAll(/([^{}]+)\{([^{}]*)\}/g)) {
15
+ const declarations = body.split(';').map(declaration => declaration.trim().replace(/\s+/g, ' ')).filter(Boolean);
16
+ for (const selector of selectorList.split(',').map(selector => selector.trim().replace(/\s+/g, ' '))) {
17
+ rules.set(selector, [...(rules.get(selector) ?? []), ...declarations]);
18
+ }
19
+ }
20
+ return rules;
21
+ };
22
+ const rules = parseRules(compiledPageTitleCss);
23
+ const declarationsOf = selector => rules.get(selector) ?? [];
24
+ const propertiesOf = selector => declarationsOf(selector).map(declaration => declaration.split(':')[0].trim());
25
+ const ROOT = '.ncua-page-title';
26
+ const FIXED = '.ncua-page-title--fixed';
27
+ const PAGE_HEADER = '.ncua-page-title__page-header';
28
+ const FIXED_PAGE_HEADER = '.ncua-page-title--fixed .ncua-page-title__page-header';
29
+ (0, _vitest.describe)('PageTitle 스타일 — Default (·Detail)', () => {
30
+ (0, _vitest.it)('.ncua-page-title 에 background·box-shadow 가 없다 (투명, 그림자 없음)', () => {
31
+ // Given: 컴파일된 PageTitle CSS 에서
32
+ // When: 루트 규칙의 속성을 모으면
33
+ const properties = propertiesOf(ROOT);
34
+ // Then: 루트 규칙은 존재하지만 배경·그림자를 지정하지 않는다
35
+ (0, _vitest.expect)(properties.length).toBeGreaterThan(0);
36
+ (0, _vitest.expect)(properties).not.toContain('background');
37
+ (0, _vitest.expect)(properties).not.toContain('background-color');
38
+ (0, _vitest.expect)(properties).not.toContain('box-shadow');
39
+ });
40
+ (0, _vitest.it)('.ncua-page-title__page-header 패딩은 32px 40px 0 이다', () => {
41
+ // Given: 컴파일된 PageTitle CSS 에서
42
+ // When: page-header 규칙을 찾으면
43
+ const declarations = declarationsOf(PAGE_HEADER);
44
+ // Then: 위 32px · 좌우 40px · 아래 0 이다
45
+ (0, _vitest.expect)(declarations).toContain('padding: 32px 40px 0');
46
+ (0, _vitest.expect)(declarations).not.toContain('padding: 24px 40px');
47
+ });
48
+ });
49
+ (0, _vitest.describe)('PageTitle 스타일 — Fixed (·Fixed Detail)', () => {
50
+ (0, _vitest.it)('.ncua-page-title--fixed 배경은 --gray-50 이다', () => {
51
+ // Given: 컴파일된 PageTitle CSS 에서
52
+ // When: fixed modifier 규칙을 찾으면
53
+ const declarations = declarationsOf(FIXED);
54
+ // Then: sticky 로 콘텐츠 위에 겹치므로 배경 Gray/50 을 가진다
55
+ (0, _vitest.expect)(declarations).toContain('background: var(--gray-50)');
56
+ });
57
+ (0, _vitest.it)('.ncua-page-title--fixed 하단 border 는 1px solid --gray-100 이다', () => {
58
+ // Given/When: fixed modifier 규칙을 찾으면
59
+ const declarations = declarationsOf(FIXED);
60
+ // Then: 기존 Gray/300 이 아니라 Gray/100 border 를 쓴다
61
+ (0, _vitest.expect)(declarations).toContain('border-bottom: 1px solid var(--gray-100)');
62
+ (0, _vitest.expect)(declarations).not.toContain('border-bottom: 1px solid var(--gray-300)');
63
+ });
64
+ (0, _vitest.it)('.ncua-page-title--fixed 에 box-shadow 가 없다', () => {
65
+ // Given/When: fixed modifier 규칙의 속성을 모으면
66
+ // Then: 그림자를 지정하지 않는다
67
+ (0, _vitest.expect)(propertiesOf(FIXED)).not.toContain('box-shadow');
68
+ });
69
+ (0, _vitest.it)('Fixed 의 page-header 패딩은 12px 40px 로 유지된다', () => {
70
+ // Given/When: fixed 하위 page-header 규칙을 찾으면
71
+ // Then: 기존 Fixed 패딩이 그대로다 (범위 밖)
72
+ (0, _vitest.expect)(declarationsOf(FIXED_PAGE_HEADER)).toContain('padding: 12px 40px');
73
+ });
74
+ (0, _vitest.it)('Fixed sticky 동작(position·top·z-index)은 유지된다', () => {
75
+ // Given/When: fixed modifier 규칙을 찾으면
76
+ const declarations = declarationsOf(FIXED);
77
+ // Then: 기존 sticky 선언이 그대로다
78
+ (0, _vitest.expect)(declarations).toContain('position: sticky');
79
+ (0, _vitest.expect)(declarations).toContain('top: 0');
80
+ (0, _vitest.expect)(declarations).toContain('z-index: 999');
81
+ });
82
+ });
83
+ (0, _vitest.describe)('PageTitle 스타일 — 토큰 사용', () => {
84
+ (0, _vitest.it)('배경·border 색상에 하드코딩 값 없이 CSS 변수만 쓴다 (ADR-4)', () => {
85
+ // Given/When: 루트·fixed 규칙의 배경·border 선언을 모으면
86
+ const colorDeclarations = [...declarationsOf(ROOT), ...declarationsOf(FIXED)].filter(declaration => /^(background|border-bottom)/.test(declaration));
87
+ // Then: hex·rgb·색 이름 대신 var(--*) 만 쓴다
88
+ (0, _vitest.expect)(colorDeclarations.length).toBeGreaterThan(0);
89
+ for (const declaration of colorDeclarations) {
90
+ (0, _vitest.expect)(declaration).not.toMatch(/#[0-9a-f]{3,8}\b|rgba?\(|(?<![-\w])white\b/i);
91
+ (0, _vitest.expect)(declaration).toMatch(/var\(--[a-z0-9-]+\)/);
92
+ }
93
+ });
94
+ });
@@ -36,28 +36,28 @@ const Pagination = _ref => {
36
36
  };
37
37
  (0, _react.useEffect)(() => {
38
38
  const lastGroupStart = Math.max(1, Math.floor((totalPage - 1) / pageCount) * pageCount + 1);
39
- // totalPage/pageCount 가 줄어 start 가 마지막 그룹을 넘으면 마지막 그룹으로 보정한다.
39
+ // totalPage/pageCount 가 줄어 start 가 마지막 그룹을 넘으면 마지막 그룹에서 시작해 아래 규칙을 계속 적용한다.
40
40
  // (예: 100→50 페이지로 축소 시 start 가 91 에 머물러 범위 밖 버튼을 표시하던 문제)
41
- if (start > lastGroupStart) {
42
- setStart(lastGroupStart);
43
- return;
41
+ // 바로 return 하면 새 검색으로 currentPage 가 1 이 돼도 1 이 목록에 없다 (PR #603 리뷰).
42
+ const baseStart = Math.min(start, lastGroupStart);
43
+ let nextStart = baseStart;
44
+ if (currentPage === baseStart + pageCount) {
45
+ nextStart = baseStart + pageCount;
44
46
  }
45
- if (currentPage === start + pageCount) {
46
- setStart(start + pageCount);
47
+ if (currentPage > baseStart + pageCount) {
48
+ nextStart = Math.floor((currentPage - 1) / pageCount) * pageCount + 1;
47
49
  }
48
- if (currentPage > start + pageCount) {
49
- const newStart = Math.floor((currentPage - 1) / pageCount) * pageCount + 1;
50
- setStart(newStart);
51
- }
52
- if (currentPage < start) {
53
- setStart(Math.max(1, start - pageCount));
50
+ if (currentPage < baseStart) {
51
+ nextStart = Math.max(1, baseStart - pageCount);
54
52
  }
55
53
  if (currentPage === 1) {
56
- setStart(1);
54
+ nextStart = 1;
57
55
  }
58
56
  if (currentPage === totalPage) {
59
- setStart(lastGroupStart);
57
+ nextStart = lastGroupStart;
60
58
  }
59
+ // currentPage 가 totalPage 를 넘는 값이어도 마지막 그룹을 넘지 않는다
60
+ setStart(Math.min(nextStart, lastGroupStart));
61
61
  // start 는 이 effect 가 setStart 로 갱신하는 대상이라 deps 에서 제외한다(넣으면 자기 갱신으로
62
62
  // 재실행). currentPage 외에 totalPage/pageCount 도 추적해, 이들이 줄어 start 가 범위를 벗어나면
63
63
  // 위에서 보정한다.
@@ -67,6 +67,23 @@ const nextOf = el => el.querySelector('.ncua-pagination__next');
67
67
  (0, _vitest.expect)(nums[0]).toBe(GROUP_START_50_PAGES);
68
68
  (0, _vitest.expect)(Math.max(...nums)).toBeLessThanOrEqual(LAST_PAGE_50);
69
69
  });
70
+ (0, _vitest.it)('totalPage 가 줄면서 currentPage 가 1 로 돌아오면 1 이 든 첫 그룹을 보인다 (PR #603 리뷰)', () => {
71
+ // 50 페이지 중 35 페이지(31~40 그룹) → 새 검색으로 25 페이지 결과의 1 페이지
72
+ const el = render({
73
+ totalCount: 750,
74
+ itemCountPerPage: 15,
75
+ pageCount: PAGE_GROUP_SIZE,
76
+ currentPage: 35
77
+ });
78
+ render({
79
+ totalCount: 375,
80
+ itemCountPerPage: 15,
81
+ pageCount: PAGE_GROUP_SIZE,
82
+ currentPage: 1
83
+ });
84
+ (0, _vitest.expect)(pageNums(el)[0]).toBe(1);
85
+ (0, _vitest.expect)(el.querySelector('.ncua-pagination__page-num.is-current')?.textContent).toBe('1');
86
+ });
70
87
  });
71
88
  (0, _vitest.describe)('Pagination — mo 모드 이전/다음 버튼 노출', () => {
72
89
  (0, _vitest.it)('페이지가 그룹 크기 이하여도 mo 에서는 이전·다음 버튼이 노출된다', () => {