@iyulab/data-components 0.3.0 → 0.4.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.
Files changed (27) hide show
  1. package/CHANGELOG.md +65 -2
  2. package/README.md +7 -17
  3. package/dist/_virtual/_@oxc-project_runtime@0.127.0/helpers/decorate.js +9 -0
  4. package/dist/_virtual/_@oxc-project_runtime@0.127.0/helpers/decorateMetadata.js +6 -0
  5. package/dist/components/data-view/UDataView.d.ts +44 -3
  6. package/dist/components/data-view/UDataView.js +172 -4
  7. package/dist/components/data-view/UDataView.styles.js +4 -83
  8. package/dist/components/simple-sheet/USimpleSheet.d.ts +167 -3
  9. package/dist/components/simple-sheet/USimpleSheet.js +934 -4
  10. package/dist/components/simple-sheet/USimpleSheet.styles.js +4 -4
  11. package/dist/components/u-rich-table/URichTable.d.ts +70 -3
  12. package/dist/components/u-rich-table/URichTable.js +618 -4
  13. package/dist/components/u-rich-table/styles.js +4 -4
  14. package/dist/components/u-rich-table/utils/clipboard.js +26 -29
  15. package/dist/index.d.ts +0 -2
  16. package/dist/index.js +4 -7
  17. package/package.json +16 -46
  18. package/dist/components/data-grid/UDataGrid.d.ts +0 -2
  19. package/dist/components/data-grid/UDataGrid.js +0 -174
  20. package/dist/components/data-grid/UDataGrid.types.d.ts +0 -42
  21. package/dist/components/data-view/UDataView.component.d.ts +0 -47
  22. package/dist/components/data-view/UDataView.component.js +0 -226
  23. package/dist/components/simple-sheet/USimpleSheet.component.d.ts +0 -167
  24. package/dist/components/simple-sheet/USimpleSheet.component.js +0 -1034
  25. package/dist/components/u-rich-table/URichTable.component.d.ts +0 -70
  26. package/dist/components/u-rich-table/URichTable.component.js +0 -672
  27. package/dist/utilities/devExtremeCssInjection.d.ts +0 -23
@@ -1,34 +1,31 @@
1
+ //#region src/components/u-rich-table/utils/clipboard.ts
2
+ /**
3
+ * 탭/줄바꿈 구분 텍스트(TSV)를 파싱하여 행 배열로 반환
4
+ */
1
5
  function parseTSV(text, columns) {
2
- const lines = text.trim().split("\n");
3
- return lines.map((line) => {
4
- const cells = line.split(" ");
5
- const row = {};
6
- columns.forEach((col, i) => {
7
- if (i < cells.length) {
8
- const raw = cells[i].trim();
9
- if (col.clipboardParse) {
10
- row[col.key] = col.clipboardParse(raw);
11
- } else if (col.type === "number") {
12
- row[col.key] = Number(raw.replace(/,/g, "")) || 0;
13
- } else {
14
- row[col.key] = raw;
15
- }
16
- }
17
- });
18
- return row;
19
- });
6
+ return text.trim().split("\n").map((line) => {
7
+ const cells = line.split(" ");
8
+ const row = {};
9
+ columns.forEach((col, i) => {
10
+ if (i < cells.length) {
11
+ const raw = cells[i].trim();
12
+ if (col.clipboardParse) row[col.key] = col.clipboardParse(raw);
13
+ else if (col.type === "number") row[col.key] = Number(raw.replace(/,/g, "")) || 0;
14
+ else row[col.key] = raw;
15
+ }
16
+ });
17
+ return row;
18
+ });
20
19
  }
20
+ /**
21
+ * 행 배열을 탭/줄바꿈 구분 텍스트(TSV)로 변환
22
+ */
21
23
  function toTSV(rows, columns) {
22
- const header = columns.map((c) => c.label).join(" ");
23
- const body = rows.map(
24
- (row) => columns.map((col) => {
25
- const value = row[col.key];
26
- if (col.clipboardFormat) return col.clipboardFormat(value);
27
- return String(value ?? "");
28
- }).join(" ")
29
- ).join("\n");
30
- return `${header}
31
- ${body}`;
24
+ return `${columns.map((c) => c.label).join(" ")}\n${rows.map((row) => columns.map((col) => {
25
+ const value = row[col.key];
26
+ if (col.clipboardFormat) return col.clipboardFormat(value);
27
+ return String(value ?? "");
28
+ }).join(" ")).join("\n")}`;
32
29
  }
33
-
30
+ //#endregion
34
31
  export { parseTSV, toTSV };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,3 @@
1
- export { UDataGrid } from './components/data-grid/UDataGrid';
2
- export type { UDataGridColumn, UDataGridProps } from './components/data-grid/UDataGrid.types';
3
1
  export * from './components/data-view/UDataView';
4
2
  export * from './components/simple-sheet/USimpleSheet';
5
3
  export * from './components/u-rich-table/URichTable';
package/dist/index.js CHANGED
@@ -1,7 +1,4 @@
1
- export { UDataGrid } from './components/data-grid/UDataGrid.js';
2
- import './components/data-view/UDataView.js';
3
- import './components/simple-sheet/USimpleSheet.js';
4
- import './components/u-rich-table/URichTable.js';
5
- export { UDataView } from './components/data-view/UDataView.component.js';
6
- export { URichTable } from './components/u-rich-table/URichTable.component.js';
7
- export { USimpleSheet } from './components/simple-sheet/USimpleSheet.component.js';
1
+ import { UDataView } from "./components/data-view/UDataView.js";
2
+ import { USimpleSheet } from "./components/simple-sheet/USimpleSheet.js";
3
+ import { URichTable } from "./components/u-rich-table/URichTable.js";
4
+ export { UDataView, URichTable, USimpleSheet };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@iyulab/data-components",
3
3
  "description": "iyulab data visualization components",
4
- "version": "0.3.0",
4
+ "version": "0.4.1",
5
5
  "keywords": [
6
6
  "iyulab",
7
7
  "web-components",
@@ -27,35 +27,14 @@
27
27
  "types": "./dist/index.d.ts",
28
28
  "import": "./dist/index.js"
29
29
  },
30
- "./dist/*": {
31
- "types": "./dist/*.d.ts",
32
- "import": "./dist/*"
33
- },
34
- "./init": {
35
- "types": "./dist/init.d.ts",
36
- "import": "./dist/init.js"
37
- },
38
- "./simple-sheet": {
39
- "types": "./dist/components/simple-sheet/USimpleSheet.d.ts",
40
- "import": "./dist/components/simple-sheet/USimpleSheet.js"
41
- },
42
- "./data-view": {
43
- "types": "./dist/components/data-view/UDataView.d.ts",
44
- "import": "./dist/components/data-view/UDataView.js"
45
- },
46
- "./data-grid": {
47
- "types": "./dist/components/data-grid/UDataGrid.d.ts",
48
- "import": "./dist/components/data-grid/UDataGrid.js"
49
- },
50
- "./u-rich-table": {
51
- "types": "./dist/components/u-rich-table/URichTable.d.ts",
52
- "import": "./dist/components/u-rich-table/URichTable.js"
53
- }
30
+ "./dist/*": "./dist/*",
31
+ "./init": "./dist/init.js",
32
+ "./simple-sheet": "./dist/components/simple-sheet/USimpleSheet.js",
33
+ "./data-view": "./dist/components/data-view/UDataView.js",
34
+ "./u-rich-table": "./dist/components/u-rich-table/URichTable.js"
54
35
  },
55
36
  "sideEffects": [
56
37
  "./dist/utilities/shadowDomProtection.js",
57
- "./dist/utilities/devExtremeCssInjection.js",
58
- "./dist/components/data-grid/UDataGrid.js",
59
38
  "./dist/components/data-view/UDataView.js",
60
39
  "./dist/components/simple-sheet/USimpleSheet.js",
61
40
  "./dist/components/u-rich-table/URichTable.js",
@@ -66,27 +45,18 @@
66
45
  "build": "eslint && vite build"
67
46
  },
68
47
  "dependencies": {
69
- "@iyulab/components": "^0.4.0",
70
- "devextreme": "^25.2.4",
71
- "devextreme-react": "^25.2.4",
72
- "lit": "^3.3.2",
73
- "react": "^19.2.4",
74
- "react-dom": "^19.2.4"
48
+ "@iyulab/components": "^1.0.4",
49
+ "lit": "^3.3.2"
75
50
  },
76
51
  "devDependencies": {
77
- "@eslint/js": "^9.39.3",
78
- "@lit/react": "^1.0.8",
79
- "@types/node": "^25.3.2",
80
- "@types/react": "^19.2.14",
81
- "@types/react-dom": "^19.2.3",
82
- "@vitejs/plugin-react": "^5.1.4",
83
- "eslint": "^9.39.3",
84
- "eslint-plugin-react-hooks": "^7.0.1",
85
- "eslint-plugin-react-refresh": "^0.5.2",
86
- "globals": "^17.3.0",
87
- "typescript": "~5.9.3",
88
- "typescript-eslint": "^8.56.1",
89
- "vite": "^7.3.1",
52
+ "@eslint/js": "^9.39.4",
53
+ "@types/node": "^25.6.0",
54
+ "eslint": "^9.39.4",
55
+ "glob": "^13.0.6",
56
+ "globals": "^17.5.0",
57
+ "typescript": "^5.9.3",
58
+ "typescript-eslint": "^8.58.2",
59
+ "vite": "^8.0.8",
90
60
  "vite-plugin-dts": "^4.5.4"
91
61
  }
92
62
  }
@@ -1,2 +0,0 @@
1
- import { UDataGridProps } from './UDataGrid.types.js';
2
- export declare function UDataGrid({ dataSourceUrl, keyField, selectFields, columns, pageSize, showBorders, allowColumnReordering, allowColumnResizing, showGroupPanel, showSearchPanel, showFilterRow, showHeaderFilter, allowExport, exportFileName, isDevelopment, onDataLoaded, onDataLoadError, onExporting, onRowClick, beforeSend }: UDataGridProps): import("react/jsx-runtime").JSX.Element;
@@ -1,174 +0,0 @@
1
- import { jsx, jsxs } from 'react/jsx-runtime';
2
- import { useMemo } from 'react';
3
- import 'devextreme/data/odata/store';
4
- import DataGrid, { LoadPanel, Selection, FilterRow, HeaderFilter, SearchPanel, Grouping, GroupPanel, ColumnChooser, Paging, Export, Toolbar, Item, Column } from 'devextreme-react/data-grid';
5
-
6
- function UDataGrid({
7
- dataSourceUrl,
8
- keyField,
9
- selectFields,
10
- columns,
11
- pageSize = 25,
12
- showBorders = true,
13
- allowColumnReordering = true,
14
- allowColumnResizing = true,
15
- showGroupPanel = true,
16
- showSearchPanel = true,
17
- showFilterRow = true,
18
- showHeaderFilter = true,
19
- allowExport = true,
20
- exportFileName,
21
- isDevelopment = false,
22
- onDataLoaded,
23
- onDataLoadError,
24
- onExporting,
25
- onRowClick,
26
- beforeSend
27
- }) {
28
- const defaultBeforeSend = (operation, ajaxOptions) => {
29
- try {
30
- if (!ajaxOptions) {
31
- console.warn("ajaxOptions가 undefined입니다");
32
- return;
33
- }
34
- if (!ajaxOptions.headers || typeof ajaxOptions.headers !== "object") {
35
- ajaxOptions.headers = {};
36
- }
37
- ajaxOptions.headers["Accept"] = "application/json";
38
- ajaxOptions.headers["Content-Type"] = "application/json";
39
- if (isDevelopment) {
40
- ajaxOptions.crossDomain = true;
41
- ajaxOptions.headers["Access-Control-Allow-Origin"] = "*";
42
- }
43
- console.log(`U-DataGrid ${operation} 요청:`, {
44
- url: ajaxOptions.url,
45
- headers: ajaxOptions.headers,
46
- method: ajaxOptions.type || "GET"
47
- });
48
- } catch (error) {
49
- console.error("beforeSend 처리 중 오류:", error);
50
- }
51
- };
52
- const defaultOnLoadError = (error) => {
53
- console.error("U-DataGrid 데이터 로딩 오류:", error);
54
- let errorMessage = "데이터를 불러오는 중 오류가 발생했습니다.";
55
- try {
56
- if (error && typeof error === "object") {
57
- if (error.status === 404) {
58
- errorMessage = "API 엔드포인트를 찾을 수 없습니다. 서버가 실행중인지 확인해주세요.";
59
- } else if (error.status === 0) {
60
- errorMessage = "CORS 오류 또는 네트워크 연결 문제입니다. 서버 설정을 확인해주세요.";
61
- } else if (error.status >= 500) {
62
- errorMessage = "서버 내부 오류입니다. 서버 로그를 확인해주세요.";
63
- } else if (error.message) {
64
- errorMessage = error.message;
65
- } else if (typeof error === "string") {
66
- errorMessage = error;
67
- }
68
- }
69
- } catch (parseError) {
70
- console.error("오류 메시지 파싱 중 문제:", parseError);
71
- }
72
- alert(`${errorMessage}
73
-
74
- 요청 URL: ${dataSourceUrl}`);
75
- };
76
- const dataSource = useMemo(() => {
77
- return {
78
- store: {
79
- type: "odata",
80
- version: 4,
81
- url: dataSourceUrl,
82
- key: keyField,
83
- beforeSend: beforeSend || defaultBeforeSend,
84
- onLoading: () => {
85
- console.log("U-DataGrid 데이터 로딩 시작...");
86
- },
87
- onLoaded: (data) => {
88
- console.log("U-DataGrid 데이터 로딩 완료:", data);
89
- onDataLoaded?.(data);
90
- },
91
- onLoadError: onDataLoadError || defaultOnLoadError
92
- },
93
- select: selectFields
94
- };
95
- }, [dataSourceUrl, keyField, selectFields, beforeSend, onDataLoaded, onDataLoadError]);
96
- const handleExporting = (e) => {
97
- if (exportFileName) {
98
- e.fileName = exportFileName;
99
- } else {
100
- e.fileName = `DataGrid_Export_${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}`;
101
- }
102
- onExporting?.(e);
103
- };
104
- return /* @__PURE__ */ jsx("div", { style: {
105
- width: "100%",
106
- height: "100%",
107
- position: "relative",
108
- contain: "layout style",
109
- isolation: "isolate",
110
- overflow: "hidden"
111
- }, children: /* @__PURE__ */ jsxs(
112
- DataGrid,
113
- {
114
- dataSource,
115
- showBorders,
116
- allowColumnReordering,
117
- allowColumnResizing,
118
- columnAutoWidth: false,
119
- showColumnLines: true,
120
- showRowLines: true,
121
- rowAlternationEnabled: true,
122
- hoverStateEnabled: true,
123
- height: "100%",
124
- width: "100%",
125
- wordWrapEnabled: true,
126
- columnResizingMode: "widget",
127
- remoteOperations: true,
128
- onExporting: handleExporting,
129
- onRowClick,
130
- children: [
131
- /* @__PURE__ */ jsx(LoadPanel, { enabled: true }),
132
- /* @__PURE__ */ jsx(Selection, { mode: "multiple" }),
133
- showFilterRow && /* @__PURE__ */ jsx(FilterRow, { visible: true }),
134
- showHeaderFilter && /* @__PURE__ */ jsx(HeaderFilter, { visible: true }),
135
- showSearchPanel && /* @__PURE__ */ jsx(SearchPanel, { visible: true, placeholder: "검색..." }),
136
- /* @__PURE__ */ jsx(Grouping, { autoExpandAll: false }),
137
- showGroupPanel && /* @__PURE__ */ jsx(GroupPanel, { visible: true }),
138
- /* @__PURE__ */ jsx(ColumnChooser, { enabled: true }),
139
- /* @__PURE__ */ jsx(Paging, { defaultPageSize: pageSize }),
140
- allowExport && /* @__PURE__ */ jsx(Export, { enabled: true }),
141
- /* @__PURE__ */ jsxs(Toolbar, { children: [
142
- showGroupPanel && /* @__PURE__ */ jsx(Item, { name: "groupPanel" }),
143
- allowExport && /* @__PURE__ */ jsx(Item, { name: "exportButton" }),
144
- /* @__PURE__ */ jsx(Item, { name: "columnChooserButton" }),
145
- showSearchPanel && /* @__PURE__ */ jsx(Item, { name: "searchPanel" })
146
- ] }),
147
- columns.map((col, index) => /* @__PURE__ */ jsx(
148
- Column,
149
- {
150
- dataField: col.dataField,
151
- caption: col.caption,
152
- width: col.width,
153
- minWidth: col.minWidth,
154
- dataType: col.dataType,
155
- format: col.format,
156
- alignment: col.alignment,
157
- fixed: col.fixed,
158
- fixedPosition: col.fixedPosition,
159
- allowHiding: col.allowHiding,
160
- allowSorting: col.allowSorting,
161
- allowFiltering: col.allowFiltering,
162
- allowGrouping: col.allowGrouping,
163
- sortOrder: col.sortOrder,
164
- cellRender: col.cellRender,
165
- visible: col.visible
166
- },
167
- col.dataField || `column-${index}`
168
- ))
169
- ]
170
- }
171
- ) });
172
- }
173
-
174
- export { UDataGrid };
@@ -1,42 +0,0 @@
1
- export interface UDataGridColumn {
2
- dataField?: string;
3
- caption: string;
4
- width?: number;
5
- minWidth?: number;
6
- dataType?: 'string' | 'number' | 'date' | 'datetime' | 'boolean';
7
- format?: string;
8
- alignment?: 'left' | 'center' | 'right';
9
- fixed?: boolean;
10
- fixedPosition?: 'left' | 'right';
11
- allowHiding?: boolean;
12
- allowSorting?: boolean;
13
- allowFiltering?: boolean;
14
- allowGrouping?: boolean;
15
- sortOrder?: 'asc' | 'desc';
16
- cellRender?: (cellData: any) => React.ReactNode;
17
- visible?: boolean;
18
- }
19
- export interface UDataGridProps {
20
- dataSourceUrl: string;
21
- keyField: string;
22
- selectFields?: string[];
23
- columns: UDataGridColumn[];
24
- pageSize?: number;
25
- showBorders?: boolean;
26
- allowColumnReordering?: boolean;
27
- allowColumnResizing?: boolean;
28
- showGroupPanel?: boolean;
29
- showSearchPanel?: boolean;
30
- showFilterRow?: boolean;
31
- showHeaderFilter?: boolean;
32
- allowExport?: boolean;
33
- exportFileName?: string;
34
- isDevelopment?: boolean;
35
- onDataLoaded?: (data: any) => void;
36
- onDataLoadError?: (error: any) => void;
37
- onExporting?: (e: any) => void;
38
- onRowClick?: (e: {
39
- data: Record<string, unknown>;
40
- }) => void;
41
- beforeSend?: (operation: string, ajaxOptions: any) => void;
42
- }
@@ -1,47 +0,0 @@
1
- import { TemplateResult } from 'lit';
2
- import { UElement } from '@iyulab/components/dist/components/UElement.js';
3
- export type ViewMode = 'grid' | 'list' | 'table';
4
- export interface Column {
5
- key: string;
6
- label?: string;
7
- width?: string;
8
- }
9
- /**
10
- * Data View Component
11
- * 데이터를 3가지 레이아웃(grid, list, table)으로 표시하는 컴포넌트
12
- */
13
- export declare class UDataView extends UElement {
14
- static styles: import('lit').CSSResultGroup[];
15
- static dependencies: Record<string, typeof UElement>;
16
- /** 표시할 데이터 배열 */
17
- items: any[];
18
- /** 현재 뷰 모드 */
19
- mode: ViewMode;
20
- /** 표시할 컬럼 설정 (미지정시 자동 감지) */
21
- columns?: Column[];
22
- /** 그리드 모드 최소 폭 */
23
- gridMinWidth: string;
24
- /** 아이템 간격 */
25
- gap: string;
26
- /** 커스텀 렌더 함수 (grid/list 카드용) */
27
- renderCard?: (item: any, index: number) => TemplateResult;
28
- /** 커스텀 셀 렌더 함수 (table용) */
29
- renderCell?: (item: any, column: Column, index: number) => TemplateResult | string;
30
- private selectedIndex;
31
- render(): TemplateResult<1>;
32
- private renderToolbar;
33
- private renderViewButton;
34
- private renderContent;
35
- private renderGrid;
36
- private renderList;
37
- private renderTable;
38
- private renderGridItem;
39
- private renderListItem;
40
- private renderDefaultCard;
41
- private getCellContent;
42
- private getColumns;
43
- private formatLabel;
44
- private formatValue;
45
- private switchMode;
46
- private selectItem;
47
- }
@@ -1,226 +0,0 @@
1
- import { html } from 'lit';
2
- import { property, state } from 'lit/decorators.js';
3
- import { UElement } from '@iyulab/components/dist/components/UElement.js';
4
- import { UIcon } from '@iyulab/components/dist/components/icon/UIcon.component.js';
5
- import { UButton } from '@iyulab/components/dist/components/button/UButton.component.js';
6
- import { styles } from './UDataView.styles.js';
7
-
8
- var __defProp = Object.defineProperty;
9
- var __decorateClass = (decorators, target, key, kind) => {
10
- var result = void 0 ;
11
- for (var i = decorators.length - 1, decorator; i >= 0; i--)
12
- if (decorator = decorators[i])
13
- result = (decorator(target, key, result) ) || result;
14
- if (result) __defProp(target, key, result);
15
- return result;
16
- };
17
- class UDataView extends UElement {
18
- constructor() {
19
- super(...arguments);
20
- this.items = [];
21
- this.mode = "grid";
22
- this.gridMinWidth = "200px";
23
- this.gap = "1rem";
24
- this.selectedIndex = null;
25
- }
26
- static {
27
- this.styles = [super.styles, styles];
28
- }
29
- static {
30
- this.dependencies = {
31
- "u-icon": UIcon,
32
- "u-button": UButton
33
- };
34
- }
35
- render() {
36
- return html`
37
- <div class="data-view">
38
- ${this.renderToolbar()}
39
- ${this.renderContent()}
40
- </div>
41
- `;
42
- }
43
- renderToolbar() {
44
- return html`
45
- <div class="toolbar">
46
- <div class="view-toggles">
47
- ${this.renderViewButton("grid", "grid-3x3-gap", "Grid")}
48
- ${this.renderViewButton("list", "list-ul", "List")}
49
- ${this.renderViewButton("table", "table", "Table")}
50
- </div>
51
- <div class="info">
52
- ${this.items.length} items
53
- </div>
54
- </div>
55
- `;
56
- }
57
- renderViewButton(mode, icon, label) {
58
- return html`
59
- <u-button
60
- ?active=${this.mode === mode}
61
- @click=${() => this.switchMode(mode)}
62
- title=${label}
63
- >
64
- <u-icon lib="bootstrap" name=${icon}></u-icon>
65
- </u-button>
66
- `;
67
- }
68
- renderContent() {
69
- if (!this.items?.length) {
70
- return html`<div class="empty">No data available</div>`;
71
- }
72
- switch (this.mode) {
73
- case "grid":
74
- return this.renderGrid();
75
- case "list":
76
- return this.renderList();
77
- case "table":
78
- return this.renderTable();
79
- }
80
- }
81
- renderGrid() {
82
- return html`
83
- <div class="grid" style="--min-width: ${this.gridMinWidth}; --gap: ${this.gap};">
84
- ${this.items.map((item, index) => this.renderGridItem(item, index))}
85
- </div>
86
- `;
87
- }
88
- renderList() {
89
- return html`
90
- <div class="list" style="--gap: ${this.gap};">
91
- ${this.items.map((item, index) => this.renderListItem(item, index))}
92
- </div>
93
- `;
94
- }
95
- renderTable() {
96
- const cols = this.getColumns();
97
- return html`
98
- <div class="table-wrapper">
99
- <table>
100
- <thead>
101
- <tr>
102
- ${cols.map((col) => html`
103
- <th style=${col.width ? `width: ${col.width}` : ""}>
104
- ${col.label || this.formatLabel(col.key)}
105
- </th>
106
- `)}
107
- </tr>
108
- </thead>
109
- <tbody>
110
- ${this.items.map((item, index) => html`
111
- <tr
112
- class=${this.selectedIndex === index ? "selected" : ""}
113
- @click=${() => this.selectItem(index)}
114
- >
115
- ${cols.map((col) => html`
116
- <td>${this.getCellContent(item, col, index)}</td>
117
- `)}
118
- </tr>
119
- `)}
120
- </tbody>
121
- </table>
122
- </div>
123
- `;
124
- }
125
- renderGridItem(item, index) {
126
- const content = this.renderCard ? this.renderCard(item, index) : this.renderDefaultCard(item);
127
- return html`
128
- <div
129
- class="card ${this.selectedIndex === index ? "selected" : ""}"
130
- @click=${() => this.selectItem(index)}
131
- >
132
- ${content}
133
- </div>
134
- `;
135
- }
136
- renderListItem(item, index) {
137
- const content = this.renderCard ? this.renderCard(item, index) : this.renderDefaultCard(item);
138
- return html`
139
- <div
140
- class="card list-card ${this.selectedIndex === index ? "selected" : ""}"
141
- @click=${() => this.selectItem(index)}
142
- >
143
- ${content}
144
- </div>
145
- `;
146
- }
147
- renderDefaultCard(item) {
148
- const cols = this.getColumns();
149
- return html`
150
- <div class="card-content">
151
- ${cols.slice(0, 5).map((col) => {
152
- const value = item[col.key];
153
- return html`
154
- <div class="card-field">
155
- <span class="label">${col.label || this.formatLabel(col.key)}:</span>
156
- <span class="value">${this.formatValue(value)}</span>
157
- </div>
158
- `;
159
- })}
160
- </div>
161
- `;
162
- }
163
- getCellContent(item, column, index) {
164
- if (this.renderCell) {
165
- return this.renderCell(item, column, index);
166
- }
167
- return this.formatValue(item[column.key]);
168
- }
169
- getColumns() {
170
- if (this.columns?.length) {
171
- return this.columns;
172
- }
173
- if (this.items.length > 0) {
174
- const firstItem = this.items[0];
175
- return Object.keys(firstItem).map((key) => ({ key }));
176
- }
177
- return [];
178
- }
179
- formatLabel(key) {
180
- return key.replace(/([A-Z])/g, " $1").replace(/^./, (str) => str.toUpperCase()).trim();
181
- }
182
- formatValue(value) {
183
- if (value == null) return "—";
184
- if (typeof value === "boolean") return value ? "✓" : "✗";
185
- if (value instanceof Date) return value.toLocaleString();
186
- if (typeof value === "object") return JSON.stringify(value);
187
- return String(value);
188
- }
189
- switchMode(mode) {
190
- this.mode = mode;
191
- this.emit("mode-change", { mode });
192
- }
193
- selectItem(index) {
194
- this.selectedIndex = index;
195
- this.emit("select", {
196
- item: this.items[index],
197
- index
198
- });
199
- }
200
- }
201
- __decorateClass([
202
- property({ type: Array })
203
- ], UDataView.prototype, "items");
204
- __decorateClass([
205
- property({ type: String })
206
- ], UDataView.prototype, "mode");
207
- __decorateClass([
208
- property({ type: Array })
209
- ], UDataView.prototype, "columns");
210
- __decorateClass([
211
- property({ type: String })
212
- ], UDataView.prototype, "gridMinWidth");
213
- __decorateClass([
214
- property({ type: String })
215
- ], UDataView.prototype, "gap");
216
- __decorateClass([
217
- property({ attribute: false })
218
- ], UDataView.prototype, "renderCard");
219
- __decorateClass([
220
- property({ attribute: false })
221
- ], UDataView.prototype, "renderCell");
222
- __decorateClass([
223
- state()
224
- ], UDataView.prototype, "selectedIndex");
225
-
226
- export { UDataView };