@ceed/cds 1.24.1-next.3 → 1.25.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 (63) hide show
  1. package/dist/chunks/rehype-accent-FZRUD7VI.js +39 -0
  2. package/dist/components/CurrencyInput/CurrencyInput.d.ts +1 -1
  3. package/dist/components/CurrencyInput/hooks/use-currency-setting.d.ts +2 -2
  4. package/dist/components/DataTable/components.d.ts +2 -1
  5. package/dist/components/DataTable/styled.d.ts +3 -1
  6. package/dist/components/DataTable/types.d.ts +1 -0
  7. package/dist/components/RadioTileGroup/RadioTileGroup.d.ts +56 -0
  8. package/dist/components/RadioTileGroup/index.d.ts +3 -0
  9. package/dist/components/data-display/DataTable.md +77 -1
  10. package/dist/components/data-display/InfoSign.md +74 -91
  11. package/dist/components/data-display/Typography.md +411 -94
  12. package/dist/components/feedback/CircularProgress.md +257 -0
  13. package/dist/components/feedback/Dialog.md +76 -62
  14. package/dist/components/feedback/Modal.md +430 -138
  15. package/dist/components/feedback/Skeleton.md +280 -0
  16. package/dist/components/feedback/llms.txt +2 -0
  17. package/dist/components/index.d.ts +1 -0
  18. package/dist/components/inputs/Autocomplete.md +356 -107
  19. package/dist/components/inputs/ButtonGroup.md +115 -104
  20. package/dist/components/inputs/CurrencyInput.md +183 -5
  21. package/dist/components/inputs/DatePicker.md +108 -431
  22. package/dist/components/inputs/DateRangePicker.md +131 -492
  23. package/dist/components/inputs/FilterableCheckboxGroup.md +145 -19
  24. package/dist/components/inputs/FormControl.md +361 -0
  25. package/dist/components/inputs/IconButton.md +137 -88
  26. package/dist/components/inputs/Input.md +204 -73
  27. package/dist/components/inputs/MonthPicker.md +95 -422
  28. package/dist/components/inputs/MonthRangePicker.md +89 -466
  29. package/dist/components/inputs/PercentageInput.md +185 -16
  30. package/dist/components/inputs/RadioButton.md +163 -35
  31. package/dist/components/inputs/RadioList.md +241 -0
  32. package/dist/components/inputs/RadioTileGroup.md +507 -0
  33. package/dist/components/inputs/Select.md +222 -326
  34. package/dist/components/inputs/Slider.md +334 -0
  35. package/dist/components/inputs/Switch.md +143 -376
  36. package/dist/components/inputs/Textarea.md +213 -10
  37. package/dist/components/inputs/Uploader/Uploader.md +145 -66
  38. package/dist/components/inputs/llms.txt +4 -0
  39. package/dist/components/navigation/Breadcrumbs.md +57 -308
  40. package/dist/components/navigation/Drawer.md +180 -0
  41. package/dist/components/navigation/Dropdown.md +98 -215
  42. package/dist/components/navigation/IconMenuButton.md +40 -502
  43. package/dist/components/navigation/InsetDrawer.md +281 -650
  44. package/dist/components/navigation/Link.md +31 -348
  45. package/dist/components/navigation/Menu.md +92 -285
  46. package/dist/components/navigation/MenuButton.md +55 -448
  47. package/dist/components/navigation/Pagination.md +47 -338
  48. package/dist/components/navigation/Stepper.md +160 -28
  49. package/dist/components/navigation/Tabs.md +57 -316
  50. package/dist/components/surfaces/Accordions.md +49 -804
  51. package/dist/components/surfaces/Card.md +97 -157
  52. package/dist/components/surfaces/Divider.md +83 -234
  53. package/dist/components/surfaces/Sheet.md +153 -328
  54. package/dist/guides/ThemeProvider.md +89 -0
  55. package/dist/guides/llms.txt +9 -0
  56. package/dist/index.browser.js +224 -0
  57. package/dist/index.browser.js.map +7 -0
  58. package/dist/index.cjs +648 -390
  59. package/dist/index.d.ts +1 -1
  60. package/dist/index.js +563 -361
  61. package/dist/llms.txt +9 -0
  62. package/framer/index.js +1 -163
  63. package/package.json +22 -17
@@ -0,0 +1,39 @@
1
+ // src/libs/rehype-accent/index.ts
2
+ import { visit } from "unist-util-visit";
3
+ function rehypeAccent(options) {
4
+ const { accentColor } = options;
5
+ return (tree) => {
6
+ visit(tree, "text", (node, index, parent) => {
7
+ const value = node.value;
8
+ const regex = /\|\|.*?\|\|/g;
9
+ let match;
10
+ let lastIndex = 0;
11
+ const newNodes = [];
12
+ while ((match = regex.exec(value)) !== null) {
13
+ if (match.index > lastIndex) {
14
+ newNodes.push({
15
+ type: "text",
16
+ value: value.slice(lastIndex, match.index)
17
+ });
18
+ }
19
+ const innerText = match[0].split("||")[1];
20
+ newNodes.push({
21
+ type: "element",
22
+ tagName: "span",
23
+ properties: { textColor: accentColor },
24
+ children: [{ type: "text", value: innerText }]
25
+ });
26
+ lastIndex = match.index + match[0].length;
27
+ }
28
+ if (lastIndex < value.length) {
29
+ newNodes.push({ type: "text", value: value.slice(lastIndex) });
30
+ }
31
+ if (newNodes.length) {
32
+ parent.children.splice(index, 1, ...newNodes);
33
+ }
34
+ });
35
+ };
36
+ }
37
+ export {
38
+ rehypeAccent
39
+ };
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import { InputProps } from '@mui/joy';
3
3
  import { MotionProps } from 'framer-motion';
4
4
  interface CurrencyInputProps {
5
- currency?: 'USD' | 'KRW';
5
+ currency?: 'USD' | 'KRW' | 'CAD';
6
6
  max?: number;
7
7
  value?: number;
8
8
  defaultValue?: number;
@@ -1,10 +1,10 @@
1
1
  export declare const useCurrencySetting: (props: {
2
- currency?: "USD" | "KRW" | "BHD" | undefined;
2
+ currency?: "USD" | "KRW" | "BHD" | "CAD" | undefined;
3
3
  placeholder?: string | undefined;
4
4
  }) => {
5
5
  symbol: string;
6
6
  thousandSeparator: string;
7
- decimalSeparator: string;
7
+ decimalSeparator: string | undefined;
8
8
  placeholder: string;
9
9
  fixedDecimalScale: boolean;
10
10
  decimalScale: number;
@@ -1,7 +1,8 @@
1
1
  import React, { ReactNode } from 'react';
2
2
  import type { ObjectLike, ColumnDef, Sort } from './types';
3
- export declare const TextEllipsis: ({ children }: {
3
+ export declare const TextEllipsis: ({ children, lineClamp }: {
4
4
  children: ReactNode;
5
+ lineClamp?: number | undefined;
5
6
  }) => React.JSX.Element;
6
7
  export declare const CellTextEllipsis: ({ children }: {
7
8
  children: ReactNode;
@@ -1,5 +1,7 @@
1
1
  import React, { RefObject } from 'react';
2
- export declare const EllipsisDiv: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/joy").Theme>, Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof React.ClassAttributes<HTMLDivElement> | keyof React.HTMLAttributes<HTMLDivElement>>, {}>;
2
+ export declare const EllipsisDiv: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/joy").Theme> & {
3
+ lineClamp?: number | undefined;
4
+ }, React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
3
5
  export declare const OverlayWrapper: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/joy").Theme>, Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLTableRowElement>, HTMLTableRowElement>, keyof React.ClassAttributes<HTMLTableRowElement> | keyof React.HTMLAttributes<HTMLTableRowElement>>, {}>;
4
6
  export declare const VirtualizedTableBody: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/joy").Theme>, Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLTableSectionElement>, HTMLTableSectionElement>, keyof React.ClassAttributes<HTMLTableSectionElement> | keyof React.HTMLAttributes<HTMLTableSectionElement>>, {}>;
5
7
  export declare const StyledTableRow: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/joy").Theme> & {
@@ -103,6 +103,7 @@ export type BaseColumnDef<T extends Record<PropertyKey, V>, V, ID> = {
103
103
  description?: string;
104
104
  cellClassName?: TableCellClassNamePropType<T, T[K]>;
105
105
  headerClassName?: TableColumnHeaderClassNamePropType<T, T[K]>;
106
+ headerLineClamp?: 1 | 2;
106
107
  };
107
108
  }[keyof T];
108
109
  export type AutocompleteColumnDef<T extends Record<PropertyKey, string>, ID> = BaseColumnDef<T, string, ID> & {
@@ -0,0 +1,56 @@
1
+ import React, { ReactNode } from 'react';
2
+ import type { SxProps } from '@mui/joy/styles/types';
3
+ export interface RadioTileOption<T = string> {
4
+ value: T;
5
+ label: ReactNode;
6
+ disabled?: boolean;
7
+ startDecorator?: ReactNode;
8
+ }
9
+ export interface RadioTileGroupProps<T = string> {
10
+ /**
11
+ * @default 'sm'
12
+ */
13
+ size?: 'sm' | 'md' | 'lg';
14
+ options: RadioTileOption<T>[];
15
+ value?: T;
16
+ defaultValue?: T;
17
+ name?: string;
18
+ onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
19
+ sx?: SxProps;
20
+ disabled?: boolean;
21
+ className?: string;
22
+ useIndicator?: boolean;
23
+ flex?: boolean;
24
+ /**
25
+ * 지정하지 않으면 한 row에 모든 옵션이 렌더링된다.
26
+ * - 특정 rows 이내로 렌더링 하고 싶으면 `columns: Math.ceil(options.length / 원하는 rows)`로 설정할 수 있다.
27
+ * - 수직으로 렌더링 하고 싶으면 `columns: 1`로 설정할 수 있다.
28
+ * - `flex` 옵션과 함께 사용할수 있다.
29
+ */
30
+ columns?: number;
31
+ /**
32
+ * @default 'center'
33
+ */
34
+ textAlign?: 'start' | 'center';
35
+ /**
36
+ * Label for the RadioTileGroup
37
+ */
38
+ label?: React.ReactNode;
39
+ /**
40
+ * Helper text for the RadioTileGroup
41
+ */
42
+ helperText?: React.ReactNode;
43
+ /**
44
+ * Whether the RadioTileGroup has an error
45
+ */
46
+ error?: boolean;
47
+ /**
48
+ * Whether the RadioTileGroup is required
49
+ */
50
+ required?: boolean;
51
+ }
52
+ declare function RadioTileGroup<T extends string | number = string>(props: RadioTileGroupProps<T>): React.JSX.Element;
53
+ declare namespace RadioTileGroup {
54
+ var displayName: string;
55
+ }
56
+ export { RadioTileGroup };
@@ -0,0 +1,3 @@
1
+ import { RadioTileGroup } from './RadioTileGroup';
2
+ export * from './RadioTileGroup';
3
+ export default RadioTileGroup;
@@ -895,6 +895,82 @@ const columns = [
895
895
  ];
896
896
  ```
897
897
 
898
+ ### Two-Line Headers (headerLineClamp)
899
+
900
+ Setting `headerLineClamp: 2` on a column allows the header text to wrap up to 2 lines. Text exceeding 2 lines is truncated with an ellipsis, and a tooltip is displayed on hover when truncation occurs.
901
+
902
+ ```tsx
903
+ <Box sx={{
904
+ width: 500
905
+ }}>
906
+ <DataTable rows={manyRows} columns={[{
907
+ field: 'dessert',
908
+ headerName: 'Dessert Name (100g serving)',
909
+ headerLineClamp: 2,
910
+ width: '120px'
911
+ }, {
912
+ field: 'calories',
913
+ headerName: 'Calories (kcal)',
914
+ headerLineClamp: 2,
915
+ type: 'number',
916
+ width: '80px'
917
+ }, {
918
+ field: 'fat',
919
+ headerName: 'Fat Content (grams)',
920
+ headerLineClamp: 2,
921
+ type: 'number',
922
+ width: '80px'
923
+ }, {
924
+ field: 'carbs',
925
+ headerName: 'Total Carbohydrates (g)',
926
+ headerLineClamp: 2,
927
+ type: 'number',
928
+ width: '90px'
929
+ }, {
930
+ field: 'protein',
931
+ headerName: 'Protein Amount (g)',
932
+ type: 'number',
933
+ width: '120px'
934
+ }]} stickyHeader slotProps={{
935
+ background: {
936
+ style: {
937
+ height: '400px'
938
+ }
939
+ }
940
+ }} />
941
+ </Box>
942
+ ```
943
+
944
+ ```tsx
945
+ const columns = [
946
+ {
947
+ field: 'calories',
948
+ headerName: 'Calories (kcal)',
949
+ headerLineClamp: 2,
950
+ type: 'number',
951
+ width: '80px',
952
+ },
953
+ {
954
+ field: 'fat',
955
+ headerName: 'Fat Content (grams)',
956
+ headerLineClamp: 2,
957
+ type: 'number',
958
+ width: '80px',
959
+ },
960
+ {
961
+ field: 'protein',
962
+ headerName: 'Protein (g)', // no headerLineClamp — single line (default)
963
+ type: 'number',
964
+ },
965
+ ];
966
+ ```
967
+
968
+ #### Notes
969
+
970
+ - `headerLineClamp` is opt-in per column. Columns without it remain single-line.
971
+ - Supported values: `1 | 2`.
972
+ - Works with all existing features: sorting, pinning, resizing, and column grouping.
973
+
898
974
  ## Editing Features
899
975
 
900
976
  ### Inline Editing
@@ -1038,7 +1114,7 @@ You can use `onCellEditStart` and `onCellEditStop` to detect when editing starts
1038
1114
  </Typography>
1039
1115
  {editLog.length === 0 ? <Typography level="body-xs" textColor="text.secondary">
1040
1116
  No edits yet. Click on a cell to edit.
1041
- </Typography> : editLog.map((log, i) => <Typography key={i} level="body-xs">
1117
+ </Typography> : editLog.map(log => <Typography key={log} level="body-xs">
1042
1118
  {log}
1043
1119
  </Typography>)}
1044
1120
  </Box>
@@ -2,7 +2,9 @@
2
2
 
3
3
  ## Introduction
4
4
 
5
- InfoSign 컴포넌트는 사용자에게 추가 정보를 제공하기 위한 툴팁 아이콘입니다. 물음표 아이콘을 클릭하거나 호버할 상세한 설명이나 도움말을 표시할 있습니다. 필드, 설정 항목, 복잡한 기능에 대한 설명을 제공할 유용합니다.
5
+ InfoSign is a compact tooltip-trigger component that displays a small question-mark icon. When users hover over or focus on the icon, a tooltip appears with supplementary information. It is designed to provide contextual help without cluttering the interface -- ideal for explaining form fields, settings options, table column headers, and complex metrics.
6
+
7
+ The component accepts a `message` prop for the tooltip content and a `placement` prop to control where the tooltip appears relative to the icon. InfoSign keeps the main UI clean while ensuring that detailed guidance is always one interaction away.
6
8
 
7
9
  ```tsx
8
10
  <InfoSign
@@ -22,21 +24,19 @@ import { InfoSign } from '@ceed/cds';
22
24
 
23
25
  function MyComponent() {
24
26
  return (
25
- <div>
26
- <label>
27
- 복잡한 설정 항목
28
- <InfoSign message=" 설정은 시스템 전체 성능에 영향을 있습니다. 변경하기 전에 관리자와 상의하세요." />
29
- </label>
30
- </div>
27
+ <label>
28
+ Complex Setting
29
+ <InfoSign
30
+ message="This setting affects overall system performance. Consult an administrator before making changes."
31
+ />
32
+ </label>
31
33
  );
32
34
  }
33
35
  ```
34
36
 
35
- ## Examples
36
-
37
- ### Basic Usage
37
+ ## Basic
38
38
 
39
- 가장 기본적인 InfoSign 사용법입니다.
39
+ The default InfoSign displays a question-mark icon that reveals a tooltip on hover or focus.
40
40
 
41
41
  ```tsx
42
42
  <InfoSign
@@ -50,104 +50,87 @@ function MyComponent() {
50
50
  ### Form Field Help
51
51
 
52
52
  ```tsx
53
- <FormControl>
54
- <FormLabel>
55
- 비밀번호 복잡도
56
- <InfoSign
57
- message="비밀번호는 최소 8자 이상이며, 대문자, 소문자, 숫자, 특수문자를 포함해야 합니다."
58
- placement="top"
59
- />
60
- </FormLabel>
61
- <Input type="password" />
62
- </FormControl>
63
- ```
64
-
65
- ### Settings Explanation
53
+ import { InfoSign } from '@ceed/cds';
54
+ import { FormControl, FormLabel, Input } from '@ceed/cds';
66
55
 
67
- ```tsx
68
- <Stack spacing={2}>
69
- <Box>
70
- <Typography level="title-sm">
71
- 자동 저장
72
- <InfoSign message="이 기능을 활성화하면 5분마다 자동으로 작업 내용이 저장됩니다." placement="right" />
73
- </Typography>
74
- <Switch />
75
- </Box>
76
- </Stack>
56
+ function PasswordField() {
57
+ return (
58
+ <FormControl>
59
+ <FormLabel>
60
+ Password
61
+ <InfoSign
62
+ message="Must be at least 8 characters and include uppercase, lowercase, number, and special character."
63
+ placement="top"
64
+ />
65
+ </FormLabel>
66
+ <Input type="password" />
67
+ </FormControl>
68
+ );
69
+ }
77
70
  ```
78
71
 
79
- ### Complex Data Explanation
72
+ ### Table Column Header
80
73
 
81
74
  ```tsx
82
- <Card>
83
- <CardContent>
84
- <Typography level="title-md">
85
- 처리량 지표
86
- <InfoSign
87
- message="처리량은 최근 24시간 동안의 평균 요청 수를 나타냅니다. 이 값이 높을수록 시스템이 더 많은 작업을 처리하고 있다는 의미입니다."
88
- placement="bottom"
89
- />
90
- </Typography>
91
- <Typography level="h2">1,234 req/min</Typography>
92
- </CardContent>
93
- </Card>
94
- ```
95
-
96
- ### Table Header Help
75
+ import { InfoSign } from '@ceed/cds';
97
76
 
98
- ```tsx
99
- <Table>
100
- <thead>
101
- <tr>
102
- <th>
103
- 사용자 ID
104
- <InfoSign message="시스템에서 자동 생성된 고유 식별자입니다." />
105
- </th>
106
- <th>
107
- 마지막 활동
108
- <InfoSign message="사용자가 마지막으로 로그인하거나 활동한 시간입니다." />
109
- </th>
110
- <th>상태</th>
111
- </tr>
112
- </thead>
113
- </Table>
77
+ function TableHeader() {
78
+ return (
79
+ <thead>
80
+ <tr>
81
+ <th>
82
+ User ID
83
+ <InfoSign message="Auto-generated unique identifier assigned by the system." />
84
+ </th>
85
+ <th>
86
+ Last Activity
87
+ <InfoSign message="The most recent login or action timestamp for this user." />
88
+ </th>
89
+ <th>Status</th>
90
+ </tr>
91
+ </thead>
92
+ );
93
+ }
114
94
  ```
115
95
 
116
- ## Props
117
-
118
- ### placement
119
-
120
- 툴팁이 나타나는 위치를 설정할 수 있습니다.
96
+ ### Dashboard Metric Explanation
121
97
 
122
98
  ```tsx
123
- <InfoSign placement="top" message="위쪽에 표시" />
124
- <InfoSign placement="bottom" message="아래쪽에 표시" />
125
- <InfoSign placement="left" message="왼쪽에 표시" />
126
- <InfoSign placement="right" message="오른쪽에 표시" />
127
- ```
128
-
129
- ### message
99
+ import { InfoSign, Typography, Stack } from '@ceed/cds';
130
100
 
131
- 표시할 메시지 내용입니다. 긴 텍스트도 지원합니다.
132
-
133
- ```tsx
134
- <InfoSign message="여러 줄로 된 긴 설명문도 표시할 수 있습니다.\n줄바꿈도 지원되므로 상세한 설명을 제공할 수 있습니다." />
101
+ function MetricCard() {
102
+ return (
103
+ <Stack spacing={1}>
104
+ <Typography level="title-md">
105
+ Throughput
106
+ <InfoSign
107
+ message="Average requests per minute over the last 24 hours. Higher values indicate greater system load."
108
+ placement="right"
109
+ />
110
+ </Typography>
111
+ <Typography level="h2">1,234 req/min</Typography>
112
+ </Stack>
113
+ );
114
+ }
135
115
  ```
136
116
 
137
117
  ## Best Practices
138
118
 
139
- 1. **간결한 메시지**: 핵심 정보만 포함하여 사용자가 빠르게 이해할 있도록 합니다.
119
+ - **Keep messages concise.** Tooltip messages should be 1-2 sentences that quickly answer "what does this mean?" Avoid paragraphs of text.
120
+ - ✔ "Maximum file size per upload. Files exceeding this limit will be rejected."
121
+ - ✘ A multi-paragraph explanation with examples and edge cases
140
122
 
141
- 2. **적절한 배치**: 설명하려는 요소 바로 옆에 배치하여 연관성을 명확히 합니다.
123
+ - **Place InfoSign directly adjacent to the element it explains.** Position it immediately after a label or header text so users can easily associate the help icon with the relevant field.
142
124
 
143
- 3. **일관된 사용**: 비슷한 성격의 정보에는 일관되게 InfoSign을 사용합니다.
125
+ - **Do not overuse InfoSign.** Adding a help icon to every single field creates visual noise and suggests the interface itself is too confusing. Reserve it for genuinely complex or ambiguous items.
144
126
 
145
- 4. **과도한 사용 금지**: 모든 요소에 InfoSign을 붙이면 인터페이스가 복잡해집니다.
127
+ - **Choose placement that avoids overlap.** Use `placement="top"` or `placement="right"` for fields near the bottom of a viewport, and `placement="bottom"` for elements near the top.
146
128
 
147
- ## Accessibility
129
+ - **Use InfoSign for supplementary information only.** Critical instructions or warnings should be displayed inline (e.g., with FormHelperText or Alert), not hidden behind a tooltip.
148
130
 
149
- - InfoSign은 키보드 탐색이 가능합니다
150
- - 스크린 리더가 메시지 내용을 읽을 수 있습니다
151
- - ARIA 라벨이 자동으로 적용됩니다
131
+ ## Accessibility
152
132
 
153
- InfoSign 사용자에게 필요한 추가 정보를 제공하면서도 인터페이스를 깔끔하게 유지하는 도움이 되는 유용한 컴포넌트입니다.
133
+ - InfoSign is keyboard-focusable, allowing users to trigger the tooltip using **Tab** navigation without requiring a mouse.
134
+ - The tooltip content is announced by screen readers when the InfoSign receives focus, thanks to built-in ARIA attributes.
135
+ - The question-mark icon serves as a universally recognized visual cue for "more information," making it intuitive for all users.
136
+ - Ensure that the `message` text provides the same information available through other channels -- do not make the tooltip the only way to learn critical information.