@ticatec/uniface-element 0.1.14 → 0.1.15

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.
@@ -0,0 +1,9 @@
1
+ export default interface Column {
2
+ title: string;
3
+ field: string;
4
+ width: number;
5
+ align?: "left" | "center" | "right";
6
+ weight?: number;
7
+ formatter?: (value: any) => string;
8
+ escapeHTML?: boolean;
9
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,154 @@
1
+ <script lang="ts">
2
+
3
+ import {onMount, onDestroy, tick} from 'svelte';
4
+ import DataRow from "./DataRow.svelte";
5
+ import {type RowClickHandler, type TableOptions} from "./TableOptions";
6
+ import utils from "./utils";
7
+
8
+ // list array to display
9
+ export let list: Array<any>;
10
+ // Column definitions with configuration
11
+ export let columns: Array<Column>;
12
+ // Enable auto-scroll feature
13
+ export let autoScroll: boolean = false;
14
+ // Milliseconds between each scroll step
15
+ export let scrollInterval: number = 2000;
16
+ export let rowClickHandler: RowClickHandler | null = null;
17
+ //行高
18
+
19
+ // Height of the component in pixels
20
+ //table background color
21
+ export let options: TableOptions;
22
+
23
+ let tabOptions: TableOptions;
24
+
25
+ $: tabOptions = {headerHeight: 36, rowHeight: 32, ...options}
26
+
27
+
28
+ let id = (new Date().getTime() * 1000 + Math.floor(Math.random() * 1000)).toString(36);
29
+ let tableStyle: string = '';
30
+ let tableContainer: any;
31
+ let viewPanel: any;
32
+ let headerRow: any;
33
+ let scrollTimer: any;
34
+ let currentScrollIndex: number = 0;
35
+ let visibleRowCount: number = 0;
36
+
37
+ $: totalWeight = columns.reduce((sum, col) => sum + (col.weight || 0), 0);
38
+
39
+ let rowHeight: number;
40
+
41
+
42
+ let clonedRows: Array<any> = []; // 用于无缝滚动的克隆行
43
+ let viewWidth = 0;
44
+ let viewHeight = 0;
45
+ let resizeObserver: any;
46
+
47
+ onMount(async () => {
48
+ resizeObserver = new ResizeObserver(() => {
49
+ viewWidth = Math.round(viewPanel?.clientWidth) - 1;
50
+ viewHeight = Math.round(viewPanel?.clientHeight) - 1;
51
+ });
52
+ resizeObserver.observe(viewPanel);
53
+ });
54
+
55
+ onDestroy(() => {
56
+ resizeObserver.disconnect();
57
+ })
58
+
59
+
60
+ const setupAutoScroll = async () => {
61
+ if (autoScroll && tableContainer && list.length > 0) {
62
+ await tick();
63
+ const tableBody = tableContainer.querySelector('.table-body');
64
+ if (tableBody && tableBody.children.length > 0) {
65
+ rowHeight = tableBody.children[0].offsetHeight;
66
+ visibleRowCount = Math.floor((tableContainer.offsetHeight - headerRow.offsetHeight) / rowHeight);
67
+ if (list.length <= visibleRowCount) return;
68
+ clonedRows = [...list];
69
+ startAutoScroll();
70
+ }
71
+ }
72
+ }
73
+
74
+ const startAutoScroll = () => {
75
+ // Clear any existing timer
76
+ if (scrollTimer) clearInterval(scrollTimer);
77
+
78
+ currentScrollIndex = 0;
79
+
80
+ scrollTimer = setInterval(() => {
81
+ currentScrollIndex++;
82
+ const tableBody = tableContainer.querySelector('.table-body');
83
+ if (tableBody) {
84
+ tableBody.style.transform = `translateY(-${currentScrollIndex * rowHeight}px)`;
85
+ if (currentScrollIndex >= list.length) {
86
+ setTimeout(() => {
87
+ tableBody.style.transition = 'none';
88
+ tableBody.style.transform = `translateY(0)`;
89
+ currentScrollIndex = 0;
90
+
91
+ // 恢复过渡效果
92
+ setTimeout(() => {
93
+ tableBody.style.transition = 'transform 2s ease';
94
+ }, 50);
95
+ }, 50);
96
+ }
97
+ }
98
+ }, scrollInterval);
99
+ }
100
+
101
+ const stopAutoScroll = () => {
102
+ if (scrollTimer) {
103
+ clearInterval(scrollTimer);
104
+ scrollTimer = null;
105
+ }
106
+ }
107
+
108
+ onMount(async () => {
109
+ await setupAutoScroll();
110
+ });
111
+
112
+ onDestroy(() => {
113
+ stopAutoScroll();
114
+ });
115
+
116
+ $: if (list || autoScroll || scrollInterval) {
117
+ stopAutoScroll();
118
+ setupAutoScroll();
119
+ }
120
+
121
+ $: tableStyle = utils.generateTableStyle(id, columns, tabOptions, viewWidth);
122
+
123
+
124
+ </script>
125
+
126
+ <div id="tab_{id}" class="uniface-concise-datatable">
127
+ {@html tableStyle}
128
+ <div class="table-container" bind:this={tableContainer}>
129
+ <!-- Fixed header -->
130
+ <div class="table-header">
131
+ <div class="table-row" bind:this={headerRow}>
132
+ {#each columns as column, idx}
133
+ <div class="data-cell col_{idx}">
134
+ {column.title ?? ''}
135
+ </div>
136
+ {/each}
137
+ </div>
138
+ </div>
139
+
140
+ <!-- Scrollable body -->
141
+ <div class="table-body-container" bind:this={viewPanel} class:auto-scroll={autoScroll}>
142
+ <div class="table-body" style="transition: transform {autoScroll ? '2s' : '0s'} ease;">
143
+ {#each list as row, rowIndex}
144
+ <DataRow data={row} {columns} showAlternative={rowIndex % 2 == 1} on:click={rowClickHandler?.(row)}/>
145
+ {/each}
146
+ {#if autoScroll && list.length > visibleRowCount}
147
+ {#each list.slice(0, visibleRowCount) as row, rowIndex}
148
+ <DataRow data={row} {columns} showAlternative={rowIndex % 2 == 1} on:click={rowClickHandler?.(row)}/>
149
+ {/each}
150
+ {/if}
151
+ </div>
152
+ </div>
153
+ </div>
154
+ </div>
@@ -0,0 +1,26 @@
1
+ import { type RowClickHandler, type TableOptions } from "./TableOptions";
2
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
3
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
4
+ $$bindings?: Bindings;
5
+ } & Exports;
6
+ (internal: unknown, props: Props & {
7
+ $$events?: Events;
8
+ $$slots?: Slots;
9
+ }): Exports & {
10
+ $set?: any;
11
+ $on?: any;
12
+ };
13
+ z_$$bindings?: Bindings;
14
+ }
15
+ declare const ConciseListTable: $$__sveltets_2_IsomorphicComponent<{
16
+ list: Array<any>;
17
+ columns: Array<Column>;
18
+ autoScroll?: boolean;
19
+ scrollInterval?: number;
20
+ rowClickHandler?: RowClickHandler | null;
21
+ options: TableOptions;
22
+ }, {
23
+ [evt: string]: CustomEvent<any>;
24
+ }, {}, {}, string>;
25
+ type ConciseListTable = InstanceType<typeof ConciseListTable>;
26
+ export default ConciseListTable;
@@ -0,0 +1,22 @@
1
+ <script lang="ts">
2
+ import type Column from "./Column";
3
+
4
+ export let column: Column;
5
+ export let idx: number;
6
+
7
+ export let data: any;
8
+
9
+ let text: string;
10
+ let escapeHTML: boolean = false;
11
+
12
+ $: text = column.formatter ? column.formatter(data[column.field]) : data[column.field];
13
+
14
+ </script>
15
+
16
+ <div class="data-cell col_{idx}">
17
+ {#if escapeHTML}
18
+ {@html text}
19
+ {:else }
20
+ <span>{text}</span>
21
+ {/if}
22
+ </div>
@@ -1,3 +1,4 @@
1
+ import type Column from "./Column";
1
2
  interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
2
3
  new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
3
4
  $$bindings?: Bindings;
@@ -11,12 +12,12 @@ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> =
11
12
  };
12
13
  z_$$bindings?: Bindings;
13
14
  }
14
- declare const LinkButton: $$__sveltets_2_IsomorphicComponent<{
15
- text: any;
16
- action: any;
17
- style?: string;
15
+ declare const DataCell: $$__sveltets_2_IsomorphicComponent<{
16
+ column: Column;
17
+ idx: number;
18
+ data: any;
18
19
  }, {
19
20
  [evt: string]: CustomEvent<any>;
20
21
  }, {}, {}, string>;
21
- type LinkButton = InstanceType<typeof LinkButton>;
22
- export default LinkButton;
22
+ type DataCell = InstanceType<typeof DataCell>;
23
+ export default DataCell;
@@ -0,0 +1,15 @@
1
+ <script lang="ts">
2
+ import type Column from "./Column";
3
+ import DataCell from "./DataCell.svelte";
4
+
5
+ export let columns: Array<Column>;
6
+ export let data: any;
7
+
8
+ export let showAlternative: boolean;
9
+ </script>
10
+
11
+ <div class="table-row" class:alternative={showAlternative} on:click>
12
+ {#each columns as column, idx}
13
+ <DataCell {idx} {column} {data}/>
14
+ {/each}
15
+ </div>
@@ -0,0 +1,25 @@
1
+ import type Column from "./Column";
2
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
3
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
4
+ $$bindings?: Bindings;
5
+ } & Exports;
6
+ (internal: unknown, props: Props & {
7
+ $$events?: Events;
8
+ $$slots?: Slots;
9
+ }): Exports & {
10
+ $set?: any;
11
+ $on?: any;
12
+ };
13
+ z_$$bindings?: Bindings;
14
+ }
15
+ declare const DataRow: $$__sveltets_2_IsomorphicComponent<{
16
+ columns: Array<Column>;
17
+ data: any;
18
+ showAlternative: boolean;
19
+ }, {
20
+ click: MouseEvent;
21
+ } & {
22
+ [evt: string]: CustomEvent<any>;
23
+ }, {}, {}, string>;
24
+ type DataRow = InstanceType<typeof DataRow>;
25
+ export default DataRow;
@@ -0,0 +1,11 @@
1
+ export interface TableOptions {
2
+ backgroundColor?: string;
3
+ color?: string;
4
+ headerHeight?: number;
5
+ headerBackgroundColor?: string;
6
+ headerColor?: string;
7
+ alternativeBackgroundColor?: string;
8
+ alternativeColor?: string;
9
+ rowHeight?: number;
10
+ }
11
+ export type RowClickHandler = (row: any) => (event: MouseEvent) => void;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ import ConciseListTable from "./ConciseListTable.svelte";
2
+ import type Column from "./Column";
3
+ import type { TableOptions } from "./TableOptions";
4
+ export default ConciseListTable;
5
+ export type { Column, TableOptions };
@@ -0,0 +1,2 @@
1
+ import ConciseListTable from "./ConciseListTable.svelte";
2
+ export default ConciseListTable;
@@ -0,0 +1,6 @@
1
+ import type Column from "./Column";
2
+ import type { TableOptions } from "./TableOptions";
3
+ declare const _default: {
4
+ generateTableStyle: (id: string, columns: Array<Column>, options: TableOptions, viewWidth: number) => string;
5
+ };
6
+ export default _default;
@@ -0,0 +1,38 @@
1
+ const generateBlockStyle = (prefix, options, keys) => {
2
+ let style = '';
3
+ keys.forEach(key => {
4
+ if (options[key.code]) {
5
+ style += `${key.attr}: ${options[key.code]}${key.suffix ?? ''};\n`;
6
+ }
7
+ });
8
+ if (style.length > 0) {
9
+ return `${prefix} { ${style} }`;
10
+ }
11
+ else {
12
+ return '';
13
+ }
14
+ };
15
+ /**
16
+ *
17
+ * @param id
18
+ * @param columns
19
+ * @param options
20
+ * @param viewWidth
21
+ */
22
+ const generateTableStyle = (id, columns, options, viewWidth) => {
23
+ let style = '';
24
+ if (options && columns) {
25
+ style += generateBlockStyle(`#tab_${id}`, options, [{ code: 'backgroundColor', attr: 'background-color' }, { code: 'color', attr: 'color' }]);
26
+ style += generateBlockStyle(`#tab_${id} .table-row.alternative `, options, [{ code: 'alternativeBackgroundColor', attr: 'background-color' }, { code: 'alternativeColor', attr: 'color' }]);
27
+ style += generateBlockStyle(`#tab_${id} .table-header .table-row `, options, [{ code: 'headerBackgroundColor', attr: 'background-color' }, { code: 'headerColor', attr: 'color' }, { code: 'headerHeight', attr: 'height', suffix: 'px' }]);
28
+ style += generateBlockStyle(`#tab_${id} .table-body .table-row`, options, [{ code: 'headerHeight', attr: 'height', suffix: 'px' }]);
29
+ let totalWeight = columns.reduce((sum, col) => sum + (col.weight || 0), 0);
30
+ let tabWidth = columns.reduce((sum, col) => sum + col.width, 0);
31
+ let diff = (viewWidth - tabWidth) / totalWeight;
32
+ columns.forEach((col, idx) => {
33
+ style += `#tab_${id} .col_${idx} {\n width: ${col.width + (col.weight ?? 0) * diff}px; \n text-align: ${col.align ?? 'left'};} \n`;
34
+ });
35
+ }
36
+ return `<style>${style}</style>`;
37
+ };
38
+ export default { generateTableStyle };
@@ -96,6 +96,8 @@
96
96
  }
97
97
  }
98
98
 
99
+ $: rowHeight = rowHeight ?? 42;
100
+
99
101
  </script>
100
102
 
101
103
  <div id="tab-{id}" {style} class="uniface-data-table" class:cell-border={colBorder} class:row-border={rowBorder}>
@@ -1,9 +1,5 @@
1
1
  import type { GetRowActions } from "./RowAction";
2
2
  export default interface ActionsColumn {
3
- /**
4
- * 栏标题
5
- */
6
- title: string;
7
3
  /**
8
4
  * 宽度
9
5
  */
@@ -1,4 +1,4 @@
1
- export type HrefBuilder = (item: any) => Array<HrefLink | string> | HrefLink;
1
+ export type HrefBuilder = (item: any) => Array<HrefLink> | HrefLink;
2
2
  export type HrefAction = () => void;
3
3
  export default interface HrefLink {
4
4
  /**
@@ -3,7 +3,7 @@
3
3
  import DataRow from "./DataRow.svelte";
4
4
  import type DataColumn from "../lib/DataColumn";
5
5
  import type TableRow from "./TableRow";
6
- import {onMount} from "svelte";
6
+ import {onDestroy, onMount} from "svelte";
7
7
  import TableHeaderPanel from "./TableHeaderPanel.svelte";
8
8
  import UniDataTable, {type TableEventHandler} from "../UniDataTable";
9
9
  import {OrderDirection} from "../lib/OrderDirection";
@@ -52,6 +52,10 @@
52
52
  resizeObserver.observe(viewPanel);
53
53
  });
54
54
 
55
+ onDestroy(()=>{
56
+ resizeObserver.disconnect();
57
+ })
58
+
55
59
  const handleDataTableScroll = (e: Event) => {
56
60
  if (showVerticalScroll) {
57
61
  scrollTop = e.target?.scrollTop;
@@ -121,7 +125,7 @@
121
125
  <div class="expand-data-row" bind:clientHeight={inlineRowHeight}
122
126
  style="position: relative; box-sizing: content-box; width: 100%; height: auto">
123
127
  <div class="inline-panel">
124
- <svelte:component this={inlineComponent} data={row}/>
128
+ <svelte:component this={inlineComponent} data={row.data}/>
125
129
  </div>
126
130
  </div>
127
131
  {/if}
@@ -22,7 +22,7 @@
22
22
 
23
23
  </script>
24
24
  <div class="data-cell {col$class}">
25
- <div>
25
+ <div class="vertical-center">
26
26
  {#if column.render}
27
27
  <svelte:component this={column.render.component} {...column.render.props} {data}/>
28
28
  {:else if column.href}
@@ -1,22 +1,20 @@
1
1
  <script lang="ts">
2
+ import type HrefLink from "../lib/HrefLink";
2
3
  import type {HrefBuilder} from "../lib/HrefLink";
3
4
 
4
5
  export let data;
5
6
  export let href: HrefBuilder;
6
7
 
7
- let text: string;
8
- let action: any;
8
+ let list: Array<HrefLink> = [];
9
+
9
10
 
10
11
  $: {
11
12
  let h = href(data);
12
- if (Array.isArray(h)) {
13
-
14
- } else {
15
- text = h.text;
16
- action = h.action;
17
- }
13
+ list = Array.isArray(h) ? h : [h];
18
14
  }
19
15
  </script>
20
- <div>
21
- <a href="javascript:void(0)" on:click={()=>action(data)}>{text}</a>
16
+ <div style="display: flex; flex-direction: row; gap: 8px; justify-content: center">
17
+ {#each list as item, idx}
18
+ <a href="javascript:void(0)" on:click={()=>item.action()}>{item.text}</a>
19
+ {/each}
22
20
  </div>
@@ -10,8 +10,6 @@
10
10
  let escapeHTML: boolean = false;
11
11
 
12
12
 
13
-
14
-
15
13
  $: {
16
14
  let value = tableUtils.extractFieldValue(data, column.field);
17
15
  if (column.formatter) {
@@ -26,10 +24,9 @@
26
24
 
27
25
  </script>
28
26
 
29
- <div class="cell-text">
30
- {#if escapeHTML == true}
31
- {@html text}
32
- {:else}
33
- <span>{text}</span>
34
- {/if}
35
- </div>
27
+
28
+ {#if escapeHTML == true}
29
+ {@html text}
30
+ {:else}
31
+ <span>{text}</span>
32
+ {/if}
@@ -3076,7 +3076,6 @@
3076
3076
  box-sizing: border-box;
3077
3077
  overflow-y: auto;
3078
3078
  overflow-x: hidden;
3079
- padding: var(--uniface-navigator-vertical-padding, 16px) 0;
3080
3079
  position: relative;
3081
3080
  user-select: none;
3082
3081
  }
@@ -3086,6 +3085,16 @@
3086
3085
  position: relative;
3087
3086
  background: linear-gradient(to right, transparent 12px, lightgray 12px, lightgray 13px, transparent 13px);
3088
3087
  }
3088
+ .uniface-navigator-panel .navigator-content .uniface-navigator-item:first-child {
3089
+ background-size: 100% 60%; /* 只占元素高度的一半 */
3090
+ background-position: bottom; /* 从底部开始 */
3091
+ background-repeat: no-repeat; /* 防止背景重复 */
3092
+ }
3093
+ .uniface-navigator-panel .navigator-content .uniface-navigator-item:last-child {
3094
+ background-size: 100% 60%; /* 只占元素高度的一半 */
3095
+ background-position: top; /* 从底部开始 */
3096
+ background-repeat: no-repeat; /* 防止背景重复 */
3097
+ }
3089
3098
  .uniface-navigator-panel .navigator-content .uniface-navigator-item.nav-completed {
3090
3099
  color: var(--uniface-navigator-completed-text-color, #374151);
3091
3100
  }
@@ -3119,11 +3128,11 @@
3119
3128
  .uniface-navigator-panel .navigator-content .uniface-navigator-item.active::before {
3120
3129
  content: "";
3121
3130
  position: absolute;
3122
- left: 6px;
3131
+ left: 5px;
3123
3132
  top: 50%;
3124
3133
  transform: translateY(-50%);
3125
- width: 5px;
3126
- height: 5px;
3134
+ width: 15px;
3135
+ height: 15px;
3127
3136
  border: 4px solid var(--uniface-active-label-text-color, #0061FF);
3128
3137
  border-radius: 50%; /* 圆形 */
3129
3138
  background-color: white;
@@ -3704,10 +3713,6 @@
3704
3713
  border-right: none;
3705
3714
  }
3706
3715
  .uniface-data-table .data-cell > div:first-child {
3707
- width: 100%;
3708
- position: relative;
3709
- top: 50%;
3710
- transform: translateY(-50%);
3711
3716
  overflow: hidden;
3712
3717
  }
3713
3718
  .uniface-data-table .data-row {
@@ -3781,9 +3786,6 @@
3781
3786
  right: 4px;
3782
3787
  cursor: pointer;
3783
3788
  }
3784
- .uniface-data-table .left-fixed-panel .indicator-cell .expand-icon:active {
3785
- top: 5px;
3786
- }
3787
3789
  .uniface-data-table .left-fixed-panel .indicator-cell:hover .expand-icon {
3788
3790
  display: block;
3789
3791
  }
@@ -3806,19 +3808,6 @@
3806
3808
  white-space: nowrap;
3807
3809
  position: relative;
3808
3810
  }
3809
- .uniface-data-table .table-row {
3810
- position: relative;
3811
- display: flex;
3812
- width: 100%;
3813
- flex-wrap: nowrap;
3814
- flex-direction: row;
3815
- align-items: center;
3816
- background-color: var(--uniface-data-table-background-color, #ffffff);
3817
- height: 36px;
3818
- }
3819
- .uniface-data-table .table-row.alternative {
3820
- background-color: var(--uniface-data-table-background-color, #f7f7f7);
3821
- }
3822
3811
  .uniface-data-table.row-border .table-row {
3823
3812
  border-bottom: 1px solid var(--uniface-data-table-row-border-color, #f0f0f0);
3824
3813
  }
@@ -3990,6 +3979,80 @@
3990
3979
  width: fit-content;
3991
3980
  }
3992
3981
 
3982
+ :root {
3983
+ --uniface-concise-table-primary-color: #333;
3984
+ --uniface-concise-table-primary-background-color: #ffffff;
3985
+ --uniface-concise-table-out-border: #333;
3986
+ --uniface-concise-table-header-background: #E1F5FE;
3987
+ --uniface-concise-table-header-color: #333;
3988
+ --uniface-concise-table-header-line-color: #fff;
3989
+ --uniface-concise-table-data-line-color: #7f7f7f;
3990
+ --uniface-concise-table-fixed-columns-background: #E0E0E0;
3991
+ --uniface-concise-table-bg: unset;
3992
+ }
3993
+
3994
+ .uniface-concise-datatable {
3995
+ width: 100%;
3996
+ height: 100%;
3997
+ overflow: hidden;
3998
+ display: flex;
3999
+ flex-direction: column;
4000
+ color: var(--uniface-concise-table-bg, unset);
4001
+ }
4002
+ .uniface-concise-datatable .table-container {
4003
+ display: flex;
4004
+ flex-direction: column;
4005
+ height: 100%;
4006
+ width: 100%;
4007
+ overflow: hidden;
4008
+ }
4009
+ .uniface-concise-datatable .table-row {
4010
+ display: flex;
4011
+ width: 100%;
4012
+ position: relative;
4013
+ align-items: center;
4014
+ }
4015
+ .uniface-concise-datatable .table-row .data-cell {
4016
+ overflow: hidden;
4017
+ text-overflow: ellipsis;
4018
+ white-space: nowrap;
4019
+ padding: 2px 4px;
4020
+ }
4021
+ .uniface-concise-datatable .table-header {
4022
+ background-color: #f5f5f5;
4023
+ padding: 0;
4024
+ flex-shrink: 0;
4025
+ z-index: 10;
4026
+ user-select: none;
4027
+ }
4028
+ .uniface-concise-datatable .table-header .table-row {
4029
+ font-weight: 600;
4030
+ }
4031
+ .uniface-concise-datatable .table-header .table-row .data-cell {
4032
+ text-align: center !important;
4033
+ }
4034
+ .uniface-concise-datatable .table-body-container {
4035
+ flex: 1;
4036
+ overflow-y: auto;
4037
+ overflow-x: hidden;
4038
+ }
4039
+ .uniface-concise-datatable .table-body-container .table-body {
4040
+ width: 100%;
4041
+ }
4042
+ .uniface-concise-datatable .table-body-container .table-row {
4043
+ cursor: pointer;
4044
+ }
4045
+ .uniface-concise-datatable .table-body-container .table-row.alternative {
4046
+ background-color: var(--uniface-concise-table-row-alter-bg, #F8FAFC);
4047
+ color: var(--uniface-concise-table-row-alter-color, #374151);
4048
+ }
4049
+ .uniface-concise-datatable .table-body-container .table-row:hover {
4050
+ background-color: #f9f9f9;
4051
+ }
4052
+ .uniface-concise-datatable .table-body-container.auto-scroll {
4053
+ overflow-y: hidden;
4054
+ }
4055
+
3993
4056
  html {
3994
4057
  box-sizing: border-box;
3995
4058
  }
@@ -72,16 +72,14 @@
72
72
  <div class="node-item" class:selected={activeNode===node} on:click={handleNodeClick} aria-hidden="true"
73
73
  on:contextmenu={handleContextMenu}>
74
74
  <div class="item-icon">
75
- {#if loading}
76
- <img alt="" style="cursor: default" src={iconLoading}/>
77
- {:else }
78
- <span aria-hidden="true" on:click={handleNodeIconClick}>{expanded ? '▼' : '▶'}</span>
75
+ {#if isBranch()}
76
+ {#if loading}
77
+ <img alt="" style="cursor: default" src={iconLoading}/>
78
+ {:else }
79
+ <span aria-hidden="true" on:click={handleNodeIconClick}>{expanded ? '▼' : '▶'}</span>
80
+ {/if}
79
81
  {/if}
80
82
  </div>
81
- <div class="item-icon" style="margin-left: 4px;">
82
- <i class={isBranch() ? "uniface-icon-folder" : "uniface-icon-file"}
83
- aria-hidden="true"></i>
84
- </div>
85
83
  <span class="item-text">{node.text}</span>
86
84
  </div>
87
85
  {#if expanded && node.children}
@@ -24,7 +24,7 @@ const buildTreeNode = (list, idKey, joinKey, textField, valueField, isRoot, sort
24
24
  else {
25
25
  let parent = map.get(item[joinKey]);
26
26
  if (parent != null) {
27
- parent.children = [...parent.children, node];
27
+ parent.children = [...(parent.children ?? []), node];
28
28
  node.parent = parent;
29
29
  map.set(item[idKey], node);
30
30
  }
@@ -36,7 +36,7 @@ const buildTreeNode = (list, idKey, joinKey, textField, valueField, isRoot, sort
36
36
  else {
37
37
  let parent = map.get(item[joinKey]);
38
38
  if (parent != null) {
39
- parent.children = [...parent.children, item];
39
+ parent.children = [...(parent.children ?? []), item];
40
40
  node.parent = parent;
41
41
  map.set(item[idKey], node);
42
42
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ticatec/uniface-element",
3
- "version": "0.1.14",
3
+ "version": "0.1.15",
4
4
  "description": "uniface web elements",
5
5
  "scripts": {
6
6
  "dev": "vite dev",
@@ -100,6 +100,10 @@
100
100
  "types": "./dist/common/FullscreenOverlay.svelte.d.ts",
101
101
  "import": "./dist/common/FullscreenOverlay.svelte"
102
102
  },
103
+ "./ConciseDataTable": {
104
+ "types": "./dist/concise-data-table/index.d.ts",
105
+ "import": "./dist/concise-data-table/index.js"
106
+ },
103
107
  "./PromptsTextEditor": {
104
108
  "types": "./dist/prompts-text-editor/index.d.ts",
105
109
  "import": "./dist/prompts-text-editor/index.js"
@@ -1,19 +0,0 @@
1
- <script lang="ts">
2
- export let text;
3
- export let action;
4
- export let style: string = '';
5
-
6
- let silent: boolean = false;
7
-
8
- const handleButtonClick = (e) => {
9
- if (!silent) {
10
- silent = true;
11
- setTimeout(()=>{silent=false}, 500);
12
- action();
13
- }
14
- }
15
-
16
- </script>
17
- <a {style} class="action-button" href="javascript:void(0)" on:click={handleButtonClick}>
18
- <span>{text}</span>
19
- </a>