@bigtablet/design-system 1.20.1 โ†’ 1.21.1

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/README.md CHANGED
@@ -8,7 +8,6 @@
8
8
  [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
9
9
  [![Test Coverage](https://img.shields.io/badge/coverage-86%25-brightgreen.svg)](https://github.com/Bigtablet/bigtablet-design-system/actions)
10
10
  [![CI](https://github.com/Bigtablet/bigtablet-design-system/actions/workflows/ci.yml/badge.svg)](https://github.com/Bigtablet/bigtablet-design-system/actions/workflows/ci.yml)
11
- [![Storybook](https://img.shields.io/badge/Storybook-FF4785?logo=storybook&logoColor=white)](https://bigtablet.github.io/bigtablet-design-system)
12
11
 
13
12
  [๐Ÿ‡ฐ๐Ÿ‡ท ํ•œ๊ตญ์–ด](./README_KR.md) ยท ๐Ÿ‡บ๐Ÿ‡ธ English
14
13
 
@@ -17,7 +16,7 @@ The official design system of Bigtablet โ€” a unified UI library composed of Fou
17
16
  > **Note**: This is Bigtablet's in-house design system, open-sourced for community reference.
18
17
  > External use is welcome, but minor versions may include breaking changes without prior notice.
19
18
 
20
- [GitHub](https://github.com/Bigtablet/bigtablet-design-system) ยท [NPM](https://www.npmjs.com/package/@bigtablet/design-system) ยท [Storybook](https://bigtablet.github.io/bigtablet-design-system)
19
+ [GitHub](https://github.com/Bigtablet/bigtablet-design-system) ยท [NPM](https://www.npmjs.com/package/@bigtablet/design-system)
21
20
 
22
21
  </div>
23
22
 
@@ -34,7 +33,7 @@ The official design system of Bigtablet โ€” a unified UI library composed of Fou
34
33
  | ๐ŸŽจ **Design Tokens** | Consistent token-based system for colors, typography, spacing |
35
34
  | โ™ฟ **Accessibility** | Keyboard navigation, screen reader support, full ARIA attributes |
36
35
  | ๐Ÿงช **86% Coverage** | Stable test coverage powered by Vitest |
37
- | ๐ŸŽญ **Storybook** | Interactive documentation for all components |
36
+ | ๐ŸŽญ **Storybook** | Interactive component documentation (run locally via `pnpm storybook`) |
38
37
  | ๐ŸŽฏ **Zero Dependencies** | No bundled runtime dependencies โ€” peer deps only |
39
38
 
40
39
  ---
@@ -315,6 +314,6 @@ pnpm test:coverage # Coverage report
315
314
 
316
315
  <div align="center">
317
316
 
318
- [GitHub](https://github.com/Bigtablet/bigtablet-design-system) ยท [NPM](https://www.npmjs.com/package/@bigtablet/design-system) ยท [Storybook](https://bigtablet.github.io/bigtablet-design-system) ยท [Issues](https://github.com/Bigtablet/bigtablet-design-system/issues)
317
+ [GitHub](https://github.com/Bigtablet/bigtablet-design-system) ยท [NPM](https://www.npmjs.com/package/@bigtablet/design-system) ยท [Issues](https://github.com/Bigtablet/bigtablet-design-system/issues)
319
318
 
320
319
  </div>
package/dist/index.css CHANGED
@@ -565,7 +565,8 @@
565
565
  .file_input {
566
566
  position: relative;
567
567
  display: inline-flex;
568
- align-items: center;
568
+ flex-direction: column;
569
+ align-items: flex-start;
569
570
  cursor: pointer;
570
571
  }
571
572
  .file_input:hover .file_input_label {
@@ -595,6 +596,13 @@
595
596
  box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.08);
596
597
  border-color: #000000;
597
598
  }
599
+ .file_input_helper {
600
+ display: block;
601
+ margin-top: 0.25rem;
602
+ font-size: 0.875rem;
603
+ line-height: 1.5;
604
+ color: #666666;
605
+ }
598
606
  .file_input_disabled {
599
607
  cursor: not-allowed;
600
608
  }
@@ -1152,6 +1160,17 @@
1152
1160
  .date_picker_disabled .date_picker_label {
1153
1161
  color: #9ca3af;
1154
1162
  }
1163
+ .date_picker_sr_only {
1164
+ position: absolute;
1165
+ width: 1px;
1166
+ height: 1px;
1167
+ padding: 0;
1168
+ margin: -1px;
1169
+ overflow: hidden;
1170
+ clip: rect(0, 0, 0, 0);
1171
+ white-space: nowrap;
1172
+ border: 0;
1173
+ }
1155
1174
 
1156
1175
  /* src/ui/navigation/pagination/style.scss */
1157
1176
  .pagination {
package/dist/index.d.ts CHANGED
@@ -4,6 +4,8 @@ import * as React from 'react';
4
4
  interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
5
5
  /** ์นด๋“œ ์ƒ๋‹จ์— ํ‘œ์‹œํ•  ์ œ๋ชฉ */
6
6
  heading?: React.ReactNode;
7
+ /** ์ œ๋ชฉ์— ์‚ฌ์šฉํ•  ์‹œ๋งจํ‹ฑ ํ—ค๋”ฉ ํƒœ๊ทธ (๊ธฐ๋ณธ๊ฐ’: "h3"). ์Šคํฌ๋ฆฐ๋ฆฌ๋” outline์— ๋ฐ˜์˜๋ฉ๋‹ˆ๋‹ค. */
8
+ headingAs?: "h2" | "h3" | "h4" | "h5" | "h6";
7
9
  /** ์นด๋“œ ๊ทธ๋ฆผ์ž ํฌ๊ธฐ (๊ธฐ๋ณธ๊ฐ’: "sm") */
8
10
  shadow?: "none" | "sm" | "md" | "lg";
9
11
  /** ์นด๋“œ ๋‚ด๋ถ€ ์—ฌ๋ฐฑ (๊ธฐ๋ณธ๊ฐ’: "md") */
@@ -17,7 +19,7 @@ interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
17
19
  * @param props ์นด๋“œ ์†์„ฑ
18
20
  * @returns ๋ Œ๋”๋ง๋œ ์นด๋“œ UI
19
21
  */
20
- declare const Card: ({ heading, shadow, padding, bordered, className, children, ...props }: CardProps) => react_jsx_runtime.JSX.Element;
22
+ declare const Card: ({ heading, headingAs: HeadingTag, shadow, padding, bordered, className, children, ...props }: CardProps) => react_jsx_runtime.JSX.Element;
21
23
 
22
24
  type AlertVariant = "info" | "success" | "warning" | "error";
23
25
  type AlertActionsAlign = "left" | "center" | "right";
@@ -167,10 +169,12 @@ interface CheckboxProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>
167
169
  declare const Checkbox: React.ForwardRefExoticComponent<CheckboxProps & React.RefAttributes<HTMLInputElement>>;
168
170
 
169
171
  interface FileInputProps extends React.InputHTMLAttributes<HTMLInputElement> {
170
- /** ํŒŒ์ผ ์„ ํƒ ๋ฒ„ํŠผ ๋ผ๋ฒจ ํ…์ŠคํŠธ (๊ธฐ๋ณธ๊ฐ’: "ํŒŒ์ผ ์„ ํƒ") */
172
+ /** ํŒŒ์ผ ์„ ํƒ ๋ฒ„ํŠผ ๋ผ๋ฒจ ํ…์ŠคํŠธ (๊ธฐ๋ณธ๊ฐ’: "Choose file") */
171
173
  label?: string;
172
174
  /** ํŒŒ์ผ ์„ ํƒ ์‹œ ํ˜ธ์ถœ๋˜๋Š” ์ฝœ๋ฐฑ */
173
175
  onFiles?: (files: FileList | null) => void;
176
+ /** ํ—ˆ์šฉ ํŒŒ์ผ ํ˜•์‹ ์•ˆ๋‚ด ํ…์ŠคํŠธ. ์Šคํฌ๋ฆฐ๋ฆฌ๋”์—๊ฒŒ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค. (์˜ˆ: "PDF, DOC ํŒŒ์ผ๋งŒ ์—…๋กœ๋“œ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค") */
177
+ helperText?: string;
174
178
  }
175
179
  /**
176
180
  * ํŒŒ์ผ ์ž…๋ ฅ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•œ๋‹ค.
@@ -178,7 +182,7 @@ interface FileInputProps extends React.InputHTMLAttributes<HTMLInputElement> {
178
182
  * @param props ํŒŒ์ผ ์ž…๋ ฅ ์†์„ฑ
179
183
  * @returns ๋ Œ๋”๋ง๋œ ํŒŒ์ผ ์ž…๋ ฅ UI
180
184
  */
181
- declare const FileInput: ({ label, onFiles, className, disabled, ...props }: FileInputProps) => react_jsx_runtime.JSX.Element;
185
+ declare const FileInput: ({ label, onFiles, helperText, className, disabled, ...props }: FileInputProps) => react_jsx_runtime.JSX.Element;
182
186
 
183
187
  interface RadioProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "size"> {
184
188
  /** ๋ผ๋””์˜ค ๋ฒ„ํŠผ ์˜†์— ํ‘œ์‹œํ•  ๋ผ๋ฒจ */
@@ -334,6 +338,16 @@ interface DatePickerProps {
334
338
  monthLabel?: string;
335
339
  /** ์ผ select์˜ aria-label ๋ฐ ๋นˆ ์˜ต์…˜ ํ…์ŠคํŠธ (๊ธฐ๋ณธ๊ฐ’: "Day") */
336
340
  dayLabel?: string;
341
+ /**
342
+ * minDate ์„ค์ • ์‹œ ์Šคํฌ๋ฆฐ๋ฆฌ๋”์— ์ „๋‹ฌํ•  ์•ˆ๋‚ด ๋ฌธ๊ตฌ ํฌ๋งท.
343
+ * `{date}` ์ž๋ฆฌ์— minDate ๊ฐ’์ด ์น˜ํ™˜๋ฉ๋‹ˆ๋‹ค. (๊ธฐ๋ณธ๊ฐ’: "Minimum date: {date}")
344
+ */
345
+ minDateSrFormat?: string;
346
+ /**
347
+ * selectableRange="until-today" ์„ค์ • ์‹œ ์Šคํฌ๋ฆฐ๋ฆฌ๋”์— ์ „๋‹ฌํ•  ์•ˆ๋‚ด ๋ฌธ๊ตฌ.
348
+ * (๊ธฐ๋ณธ๊ฐ’: "Selectable up to today")
349
+ */
350
+ selectableRangeUntilTodaySrText?: string;
337
351
  }
338
352
  /**
339
353
  * ์—ฐ/์›”/์ผ ์„ ํƒํ˜• ๋ฐ์ดํŠธ ํ”ผ์ปค๋ฅผ ๋ Œ๋”๋งํ•œ๋‹ค.
@@ -341,7 +355,7 @@ interface DatePickerProps {
341
355
  * @param props ๋ฐ์ดํŠธ ํ”ผ์ปค ์†์„ฑ
342
356
  * @returns ๋ Œ๋”๋ง๋œ ๋ฐ์ดํŠธ ํ”ผ์ปค UI
343
357
  */
344
- declare const DatePicker: ({ label, value, onChange, mode, startYear, endYear, minDate, selectableRange, disabled, fullWidth, width, yearLabel, monthLabel, dayLabel, }: DatePickerProps) => react_jsx_runtime.JSX.Element;
358
+ declare const DatePicker: ({ label, value, onChange, mode, startYear, endYear, minDate, selectableRange, disabled, fullWidth, width, yearLabel, monthLabel, dayLabel, minDateSrFormat, selectableRangeUntilTodaySrText, }: DatePickerProps) => react_jsx_runtime.JSX.Element;
345
359
 
346
360
  interface PaginationProps {
347
361
  /** ํ˜„์žฌ ํŽ˜์ด์ง€ ๋ฒˆํ˜ธ (1-based) */
package/dist/index.js CHANGED
@@ -90,6 +90,7 @@ function useFocusTrap(containerRef, isActive) {
90
90
  }
91
91
  var Card = ({
92
92
  heading,
93
+ headingAs: HeadingTag = "h3",
93
94
  shadow = "sm",
94
95
  padding = "md",
95
96
  bordered = false,
@@ -105,7 +106,7 @@ var Card = ({
105
106
  className
106
107
  );
107
108
  return /* @__PURE__ */ jsxs("div", { className: cardClassName, ...props, children: [
108
- heading ? /* @__PURE__ */ jsx("div", { className: "card_title", children: heading }) : null,
109
+ heading ? /* @__PURE__ */ jsx(HeadingTag, { className: "card_title", children: heading }) : null,
109
110
  /* @__PURE__ */ jsx("div", { className: "card_body", children })
110
111
  ] });
111
112
  };
@@ -431,11 +432,13 @@ Checkbox.displayName = "Checkbox";
431
432
  var FileInput = ({
432
433
  label = "Choose file",
433
434
  onFiles,
435
+ helperText,
434
436
  className,
435
437
  disabled,
436
438
  ...props
437
439
  }) => {
438
440
  const inputId = React7.useId();
441
+ const helperId = React7.useId();
439
442
  const rootClassName = [
440
443
  "file_input",
441
444
  disabled && "file_input_disabled",
@@ -449,11 +452,13 @@ var FileInput = ({
449
452
  type: "file",
450
453
  className: "file_input_control",
451
454
  disabled,
455
+ "aria-describedby": helperText ? helperId : void 0,
452
456
  onChange: (e) => onFiles?.(e.currentTarget.files),
453
457
  ...props
454
458
  }
455
459
  ),
456
- /* @__PURE__ */ jsx("label", { htmlFor: inputId, className: "file_input_label", children: label })
460
+ /* @__PURE__ */ jsx("label", { htmlFor: inputId, className: "file_input_label", children: label }),
461
+ helperText && /* @__PURE__ */ jsx("span", { id: helperId, className: "file_input_helper", children: helperText })
457
462
  ] });
458
463
  };
459
464
  var Radio = React7.forwardRef(
@@ -823,9 +828,12 @@ var DatePicker = ({
823
828
  width,
824
829
  yearLabel = "Year",
825
830
  monthLabel = "Month",
826
- dayLabel = "Day"
831
+ dayLabel = "Day",
832
+ minDateSrFormat = "Minimum date: {date}",
833
+ selectableRangeUntilTodaySrText = "Selectable up to today"
827
834
  }) => {
828
835
  const groupId = React7.useId();
836
+ const constraintId = React7.useId();
829
837
  const today = /* @__PURE__ */ new Date();
830
838
  const todayYear = today.getFullYear();
831
839
  const todayMonth = today.getMonth() + 1;
@@ -852,14 +860,20 @@ var DatePicker = ({
852
860
  };
853
861
  const containerStyle = width ? { width: normalizeWidth(width) } : void 0;
854
862
  const rootClassName = cn("date_picker", { date_picker_full_width: fullWidth && !width });
863
+ const constraintParts = [];
864
+ if (minDate) constraintParts.push(minDateSrFormat.replace("{date}", minDate));
865
+ if (selectableRange === "until-today") constraintParts.push(selectableRangeUntilTodaySrText);
866
+ const constraintDesc = constraintParts.join(". ");
855
867
  return /* @__PURE__ */ jsxs("div", { className: rootClassName, style: containerStyle, children: [
856
868
  label && /* @__PURE__ */ jsx("label", { className: "date_picker_label", id: groupId, children: label }),
869
+ constraintDesc && /* @__PURE__ */ jsx("span", { id: constraintId, className: "date_picker_sr_only", children: constraintDesc }),
857
870
  /* @__PURE__ */ jsxs(
858
871
  "div",
859
872
  {
860
873
  className: "date_picker_fields",
861
874
  role: "group",
862
875
  "aria-labelledby": label ? groupId : void 0,
876
+ "aria-describedby": constraintDesc ? constraintId : void 0,
863
877
  children: [
864
878
  /* @__PURE__ */ jsxs(
865
879
  "select",
@@ -953,6 +967,7 @@ var Pagination = ({ page, totalPages, onChange, prevLabel = "Previous page", nex
953
967
  /* @__PURE__ */ jsx(
954
968
  "button",
955
969
  {
970
+ type: "button",
956
971
  className: "pagination_item",
957
972
  onClick: () => onChange(page - 1),
958
973
  disabled: prevDisabled,
@@ -983,6 +998,7 @@ var Pagination = ({ page, totalPages, onChange, prevLabel = "Previous page", nex
983
998
  /* @__PURE__ */ jsx(
984
999
  "button",
985
1000
  {
1001
+ type: "button",
986
1002
  className: "pagination_item",
987
1003
  onClick: () => onChange(page + 1),
988
1004
  disabled: nextDisabled,
package/dist/next.js CHANGED
@@ -94,6 +94,7 @@ var Sidebar = ({
94
94
  "sidebar_chevron",
95
95
  open && "sidebar_chevron_open"
96
96
  ].filter(Boolean).join(" ");
97
+ const subId = `sidebar_sub_${item.id}`;
97
98
  return /* @__PURE__ */ jsxs("div", { className: "sidebar_group", children: [
98
99
  /* @__PURE__ */ jsxs(
99
100
  "button",
@@ -101,6 +102,7 @@ var Sidebar = ({
101
102
  type: "button",
102
103
  className: "sidebar_item",
103
104
  "aria-expanded": open,
105
+ "aria-controls": subId,
104
106
  onClick: () => toggleGroup(item.id),
105
107
  children: [
106
108
  /* @__PURE__ */ jsxs("div", { className: "sidebar_item_left", children: [
@@ -117,7 +119,7 @@ var Sidebar = ({
117
119
  ]
118
120
  }
119
121
  ),
120
- /* @__PURE__ */ jsx("div", { className: subClassName, children: item.children.map((child) => {
122
+ /* @__PURE__ */ jsx("div", { id: subId, className: subClassName, children: item.children.map((child) => {
121
123
  const active2 = isActive(
122
124
  child.href
123
125
  );
@@ -131,6 +133,7 @@ var Sidebar = ({
131
133
  href: child.href,
132
134
  className: subItemClassName,
133
135
  "aria-current": active2 ? "page" : void 0,
136
+ tabIndex: open ? void 0 : -1,
134
137
  onClick: () => onItemSelect?.(
135
138
  child.href
136
139
  ),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bigtablet/design-system",
3
- "version": "1.20.1",
3
+ "version": "1.21.1",
4
4
  "description": "Bigtablet Design System UI Components",
5
5
  "type": "module",
6
6
  "types": "dist/index.d.ts",
@@ -55,7 +55,8 @@
55
55
  "figma:snapshot": "node scripts/figma-snapshot.mjs",
56
56
  "figma:diff": "node scripts/figma-diff.mjs",
57
57
  "figma:apply": "node scripts/figma-apply.mjs",
58
- "size": "size-limit"
58
+ "size": "size-limit",
59
+ "prepare": "husky"
59
60
  },
60
61
  "keywords": [
61
62
  "design-system",
@@ -81,6 +82,8 @@
81
82
  }
82
83
  },
83
84
  "devDependencies": {
85
+ "@commitlint/cli": "^20.4.4",
86
+ "@commitlint/core": "^20.4.4",
84
87
  "@semantic-release/changelog": "^6.0.3",
85
88
  "@semantic-release/git": "^10.0.1",
86
89
  "@semantic-release/github": "^12.0.1",
@@ -101,9 +104,10 @@
101
104
  "chromatic": "^13.3.3",
102
105
  "conventional-changelog-conventionalcommits": "^9.1.0",
103
106
  "esbuild-sass-plugin": "^3",
107
+ "husky": "^9.1.7",
104
108
  "jsdom": "^28.0.0",
105
109
  "lucide-react": "^0.552.0",
106
- "next": "16.1.5",
110
+ "next": "16.1.6",
107
111
  "playwright": "^1.57.0",
108
112
  "react": "19.2.0",
109
113
  "react-dom": "19.2.0",