maru_design2 3.1.1 → 3.2.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 CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## [3.2.0](https://github.com/42maru-ai/maru-design2/compare/v3.1.1...v3.2.0) (2026-09-10)
4
+
5
+
6
+ ### Features
7
+
8
+ * support localized pagination labels and formatters ([5cd30a8](https://github.com/42maru-ai/maru-design2/commit/5cd30a8a01c60974a90dd0f7e8c827d1e2f28415))
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * align modal footer buttons with shared button styles ([5084958](https://github.com/42maru-ai/maru-design2/commit/5084958685415ed0083009ed4c5a06cde996e791))
14
+ * prevent dropdown tooltips from covering adjacent options ([6d3cb7a](https://github.com/42maru-ai/maru-design2/commit/6d3cb7a0e6d8a938911fffa69d3591e0895f0b7d))
15
+
3
16
  ## [3.1.1](https://github.com/42maru-ai/maru-design2/compare/v3.1.0...v3.1.1) (2026-09-09)
4
17
 
5
18
 
@@ -16,7 +16,7 @@ export interface ModalProps {
16
16
  */
17
17
  backdrop?: boolean;
18
18
  /**
19
- * 모달 취소버튼 설정
19
+ * 모달 취소버튼 설정. 공통 Button의 secondary / outline / large를 사용합니다.
20
20
  */
21
21
  cancelButton?: {
22
22
  content: string;
@@ -45,7 +45,7 @@ export interface ModalProps {
45
45
  */
46
46
  icon?: React.ReactNode;
47
47
  /**
48
- * 모달 확인버튼 설정 (@v1 confirmButton)
48
+ * 모달 확인버튼 설정 (@v1 confirmButton). 공통 Button의 default / large를 사용합니다.
49
49
  */
50
50
  okButton?: {
51
51
  content: string;
@@ -1,6 +1,29 @@
1
1
  import React from 'react';
2
2
  import './pagination.scss';
3
3
  export type PaginationVariant = 'default' | 'simple' | 'number';
4
+ export interface PaginationLabels {
5
+ /** 이전 버튼의 표시 문구. @default '이전' */
6
+ previous: string;
7
+ /** 다음 버튼의 표시 문구. @default '다음' */
8
+ next: string;
9
+ /** 첫 페이지 버튼의 접근성 이름. @default '첫 페이지' */
10
+ firstPage: string;
11
+ /** 이전 페이지 버튼의 접근성 이름. @default '이전 페이지' */
12
+ previousPage: string;
13
+ /** 다음 페이지 버튼의 접근성 이름. @default '다음 페이지' */
14
+ nextPage: string;
15
+ /** 마지막 페이지 버튼의 접근성 이름. @default '마지막 페이지' */
16
+ lastPage: string;
17
+ /** 페이지 입력의 접근성 이름. @default '현재 페이지' */
18
+ currentPage: string;
19
+ /** 페이지 크기 선택의 접근성 이름. @default '페이지당 항목 수' */
20
+ pageSize: string;
21
+ }
22
+ export interface PaginationSummary {
23
+ totalCount: number;
24
+ rangeStart: number;
25
+ rangeEnd: number;
26
+ }
4
27
  export interface PaginationProps {
5
28
  /** 현재 페이지 (1부터 시작). */
6
29
  page: number;
@@ -26,8 +49,16 @@ export interface PaginationProps {
26
49
  buttonVisibility?: 'visible' | 'hidden';
27
50
  /** 전체 페이지 수 뒤에 붙는 문구. @default '페이지' */
28
51
  label?: string;
52
+ /** 표시 문구와 접근성 이름. 생략한 항목은 기존 한국어 문구를 사용합니다. */
53
+ labels?: Partial<PaginationLabels>;
54
+ /** 기본형의 전체 범위 문구. totalCount가 있을 때만 정규화된 수치로 호출합니다. */
55
+ formatSummary?: (summary: PaginationSummary) => React.ReactNode;
56
+ /** 페이지 크기 선택 문구. 기본값은 `${size}개 씩`입니다. */
57
+ formatPageSize?: (size: number) => string;
58
+ /** 번호 버튼의 접근성 이름. 기본값은 `${page} 페이지`입니다. */
59
+ formatPageAriaLabel?: (page: number) => string;
29
60
  /** 탐색 영역의 접근성 이름. @default '페이지네이션' */
30
61
  'aria-label'?: string;
31
62
  className?: string;
32
63
  }
33
- export declare function Pagination({ page, onPageChange, totalPage, variant, totalCount, pageSize, pageSizeOptions, onPageSizeChange, divider, disabled, buttonVisibility, label, 'aria-label': ariaLabel, className, }: PaginationProps): React.JSX.Element;
64
+ export declare function Pagination({ page, onPageChange, totalPage, variant, totalCount, pageSize, pageSizeOptions, onPageSizeChange, divider, disabled, buttonVisibility, label, labels, formatSummary, formatPageSize, formatPageAriaLabel, 'aria-label': ariaLabel, className, }: PaginationProps): React.JSX.Element;
package/dist/index.js CHANGED
@@ -90282,7 +90282,7 @@ function MenuItem$1(_a) {
90282
90282
  var overflow = useOverflow(textRef, item[displayKey]);
90283
90283
  return jsx(Tooltip, __assign({
90284
90284
  content: item[displayKey],
90285
- direction: "bottom-start",
90285
+ direction: "right-start",
90286
90286
  hidden: !overflow,
90287
90287
  portal: true
90288
90288
  }, {
@@ -91794,12 +91794,16 @@ function Modal(_a) {
91794
91794
  }, {
91795
91795
  children: [cancelButton && jsx(Button, __assign({
91796
91796
  color: "secondary",
91797
+ variant: "outline",
91798
+ size: "large",
91797
91799
  onClick: handleClose,
91798
91800
  disabled: cancelButton.disabled
91799
91801
  }, {
91800
91802
  children: cancelButton.content
91801
91803
  })), okButton && jsx(Button, __assign({
91802
91804
  color: okButton.color || 'primary',
91805
+ variant: "default",
91806
+ size: "large",
91803
91807
  onClick: handleOkButtonClick,
91804
91808
  disabled: okButton.disabled
91805
91809
  }, {
@@ -92686,27 +92690,39 @@ function getPageItems(page, total) {
92686
92690
  return items;
92687
92691
  }
92688
92692
  function Pagination(_a) {
92693
+ var _b, _c;
92689
92694
  var page = _a.page,
92690
92695
  onPageChange = _a.onPageChange,
92691
92696
  totalPage = _a.totalPage,
92692
- _b = _a.variant,
92693
- variant = _b === void 0 ? 'default' : _b,
92697
+ _d = _a.variant,
92698
+ variant = _d === void 0 ? 'default' : _d,
92694
92699
  totalCount = _a.totalCount,
92695
- _c = _a.pageSize,
92696
- pageSize = _c === void 0 ? 30 : _c,
92697
- _d = _a.pageSizeOptions,
92698
- pageSizeOptions = _d === void 0 ? [15, 30, 50, 100] : _d,
92700
+ _e = _a.pageSize,
92701
+ pageSize = _e === void 0 ? 30 : _e,
92702
+ _f = _a.pageSizeOptions,
92703
+ pageSizeOptions = _f === void 0 ? [15, 30, 50, 100] : _f,
92699
92704
  onPageSizeChange = _a.onPageSizeChange,
92700
- _e = _a.divider,
92701
- divider = _e === void 0 ? true : _e,
92702
- _f = _a.disabled,
92703
- disabled = _f === void 0 ? false : _f,
92704
- _g = _a.buttonVisibility,
92705
- buttonVisibility = _g === void 0 ? 'visible' : _g,
92706
- _h = _a.label,
92707
- label = _h === void 0 ? '페이지' : _h,
92708
- _j = _a["aria-label"],
92709
- ariaLabel = _j === void 0 ? '페이지네이션' : _j,
92705
+ _g = _a.divider,
92706
+ divider = _g === void 0 ? true : _g,
92707
+ _h = _a.disabled,
92708
+ disabled = _h === void 0 ? false : _h,
92709
+ _j = _a.buttonVisibility,
92710
+ buttonVisibility = _j === void 0 ? 'visible' : _j,
92711
+ _k = _a.label,
92712
+ label = _k === void 0 ? '페이지' : _k,
92713
+ _l = _a.labels,
92714
+ labels = _l === void 0 ? {} : _l,
92715
+ formatSummary = _a.formatSummary,
92716
+ _m = _a.formatPageSize,
92717
+ formatPageSize = _m === void 0 ? function (value) {
92718
+ return "".concat(value, "\uAC1C \uC529");
92719
+ } : _m,
92720
+ _o = _a.formatPageAriaLabel,
92721
+ formatPageAriaLabel = _o === void 0 ? function (value) {
92722
+ return "".concat(value, " \uD398\uC774\uC9C0");
92723
+ } : _o,
92724
+ _p = _a["aria-label"],
92725
+ ariaLabel = _p === void 0 ? '페이지네이션' : _p,
92710
92726
  className = _a.className;
92711
92727
  var total = nonNegativeInteger(totalPage);
92712
92728
  var currentPage = total === 0 ? 0 : Math.min(total, Math.max(1, nonNegativeInteger(page)));
@@ -92714,9 +92730,9 @@ function Pagination(_a) {
92714
92730
  var count = totalCount == null ? undefined : nonNegativeInteger(totalCount);
92715
92731
  var rangeEnd = count == null ? 0 : Math.min(currentPage * size, count);
92716
92732
  var rangeStart = rangeEnd === 0 ? 0 : Math.min((currentPage - 1) * size + 1, rangeEnd);
92717
- var _k = useState(String(currentPage)),
92718
- inputValue = _k[0],
92719
- setInputValue = _k[1];
92733
+ var _q = useState(String(currentPage)),
92734
+ inputValue = _q[0],
92735
+ setInputValue = _q[1];
92720
92736
  var dirty = useRef(false);
92721
92737
  var pointerNavigation = useRef(false);
92722
92738
  useEffect(function () {
@@ -92741,14 +92757,15 @@ function Pagination(_a) {
92741
92757
  }
92742
92758
  };
92743
92759
  var navigationButton = function navigationButton(direction) {
92760
+ var _a, _b, _c, _d, _e, _f;
92744
92761
  var backwards = direction === 'first' || direction === 'previous';
92745
92762
  var atBoundary = total <= 1 || (backwards ? currentPage === 1 : currentPage === total);
92746
92763
  var isDefault = variant === 'default';
92747
92764
  var names = {
92748
- first: '첫 페이지',
92749
- previous: '이전 페이지',
92750
- next: '다음 페이지',
92751
- last: '마지막 페이지'
92765
+ first: (_a = labels.firstPage) !== null && _a !== void 0 ? _a : '첫 페이지',
92766
+ previous: (_b = labels.previousPage) !== null && _b !== void 0 ? _b : '이전 페이지',
92767
+ next: (_c = labels.nextPage) !== null && _c !== void 0 ? _c : '다음 페이지',
92768
+ last: (_d = labels.lastPage) !== null && _d !== void 0 ? _d : '마지막 페이지'
92752
92769
  };
92753
92770
  var icons = {
92754
92771
  first: img$5,
@@ -92783,7 +92800,7 @@ function Pagination(_a) {
92783
92800
  return requestPage(targets[direction]);
92784
92801
  }
92785
92802
  }, {
92786
- children: isDefault ? undefined : backwards ? '이전' : '다음'
92803
+ children: isDefault ? undefined : backwards ? (_e = labels.previous) !== null && _e !== void 0 ? _e : '이전' : (_f = labels.next) !== null && _f !== void 0 ? _f : '다음'
92787
92804
  }));
92788
92805
  };
92789
92806
  return jsx("nav", __assign({
@@ -92805,22 +92822,28 @@ function Pagination(_a) {
92805
92822
  className: "maru-pagination"
92806
92823
  }, {
92807
92824
  children: [variant === 'default' && jsxs(Fragment, {
92808
- children: [count != null && jsxs("span", __assign({
92825
+ children: [count != null && jsx("span", __assign({
92809
92826
  className: "maru-pagination-summary",
92810
92827
  "aria-live": "polite",
92811
92828
  "aria-atomic": "true"
92812
92829
  }, {
92813
- children: [jsxs("span", __assign({
92814
- className: "maru-pagination-count"
92815
- }, {
92816
- children: [jsx("span", {
92817
- children: count
92818
- }), jsx("span", {
92819
- children: "\uAC1C \uC911"
92830
+ children: formatSummary ? formatSummary({
92831
+ totalCount: count,
92832
+ rangeStart: rangeStart,
92833
+ rangeEnd: rangeEnd
92834
+ }) : jsxs(Fragment, {
92835
+ children: [jsxs("span", __assign({
92836
+ className: "maru-pagination-count"
92837
+ }, {
92838
+ children: [jsx("span", {
92839
+ children: count
92840
+ }), jsx("span", {
92841
+ children: "\uAC1C \uC911"
92842
+ })]
92843
+ })), jsx("span", {
92844
+ children: "".concat(rangeStart, "-").concat(rangeEnd)
92820
92845
  })]
92821
- })), jsx("span", {
92822
- children: "".concat(rangeStart, "-").concat(rangeEnd)
92823
- })]
92846
+ })
92824
92847
  })), jsxs("div", __assign({
92825
92848
  className: "maru-pagination-controls"
92826
92849
  }, {
@@ -92831,7 +92854,7 @@ function Pagination(_a) {
92831
92854
  className: "maru-pagination-input",
92832
92855
  type: "number",
92833
92856
  inputMode: "numeric",
92834
- "aria-label": "\uD604\uC7AC \uD398\uC774\uC9C0",
92857
+ "aria-label": (_b = labels.currentPage) !== null && _b !== void 0 ? _b : '현재 페이지',
92835
92858
  min: total === 0 ? 0 : 1,
92836
92859
  max: total,
92837
92860
  step: 1,
@@ -92886,7 +92909,7 @@ function Pagination(_a) {
92886
92909
  children: "".concat(currentPage, " / ").concat(total).concat(label ? " ".concat(label) : '')
92887
92910
  })), jsx(Dropdown, {
92888
92911
  className: "maru-pagination-size-select",
92889
- "aria-label": "\uD398\uC774\uC9C0\uB2F9 \uD56D\uBAA9 \uC218",
92912
+ "aria-label": (_c = labels.pageSize) !== null && _c !== void 0 ? _c : '페이지당 항목 수',
92890
92913
  data: Array.from(new Set(__spreadArray([size], pageSizeOptions.filter(function (option) {
92891
92914
  return Number.isInteger(option) && option > 0;
92892
92915
  }), true))).sort(function (a, b) {
@@ -92894,7 +92917,7 @@ function Pagination(_a) {
92894
92917
  }).map(function (option) {
92895
92918
  return {
92896
92919
  id: String(option),
92897
- text: "".concat(option, "\uAC1C \uC529")
92920
+ text: formatPageSize(option)
92898
92921
  };
92899
92922
  }),
92900
92923
  selectedId: String(size),
@@ -92920,7 +92943,7 @@ function Pagination(_a) {
92920
92943
  color: "secondary",
92921
92944
  variant: "text",
92922
92945
  size: "small",
92923
- "aria-label": "".concat(item, " \uD398\uC774\uC9C0"),
92946
+ "aria-label": formatPageAriaLabel(item),
92924
92947
  "aria-current": item === currentPage ? 'page' : undefined,
92925
92948
  disabled: disabled,
92926
92949
  onClick: function onClick() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "maru_design2",
3
- "version": "3.1.1",
3
+ "version": "3.2.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",