@wipco/sdui 1.6.0 → 1.7.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 (98) hide show
  1. package/dist/{DatePicker-DX9juElE.d.ts → DatePicker-BOOKdd5x.d.ts} +6 -6
  2. package/dist/calendar-nav-BSGsgJc4.d.ts +54 -0
  3. package/dist/{chunk-53KS4E5N.js → chunk-27ILQUWE.js} +121 -28
  4. package/dist/{chunk-AY4GM6KQ.js → chunk-466W3XNK.js} +1 -1
  5. package/dist/{chunk-X2NIRVLN.js → chunk-4VQIKSDS.js} +157 -190
  6. package/dist/{chunk-LIZTK3HO.js → chunk-5FZBH3T5.js} +1 -1
  7. package/dist/{chunk-NA232CBX.js → chunk-5LIFU57A.js} +2 -2
  8. package/dist/{chunk-LKQJJSVJ.js → chunk-63GM4S25.js} +1 -1
  9. package/dist/{chunk-CSE3PZOZ.js → chunk-7EDFYBUA.js} +4 -4
  10. package/dist/{chunk-MN4RZ2WP.js → chunk-7YTZB5LQ.js} +3 -3
  11. package/dist/{chunk-WEG3V7ZB.js → chunk-7ZCM6XEM.js} +2 -2
  12. package/dist/{chunk-6XI2VF2O.js → chunk-A22QR6PM.js} +2 -2
  13. package/dist/{chunk-CEVZAFPO.js → chunk-A3SO6H47.js} +2 -2
  14. package/dist/{chunk-2KQL6DYG.js → chunk-AP33B24H.js} +65 -9
  15. package/dist/{chunk-FEKKOBPX.js → chunk-B5MB64YQ.js} +209 -25
  16. package/dist/{chunk-IQXLNICY.js → chunk-DCSUBFFG.js} +4 -4
  17. package/dist/{chunk-OUEJWC2Z.js → chunk-DILQ2DJV.js} +5 -5
  18. package/dist/{chunk-NAIWQQPW.js → chunk-ENZBX4AR.js} +1 -1
  19. package/dist/{chunk-WTIYILY3.js → chunk-FGKBXUUA.js} +1 -1
  20. package/dist/{chunk-CI5OZ2QT.js → chunk-FUNCQCKN.js} +2 -2
  21. package/dist/{chunk-XG22XKKD.js → chunk-GWT5UF5B.js} +2 -2
  22. package/dist/{chunk-K6RE23XX.js → chunk-H5QRRPBJ.js} +3 -3
  23. package/dist/{chunk-AZSLSAJB.js → chunk-JCG4575S.js} +2 -2
  24. package/dist/{chunk-YZTTFEL4.js → chunk-JMNUFA5M.js} +1 -1
  25. package/dist/{chunk-KZ6U6FKB.js → chunk-L6ODTHTX.js} +1 -1
  26. package/dist/{chunk-W4VA76QO.js → chunk-LKA43GYA.js} +1 -1
  27. package/dist/{chunk-6TI4WF5Y.js → chunk-LKL3SCBJ.js} +2 -2
  28. package/dist/{chunk-4OABUPIU.js → chunk-LN4KPZIX.js} +3 -3
  29. package/dist/chunk-MUXGTVEA.js +421 -0
  30. package/dist/{chunk-7C54CKFZ.js → chunk-MWBCQHKQ.js} +3 -3
  31. package/dist/{chunk-7JP52QQO.js → chunk-NI3LMETK.js} +2 -2
  32. package/dist/{chunk-HXLQSO66.js → chunk-NJTIJAFU.js} +2 -2
  33. package/dist/{chunk-YN7X7BEO.js → chunk-NQDHGK7C.js} +3 -3
  34. package/dist/{chunk-BLFJMMBW.js → chunk-OWM7E55U.js} +25 -2
  35. package/dist/{chunk-VPOOIEKT.js → chunk-P62INTQ5.js} +1 -1
  36. package/dist/{chunk-QVS6K4FP.js → chunk-Q56LZJFX.js} +1 -1
  37. package/dist/{chunk-BITS7UJY.js → chunk-R2ORCOTG.js} +2 -2
  38. package/dist/{chunk-2QXA52DG.js → chunk-RA74PUMP.js} +3 -3
  39. package/dist/{chunk-GSM664TX.js → chunk-TAVKGYH5.js} +24 -1
  40. package/dist/{chunk-OYDJHQNZ.js → chunk-UBVYPV7H.js} +2 -2
  41. package/dist/chunk-VR4DQTWR.js +391 -0
  42. package/dist/{chunk-M6H3SHIS.js → chunk-WPAZBAUW.js} +1 -1
  43. package/dist/{chunk-NWYYNE3Q.js → chunk-WTQH2NI2.js} +1 -1
  44. package/dist/{chunk-HRHKQOOF.js → chunk-X7RSKFWF.js} +1 -1
  45. package/dist/{chunk-CSZCWBOE.js → chunk-XDR6HC4U.js} +14 -7
  46. package/dist/{chunk-RU5U2YMT.js → chunk-Z4JZUIKE.js} +3 -3
  47. package/dist/{chunk-V7BWMOHO.js → chunk-Z4LFZWHH.js} +2 -2
  48. package/dist/{chunk-YNEEJCSZ.js → chunk-ZBX2CAOO.js} +2 -2
  49. package/dist/index.d.ts +57 -7
  50. package/dist/index.js +93 -37
  51. package/dist/meta.d.ts +1 -1
  52. package/dist/meta.js +129 -4
  53. package/dist/rich/ExcelUploadCard.js +4 -4
  54. package/dist/rich.d.ts +4 -2
  55. package/dist/rich.js +36 -8
  56. package/dist/styles.css +27 -0
  57. package/dist/{types-CYfIthux.d.ts → types-CMikpoN5.d.ts} +8 -1
  58. package/dist/widgets/ApprovalLineEditor.js +9 -8
  59. package/dist/widgets/ApprovalOverridesEditor.js +11 -10
  60. package/dist/widgets/ApprovalStepper.js +2 -2
  61. package/dist/widgets/AutocompleteField.js +9 -8
  62. package/dist/widgets/ColumnBoard.js +2 -2
  63. package/dist/widgets/DiffView.js +2 -2
  64. package/dist/widgets/Disclosure.js +2 -2
  65. package/dist/widgets/EventCalendar.d.ts +14 -10
  66. package/dist/widgets/EventCalendar.js +5 -3
  67. package/dist/widgets/FileDropzone.js +7 -7
  68. package/dist/widgets/ImageLightbox.js +5 -5
  69. package/dist/widgets/InlineEdit.js +2 -2
  70. package/dist/widgets/JsonField.js +2 -2
  71. package/dist/widgets/OptionSchemaEditor.js +3 -3
  72. package/dist/widgets/OptionValueFields.js +3 -3
  73. package/dist/widgets/OrgChart.js +3 -3
  74. package/dist/widgets/OrgChartBoard.d.ts +57 -4
  75. package/dist/widgets/OrgChartBoard.js +8 -8
  76. package/dist/widgets/PeriodFilter.js +6 -5
  77. package/dist/widgets/PermissionMatrixEditor.js +4 -4
  78. package/dist/widgets/PositionSelect.js +4 -4
  79. package/dist/widgets/PrintSheet.js +2 -2
  80. package/dist/widgets/ProfileEditDiffCard.js +4 -4
  81. package/dist/widgets/QRDisplay.js +4 -4
  82. package/dist/widgets/RankBoard.js +6 -6
  83. package/dist/widgets/RecordSheet.d.ts +48 -1
  84. package/dist/widgets/RecordSheet.js +2 -1
  85. package/dist/widgets/RoleMemberPicker.js +5 -5
  86. package/dist/widgets/SearchableMultiPicker.js +7 -6
  87. package/dist/widgets/SecureScreen.js +2 -2
  88. package/dist/widgets/StagePeriodEditor.js +6 -5
  89. package/dist/widgets/TagInput.js +2 -2
  90. package/dist/widgets/TagMultiSelect.js +4 -4
  91. package/dist/widgets/Timeline.js +3 -3
  92. package/dist/widgets/TreePicker.js +8 -7
  93. package/dist/widgets/TreeView.d.ts +16 -2
  94. package/dist/widgets/TreeView.js +7 -6
  95. package/dist/widgets/index.d.ts +1 -0
  96. package/dist/widgets/index.js +76 -75
  97. package/package.json +1 -1
  98. package/dist/chunk-IB2ZPUTF.js +0 -172
package/dist/index.js CHANGED
@@ -1,23 +1,24 @@
1
- export { loadOptionalModule } from './chunk-NWYYNE3Q.js';
2
- import { useSduiDispatch, SduiDialog, useSduiCan, useSduiRuntime, SduiDirtyRegistryContext, SduiLeaveRegistryContext, SduiFormScopeContext, SduiDispatchContext, SduiRuntimeContext, SduiPermissionProvider } from './chunk-CI5OZ2QT.js';
3
- export { SduiDialog, SduiPermissionProvider, useSduiCan, useSduiDispatch, useSduiRuntime } from './chunk-CI5OZ2QT.js';
4
- import { Text, Spacer, Show, Section, Row, PageHead, KeyValueList, Grid, Divider, Col, Actions } from './chunk-LIZTK3HO.js';
5
- export { Actions, Col, Divider, Grid, KeyValueList, PageHead, Row, Section, Show, Spacer, Text } from './chunk-LIZTK3HO.js';
6
- import { ImageViewer } from './chunk-AZSLSAJB.js';
7
- export { ImageViewer } from './chunk-AZSLSAJB.js';
8
- import { normalizeSearchFields, searchValuesFromParams, splitMultiValue, includesLooseSearch, cascadingValuePaths, SearchToolbar, searchFieldKeys, Popover } from './chunk-4OABUPIU.js';
9
- export { SearchToolbar, cascadingValuePaths, cleanSearchValues, includesLooseSearch, joinMultiValue, normalizeSearchText, searchFieldKeys, searchValuesFromParams, splitMultiValue } from './chunk-4OABUPIU.js';
10
- import { parseYmd, YMD_RE, TimePicker, DateRangePicker, DatePicker } from './chunk-X2NIRVLN.js';
11
- export { DatePicker, DateRangePicker, TimePicker } from './chunk-X2NIRVLN.js';
12
- import { OverlayContainerContext, OverlayLayer, useAnyModalOpen } from './chunk-BITS7UJY.js';
13
- export { OverlayContainerContext, OverlayLayer, getOverlayRoot, useAnyModalOpen, useOverlayLayer } from './chunk-BITS7UJY.js';
1
+ export { loadOptionalModule } from './chunk-WTQH2NI2.js';
2
+ import { useSduiDispatch, SduiDialog, useSduiCan, useSduiRuntime, SduiDirtyRegistryContext, SduiLeaveRegistryContext, SduiFormScopeContext, SduiDispatchContext, SduiRuntimeContext, SduiPermissionProvider } from './chunk-FUNCQCKN.js';
3
+ export { SduiDialog, SduiPermissionProvider, useSduiCan, useSduiDispatch, useSduiRuntime } from './chunk-FUNCQCKN.js';
4
+ import { Text, Spacer, Show, Section, Row, PageHead, KeyValueList, Grid, Divider, Col, Actions } from './chunk-5FZBH3T5.js';
5
+ export { Actions, Col, Divider, Grid, KeyValueList, PageHead, Row, Section, Show, Spacer, Text } from './chunk-5FZBH3T5.js';
6
+ import { ImageViewer } from './chunk-JCG4575S.js';
7
+ export { ImageViewer } from './chunk-JCG4575S.js';
8
+ import { normalizeSearchFields, searchValuesFromParams, splitMultiValue, includesLooseSearch, cascadingValuePaths, SearchToolbar, searchFieldKeys, Popover } from './chunk-LN4KPZIX.js';
9
+ export { SearchToolbar, cascadingValuePaths, cleanSearchValues, includesLooseSearch, joinMultiValue, normalizeSearchText, searchFieldKeys, searchValuesFromParams, splitMultiValue } from './chunk-LN4KPZIX.js';
10
+ import { parseYmd, YMD_RE, TimePicker, DateRangePicker, DatePicker } from './chunk-4VQIKSDS.js';
11
+ export { DatePicker, DateRangePicker, TimePicker } from './chunk-4VQIKSDS.js';
12
+ import './chunk-MUXGTVEA.js';
13
+ import { OverlayContainerContext, OverlayLayer, useAnyModalOpen } from './chunk-R2ORCOTG.js';
14
+ export { OverlayContainerContext, OverlayLayer, getOverlayRoot, useAnyModalOpen, useOverlayLayer } from './chunk-R2ORCOTG.js';
14
15
  import { HoistedStyle } from './chunk-RIZRM7OO.js';
15
- import { useSduiAdapter, hostFetchOf, isSafeNavigationTarget, useSduiSandbox, resolveAdapter, assetResolverOf, SduiAdapterContext } from './chunk-YNEEJCSZ.js';
16
- export { defaultAdapter, useSduiAssetResolver, useSduiSandbox } from './chunk-YNEEJCSZ.js';
17
- import { DEV, useIsMobile } from './chunk-GSM664TX.js';
18
- export { MOBILE_MEDIA_QUERY, useIsMobile } from './chunk-GSM664TX.js';
19
- import { EmptyState, Button, Checkbox, Select, Tabs, SegmentedControl, Spinner, Pagination, fieldOf, StatCard, isZonedIsoDateTime, formatDateValue, Icon, Card, Badge, ProgressBar, Tag, Toast, Textarea, Table, Switch, Input, IconButton, Field, Alert, warnOnce, isPlainObject, CALC_OPS, evaluateCalc, Dialog, ICON_NODES, toNumber } from './chunk-BLFJMMBW.js';
20
- export { Alert, Avatar, Badge, Breadcrumb, Button, CALC_OPS, Card, Checkbox, Dialog, EmptyState, Field, Icon, IconButton, Input, Pagination, ProgressBar, Radio, SegmentedControl, Select, SidebarNav, Spinner, StatCard, Switch, Table, Tabs, Tag, Textarea, Toast, Tooltip, formatDateValue, formatDisplayValue, formatNumberValue, isZonedIsoDateTime, parseNumeric } from './chunk-BLFJMMBW.js';
16
+ import { useSduiAdapter, hostFetchOf, isSafeNavigationTarget, useSduiSandbox, resolveAdapter, assetResolverOf, SduiAdapterContext } from './chunk-ZBX2CAOO.js';
17
+ export { defaultAdapter, useSduiAssetResolver, useSduiSandbox } from './chunk-ZBX2CAOO.js';
18
+ import { DEV, useIsMobile } from './chunk-TAVKGYH5.js';
19
+ export { MOBILE_MEDIA_QUERY, useIsMobile } from './chunk-TAVKGYH5.js';
20
+ import { EmptyState, Button, Checkbox, Select, Tabs, SegmentedControl, Spinner, Pagination, fieldOf, StatCard, isZonedIsoDateTime, formatDateValue, Icon, Card, Badge, ProgressBar, Tag, Toast, Textarea, Table, Switch, Input, IconButton, Field, Alert, warnOnce, isPlainObject, CALC_OPS, evaluateCalc, Dialog, ICON_NODES, toNumber } from './chunk-OWM7E55U.js';
21
+ export { Alert, Avatar, Badge, Breadcrumb, Button, CALC_OPS, Card, Checkbox, Dialog, EmptyState, Field, Icon, IconButton, Input, Pagination, ProgressBar, Radio, SegmentedControl, Select, SidebarNav, Spinner, StatCard, Switch, Table, Tabs, Tag, Textarea, Toast, Tooltip, formatDateValue, formatDisplayValue, formatNumberValue, isZonedIsoDateTime, parseNumeric } from './chunk-OWM7E55U.js';
21
22
  import { boxed, LAYOUT_CSS, childLayoutFrom, CHILD_LAYOUT_PROPS } from './chunk-3JTBOABA.js';
22
23
  export { CHILD_LAYOUT_PROPS, LAYOUT_CSS, boxed, childLayoutFrom, columnsClass, containerLayoutStyle, joinClass, mergeStyle, typographyStyle } from './chunk-3JTBOABA.js';
23
24
  import React9, { createContext, useState, useMemo, useEffect, useRef, useContext, useCallback, useSyncExternalStore } from 'react';
@@ -747,6 +748,7 @@ function ResultTable({
747
748
  onSort,
748
749
  onRowClick,
749
750
  selectedIds,
751
+ pickedIds,
750
752
  empty,
751
753
  virtual = false,
752
754
  height = 560,
@@ -767,6 +769,7 @@ function ResultTable({
767
769
  });
768
770
  if (!rows.length && empty) return /* @__PURE__ */ jsx(Fragment, { children: empty });
769
771
  const selectedSet = selectedIds && selectedIds.length > 0 ? new Set(selectedIds) : null;
772
+ const pickedSet = pickedIds && pickedIds.length > 0 ? new Set(pickedIds) : null;
770
773
  const unit = measured ?? rowHeight;
771
774
  const start = virtual ? Math.max(0, Math.floor(scrollTop / unit) - OVERSCAN) : 0;
772
775
  const end = virtual ? Math.min(rows.length, Math.ceil((scrollTop + height) / unit) + OVERSCAN) : rows.length;
@@ -783,6 +786,7 @@ function ResultTable({
783
786
  {
784
787
  style: { width: column.width, textAlign: column.align === "right" ? "right" : void 0 },
785
788
  "data-mobile": column.mobile,
789
+ "data-tablet": column.tablet,
786
790
  children: column.sortable && onSort ? (
787
791
  // 인라인 style로는 :hover를 표현할 수 없다 — 색 피드백은 .wp-table__sort:hover가 낸다
788
792
  /* @__PURE__ */ jsxs("button", { type: "button", className: "wp-table__sort", onClick: () => onSort(column.key), children: [
@@ -804,17 +808,21 @@ function ResultTable({
804
808
  rows.slice(start, end).map((row, offset) => {
805
809
  const index = start + offset;
806
810
  const selected = selectedSet ? selectedSet.has(row.id) : false;
811
+ const picked = pickedSet ? pickedSet.has(String(row.id)) : false;
807
812
  return /* @__PURE__ */ jsx(
808
813
  "tr",
809
814
  {
810
815
  ref: offset === 0 ? firstRowRef : void 0,
811
816
  "aria-selected": selected || void 0,
817
+ "aria-current": picked ? "true" : void 0,
818
+ className: picked ? "wp-row--selected" : void 0,
812
819
  onClick: onRowClick ? () => onRowClick(row) : void 0,
813
820
  style: onRowClick ? { cursor: "pointer" } : void 0,
814
821
  children: columns.map((column) => {
815
822
  const cls = [];
816
823
  if (column.align === "right") cls.push("wp-table__num");
817
824
  if (column.mono) cls.push("wp-table__mono");
825
+ if (column.nowrap) cls.push("wp-table__nowrap");
818
826
  if (column.strong) cls.push("wp-table__strong");
819
827
  const value = column.render ? column.render(row, index) : (
820
828
  // 평면 키 우선, 없으면 점 경로 — 셀 렌더러(cells.tsx)와 같은 조회 규칙이다
@@ -826,6 +834,7 @@ function ResultTable({
826
834
  className: cls.join(" ") || void 0,
827
835
  "data-label": labelOf(column),
828
836
  "data-mobile": column.mobile,
837
+ "data-tablet": column.tablet,
829
838
  children: isBlankCell(value) ? /* @__PURE__ */ jsx("span", { style: { color: "var(--wp-text-subtle)" }, children: "\u2014" }) : value
830
839
  },
831
840
  column.key
@@ -868,6 +877,15 @@ function ResultEmptyState({ title, filtered = false, emptyTitle, emptyText, scop
868
877
  }
869
878
  return /* @__PURE__ */ jsx(EmptyState, { title: emptyTitle || `${scoped ? "" : "\uC544\uC9C1 "}${name}${josaOf(name, "\uC774/\uAC00")} \uC5C6\uC2B5\uB2C8\uB2E4`, tight: true, children: emptyText || void 0 });
870
879
  }
880
+ function normalizeSelectedIds(ids) {
881
+ if (!Array.isArray(ids)) return [];
882
+ const out = [];
883
+ for (const id of ids) {
884
+ if (typeof id === "string" && id !== "") out.push(id);
885
+ else if (typeof id === "number" && Number.isFinite(id)) out.push(String(id));
886
+ }
887
+ return out;
888
+ }
871
889
  var EMPTY_FILTERS = [];
872
890
  var EMPTY_FIELDS = [];
873
891
  var PAGE_SIZE_CHOICES = [10, 20, 50, 100];
@@ -951,10 +969,13 @@ function SearchResults({
951
969
  primaryKey,
952
970
  emptyTitle,
953
971
  emptyText,
954
- serverFiltered = false
972
+ serverFiltered = false,
973
+ selectedIds
955
974
  }) {
956
975
  const hasActions = actions.length > 0;
957
976
  const isMobile = useIsMobile();
977
+ const pickedIds = normalizeSelectedIds(selectedIds);
978
+ const pickedSet = pickedIds.length > 0 ? new Set(pickedIds) : null;
958
979
  const advancedSearchFields = useMemo(
959
980
  () => normalizeSearchFields(rawAdvancedSearchFields),
960
981
  [rawAdvancedSearchFields]
@@ -1191,6 +1212,8 @@ function SearchResults({
1191
1212
  header: column.title,
1192
1213
  label: column.title,
1193
1214
  mobile: column.mobile ?? (column.key === titleColumnKey ? "title" : void 0),
1215
+ tablet: column.tablet,
1216
+ nowrap: column.nowrap,
1194
1217
  sortable: column.sortable && sortAllowed(column.key),
1195
1218
  align: column.textAlign === "right" ? "right" : "left",
1196
1219
  mono: column.mono,
@@ -1364,10 +1387,20 @@ function SearchResults({
1364
1387
  onSort: handleSort,
1365
1388
  onRowClick,
1366
1389
  selectedIds: hasActions ? Array.from(selected) : void 0,
1390
+ pickedIds: pickedSet ? pickedIds : void 0,
1367
1391
  empty,
1368
1392
  virtual: virtualListActive
1369
1393
  }
1370
- ) : visibleItems.length === 0 ? empty : /* @__PURE__ */ jsx("div", { className: "wp-grid wp-grid--3", children: visibleItems.map((row) => /* @__PURE__ */ jsx(GridCard, { item: row, config: gridConfig, onClick: onRowClick }, row.id)) }),
1394
+ ) : visibleItems.length === 0 ? empty : /* @__PURE__ */ jsx("div", { className: "wp-grid wp-grid--3", children: visibleItems.map((row) => /* @__PURE__ */ jsx(
1395
+ GridCard,
1396
+ {
1397
+ item: row,
1398
+ config: gridConfig,
1399
+ onClick: onRowClick,
1400
+ picked: pickedSet ? pickedSet.has(String(row.id)) : false
1401
+ },
1402
+ row.id
1403
+ )) }),
1371
1404
  virtualListActive && clientPaginated || totalCount === 0 && !isLoading ? null : /* @__PURE__ */ jsxs("div", { className: "wp-row wp-row--between", children: [
1372
1405
  /* @__PURE__ */ jsxs("div", { className: "wp-row", style: { flex: "none" }, children: [
1373
1406
  /* @__PURE__ */ jsx("span", { className: "wp-caption", style: { whiteSpace: "nowrap" }, children: "\uD398\uC774\uC9C0\uB2F9" }),
@@ -1419,7 +1452,8 @@ function resolveRowPart(part, item) {
1419
1452
  function GridCard({
1420
1453
  item,
1421
1454
  config,
1422
- onClick
1455
+ onClick,
1456
+ picked = false
1423
1457
  }) {
1424
1458
  if (!config) return null;
1425
1459
  const badge = config.badge?.(item) ?? null;
@@ -1436,6 +1470,7 @@ function GridCard({
1436
1470
  Card,
1437
1471
  {
1438
1472
  interactive: Boolean(onClick),
1473
+ ...picked ? { selected: true, className: "is-selected", "aria-current": "true" } : {},
1439
1474
  cover: config.cover?.(item),
1440
1475
  title: config.title(item),
1441
1476
  subtitle: config.subtitle?.(item),
@@ -1523,6 +1558,8 @@ function mapColumns(columns, dispatch) {
1523
1558
  mono: column.mono,
1524
1559
  strong: column.strong,
1525
1560
  mobile: column.mobile === "title" || column.mobile === "hide" ? column.mobile : void 0,
1561
+ tablet: column.tablet === "hide" ? "hide" : void 0,
1562
+ nowrap: column.nowrap === true ? true : void 0,
1526
1563
  render: cellRenderer(column.cell, column.key, dispatch)
1527
1564
  }));
1528
1565
  }
@@ -1627,7 +1664,8 @@ function SduiSearchResultsImpl({
1627
1664
  virtual,
1628
1665
  emptyTitle,
1629
1666
  emptyText,
1630
- queryStateKey
1667
+ queryStateKey,
1668
+ selectedIds
1631
1669
  }) {
1632
1670
  const dispatch = useSduiDispatch();
1633
1671
  const [params, setParams] = useState(() => new URLSearchParams());
@@ -1656,6 +1694,7 @@ function SduiSearchResultsImpl({
1656
1694
  primaryKey: gridCard?.titleKey,
1657
1695
  emptyTitle,
1658
1696
  emptyText,
1697
+ selectedIds,
1659
1698
  onRowClick: rowClick ? (row) => toList(rowClick).forEach((a) => dispatch(a, row)) : void 0,
1660
1699
  searchParams: params,
1661
1700
  onParamsChange: setParams
@@ -1687,7 +1726,8 @@ function RemoteSearchResultsImpl({
1687
1726
  summary,
1688
1727
  emptyTitle,
1689
1728
  emptyText,
1690
- queryStateKey
1729
+ queryStateKey,
1730
+ selectedIds
1691
1731
  }) {
1692
1732
  const dispatch = useSduiDispatch();
1693
1733
  const defaultPageSize = normalizePageSizes(pageSizes)?.[0] ?? 10;
@@ -1760,6 +1800,7 @@ function RemoteSearchResultsImpl({
1760
1800
  primaryKey: gridCard?.titleKey,
1761
1801
  emptyTitle,
1762
1802
  emptyText,
1803
+ selectedIds,
1763
1804
  summary: summary ? /* @__PURE__ */ jsx(SearchSummaryCards, { items: summary.items, values: summaryState.values, dispatch }) : void 0,
1764
1805
  onRowClick: rowClick ? (row) => toList(rowClick).forEach((a) => dispatch(a, row)) : void 0,
1765
1806
  searchParams: params,
@@ -3333,6 +3374,24 @@ function urlSeedSettled(state, seeded, baseline) {
3333
3374
  (key) => Object.is(state[key], seeded[key]) || !Object.is(state[key], baseline[key])
3334
3375
  );
3335
3376
  }
3377
+ function encodeUrlStateValue(value) {
3378
+ if (value === void 0 || value === null || value === "") return null;
3379
+ if (typeof value !== "string") return JSON.stringify(value);
3380
+ if (/^["[{]/.test(value)) return JSON.stringify(value);
3381
+ try {
3382
+ JSON.parse(value);
3383
+ return JSON.stringify(value);
3384
+ } catch {
3385
+ return value;
3386
+ }
3387
+ }
3388
+ function decodeUrlStateValue(raw) {
3389
+ try {
3390
+ return JSON.parse(raw);
3391
+ } catch {
3392
+ return raw;
3393
+ }
3394
+ }
3336
3395
  function SduiRenderer({
3337
3396
  page,
3338
3397
  registry = defaultRegistry,
@@ -3397,13 +3456,7 @@ function SduiRenderer({
3397
3456
  const seeded = {};
3398
3457
  for (const key of page.urlState) {
3399
3458
  const raw = params.get(key);
3400
- if (raw !== null) {
3401
- try {
3402
- seeded[key] = JSON.parse(raw);
3403
- } catch {
3404
- seeded[key] = raw;
3405
- }
3406
- }
3459
+ if (raw !== null) seeded[key] = decodeUrlStateValue(raw);
3407
3460
  }
3408
3461
  if (Object.keys(seeded).length > 0) {
3409
3462
  const baseline = {};
@@ -3433,16 +3486,19 @@ function SduiRenderer({
3433
3486
  const params = new URLSearchParams(window.location.search);
3434
3487
  let changed = false;
3435
3488
  for (const key of page.urlState) {
3436
- const value = state[key];
3437
- const serialized = value === void 0 || value === null || value === "" ? null : JSON.stringify(value);
3489
+ const serialized = encodeUrlStateValue(state[key]);
3490
+ const current = params.get(key);
3438
3491
  if (serialized === null) {
3439
- if (params.has(key)) {
3492
+ if (current !== null) {
3440
3493
  params.delete(key);
3441
3494
  changed = true;
3442
3495
  }
3443
- } else if (params.get(key) !== serialized) {
3444
- params.set(key, serialized);
3445
- changed = true;
3496
+ } else {
3497
+ const sameValue = current !== null && (current === serialized || encodeUrlStateValue(decodeUrlStateValue(current)) === serialized);
3498
+ if (!sameValue) {
3499
+ params.set(key, serialized);
3500
+ changed = true;
3501
+ }
3446
3502
  }
3447
3503
  }
3448
3504
  if (changed) {
package/dist/meta.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { b as SduiPropValue, i as SduiNode } from './types-CYfIthux.js';
1
+ import { b as SduiPropValue, i as SduiNode } from './types-CMikpoN5.js';
2
2
 
3
3
  /**
4
4
  * 시각 빌더용 컴포넌트 메타데이터 스키마.
package/dist/meta.js CHANGED
@@ -947,6 +947,39 @@ var ButtonMeta = {
947
947
  group: "behavior",
948
948
  advanced: true
949
949
  },
950
+ {
951
+ name: "aria-label",
952
+ kind: "string",
953
+ label: "\uC811\uADFC\uC131 \uB77C\uBCA8",
954
+ bindable: true,
955
+ description: "\uBCF4\uC774\uB294 \uAE00\uC790 \uC5C6\uC774 \uC544\uC774\uCF58\uB9CC \uC788\uB294 \uBC84\uD2BC \uB4F1 \u2014 \uC2A4\uD06C\uB9B0\uB9AC\uB354\uAC00 \uC77D\uC744 \uC774\uB984. \uD589\uB9C8\uB2E4 \uB2E4\uB974\uBA74 $calc/$item \uC73C\uB85C \uC5EE\uB294\uB2E4.",
956
+ group: "content",
957
+ advanced: true
958
+ },
959
+ {
960
+ name: "role",
961
+ kind: "enum",
962
+ label: "\uC811\uADFC\uC131 \uC5ED\uD560",
963
+ description: '\uBCF4\uC870\uAE30\uC220\uC5D0 \uBC84\uD2BC\uC744 \uB2E4\uB978 \uC5ED\uD560\uB85C \uC54C\uB9B0\uB2E4(\uB098\uBA38\uC9C0 \uD504\uB86D\uCC98\uB7FC <button>\uC5D0 \uADF8\uB300\uB85C \uC5B9\uD78C\uB2E4). \uB2E8\uC77C \uC120\uD0DD \uBB36\uC74C(Row/Col role="radiogroup") \uC548\uC758 \uC120\uD0DD\uC9C0 \uBC84\uD2BC\uC774 radio \uB2E4 \u2014 \uADF8\uB54C aria-checked \uB97C \uAC19\uC774 \uC900\uB2E4.',
964
+ options: [
965
+ { value: "radio", label: "\uB2E8\uC77C \uC120\uD0DD \uD56D\uBAA9(radio)" },
966
+ { value: "checkbox", label: "\uCF1C\uACE0 \uB044\uB294 \uD56D\uBAA9(checkbox)" },
967
+ { value: "switch", label: "\uC2A4\uC704\uCE58(switch)" },
968
+ { value: "tab", label: "\uD0ED(tab)" },
969
+ { value: "menuitem", label: "\uBA54\uB274 \uD56D\uBAA9(menuitem)" }
970
+ ],
971
+ group: "behavior",
972
+ advanced: true
973
+ },
974
+ {
975
+ name: "aria-checked",
976
+ kind: "boolean",
977
+ label: "\uC811\uADFC\uC131: \uC120\uD0DD\uB428",
978
+ bindable: true,
979
+ description: 'role \uC774 radio\xB7checkbox\xB7switch \uC77C \uB54C \uC774 \uBC84\uD2BC\uC774 \uACE8\uB77C\uC838 \uC788\uB294\uAC00. \uBCF4\uD1B5 \uC0C1\uD0DC\uC640 \uBE44\uAD50\uD574 \uC5EE\uB294\uB2E4 \u2014 {"$calc":{"op":"eq","args":[{"$item":"key"},{"$state":"filter"}]}}. \uBAA8\uC591\uC740 \uBC14\uAFB8\uC9C0 \uC54A\uC73C\uB2C8 variant \uB3C4 \uAC19\uC774 \uC5EE\uB294\uB2E4.',
980
+ group: "behavior",
981
+ advanced: true
982
+ },
950
983
  { name: "onClick", kind: "action", label: "\uD074\uB9AD", group: "behavior" },
951
984
  styleProp,
952
985
  classNameProp,
@@ -992,6 +1025,15 @@ var CheckboxMeta = {
992
1025
  group: "data"
993
1026
  },
994
1027
  { name: "disabled", kind: "boolean", label: "\uBE44\uD65C\uC131", default: false, bindable: true, group: "behavior" },
1028
+ {
1029
+ name: "aria-label",
1030
+ kind: "string",
1031
+ label: "\uC811\uADFC\uC131 \uB77C\uBCA8",
1032
+ bindable: true,
1033
+ description: "\uBCF4\uC774\uB294 \uB77C\uBCA8 \uC5C6\uC774 \uC0C1\uC790\uB9CC \uB458 \uB54C(\uD45C \uCE78\xB7\uBC18\uBCF5 \uD589) \uC2A4\uD06C\uB9B0\uB9AC\uB354\uAC00 \uC77D\uC744 \uC774\uB984 \u2014 \uC228\uC740 <input>\uC5D0 \uBD99\uB294\uB2E4. \uD589\uB9C8\uB2E4 \uB2E4\uB974\uBA74 $calc/$item \uC73C\uB85C \uC5EE\uB294\uB2E4.",
1034
+ group: "content",
1035
+ advanced: true
1036
+ },
995
1037
  classNameProp
996
1038
  ],
997
1039
  children: { accepts: false },
@@ -1348,6 +1390,15 @@ var IconButtonMeta = {
1348
1390
  },
1349
1391
  { name: "onClick", kind: "action", label: "\uD074\uB9AD", group: "behavior" },
1350
1392
  { name: "disabled", kind: "boolean", label: "\uBE44\uD65C\uC131", default: false, bindable: true, group: "behavior" },
1393
+ {
1394
+ name: "aria-label",
1395
+ kind: "string",
1396
+ label: "\uC811\uADFC\uC131 \uB77C\uBCA8(\uB9CC)",
1397
+ bindable: true,
1398
+ description: "\uD234\uD301(title) \uC5C6\uC774 \uC2A4\uD06C\uB9B0\uB9AC\uB354 \uC774\uB984\uB9CC \uC904 \uB54C. \uBCF4\uD1B5\uC740 label \uD558\uB098\uBA74 \uB41C\uB2E4(aria-label\xB7title \uB458 \uB2E4 \uB41C\uB2E4). \uB458 \uB2E4 \uC8FC\uBA74 aria-label \uC740 \uC774\uCABD\uC774 \uC774\uAE34\uB2E4.",
1399
+ group: "content",
1400
+ advanced: true
1401
+ },
1351
1402
  styleProp,
1352
1403
  classNameProp
1353
1404
  ],
@@ -1414,6 +1465,15 @@ var InputMeta = {
1414
1465
  { name: "max", kind: "number", label: "\uCD5C\uB300\uAC12", description: "type=number/date\uC758 \uC0C1\uD55C", group: "validation" },
1415
1466
  { name: "step", kind: "number", label: "\uC99D\uAC10 \uB2E8\uC704", group: "validation", advanced: true },
1416
1467
  { name: "title", kind: "string", label: "\uD234\uD301", group: "content", advanced: true },
1468
+ {
1469
+ name: "aria-label",
1470
+ kind: "string",
1471
+ label: "\uC811\uADFC\uC131 \uB77C\uBCA8",
1472
+ bindable: true,
1473
+ description: "Field \uB77C\uBCA8\uC774 \uC5C6\uC744 \uB54C(\uD45C \uCE78\xB7\uBC18\uBCF5 \uD589\uC758 \uC785\uB825) \uC2A4\uD06C\uB9B0\uB9AC\uB354\uAC00 \uC77D\uC744 \uC774\uB984. \uD589\uB9C8\uB2E4 \uB2E4\uB974\uBA74 $calc/$item \uC73C\uB85C \uC5EE\uB294\uB2E4.",
1474
+ group: "content",
1475
+ advanced: true
1476
+ },
1417
1477
  {
1418
1478
  name: "trailing",
1419
1479
  kind: "icon",
@@ -1541,6 +1601,15 @@ var SwitchMeta = {
1541
1601
  group: "appearance"
1542
1602
  },
1543
1603
  { name: "disabled", kind: "boolean", label: "\uBE44\uD65C\uC131", default: false, bindable: true, group: "behavior" },
1604
+ {
1605
+ name: "aria-label",
1606
+ kind: "string",
1607
+ label: "\uC811\uADFC\uC131 \uB77C\uBCA8",
1608
+ bindable: true,
1609
+ description: '\uBCF4\uC774\uB294 \uB77C\uBCA8 \uC5C6\uC774 \uD1A0\uAE00\uB9CC \uB458 \uB54C \uC2A4\uD06C\uB9B0\uB9AC\uB354\uAC00 \uC77D\uC744 \uC774\uB984 \u2014 \uC228\uC740 <input role="switch">\uC5D0 \uBD99\uB294\uB2E4.',
1610
+ group: "content",
1611
+ advanced: true
1612
+ },
1544
1613
  classNameProp
1545
1614
  ],
1546
1615
  children: { accepts: false },
@@ -1619,6 +1688,14 @@ var BadgeMeta = {
1619
1688
  ],
1620
1689
  group: "appearance"
1621
1690
  },
1691
+ {
1692
+ name: "wrap",
1693
+ kind: "boolean",
1694
+ label: "\uC904\uBC14\uAFC8",
1695
+ default: false,
1696
+ description: "\uAE34 \uBB38\uAD6C\uB97C \uD55C \uC904\uB85C \uB450\uC9C0 \uC54A\uACE0 \uCE78 \uD3ED \uC548\uC5D0\uC11C \uC5EC\uB7EC \uC904\uB85C \uAC10\uC2FC\uB2E4(\uB192\uC774\uB294 \uAE00\uC5D0 \uB9DE\uCDB0 \uB298\uC5B4\uB09C\uB2E4).",
1697
+ group: "appearance"
1698
+ },
1622
1699
  classNameProp
1623
1700
  ],
1624
1701
  children: { accepts: true, text: true, label: "\uBC30\uC9C0 \uBB38\uAD6C" },
@@ -2207,6 +2284,19 @@ var searchCommonProps = [
2207
2284
  { value: "hide", label: "\uBAA8\uBC14\uC77C\uC5D0\uC11C \uC228\uAE40" }
2208
2285
  ]
2209
2286
  },
2287
+ {
2288
+ name: "nowrap",
2289
+ kind: "boolean",
2290
+ label: "\uC904\uBC14\uAFC8 \uC548 \uD568",
2291
+ description: "\uD45C \uCE78\uC758 \uAE00\uC790\uB97C \uD55C \uC904\uB85C \uB454\uB2E4(white-space:nowrap) \u2014 \uB0A0\uC9DC\xB7\uBC88\uD638\uCC98\uB7FC \uB450 \uC904\uB85C \uAC08\uB77C\uC9C0\uBA74 \uC77D\uAE30 \uC5B4\uB824\uC6B4 \uC9E7\uC740 \uAC12\uC5D0. \uD3ED\uC774 \uBAA8\uC790\uB77C\uBA74 \uD45C\uAC00 \uC606\uC73C\uB85C \uBC00\uB9B0\uB2E4(\uAC00\uB85C \uC2A4\uD06C\uB864 \uC0C1\uC790). \uBAA8\uBC14\uC77C \uD589 \uCE74\uB4DC\uC5D0\uB294 \uAC78\uB9AC\uC9C0 \uC54A\uB294\uB2E4."
2292
+ },
2293
+ {
2294
+ name: "tablet",
2295
+ kind: "enum",
2296
+ label: "\uD0DC\uBE14\uB9BF \uD45C\uC5D0\uC11C",
2297
+ description: "\uD0DC\uBE14\uB9BF \uD3ED(768\u20131023px)\uC758 \uD45C\uC5D0\uC11C \uC774 \uC5F4\uC744 \uBE80\uB2E4(hide). \uBAA8\uBC14\uC77C \uCE74\uB4DC \uC5ED\uD560(mobile)\uACFC \uB530\uB85C\uB2E4 \u2014 \uD0DC\uBE14\uB9BF \uD45C\uC5D0\uC11C \uB118\uCE58\uB294 \uAE34 \uBAA9\uB85D \uC5F4\uC744 \uBE7C\uB3C4 \uD3F0 \uCE74\uB4DC\uC5D0\uB294 \uB0A8\uAE38 \uC218 \uC788\uB2E4. \uC0DD\uB7B5\uD558\uBA74 \uD0DC\uBE14\uB9BF\uC5D0\uC11C\uB3C4 \uBCF4\uC778\uB2E4. \uB370\uC2A4\uD06C\uD1B1\uC740 \uC5B8\uC81C\uB098 \uADF8\uB300\uB85C\uB2E4.",
2298
+ options: [{ value: "hide", label: "\uD0DC\uBE14\uB9BF\uC5D0\uC11C \uC228\uAE40" }]
2299
+ },
2210
2300
  {
2211
2301
  name: "cell",
2212
2302
  kind: "object",
@@ -2425,6 +2515,14 @@ var searchCommonProps = [
2425
2515
  advanced: true
2426
2516
  },
2427
2517
  { name: "rowClick", kind: "action", label: "\uD589 \uD074\uB9AD", eventArg: "\uD589 \uAC1D\uCCB4 \uC804\uCCB4", group: "behavior" },
2518
+ {
2519
+ name: "selectedIds",
2520
+ kind: "binding",
2521
+ label: "\uAC15\uC870\uD560 \uD589 id",
2522
+ bindable: true,
2523
+ description: '\uC774 id \uB4E4\uC758 \uD589(\uBAA9\uB85D)\xB7\uCE74\uB4DC(\uCE74\uB4DC \uBCF4\uAE30)\uB97C \uAC15\uC870\uD55C\uB2E4 \u2014 \uD45C\uC2DC \uC804\uC6A9\uC774\uB77C \uCCB4\uD06C\uBC15\uC2A4 \uC120\uD0DD\xB7\uC77C\uAD04 \uC561\uC158\uACFC \uBB34\uAD00\uD558\uB2E4. \uC606 \uCC3D\uC5D0 \uC5F4\uC5B4 \uB454 \uD589\uC744 \uAC00\uB9AC\uD0AC \uB54C [{"$state":"rt.$picked.id"}]\uCC98\uB7FC \uC900\uB2E4. \uBE44\uC5B4 \uC788\uAC70\uB098 null \uC778 \uC6D0\uC18C\uB294 \uBB34\uC2DC\uD55C\uB2E4.',
2524
+ group: "data"
2525
+ },
2428
2526
  {
2429
2527
  name: "virtual",
2430
2528
  kind: "boolean",
@@ -2432,7 +2530,9 @@ var searchCommonProps = [
2432
2530
  description: "true\uBA74 150\uD589\uBD80\uD130. \uC22B\uC790\uB97C \uC8FC\uBA74 \uADF8 \uAC12\uC774 \uC784\uACC4 \uD589\uC218\uAC00 \uB41C\uB2E4.",
2433
2531
  group: "behavior",
2434
2532
  advanced: true
2435
- }
2533
+ },
2534
+ // 뿌리 상자(boxed)에 붙는다 — 소비 앱 시트의 옵트인 훅 자리(열 단위 태블릿 숨김은 이제 columns[].tablet).
2535
+ classNameProp
2436
2536
  ];
2437
2537
  var searchSlots = [
2438
2538
  {
@@ -3523,7 +3623,7 @@ var ChartMeta = {
3523
3623
  kind: "boolean",
3524
3624
  label: "x\uCD95 \uB77C\uBCA8 \uBAA8\uB450 \uBCF4\uC774\uAE30",
3525
3625
  default: false,
3526
- description: "\uB9C9\uB300/\uC120 \uCC28\uD2B8 \uC804\uC6A9. \uAE34 \uBC94\uC8FC \uB77C\uBCA8(\uBCF8\uBD80\uBA85 \uB4F1)\uC744 \uCE78 \uD3ED\uC5D0 \uB9DE\uCDB0 \uCD5C\uB300 3\uC904\uB85C \uC904\uBC14\uAFC8\uD558\uACE0, \uADF8\uB798\uB3C4 \uBAA8\uC790\uB77C\uBA74 45\xB0 \uAE30\uC6B8\uC5EC \uC804\uBD80 \uBCF4\uC778\uB2E4. \uB044\uBA74 \uACB9\uCE58\uB294 \uB77C\uBCA8\uC744 \uAC74\uB108\uB6F4\uB2E4.",
3626
+ description: "\uB9C9\uB300/\uC120 \uCC28\uD2B8 \uC804\uC6A9. \uAE34 \uBC94\uC8FC \uB77C\uBCA8(\uBCF8\uBD80\uBA85 \uB4F1)\uC744 \uCE78 \uD3ED\uC5D0 \uB9DE\uCDB0 \uCD5C\uB300 3\uC904\uB85C \uC904\uBC14\uAFC8\uD558\uACE0, \uADF8\uB798\uB3C4 \uBAA8\uC790\uB77C\uBA74 45\xB0 \uAE30\uC6B8\uC5EC \uC804\uBD80 \uBCF4\uC778\uB2E4(\uAE30\uC6B8\uC774\uBA74 \uCCAB \uB77C\uBCA8\uC774 \uC798\uB9AC\uC9C0 \uC54A\uAC8C \uC67C\uCABD \uC5EC\uBC31\uC744 \uB77C\uBCA8 \uAE38\uC774\uB9CC\uD07C \uB298\uB9B0\uB2E4). \uB044\uBA74 \uACB9\uCE58\uB294 \uB77C\uBCA8\uC744 \uAC74\uB108\uB6F4\uB2E4.",
3527
3627
  group: "appearance"
3528
3628
  }
3529
3629
  ],
@@ -5379,6 +5479,14 @@ var ImageLightboxMeta = {
5379
5479
  description: "\uAE30\uBCF8 \uC378\uB124\uC77C <img>\uC5D0 \uBD99\uB294\uB2E4. \uCEE4\uC2A4\uD140 \uD2B8\uB9AC\uAC70(\uC790\uC2DD)\uB97C \uC8FC\uBA74 \uC4F0\uC774\uC9C0 \uC54A\uB294\uB2E4.",
5380
5480
  group: "layout",
5381
5481
  advanced: true
5482
+ },
5483
+ {
5484
+ name: "thumbStyle",
5485
+ kind: "object",
5486
+ label: "\uC378\uB124\uC77C \uC2A4\uD0C0\uC77C",
5487
+ description: '\uAE30\uBCF8 \uC378\uB124\uC77C <img>\uC5D0 \uC5B9\uB294 CSS \uC18D\uC131 \uAC1D\uCCB4(\uD06C\uAE30\xB7\uB9DE\uCDA4\xB7\uBAA8\uC11C\uB9AC \u2014 \uC608: {"width":96,"height":96,"objectFit":"cover"}). \uCEE4\uC2A4\uD140 \uD2B8\uB9AC\uAC70(\uC790\uC2DD)\uB97C \uC8FC\uBA74 \uC4F0\uC774\uC9C0 \uC54A\uB294\uB2E4. \uCEF4\uD3EC\uB10C\uD2B8 \uC790\uCCB4\uC758 \uD3ED\xB7\uC5EC\uBC31\uC740 \uC790\uAE30 \uCD95(width\xB7marginTop \u2026)\uC73C\uB85C.',
5488
+ group: "layout",
5489
+ advanced: true
5382
5490
  }
5383
5491
  ],
5384
5492
  children: { accepts: true, label: "\uCEE4\uC2A4\uD140 \uD2B8\uB9AC\uAC70 \u2014 \uC0DD\uB7B5\uD558\uBA74 \uAE30\uBCF8 \uC378\uB124\uC77C\uC774 \uADF8\uB824\uC9C4\uB2E4" },
@@ -5775,6 +5883,14 @@ var EventCalendarMeta = {
5775
5883
  description: "\uC8FC\uBA74 \uC81C\uC5B4 \uBAA8\uB4DC\uAC00 \uB41C\uB2E4.",
5776
5884
  group: "data",
5777
5885
  advanced: true
5886
+ },
5887
+ {
5888
+ name: "className",
5889
+ kind: "string",
5890
+ label: "\uCD94\uAC00 \uD074\uB798\uC2A4",
5891
+ description: "\uB2EC\uB825 \uBFCC\uB9AC \uC0C1\uC790\uC5D0 \uB367\uBD99\uB294\uB2E4 \u2014 \uC18C\uBE44 \uC571 \uC2DC\uD2B8\uAC00 \uB2EC\uB825 \uC548\uCABD\uC744 \uB2E4\uB4EC\uB294 \uD6C5 \uC790\uB9AC.",
5892
+ group: "layout",
5893
+ advanced: true
5778
5894
  }
5779
5895
  ],
5780
5896
  children: { accepts: false },
@@ -5964,7 +6080,7 @@ var TreeViewMeta = {
5964
6080
  kind: "string",
5965
6081
  label: "\uC120\uD0DD\uB41C \uB178\uB4DC id",
5966
6082
  bindable: true,
5967
- description: "\uC8FC\uBA74 \uC81C\uC5B4 \uBAA8\uB4DC\uAC00 \uB41C\uB2E4 \u2014 \uB0B4\uBD80 \uC120\uD0DD \uC0C1\uD0DC\uB97C \uC4F0\uC9C0 \uC54A\uB294\uB2E4.",
6083
+ description: "\uC8FC\uBA74 \uC81C\uC5B4 \uBAA8\uB4DC\uAC00 \uB41C\uB2E4 \u2014 \uB0B4\uBD80 \uC120\uD0DD \uC0C1\uD0DC\uB97C \uC4F0\uC9C0 \uC54A\uB294\uB2E4. \uAC12\uC774 \uBC14\uB00C\uBA74(\uB525\uB9C1\uD06C\xB7\uD558\uC704 \uD45C\uC5D0\uC11C \uB0B4\uB824\uAC10) \uC811\uD78C \uC870\uC0C1\uC744 \uD3BC\uCE58\uACE0 \uADF8 \uD589\uC744 \uD2B8\uB9AC \uC2A4\uD06C\uB864 \uC548\uC73C\uB85C \uAC00\uC838\uC628\uB2E4. \uAC19\uC740 \uC120\uD0DD\uC5D0\uC11C \uC0AC\uC6A9\uC790\uAC00 \uC811\uC740 \uAC83\uC740 \uADF8\uB300\uB85C \uB454\uB2E4.",
5968
6084
  group: "data"
5969
6085
  },
5970
6086
  { name: "onSelect", kind: "action", label: "\uB178\uB4DC \uC120\uD0DD", eventArg: "\uC120\uD0DD\uB41C \uB178\uB4DC id", group: "behavior" },
@@ -6213,7 +6329,16 @@ var SecureScreenMeta = {
6213
6329
  description: "false\uBA74 \uC544\uBB34 \uC81C\uC57D \uC5C6\uC774 \uC790\uC2DD\uC744 \uADF8\uB300\uB85C \uADF8\uB9B0\uB2E4.",
6214
6330
  group: "behavior"
6215
6331
  },
6216
- { name: "notice", kind: "string", label: "\uAC00\uB9BC\uB9C9 \uBB38\uAD6C", group: "content" }
6332
+ { name: "notice", kind: "string", label: "\uAC00\uB9BC\uB9C9 \uBB38\uAD6C", group: "content" },
6333
+ {
6334
+ name: "documentWideKeys",
6335
+ kind: "boolean",
6336
+ label: "\uBB38\uC11C \uC804\uCCB4 \uB2E8\uCD95\uD0A4 \uCC28\uB2E8",
6337
+ default: true,
6338
+ description: "Ctrl/Cmd+A\xB7C\xB7P\xB7S\xB7U\xB7X \uCC28\uB2E8\uC744 \uBB38\uC11C \uC804\uCCB4\uC5D0 \uAC74\uB2E4(\uB798\uD37C \uBC16\uC5D0\uC11C \uC804\uCCB4\uC120\uD0DD\u2192\uBCF5\uC0AC \uC6B0\uD68C\uB97C \uB9C9\uB294\uB2E4). \uD398\uC774\uC9C0 \uC77C\uBD80\uB9CC \uAC10\uC2F8\uB294 \uD654\uBA74\uC5D0\uC11C \uBCF4\uD638 \uB300\uC0C1 \uC544\uB2CC \uC785\uB825\uC758 \uBCF5\uC0AC\xB7\uC800\uC7A5\uAE4C\uC9C0 \uB9C9\uC9C0 \uC54A\uC73C\uB824\uBA74 \uB048\uB2E4 \u2014 \uADF8\uB54C\uB294 \uB798\uD37C \uC548\uC5D0\uC11C \uB204\uB978 \uC870\uD569\uB9CC \uB9C9\uB294\uB2E4.",
6339
+ group: "behavior",
6340
+ advanced: true
6341
+ }
6217
6342
  ],
6218
6343
  children: { accepts: true, text: true, label: "\uBCF4\uD638\uD560 \uB0B4\uC6A9" },
6219
6344
  dom: { element: "div" },
@@ -1,7 +1,7 @@
1
- import { loadOptionalModule } from '../chunk-NWYYNE3Q.js';
2
- import { useSduiAdapter, useSduiSandbox, hostFetchOf, defaultAdapter, hostRawFetchOf } from '../chunk-YNEEJCSZ.js';
3
- import '../chunk-GSM664TX.js';
4
- import { Select, Input, Card, Button, Spinner, Icon, Alert, StatCard, Badge, Table, EmptyState } from '../chunk-BLFJMMBW.js';
1
+ import { loadOptionalModule } from '../chunk-WTQH2NI2.js';
2
+ import { useSduiAdapter, useSduiSandbox, hostFetchOf, defaultAdapter, hostRawFetchOf } from '../chunk-ZBX2CAOO.js';
3
+ import '../chunk-TAVKGYH5.js';
4
+ import { Select, Input, Card, Button, Spinner, Icon, Alert, StatCard, Badge, Table, EmptyState } from '../chunk-OWM7E55U.js';
5
5
  import { boxed } from '../chunk-3JTBOABA.js';
6
6
  import { useRef, useState, useMemo, useCallback } from 'react';
7
7
  import { jsx, jsxs } from 'react/jsx-runtime';
package/dist/rich.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import React__default from 'react';
2
- export { b as DatePicker, D as DatePickerProps, c as DateRangePicker, a as DateRangePickerProps, d as DateRangeValue, e as TimePicker, T as TimePickerProps } from './DatePicker-DX9juElE.js';
2
+ export { b as DatePicker, D as DatePickerProps, c as DateRangePicker, a as DateRangePickerProps, d as DateRangeValue, e as TimePicker, T as TimePickerProps } from './DatePicker-BOOKdd5x.js';
3
3
  import './layout-DmRikwZb.js';
4
+ import './calendar-nav-BSGsgJc4.js';
4
5
 
5
6
  /**
6
7
  * Chart — 선언형 recharts 래퍼 (ERP `app/components/widgets/Chart.tsx` 이식).
@@ -73,7 +74,8 @@ interface ChartProps {
73
74
  integer?: boolean;
74
75
  /**
75
76
  * x축 범주 라벨을 **모두** 보인다. 긴 라벨은 칸 폭에 맞춰 줄을 바꾸고(최대 3줄),
76
- * 그래도 모자라면 45° 기울인다. 칸이 그보다도 좁으면 겹치는 라벨만 건너뛴다(기본 동작).
77
+ * 그래도 모자라면 45° 기울인다(첫 라벨들이 왼쪽 밖으로 잘리지 않게 왼쪽 여백을 늘린다).
78
+ * 칸이 그보다도 좁으면 겹치는 라벨만 건너뛴다(기본 동작).
77
79
  * 끄면(기본) recharts가 겹치는 라벨을 건너뛴다 — 본부명처럼 긴 범주에서 라벨이 사라진다.
78
80
  */
79
81
  xTickWrap?: boolean;
package/dist/rich.js CHANGED
@@ -1,10 +1,11 @@
1
- import { useOptionalModule, DependencyPlaceholder } from './chunk-NWYYNE3Q.js';
2
- export { DatePicker, DateRangePicker, TimePicker } from './chunk-X2NIRVLN.js';
3
- import './chunk-BITS7UJY.js';
1
+ import { useOptionalModule, DependencyPlaceholder } from './chunk-WTQH2NI2.js';
2
+ export { DatePicker, DateRangePicker, TimePicker } from './chunk-4VQIKSDS.js';
3
+ import './chunk-MUXGTVEA.js';
4
+ import './chunk-R2ORCOTG.js';
4
5
  import { HoistedStyle } from './chunk-RIZRM7OO.js';
5
- import { useSduiAssetResolver } from './chunk-YNEEJCSZ.js';
6
- import './chunk-GSM664TX.js';
7
- import { Spinner, EmptyState } from './chunk-BLFJMMBW.js';
6
+ import { useSduiAssetResolver } from './chunk-ZBX2CAOO.js';
7
+ import './chunk-TAVKGYH5.js';
8
+ import { Spinner, EmptyState } from './chunk-OWM7E55U.js';
8
9
  import './chunk-3JTBOABA.js';
9
10
  import { useRef, useCallback, useMemo, useState, useEffect, useLayoutEffect } from 'react';
10
11
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
@@ -182,6 +183,31 @@ function planXTicks(labels, bandWidth, measure) {
182
183
  }
183
184
  return { mode: "skip" };
184
185
  }
186
+ var ROTATE_EDGE_PAD = 2;
187
+ function rotatedTickInset(widths, axisWidth, span, point = false) {
188
+ const n = widths.length;
189
+ if (n === 0 || !(span > 0)) return 0;
190
+ let inset = 0;
191
+ widths.forEach((width, i) => {
192
+ const f = point ? n > 1 ? i / (n - 1) : 0.5 : (i + 0.5) / n;
193
+ if (f >= 1) return;
194
+ const reach = (width + TICK_FONT / 2) * Math.SQRT1_2 + ROTATE_EDGE_PAD;
195
+ const need = (reach - axisWidth - span * f) / (1 - f);
196
+ if (need > inset) inset = need;
197
+ });
198
+ return Math.ceil(inset);
199
+ }
200
+ var ROTATE_MIN_BAND = TICK_FONT * 1.25 / Math.SQRT1_2;
201
+ function planXTicksWithInset(labels, span, axisWidth, measure, point = false) {
202
+ const count = Math.max(1, labels.length);
203
+ const plan = planXTicks(labels, span / count, measure);
204
+ if (plan.mode !== "rotate") return { plan, inset: 0 };
205
+ const want = rotatedTickInset(labels.map((label) => measure(label)), axisWidth, span, point);
206
+ const inset = Math.max(0, Math.min(want, Math.floor(span - count * ROTATE_MIN_BAND)));
207
+ if (inset === 0) return { plan, inset: 0 };
208
+ const narrowed = planXTicks(labels, (span - inset) / count, measure);
209
+ return narrowed.mode === "rotate" ? { plan: narrowed, inset } : { plan, inset: 0 };
210
+ }
185
211
  var tooltipBoxStyle = {
186
212
  background: "var(--wp-surface-card)",
187
213
  border: "1px solid var(--wp-border-subtle)",
@@ -614,8 +640,10 @@ function Chart({
614
640
  let xTick = {};
615
641
  if (xTickWrap && hostBox.width > 0) {
616
642
  const labels = rows.map((row) => String((xKey ? row[xKey] : void 0) ?? ""));
617
- const plotWidth = hostBox.width - margin.left - margin.right - Y_AXIS_WIDTH * (dual ? 2 : 1);
618
- const plan = planXTicks(labels, plotWidth / Math.max(1, labels.length), makeMeasure(hostBox.fontFamily));
643
+ const measure = makeMeasure(hostBox.fontFamily);
644
+ const span = hostBox.width - margin.right - Y_AXIS_WIDTH * (dual ? 2 : 1);
645
+ const { plan, inset } = planXTicksWithInset(labels, span - margin.left, Y_AXIS_WIDTH, measure, !hasBar);
646
+ margin.left += inset;
619
647
  if (plan.mode !== "skip") {
620
648
  xTick = { interval: 0, height: plan.height, tick: renderCategoryTick(plan) };
621
649
  }