nuance-ui 0.1.28 → 0.1.29

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.
package/dist/module.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "compatibility": {
5
5
  "nuxt": "^4.0.0"
6
6
  },
7
- "version": "0.1.28",
7
+ "version": "0.1.29",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "1.0.2",
10
10
  "unbuild": "3.6.1"
@@ -1,6 +1,11 @@
1
1
  import type { Updater } from '@tanstack/vue-table';
2
2
  import type { Ref } from 'vue';
3
- import type { TableColumn, TableData } from './model.js';
3
+ import type { TableColumn, TableData, TableProps, TableRow } from './model.js';
4
4
  export declare function processColumns<T extends TableData>(columns: TableColumn<T>[]): TableColumn<T>[];
5
5
  export declare function valueUpdater<T extends Updater<any>>(updaterOrValue: T, ref: Ref): void;
6
6
  export declare function resolveValue<T, A = undefined>(prop: T | ((arg: A) => T), arg?: A): T | undefined;
7
+ export declare function createRowHandlers<T extends TableData>(props: TableProps<T>): {
8
+ onRowSelect: (e: Event, row: TableRow<T>) => void;
9
+ onRowHover: (e: Event, row: TableRow<T> | null) => void;
10
+ onRowContextmenu: (e: Event, row: TableRow<T>) => void;
11
+ };
@@ -22,3 +22,34 @@ export function resolveValue(prop, arg) {
22
22
  return prop(arg);
23
23
  return prop;
24
24
  }
25
+ export function createRowHandlers(props) {
26
+ function onRowSelect(e, row) {
27
+ if (!props?.onSelect)
28
+ return;
29
+ const target = e.target;
30
+ const isInteractive = target.closest("button") || target.closest("a");
31
+ if (isInteractive)
32
+ return;
33
+ e.preventDefault();
34
+ e.stopPropagation();
35
+ props.onSelect(e, row);
36
+ }
37
+ function onRowHover(e, row) {
38
+ if (!props?.onHover)
39
+ return;
40
+ props.onHover(e, row);
41
+ }
42
+ function onRowContextmenu(e, row) {
43
+ if (!props?.onContextmenu)
44
+ return;
45
+ if (Array.isArray(props.onContextmenu))
46
+ props.onContextmenu.forEach((fn) => fn(e, row));
47
+ else
48
+ props.onContextmenu(e, row);
49
+ }
50
+ return {
51
+ onRowSelect,
52
+ onRowHover,
53
+ onRowContextmenu
54
+ };
55
+ }
@@ -7,15 +7,12 @@ import {
7
7
  getSortedRowModel,
8
8
  useVueTable
9
9
  } from "@tanstack/vue-table";
10
- import { useVirtualizer } from "@tanstack/vue-virtual";
11
10
  import { reactivePick, unrefElement } from "@vueuse/core";
12
11
  import { useStyleResolver } from "#imports";
13
- import defu from "defu";
14
- import { computed, ref, toRef, useTemplateRef, watch } from "vue";
12
+ import { computed, ref, useTemplateRef, watch } from "vue";
15
13
  import { getThemeColor } from "../../utils";
16
14
  import Box from "../box.vue";
17
- import TableRow from "./_ui/table-row.vue";
18
- import { processColumns, resolveValue, valueUpdater } from "./lib";
15
+ import { createRowHandlers, processColumns, resolveValue, valueUpdater } from "./lib";
19
16
  defineOptions({ inheritAttrs: false });
20
17
  const props = defineProps({
21
18
  data: { type: Array, required: false },
@@ -204,33 +201,11 @@ const rows = computed(() => table.getRowModel().rows);
204
201
  watch(() => props.data, () => {
205
202
  data.value = props.data ? [...props.data] : [];
206
203
  }, props.watchOptions);
207
- const virtualizerProps = toRef(() => defu(typeof props.virtualize === "boolean" ? {} : props.virtualize, {
208
- estimateSize: 65,
209
- overscan: 12
210
- }));
211
- const virtualizer = !!props.virtualize && useVirtualizer({
212
- ...virtualizerProps.value,
213
- get count() {
214
- return rows.value.length;
215
- },
216
- getScrollElement: () => unrefElement(rootRef),
217
- estimateSize: (index) => {
218
- const estimate = virtualizerProps.value.estimateSize;
219
- return typeof estimate === "function" ? estimate(index) : estimate;
220
- }
221
- });
222
- const renderedSize = computed(() => {
223
- if (!virtualizer)
224
- return 0;
225
- const virtualItems = virtualizer.value.getVirtualItems();
226
- if (!virtualItems?.length)
227
- return 0;
228
- return virtualItems.reduce((sum, item) => sum + item.size, 0);
229
- });
230
204
  const style = computed(() => useStyleResolver((theme) => ({
231
205
  "--table-loader-color": props.loadingColor ? getThemeColor(props.loadingColor, theme) : void 0,
232
206
  "--vertical-align": props.verticalAlign
233
207
  })));
208
+ const { onRowContextmenu, onRowHover, onRowSelect } = createRowHandlers(props);
234
209
  defineExpose({
235
210
  get $el() {
236
211
  return unrefElement(rootRef);
@@ -241,15 +216,7 @@ defineExpose({
241
216
  </script>
242
217
 
243
218
  <template>
244
- <Box
245
- ref='rootRef'
246
- :class='[$style.root, props.classes?.root]'
247
- :style='[
248
- virtualizer ? { height: `${virtualizer.getTotalSize()}px` } : void 0,
249
- style
250
- ]'
251
- :mod='{ virtualize: !!virtualizer }'
252
- >
219
+ <Box ref='rootRef' :class='[$style.root, props.classes?.root]' :style>
253
220
  <table ref='tableRef' :class='[$style.table, props.classes?.table]'>
254
221
  <caption v-if='caption || $slots.caption' :class='props.classes?.caption'>
255
222
  <slot name='caption'>
@@ -274,8 +241,15 @@ defineExpose({
274
241
  :scope="header.colSpan > 1 ? 'colgroup' : 'col'"
275
242
  :colspan='header.colSpan > 1 ? header.colSpan : void 0'
276
243
  :rowspan='header.rowSpan > 1 ? header.rowSpan : void 0'
277
- :class='[$style.th, props.classes?.th, resolveValue(header.column.columnDef.meta?.class?.th, header)]'
278
- :style='resolveValue(header.column.columnDef.meta?.style?.th, header)'
244
+ :class='[
245
+ $style.th,
246
+ props.classes?.th,
247
+ resolveValue(header.column.columnDef.meta?.class?.th, header)
248
+ ]'
249
+ :style='[
250
+ { width: header.getSize() !== 150 ? `${header.getSize()}px` : void 0 },
251
+ resolveValue(header.column.columnDef.meta?.style?.th, header)
252
+ ]'
279
253
  >
280
254
  <slot :name='`${header.id}-header`' v-bind='header.getContext()'>
281
255
  <FlexRender
@@ -294,36 +268,47 @@ defineExpose({
294
268
  <slot name='body-top' />
295
269
 
296
270
  <template v-if='rows.length'>
297
- <template v-if='virtualizer'>
298
- <template v-for='(virtualRow, index) in virtualizer.getVirtualItems()' :key='rows[virtualRow.index]?.id'>
299
- <TableRow
300
- :row='rows[virtualRow.index]'
301
- :class='[$style.tr, props.classes?.tr, resolveValue(table.options.meta?.class?.tr, virtualRow)]'
302
- :style='[
303
- {
304
- height: `${virtualRow.size}px`,
305
- transform: `translateY(${virtualRow.start - index * virtualRow.size}px)`
306
- },
307
- resolveValue(table.options.meta?.style?.tr, virtualRow)
308
- ]'
309
- :on-select='props?.onSelect'
310
- :on-hover='props?.onHover'
311
- :on-contextmenu='props?.onContextmenu'
312
- />
313
- </template>
314
- </template>
315
-
316
- <template v-else>
317
- <TableRow
318
- v-for='row in rows'
319
- :key='row.id'
320
- :row='row'
271
+ <template v-for='row in rows' :key='row.id'>
272
+ <Box
273
+ is='tr'
274
+ :mod='{
275
+ selected: row.getIsSelected(),
276
+ expanded: row.getIsExpanded(),
277
+ selectable: !!onSelect || !!onHover || !!onContextmenu
278
+ }'
279
+ :role="onSelect ? 'button' : void 0"
280
+ :tabindex='onSelect ? 0 : void 0'
321
281
  :class='[$style.tr, props.classes?.tr, resolveValue(table.options.meta?.class?.tr, row)]'
322
282
  :style='resolveValue(table.options.meta?.style?.tr, row)'
323
- :on-select='props?.onSelect'
324
- :on-hover='props?.onHover'
325
- :on-contextmenu='props?.onContextmenu'
326
- />
283
+ @click='onRowSelect($event, row)'
284
+ @pointerenter='onRowHover($event, row)'
285
+ @pointerleave='onRowHover($event, null)'
286
+ @contextmenu='onRowContextmenu($event, row)'
287
+ >
288
+ <Box
289
+ is='td'
290
+ v-for='cell in row.getVisibleCells()'
291
+ :key='cell.id'
292
+ :mod='{ pinned: cell.column.getIsPinned() }'
293
+ :colspan='resolveValue(cell.column.columnDef.meta?.colspan?.td, cell)'
294
+ :rowspan='resolveValue(cell.column.columnDef.meta?.rowspan?.td, cell)'
295
+ :class='resolveValue(cell.column.columnDef.meta?.class?.td, cell)'
296
+ :style='[
297
+ { width: cell.column.getSize() !== 150 ? `${cell.column.getSize()}px` : void 0 },
298
+ resolveValue(cell.column.columnDef.meta?.style?.td, cell)
299
+ ]'
300
+ >
301
+ <slot :name='`${cell.column.id}-cell`' v-bind='cell.getContext()'>
302
+ <FlexRender :render='cell.column.columnDef.cell' :props='cell.getContext()' />
303
+ </slot>
304
+ </Box>
305
+ </Box>
306
+
307
+ <tr v-if='row.getIsExpanded()'>
308
+ <td :colspan='row.getAllCells().length'>
309
+ <slot name='expanded' :row='row' />
310
+ </td>
311
+ </tr>
327
312
  </template>
328
313
  </template>
329
314
 
@@ -348,7 +333,6 @@ defineExpose({
348
333
  is='tfoot'
349
334
  v-if='hasFooter'
350
335
  :class='[$style.tfoot, props.classes?.tfoot]'
351
- :style='virtualizer ? { transform: `translateY(${virtualizer.getTotalSize() - renderedSize}px)` } : void 0'
352
336
  :mod='{ sticky: props.sticky === "footer" || props.sticky === true }'
353
337
  >
354
338
  <tr :class='[$style.separator, props.classes?.separator]' />
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nuance-ui",
3
- "version": "0.1.28",
3
+ "version": "0.1.29",
4
4
  "description": "A UI Library for Modern Web Apps, powered by Vue.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,35 +0,0 @@
1
- import type { Row } from '@tanstack/vue-table';
2
- import type { TableData, TableRow } from '../model.js';
3
- export interface TableRowProps<T extends TableData> {
4
- row: Row<T>;
5
- onSelect?: (e: Event, row: TableRow<T>) => void;
6
- onHover?: (e: Event, row: TableRow<T> | null) => void;
7
- onContextmenu?: ((e: Event, row: TableRow<T>) => void) | Array<((e: Event, row: TableRow<T>) => void)>;
8
- }
9
- declare const __VLS_export: <T extends TableData>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
10
- props: __VLS_PrettifyLocal<TableRowProps<T>> & import("vue").PublicProps;
11
- expose: (exposed: {}) => void;
12
- attrs: any;
13
- slots: {
14
- [x: `${string}-cell`]: ((props: {
15
- cell: import("@tanstack/table-core").Cell<T, unknown>;
16
- column: import("@tanstack/table-core").Column<T, unknown>;
17
- getValue: import("@tanstack/table-core").Getter<unknown>;
18
- renderValue: import("@tanstack/table-core").Getter<unknown>;
19
- row: Row<T>;
20
- table: import("@tanstack/table-core").Table<T>;
21
- }) => any) | undefined;
22
- } & {
23
- expanded?: (props: {
24
- row: Row<T>;
25
- }) => any;
26
- };
27
- emit: {};
28
- }>) => import("vue").VNode & {
29
- __ctx?: Awaited<typeof __VLS_setup>;
30
- };
31
- declare const _default: typeof __VLS_export;
32
- export default _default;
33
- type __VLS_PrettifyLocal<T> = {
34
- [K in keyof T as K]: T[K];
35
- } & {};
@@ -1,74 +0,0 @@
1
- <script setup>
2
- import { FlexRender } from "@tanstack/vue-table";
3
- import Box from "../../box.vue";
4
- import { resolveValue } from "../lib";
5
- const { row, onSelect, onHover, onContextmenu } = defineProps({
6
- row: { type: Object, required: true },
7
- onSelect: { type: Function, required: false },
8
- onHover: { type: Function, required: false },
9
- onContextmenu: { type: [Function, Array], required: false }
10
- });
11
- function onRowSelect(e, row2) {
12
- if (!onSelect)
13
- return;
14
- const target = e.target;
15
- const isInteractive = target.closest("button") || target.closest("a");
16
- if (isInteractive)
17
- return;
18
- e.preventDefault();
19
- e.stopPropagation();
20
- onSelect(e, row2);
21
- }
22
- function onRowHover(e, row2) {
23
- if (!onHover)
24
- return;
25
- onHover(e, row2);
26
- }
27
- function onRowContextmenu(e, row2) {
28
- if (!onContextmenu)
29
- return;
30
- if (Array.isArray(onContextmenu))
31
- onContextmenu.forEach((fn) => fn(e, row2));
32
- else
33
- onContextmenu(e, row2);
34
- }
35
- </script>
36
-
37
- <template>
38
- <Box
39
- is='tr'
40
- v-bind='$attrs'
41
- :mod='{
42
- selected: row.getIsSelected(),
43
- expanded: row.getIsExpanded(),
44
- selectable: !!onSelect || !!onHover || !!onContextmenu
45
- }'
46
- :role="onSelect ? 'button' : void 0"
47
- :tabindex='onSelect ? 0 : void 0'
48
- @click='onRowSelect($event, row)'
49
- @pointerenter='onRowHover($event, row)'
50
- @pointerleave='onRowHover($event, null)'
51
- @contextmenu='onRowContextmenu($event, row)'
52
- >
53
- <Box
54
- is='td'
55
- v-for='cell in row.getVisibleCells()'
56
- :key='cell.id'
57
- :mod='{ pinned: cell.column.getIsPinned() }'
58
- :colspan='resolveValue(cell.column.columnDef.meta?.colspan?.td, cell)'
59
- :rowspan='resolveValue(cell.column.columnDef.meta?.rowspan?.td, cell)'
60
- :class='resolveValue(cell.column.columnDef.meta?.class?.td, cell)'
61
- :style='resolveValue(cell.column.columnDef.meta?.style?.td, cell)'
62
- >
63
- <slot :name='`${cell.column.id}-cell`' v-bind='cell.getContext()'>
64
- <FlexRender :render='cell.column.columnDef.cell' :props='cell.getContext()' />
65
- </slot>
66
- </Box>
67
- </Box>
68
-
69
- <tr v-if='row.getIsExpanded()'>
70
- <td :colspan='row.getAllCells().length'>
71
- <slot name='expanded' :row='row' />
72
- </td>
73
- </tr>
74
- </template>
@@ -1,35 +0,0 @@
1
- import type { Row } from '@tanstack/vue-table';
2
- import type { TableData, TableRow } from '../model.js';
3
- export interface TableRowProps<T extends TableData> {
4
- row: Row<T>;
5
- onSelect?: (e: Event, row: TableRow<T>) => void;
6
- onHover?: (e: Event, row: TableRow<T> | null) => void;
7
- onContextmenu?: ((e: Event, row: TableRow<T>) => void) | Array<((e: Event, row: TableRow<T>) => void)>;
8
- }
9
- declare const __VLS_export: <T extends TableData>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
10
- props: __VLS_PrettifyLocal<TableRowProps<T>> & import("vue").PublicProps;
11
- expose: (exposed: {}) => void;
12
- attrs: any;
13
- slots: {
14
- [x: `${string}-cell`]: ((props: {
15
- cell: import("@tanstack/table-core").Cell<T, unknown>;
16
- column: import("@tanstack/table-core").Column<T, unknown>;
17
- getValue: import("@tanstack/table-core").Getter<unknown>;
18
- renderValue: import("@tanstack/table-core").Getter<unknown>;
19
- row: Row<T>;
20
- table: import("@tanstack/table-core").Table<T>;
21
- }) => any) | undefined;
22
- } & {
23
- expanded?: (props: {
24
- row: Row<T>;
25
- }) => any;
26
- };
27
- emit: {};
28
- }>) => import("vue").VNode & {
29
- __ctx?: Awaited<typeof __VLS_setup>;
30
- };
31
- declare const _default: typeof __VLS_export;
32
- export default _default;
33
- type __VLS_PrettifyLocal<T> = {
34
- [K in keyof T as K]: T[K];
35
- } & {};