@simplysm/angular 14.0.55 → 14.0.57

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.
@@ -410,7 +410,7 @@ export class SdSheet {
410
410
  // Inputs
411
411
  key = input(...(ngDevMode ? [undefined, { debugName: "key" }] : /* istanbul ignore next */ []));
412
412
  items = input([], ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
413
- trackByFn = input.required(...(ngDevMode ? [{ debugName: "trackByFn" }] : /* istanbul ignore next */ []));
413
+ trackByFn = input((item) => item, ...(ngDevMode ? [{ debugName: "trackByFn" }] : /* istanbul ignore next */ []));
414
414
  selectMode = input(...(ngDevMode ? [undefined, { debugName: "selectMode" }] : /* istanbul ignore next */ []));
415
415
  autoSelect = input(...(ngDevMode ? [undefined, { debugName: "autoSelect" }] : /* istanbul ignore next */ []));
416
416
  getItemSelectableFn = input(...(ngDevMode ? [undefined, { debugName: "getItemSelectableFn" }] : /* istanbul ignore next */ []));
@@ -1053,5 +1053,5 @@ export class SdSheet {
1053
1053
  <div class="_select-row-indicator-container"></div>
1054
1054
  </div>
1055
1055
  `, styles: ["sd-sheet {\n border: 1px solid var(--theme-gray-lighter);\n border-radius: var(--border-radius-default);\n}\nsd-sheet > ._tool {\n background: var(--control-color);\n border-top-left-radius: var(--border-radius-default);\n border-top-right-radius: var(--border-radius-default);\n border-bottom: 1px solid var(--theme-gray-lighter);\n}\nsd-sheet > ._sheet-container {\n position: relative;\n background: var(--sheet-bg);\n border-bottom-left-radius: var(--border-radius-default);\n border-bottom-right-radius: var(--border-radius-default);\n overflow: auto;\n}\nsd-sheet > ._sheet-container > table {\n border-spacing: 0;\n table-layout: fixed;\n margin-right: 2px;\n margin-bottom: 2px;\n border-bottom-right-radius: var(--border-radius-default);\n}\nsd-sheet > ._sheet-container > table > * > tr > *:last-child {\n border-right: 1px solid var(--theme-gray-lighter);\n}\nsd-sheet > ._sheet-container > table > * > tr:last-child > * {\n border-bottom: 1px solid var(--theme-gray-lighter);\n}\nsd-sheet > ._sheet-container > table > *:last-child > tr:last-child > td:last-child {\n border-bottom-right-radius: var(--border-radius-default);\n overflow: hidden;\n}\nsd-sheet > ._sheet-container > table > * > tr > * {\n border-right: 1px solid var(--theme-gray-lighter);\n border-bottom: 1px solid var(--theme-gray-lighter);\n white-space: nowrap;\n overflow: hidden;\n padding: 0;\n position: relative;\n}\nsd-sheet > ._sheet-container > table > * > tr > *._fixed:has(+ :not(._fixed)) + :not(._fixed):not([data-c=\"0\"]) {\n border-left: 1px solid var(--theme-gray-lighter);\n}\nsd-sheet > ._sheet-container > table > * > tr > *._feature-cell {\n background: var(--theme-gray-lightest);\n min-width: calc(var(--font-size-default) + 2px + var(--sheet-ph) * 2);\n padding: var(--sheet-pv) var(--sheet-ph);\n text-align: left;\n}\nsd-sheet > ._sheet-container > table > * > tr > *._feature-cell > ng-icon {\n cursor: pointer;\n color: var(--text-trans-lightest);\n}\nsd-sheet > ._sheet-container > table > * > tr > *._fixed {\n position: sticky;\n left: 0;\n}\nsd-sheet > ._sheet-container > table > * > tr > *._fixed:has(+ :not(._fixed)) {\n border-right: 1px solid var(--theme-gray-lighter);\n}\nsd-sheet > ._sheet-container > table > thead {\n position: sticky;\n top: 0;\n z-index: 3;\n}\nsd-sheet > ._sheet-container > table > thead > tr > th {\n position: relative;\n background: var(--theme-gray-lightest);\n vertical-align: middle;\n}\nsd-sheet > ._sheet-container > table > thead > tr > th._fixed {\n z-index: 4;\n}\nsd-sheet > ._sheet-container > table > thead > tr > th._last-depth {\n border-bottom: 1px solid var(--theme-gray-lighter);\n}\nsd-sheet > ._sheet-container > table > thead > tr > th._feature-cell {\n border-bottom: 1px solid var(--theme-gray-lighter);\n}\nsd-sheet > ._sheet-container > table > thead > tr > th._sort {\n cursor: pointer;\n}\nsd-sheet > ._sheet-container > table > thead > tr > th._sort:hover {\n text-decoration: underline;\n}\nsd-sheet > ._sheet-container > table > thead > tr > th > ._headerContent > ._sort-icon {\n padding: var(--gap-xs) var(--gap-xs) var(--gap-xs) 0;\n background-color: var(--theme-gray-lightest);\n}\nsd-sheet > ._sheet-container > table > thead > tr > th > ._resizer {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n width: 2px;\n cursor: ew-resize;\n}\nsd-sheet > ._sheet-container > table > thead:has(> tr._summary-row) > tr > th._last-depth {\n border-bottom: 1px solid var(--theme-gray-lighter);\n}\nsd-sheet > ._sheet-container > table > thead:has(> tr._summary-row) > tr._summary-row > th {\n background: var(--theme-warning-lightest);\n text-align: left;\n border-bottom: 1px solid var(--theme-gray-lighter);\n}\nsd-sheet > ._sheet-container > table > tbody > tr > td {\n background: var(--control-color);\n vertical-align: top;\n}\nsd-sheet > ._sheet-container > table > tbody > tr > td._fixed {\n z-index: 2;\n}\nsd-sheet > ._sheet-container > table > tbody > tr > td > ._depth-indicator {\n display: inline-block;\n margin-top: 0.4em;\n width: 0.5em;\n height: 0.5em;\n border-left: 1px solid var(--text-trans-default);\n border-bottom: 1px solid var(--text-trans-default);\n vertical-align: top;\n}\nsd-sheet > ._sheet-container > ._focus-row-indicator {\n display: none;\n position: absolute;\n pointer-events: none;\n background: rgba(158, 158, 158, 0.1);\n z-index: 6;\n}\nsd-sheet > ._sheet-container > ._focus-row-indicator > ._focus-cell-indicator {\n position: absolute;\n border: 2px solid var(--theme-primary-default);\n border-radius: var(--border-radius-default);\n}\nsd-sheet > ._sheet-container > ._resize-indicator {\n display: none;\n position: absolute;\n pointer-events: none;\n top: 0;\n height: 100%;\n border: 1px dotted var(--theme-gray-light);\n z-index: 7;\n}\nsd-sheet > ._sheet-container > ._select-row-indicator-container {\n display: none;\n position: absolute;\n pointer-events: none;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 5;\n}\nsd-sheet > ._sheet-container > ._select-row-indicator-container > ._select-row-indicator {\n display: block;\n left: 0;\n position: absolute;\n pointer-events: none;\n background: var(--theme-primary-default);\n opacity: 0.1;\n}\nsd-sheet ._p-sheet {\n padding: var(--sheet-pv) var(--sheet-ph);\n}\nsd-sheet[data-sd-focus-mode=row] > ._sheet-container > ._focus-row-indicator > ._focus-cell-indicator {\n display: none !important;\n}\nsd-sheet[data-sd-inset=true] {\n border: none;\n border-radius: 0;\n}"] }]
1056
- }], null, { key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: false }] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], trackByFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "trackByFn", required: true }] }], selectMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectMode", required: false }] }], autoSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoSelect", required: false }] }], getItemSelectableFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "getItemSelectableFn", required: false }] }], getChildrenFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "getChildrenFn", required: false }] }], useAutoSort: [{ type: i0.Input, args: [{ isSignal: true, alias: "useAutoSort", required: false }] }], visiblePageCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "visiblePageCount", required: false }] }], totalPageCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalPageCount", required: false }] }], itemsPerPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemsPerPage", required: false }] }], focusMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "focusMode", required: false }] }], inset: [{ type: i0.Input, args: [{ isSignal: true, alias: "inset", required: false }] }], contentStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "contentStyle", required: false }] }], getItemCellClassFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "getItemCellClassFn", required: false }] }], getItemCellStyleFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "getItemCellStyleFn", required: false }] }], hideConfigBar: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideConfigBar", required: false }] }], itemKeydown: [{ type: i0.Output, args: ["itemKeydown"] }], cellKeydown: [{ type: i0.Output, args: ["cellKeydown"] }], selectedKeys: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedKeys", required: false }] }, { type: i0.Output, args: ["selectedKeysChange"] }], expandedItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandedItems", required: false }] }, { type: i0.Output, args: ["expandedItemsChange"] }], sorts: [{ type: i0.Input, args: [{ isSignal: true, alias: "sorts", required: false }] }, { type: i0.Output, args: ["sortsChange"] }], currentPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentPage", required: false }] }, { type: i0.Output, args: ["currentPageChange"] }], columnControls: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => SdSheetColumn), { isSignal: true }] }], columnControlsInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnControlsInput", required: false }] }] }); })();
1056
+ }], null, { key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: false }] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], trackByFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "trackByFn", required: false }] }], selectMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectMode", required: false }] }], autoSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoSelect", required: false }] }], getItemSelectableFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "getItemSelectableFn", required: false }] }], getChildrenFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "getChildrenFn", required: false }] }], useAutoSort: [{ type: i0.Input, args: [{ isSignal: true, alias: "useAutoSort", required: false }] }], visiblePageCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "visiblePageCount", required: false }] }], totalPageCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalPageCount", required: false }] }], itemsPerPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemsPerPage", required: false }] }], focusMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "focusMode", required: false }] }], inset: [{ type: i0.Input, args: [{ isSignal: true, alias: "inset", required: false }] }], contentStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "contentStyle", required: false }] }], getItemCellClassFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "getItemCellClassFn", required: false }] }], getItemCellStyleFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "getItemCellStyleFn", required: false }] }], hideConfigBar: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideConfigBar", required: false }] }], itemKeydown: [{ type: i0.Output, args: ["itemKeydown"] }], cellKeydown: [{ type: i0.Output, args: ["cellKeydown"] }], selectedKeys: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedKeys", required: false }] }, { type: i0.Output, args: ["selectedKeysChange"] }], expandedItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandedItems", required: false }] }, { type: i0.Output, args: ["expandedItemsChange"] }], sorts: [{ type: i0.Input, args: [{ isSignal: true, alias: "sorts", required: false }] }, { type: i0.Output, args: ["sortsChange"] }], currentPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentPage", required: false }] }, { type: i0.Output, args: ["currentPageChange"] }], columnControls: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => SdSheetColumn), { isSignal: true }] }], columnControlsInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnControlsInput", required: false }] }] }); })();
1057
1057
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SdSheet, { className: "SdSheet", filePath: "packages/angular/src/data/sheet/sd-sheet.ts", lineNumber: 585 }); })();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simplysm/angular",
3
- "version": "14.0.55",
3
+ "version": "14.0.57",
4
4
  "description": "심플리즘 패키지 - Angular",
5
5
  "author": "심플리즘",
6
6
  "license": "Apache-2.0",
@@ -50,10 +50,10 @@
50
50
  "jspdf": "^4.2.1",
51
51
  "rxjs": "^7.8.2",
52
52
  "tabbable": "^6.4.0",
53
- "@simplysm/core-browser": "14.0.55",
54
- "@simplysm/core-common": "14.0.55",
55
- "@simplysm/service-client": "14.0.55",
56
- "@simplysm/service-common": "14.0.55"
53
+ "@simplysm/core-browser": "14.0.57",
54
+ "@simplysm/service-common": "14.0.57",
55
+ "@simplysm/core-common": "14.0.57",
56
+ "@simplysm/service-client": "14.0.57"
57
57
  },
58
58
  "devDependencies": {
59
59
  "@angular/compiler": "^21.2.10",
@@ -3,7 +3,7 @@ import { obj } from "@simplysm/core-common";
3
3
 
4
4
  export function useSelectionManager<TItem, TKey>(options: {
5
5
  displayItems: Signal<TItem[]>;
6
- selectedKeys: WritableSignal<NonNullable<TKey>[]>;
6
+ selectedKeys: WritableSignal<TKey[]>;
7
7
  selectMode: Signal<"single" | "multi" | undefined>;
8
8
  getItemSelectableFn: Signal<((item: TItem) => boolean | string) | undefined>;
9
9
  trackByFn: Signal<(item: TItem, index: number) => TKey>;
@@ -128,7 +128,7 @@ export function useSelectionManager<TItem, TKey>(options: {
128
128
  options.selectedKeys.update((arr) => {
129
129
  const newKeys = selectable
130
130
  .map((it) => fn(it, idxMap.get(it) ?? 0))
131
- .filter((k): k is NonNullable<TKey> => k != null)
131
+ .filter((k): k is TKey => k != null)
132
132
  .filter((k) => !arr.some((ek) => isKeyEqual(ek, k)));
133
133
  return [...arr, ...newKeys];
134
134
  });
@@ -6,7 +6,7 @@ import {
6
6
  inject,
7
7
  input,
8
8
  model,
9
- TemplateRef,
9
+ type TemplateRef,
10
10
  untracked,
11
11
  ViewEncapsulation,
12
12
  } from "@angular/core";
@@ -63,7 +63,9 @@ import { NgTemplateOutlet } from "@angular/common";
63
63
  }
64
64
 
65
65
  <div class="flex-fill">
66
- <ng-content />
66
+ @if (contentTplRef()) {
67
+ <ng-template [ngTemplateOutlet]="contentTplRef()" />
68
+ }
67
69
  </div>
68
70
 
69
71
  @if (bottomCommandTplRef()) {
@@ -91,6 +93,7 @@ export class SdBaseContainer {
91
93
 
92
94
  topbarTplRef = contentChild<TemplateRef<void>>("topbarTpl");
93
95
  commandTplRef = contentChild<TemplateRef<void>>("commandTpl");
96
+ contentTplRef = contentChild<TemplateRef<void>>("contentTpl");
94
97
  bottomCommandTplRef = contentChild<TemplateRef<void>>("bottomCommandTpl");
95
98
 
96
99
  constructor() {
@@ -82,19 +82,18 @@ import { tablerDeviceFloppy } from "@ng-icons/tabler-icons";
82
82
  </ng-template>
83
83
  }
84
84
 
85
- <!-- CONTENT -->
86
- <ng-template #contentTpl>
87
- <ng-content />
88
- </ng-template>
89
-
90
- @if (readonly()) {
91
- <div class="fill">
92
- <ng-template [ngTemplateOutlet]="contentTpl" />
93
- </div>
94
- } @else {
95
- <sd-form #formCtrl (formSubmit)="submit.emit()" class="block fill">
96
- <ng-template [ngTemplateOutlet]="contentTpl" />
97
- </sd-form>
85
+ @if (contentTplRef()) {
86
+ <ng-template #contentTpl>
87
+ @if (readonly()) {
88
+ <div class="fill">
89
+ <ng-template [ngTemplateOutlet]="contentTplRef()" />
90
+ </div>
91
+ } @else {
92
+ <sd-form #formCtrl (formSubmit)="submit.emit()" class="block fill">
93
+ <ng-template [ngTemplateOutlet]="contentTplRef()" />
94
+ </sd-form>
95
+ }
96
+ </ng-template>
98
97
  }
99
98
  </sd-base-container>
100
99
  `,
@@ -112,6 +111,7 @@ export class SdCrudDetail {
112
111
  submit = output();
113
112
 
114
113
  commandTplRef = contentChild<TemplateRef<void>>("commandTpl");
114
+ contentTplRef = contentChild<TemplateRef<void>>("contentTpl");
115
115
  bottomCommandTplRef = contentChild<TemplateRef<void>>("bottomCommandTpl");
116
116
 
117
117
  onSaveButtonClick() {
@@ -8,7 +8,7 @@ import {
8
8
  input,
9
9
  model,
10
10
  output,
11
- TemplateRef,
11
+ type TemplateRef,
12
12
  viewChild,
13
13
  ViewEncapsulation,
14
14
  } from "@angular/core";
@@ -115,68 +115,69 @@ import {
115
115
  </ng-template>
116
116
  }
117
117
 
118
- <!-- CONTENT -->
119
- <div class="flex-column fill">
120
- @if (filterTplRef()) {
121
- <sd-form (formSubmit)="filterSubmit.emit()" class="block p-default">
122
- <div class="form-box-inline">
123
- <div>
124
- <sd-button [type]="'submit'" [theme]="'info'">
125
- <ng-icon [svg]="tablerSearch" />
126
- 조회
127
- </sd-button>
118
+ <ng-template #contentTpl>
119
+ <div class="flex-column fill">
120
+ @if (filterTplRef()) {
121
+ <sd-form (formSubmit)="filterSubmit.emit()" class="block p-default">
122
+ <div class="form-box-inline">
123
+ <div>
124
+ <sd-button [type]="'submit'" [theme]="'info'">
125
+ <ng-icon [svg]="tablerSearch" />
126
+ 조회
127
+ </sd-button>
128
+ </div>
129
+ <ng-template [ngTemplateOutlet]="filterTplRef()" />
128
130
  </div>
129
- <ng-template [ngTemplateOutlet]="filterTplRef()" />
130
- </div>
131
- </sd-form>
132
- }
131
+ </sd-form>
132
+ }
133
133
 
134
- @if (!readonly() || toolTplRef()) {
135
- <div class="flex-row gap-sm p-xs-default">
136
- @if (!readonly()) {
137
- <sd-button [size]="'sm'" [theme]="'link-primary'" (click)="create.emit()">
138
- <ng-icon [svg]="tablerCirclePlus" />
139
- 등록
140
- </sd-button>
141
- @if (selectMode() !== "single") {
142
- <sd-button
143
- [size]="'sm'"
144
- [theme]="'link-danger'"
145
- (click)="delete.emit(currSelectedItems())"
146
- [disabled]="!hasSelectedNotDeleted()"
147
- >
148
- <ng-icon [svg]="tablerEraser" />
149
- 선택 삭제
134
+ @if (!readonly() || toolTplRef()) {
135
+ <div class="flex-row gap-sm p-xs-default">
136
+ @if (!readonly()) {
137
+ <sd-button [size]="'sm'" [theme]="'link-primary'" (click)="create.emit()">
138
+ <ng-icon [svg]="tablerCirclePlus" />
139
+ 등록
150
140
  </sd-button>
151
- @if (hasSelectedDeleted()) {
141
+ @if (selectMode() !== "single") {
152
142
  <sd-button
153
143
  [size]="'sm'"
154
- [theme]="'link-warning'"
155
- (click)="restore.emit(currSelectedItems())"
144
+ [theme]="'link-danger'"
145
+ (click)="delete.emit(currSelectedItems())"
146
+ [disabled]="!hasSelectedNotDeleted()"
156
147
  >
157
- <ng-icon [svg]="tablerRestore" />
158
- 선택 복구
148
+ <ng-icon [svg]="tablerEraser" />
149
+ 선택 삭제
159
150
  </sd-button>
151
+ @if (hasSelectedDeleted()) {
152
+ <sd-button
153
+ [size]="'sm'"
154
+ [theme]="'link-warning'"
155
+ (click)="restore.emit(currSelectedItems())"
156
+ >
157
+ <ng-icon [svg]="tablerRestore" />
158
+ 선택 복구
159
+ </sd-button>
160
+ }
160
161
  }
161
162
  }
162
- }
163
163
 
164
- @if (toolTplRef()) {
165
- <ng-template [ngTemplateOutlet]="toolTplRef()" />
166
- }
167
- </div>
168
- }
164
+ @if (toolTplRef()) {
165
+ <ng-template [ngTemplateOutlet]="toolTplRef()" />
166
+ }
167
+ </div>
168
+ }
169
169
 
170
- @if (readonly()) {
171
- <div class="flex-fill p-default pt-0">
172
- <ng-template [ngTemplateOutlet]="sheet" />
173
- </div>
174
- } @else {
175
- <sd-form #formCtrl (formSubmit)="submit.emit()" class="flex-fill p-default pt-0">
176
- <ng-template [ngTemplateOutlet]="sheet" />
177
- </sd-form>
178
- }
179
- </div>
170
+ @if (readonly()) {
171
+ <div class="flex-fill p-default pt-0">
172
+ <ng-template [ngTemplateOutlet]="sheet" />
173
+ </div>
174
+ } @else {
175
+ <sd-form #formCtrl (formSubmit)="submit.emit()" class="flex-fill p-default pt-0">
176
+ <ng-template [ngTemplateOutlet]="sheet" />
177
+ </sd-form>
178
+ }
179
+ </div>
180
+ </ng-template>
180
181
  </sd-base-container>
181
182
 
182
183
  <ng-template #sheet>
@@ -9,7 +9,7 @@ function isKeyEqual(a: unknown, b: unknown): boolean {
9
9
 
10
10
  export function injectSheetSelectRowIndicator<TItem, TKey>(options: {
11
11
  domAccessor: ReturnType<typeof injectSheetDomAccessor>;
12
- selectedKeys: Signal<NonNullable<TKey>[]>;
12
+ selectedKeys: Signal<TKey[]>;
13
13
  displayItems: Signal<TItem[]>;
14
14
  trackByFn: Signal<(item: TItem, index: number) => TKey>;
15
15
  }) {
@@ -582,11 +582,11 @@ import { SdEvents } from "../../core/events/sd-events";
582
582
  `,
583
583
  ],
584
584
  })
585
- export class SdSheet<TItem, TKey> {
585
+ export class SdSheet<TItem> {
586
586
  // Inputs
587
587
  key = input<string>();
588
588
  items = input<TItem[]>([]);
589
- trackByFn = input.required<(item: TItem, index: number) => TKey>();
589
+ trackByFn = input<(item: TItem, index: number) => unknown>((item) => item);
590
590
  selectMode = input<"single" | "multi">();
591
591
  autoSelect = input<"click" | "focus">();
592
592
  getItemSelectableFn = input<(item: TItem) => boolean | string>();
@@ -607,7 +607,7 @@ export class SdSheet<TItem, TKey> {
607
607
  cellKeydown = output<SdSheetCellKeydownEventParam<TItem>>();
608
608
 
609
609
  // Models
610
- selectedKeys = model<NonNullable<TKey>[]>([]);
610
+ selectedKeys = model<unknown[]>([]);
611
611
  expandedItems = model<TItem[]>([]);
612
612
  sorts = model<SortingDef[]>([]); // Re-exported from useSortingManager
613
613
  currentPage = model(0);
@@ -699,7 +699,7 @@ export class SdSheet<TItem, TKey> {
699
699
  });
700
700
 
701
701
  // Select row indicator
702
- private readonly _selectRowIndicator = injectSheetSelectRowIndicator<TItem, TKey>({
702
+ private readonly _selectRowIndicator = injectSheetSelectRowIndicator<TItem, unknown>({
703
703
  domAccessor: this.domAccessor,
704
704
  selectedKeys: this.selectedKeys,
705
705
  displayItems: this.displayItems,
@@ -707,7 +707,7 @@ export class SdSheet<TItem, TKey> {
707
707
  });
708
708
 
709
709
  // Selection manager
710
- selection = useSelectionManager<TItem, TKey>({
710
+ selection = useSelectionManager<TItem, unknown>({
711
711
  displayItems: this.displayItems,
712
712
  selectedKeys: this.selectedKeys,
713
713
  selectMode: this.selectMode,