@shwfed/nuxt 0.1.16 → 0.1.17
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 +1 -1
- package/dist/runtime/components/app.vue +8 -0
- package/dist/runtime/components/table.d.vue.ts +5 -4
- package/dist/runtime/components/table.vue +60 -37
- package/dist/runtime/components/table.vue.d.ts +5 -4
- package/dist/runtime/composables/useTableRenderers.d.ts +1 -1
- package/dist/runtime/table-renderers/builtins.js +13 -7
- package/dist/runtime/table-renderers/registry.d.ts +6 -9
- package/dist/runtime/table-renderers/registry.js +2 -1
- package/package.json +1 -1
package/dist/module.json
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import type { RowData, TableOptions } from '@tanstack/vue-table';
|
|
2
2
|
export type Expression = string;
|
|
3
|
+
export type Render = string | Readonly<{
|
|
4
|
+
id: string;
|
|
5
|
+
props: unknown;
|
|
6
|
+
}>;
|
|
3
7
|
export type Accessor = string | Readonly<{
|
|
4
8
|
read: Expression;
|
|
5
9
|
write: Expression;
|
|
@@ -9,10 +13,7 @@ export type Column = Readonly<{
|
|
|
9
13
|
title?: string;
|
|
10
14
|
accessor?: Accessor;
|
|
11
15
|
accessorKey?: string;
|
|
12
|
-
renderer?:
|
|
13
|
-
id: string;
|
|
14
|
-
props: unknown;
|
|
15
|
-
}>;
|
|
16
|
+
renderer?: Render;
|
|
16
17
|
tooltip?: string;
|
|
17
18
|
size?: number;
|
|
18
19
|
enableSorting?: boolean;
|
|
@@ -6,7 +6,6 @@ import { getProperty } from "dot-prop";
|
|
|
6
6
|
import { Pagination } from "reka-ui/namespaced";
|
|
7
7
|
import { computed, ref } from "vue";
|
|
8
8
|
import { useNuxtApp } from "#app";
|
|
9
|
-
import { useCheating } from "../composables/useCheating";
|
|
10
9
|
import { useTableRenderers } from "../composables/useTableRenderers";
|
|
11
10
|
import Tooltip from "./tooltip.vue";
|
|
12
11
|
</script>
|
|
@@ -23,7 +22,6 @@ const props = defineProps({
|
|
|
23
22
|
cellStyles: { type: String, required: false, default: void 0 },
|
|
24
23
|
props: { type: Object, required: false, default: void 0 }
|
|
25
24
|
});
|
|
26
|
-
const isCheating = useCheating();
|
|
27
25
|
const { $dsl, $markdown } = useNuxtApp();
|
|
28
26
|
const { resolveTableRenderer } = useTableRenderers();
|
|
29
27
|
const containerRef = ref(null);
|
|
@@ -39,29 +37,10 @@ function genColumnId(column) {
|
|
|
39
37
|
return crypto.randomUUID();
|
|
40
38
|
}
|
|
41
39
|
function translate(column) {
|
|
42
|
-
const rendererId = typeof column.renderer === "string" ? column.renderer : column.renderer?.id ? column.renderer.id : "table.renderer.text";
|
|
43
|
-
const rendererProps = column.renderer && typeof column.renderer === "object" && "props" in column.renderer ? column.renderer.props : null;
|
|
44
|
-
const renderer = resolveTableRenderer(rendererId);
|
|
45
|
-
const options = renderer.parseOptions(rendererProps);
|
|
46
|
-
const helpers = {
|
|
47
|
-
renderInline,
|
|
48
|
-
evaluate: $dsl.evaluate
|
|
49
|
-
};
|
|
50
|
-
const header = (ctx) => {
|
|
51
|
-
if (renderer.header) {
|
|
52
|
-
return renderer.header({
|
|
53
|
-
ctx,
|
|
54
|
-
title: typeof column.title === "string" ? column.title : void 0,
|
|
55
|
-
options,
|
|
56
|
-
helpers
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
return typeof column.title === "string" ? column.title : void 0;
|
|
60
|
-
};
|
|
61
40
|
if (Array.isArray(column.columns) && column.columns.length > 0) {
|
|
62
41
|
return {
|
|
63
42
|
id: column.id ?? genColumnId(column),
|
|
64
|
-
header,
|
|
43
|
+
header: column.title,
|
|
65
44
|
columns: column.columns?.map((column2) => translate(column2)) ?? [],
|
|
66
45
|
enableSorting: column.enableSorting ?? false,
|
|
67
46
|
enableMultiSort: column.enableMultiSorting,
|
|
@@ -73,13 +52,14 @@ function translate(column) {
|
|
|
73
52
|
}
|
|
74
53
|
};
|
|
75
54
|
}
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
};
|
|
55
|
+
const renderer = resolveTableRenderer(typeof column.renderer === "string" ? column.renderer : column.renderer?.id ? column.renderer.id : "table.renderer.text");
|
|
56
|
+
const options = renderer.parseOptions(column.renderer && typeof column.renderer === "object" && "props" in column.renderer ? column.renderer.props : null);
|
|
79
57
|
return {
|
|
80
58
|
id: column.id ?? genColumnId(column),
|
|
81
|
-
header,
|
|
82
|
-
cell
|
|
59
|
+
header: (ctx) => renderer.header?.({ ctx, options }) ?? column.title,
|
|
60
|
+
cell: (ctx) => {
|
|
61
|
+
return renderer.cell({ ctx, options });
|
|
62
|
+
},
|
|
83
63
|
accessorFn: (row, index) => {
|
|
84
64
|
const key = column.accessorKey ? column.accessorKey : column.accessor;
|
|
85
65
|
if (typeof key === "string") {
|
|
@@ -224,15 +204,24 @@ function getCellStyles(ctx) {
|
|
|
224
204
|
return {};
|
|
225
205
|
}
|
|
226
206
|
}
|
|
227
|
-
function
|
|
207
|
+
function shouldHaveRightBorder(column) {
|
|
228
208
|
switch (column.getIsPinned()) {
|
|
229
209
|
case "left":
|
|
230
|
-
return
|
|
231
|
-
// why would anyone pin all columns to the left?
|
|
210
|
+
return true;
|
|
232
211
|
case "right":
|
|
233
212
|
return !column.getIsLastColumn("right");
|
|
234
213
|
case false:
|
|
235
|
-
return !column.getIsLastColumn("center")
|
|
214
|
+
return !column.getIsLastColumn("center");
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
function shouldHaveLeftBorder(column) {
|
|
218
|
+
switch (column.getIsPinned()) {
|
|
219
|
+
case "left":
|
|
220
|
+
return false;
|
|
221
|
+
case "right":
|
|
222
|
+
return true;
|
|
223
|
+
case false:
|
|
224
|
+
return false;
|
|
236
225
|
}
|
|
237
226
|
}
|
|
238
227
|
function pinnedStyle(column) {
|
|
@@ -263,11 +252,10 @@ function getSortIcon(column) {
|
|
|
263
252
|
<template>
|
|
264
253
|
<div
|
|
265
254
|
class="flex flex-col h-full"
|
|
266
|
-
:style="isCheating ? { '--primary': '#BC1111' } : { '--primary': '#2DA8BC' }"
|
|
267
255
|
>
|
|
268
256
|
<div
|
|
269
257
|
ref="containerRef"
|
|
270
|
-
class="overflow-scroll flex-1 border border-zinc-200 rounded relative"
|
|
258
|
+
class="overflow-scroll overscroll-none flex-1 border border-zinc-200 rounded relative"
|
|
271
259
|
>
|
|
272
260
|
<div :style="{ height: `${rowTotalSize}px` }">
|
|
273
261
|
<table class="grid">
|
|
@@ -287,7 +275,8 @@ function getSortIcon(column) {
|
|
|
287
275
|
'text-xs flex items-center justify-center relative',
|
|
288
276
|
'bg-[color-mix(in_srgb,var(--primary)_10%,white)] group',
|
|
289
277
|
header.column.getIsPinned() && 'sticky z-15',
|
|
290
|
-
(header.column
|
|
278
|
+
shouldHaveRightBorder(header.column) && 'border-r',
|
|
279
|
+
shouldHaveLeftBorder(header.column) && 'border-l'
|
|
291
280
|
]"
|
|
292
281
|
:style="{
|
|
293
282
|
width: `${header.getSize()}px`,
|
|
@@ -354,7 +343,7 @@ function getSortIcon(column) {
|
|
|
354
343
|
v-for="r in rowWindow"
|
|
355
344
|
:key="rows[r.index]?.id ?? r.index"
|
|
356
345
|
:ref="measureRow"
|
|
357
|
-
class="flex absolute w-full"
|
|
346
|
+
class="flex absolute w-full not-last:border-b border-zinc-300"
|
|
358
347
|
:data-index="rows[r.index]?.index"
|
|
359
348
|
:style="{ transform: `translate3d(0, ${r.start}px, 0)` }"
|
|
360
349
|
>
|
|
@@ -362,10 +351,11 @@ function getSortIcon(column) {
|
|
|
362
351
|
v-for="cell in rows[r.index]?.getVisibleCells() ?? []"
|
|
363
352
|
:key="cell.id"
|
|
364
353
|
:class="[
|
|
365
|
-
'border-
|
|
354
|
+
'border-zinc-300',
|
|
366
355
|
cell.column.columnDef.meta?.grow && 'flex-1',
|
|
367
356
|
cell.column.getIsPinned() && 'sticky z-15',
|
|
368
|
-
(cell.column
|
|
357
|
+
shouldHaveRightBorder(cell.column) && 'border-r',
|
|
358
|
+
shouldHaveLeftBorder(cell.column) && 'border-l'
|
|
369
359
|
]"
|
|
370
360
|
:style="{
|
|
371
361
|
width: `${cell.column.getSize()}px`,
|
|
@@ -380,6 +370,39 @@ function getSortIcon(column) {
|
|
|
380
370
|
</td>
|
|
381
371
|
</tr>
|
|
382
372
|
</tbody>
|
|
373
|
+
|
|
374
|
+
<tfoot class="hidden has-[[data-footer]]:grid sticky bottom-0 z-10 select-none border-t border-zinc-200">
|
|
375
|
+
<tr
|
|
376
|
+
v-for="group in table.getFooterGroups()"
|
|
377
|
+
:key="group.id"
|
|
378
|
+
class="flex w-full border-zinc-200"
|
|
379
|
+
>
|
|
380
|
+
<th
|
|
381
|
+
v-for="header in group.headers"
|
|
382
|
+
:key="header.id"
|
|
383
|
+
:colSpan="header.colSpan"
|
|
384
|
+
:class="[
|
|
385
|
+
header.column.columnDef.meta?.grow && 'flex-1',
|
|
386
|
+
'flex items-center gap-2 border-zinc-300 text-zinc-600 p-0',
|
|
387
|
+
'text-xs flex items-center justify-center relative',
|
|
388
|
+
'bg-[color-mix(in_srgb,var(--primary)_10%,white)] group',
|
|
389
|
+
header.column.getIsPinned() && 'sticky z-15',
|
|
390
|
+
shouldHaveRightBorder(header.column) && 'border-r',
|
|
391
|
+
shouldHaveLeftBorder(header.column) && 'border-l'
|
|
392
|
+
]"
|
|
393
|
+
:style="{
|
|
394
|
+
width: `${header.getSize()}px`,
|
|
395
|
+
...pinnedStyle(header.column)
|
|
396
|
+
}"
|
|
397
|
+
>
|
|
398
|
+
<FlexRender
|
|
399
|
+
v-if="!header.isPlaceholder"
|
|
400
|
+
:render="header.column.columnDef.footer"
|
|
401
|
+
:props="header.getContext()"
|
|
402
|
+
/>
|
|
403
|
+
</th>
|
|
404
|
+
</tr>
|
|
405
|
+
</tfoot>
|
|
383
406
|
</table>
|
|
384
407
|
</div>
|
|
385
408
|
</div>
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import type { RowData, TableOptions } from '@tanstack/vue-table';
|
|
2
2
|
export type Expression = string;
|
|
3
|
+
export type Render = string | Readonly<{
|
|
4
|
+
id: string;
|
|
5
|
+
props: unknown;
|
|
6
|
+
}>;
|
|
3
7
|
export type Accessor = string | Readonly<{
|
|
4
8
|
read: Expression;
|
|
5
9
|
write: Expression;
|
|
@@ -9,10 +13,7 @@ export type Column = Readonly<{
|
|
|
9
13
|
title?: string;
|
|
10
14
|
accessor?: Accessor;
|
|
11
15
|
accessorKey?: string;
|
|
12
|
-
renderer?:
|
|
13
|
-
id: string;
|
|
14
|
-
props: unknown;
|
|
15
|
-
}>;
|
|
16
|
+
renderer?: Render;
|
|
16
17
|
tooltip?: string;
|
|
17
18
|
size?: number;
|
|
18
19
|
enableSorting?: boolean;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import '../table-renderers/builtins.js';
|
|
2
2
|
import { getTableRenderer, resolveTableRenderer } from '../table-renderers/registry.js';
|
|
3
3
|
export { defineTableRenderer } from '../table-renderers/registry.js';
|
|
4
|
-
export type { TableRenderer, TableRendererCellArgs, TableRendererColumnDefOverrides, TableRendererConfigComponent, TableRendererHeaderArgs, TableRendererId, } from '../table-renderers/registry.js';
|
|
4
|
+
export type { TableRenderer, TableRendererCellArgs, TableRendererColumnDefOverrides, TableRendererConfigComponent, TableRendererFooterArgs, TableRendererHeaderArgs, TableRendererId, } from '../table-renderers/registry.js';
|
|
5
5
|
export declare function useTableRenderers(): {
|
|
6
6
|
getTableRenderer: typeof getTableRenderer;
|
|
7
7
|
resolveTableRenderer: typeof resolveTableRenderer;
|
|
@@ -4,6 +4,7 @@ import { format as formatDate, isValid, toDate } from "date-fns";
|
|
|
4
4
|
import { defineComponent } from "vue";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
import { defineTableRenderer } from "./registry.js";
|
|
7
|
+
import { useNuxtApp } from "#app";
|
|
7
8
|
const JUSTIFY_CLASS = {
|
|
8
9
|
left: "justify-start",
|
|
9
10
|
center: "justify-center",
|
|
@@ -185,16 +186,17 @@ defineTableRenderer(
|
|
|
185
186
|
align: z.enum(["left", "center", "right"]).default("left")
|
|
186
187
|
},
|
|
187
188
|
{
|
|
188
|
-
cell: ({ ctx, options
|
|
189
|
+
cell: ({ ctx, options }) => {
|
|
189
190
|
const rawValue = ctx.cell.getValue();
|
|
190
191
|
const isEmpty = rawValue === void 0 || rawValue === null;
|
|
191
192
|
const align = isEmpty ? "center" : options.align ?? "left";
|
|
192
193
|
const justifyClass = JUSTIFY_CLASS[align];
|
|
194
|
+
const { $dsl } = useNuxtApp();
|
|
193
195
|
const onCopy = async () => {
|
|
194
196
|
try {
|
|
195
197
|
let text = String(ctx.cell.getValue());
|
|
196
|
-
if (options.copyExpression
|
|
197
|
-
text = String(
|
|
198
|
+
if (options.copyExpression) {
|
|
199
|
+
text = String($dsl.evaluate(options.copyExpression, {
|
|
198
200
|
row: ctx.row.original,
|
|
199
201
|
index: BigInt(ctx.row.index)
|
|
200
202
|
}));
|
|
@@ -287,7 +289,7 @@ defineTableRenderer(
|
|
|
287
289
|
type: "checkbox",
|
|
288
290
|
checked,
|
|
289
291
|
class: [
|
|
290
|
-
"peer h-4 w-4 cursor-pointer transition-colors duration-180 appearance-none rounded",
|
|
292
|
+
"peer h-4 w-4 cursor-pointer transition-colors duration-180 appearance-none rounded bg-white",
|
|
291
293
|
"border border-[color-mix(in_srgb,var(--primary)_10%,#00000033)] not-checked-group-hover:border-[color-mix(in_srgb,var(--primary)_20%,#00000033)]",
|
|
292
294
|
"not-checked-group-hover:bg-[color-mix(in_srgb,var(--primary)_5%,#00000011)] checked:border-[var(--primary)] checked:bg-[var(--primary)]"
|
|
293
295
|
],
|
|
@@ -333,7 +335,10 @@ defineTableRenderer(
|
|
|
333
335
|
children: /* @__PURE__ */ jsx(Icon, { icon: ctx.table.getIsAllRowsExpanded() ? "fluent:subtract-square-20-regular" : "fluent:add-square-20-regular" })
|
|
334
336
|
}
|
|
335
337
|
) }),
|
|
336
|
-
config: NoOptionsConfig
|
|
338
|
+
config: NoOptionsConfig,
|
|
339
|
+
columnDefOverrides: {
|
|
340
|
+
enableResizing: false
|
|
341
|
+
}
|
|
337
342
|
}
|
|
338
343
|
);
|
|
339
344
|
defineTableRenderer(
|
|
@@ -394,9 +399,10 @@ defineTableRenderer(
|
|
|
394
399
|
source: z.string().optional()
|
|
395
400
|
},
|
|
396
401
|
{
|
|
397
|
-
cell: ({ ctx, options
|
|
402
|
+
cell: ({ ctx, options }) => {
|
|
403
|
+
const { $markdown } = useNuxtApp();
|
|
398
404
|
const source = options.source ?? String(ctx.cell.getValue());
|
|
399
|
-
const html =
|
|
405
|
+
const html = $markdown.renderInline(source);
|
|
400
406
|
return /* @__PURE__ */ jsx("div", { class: "relative w-full py-2 px-1 flex items-center justify-center text-xs", children: /* @__PURE__ */ jsx("span", { class: "prose prose-zinc text-xs", innerHTML: html }) });
|
|
401
407
|
},
|
|
402
408
|
config: TableRendererMarkdownConfig
|
|
@@ -6,19 +6,14 @@ export type TableRendererColumnDefOverrides<TData extends RowData = unknown> = P
|
|
|
6
6
|
export type TableRendererCellArgs<TData extends RowData, TValue, TOptions> = Readonly<{
|
|
7
7
|
ctx: CellContext<TData, TValue>;
|
|
8
8
|
options: TOptions;
|
|
9
|
-
helpers: Readonly<{
|
|
10
|
-
renderInline: (source: string) => string;
|
|
11
|
-
evaluate?: (source: string, context?: Record<string, unknown>) => unknown;
|
|
12
|
-
}>;
|
|
13
9
|
}>;
|
|
14
10
|
export type TableRendererHeaderArgs<TData extends RowData, TValue, TOptions> = Readonly<{
|
|
15
11
|
ctx: HeaderContext<TData, TValue>;
|
|
16
|
-
title?: string;
|
|
17
12
|
options: TOptions;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
13
|
+
}>;
|
|
14
|
+
export type TableRendererFooterArgs<TData extends RowData, TValue, TOptions> = Readonly<{
|
|
15
|
+
ctx: HeaderContext<TData, TValue>;
|
|
16
|
+
options: TOptions;
|
|
22
17
|
}>;
|
|
23
18
|
export type TableRendererConfigComponent<_TOptions> = unknown;
|
|
24
19
|
export type TableRenderer<TOptions> = Readonly<{
|
|
@@ -27,12 +22,14 @@ export type TableRenderer<TOptions> = Readonly<{
|
|
|
27
22
|
parseOptions: (input: unknown) => TOptions;
|
|
28
23
|
cell: (args: TableRendererCellArgs<unknown, unknown, TOptions>) => VNodeChild;
|
|
29
24
|
header?: (args: TableRendererHeaderArgs<unknown, unknown, TOptions>) => VNodeChild;
|
|
25
|
+
footer?: (args: TableRendererFooterArgs<unknown, unknown, TOptions>) => VNodeChild;
|
|
30
26
|
config?: TableRendererConfigComponent<TOptions>;
|
|
31
27
|
columnDefOverrides?: TableRendererColumnDefOverrides;
|
|
32
28
|
}>;
|
|
33
29
|
export declare function defineTableRenderer<const TShape extends z.ZodRawShape, const TOptions = z.infer<z.ZodObject<TShape>>>(id: TableRendererId, shape: TShape, impl: Readonly<{
|
|
34
30
|
cell: TableRenderer<TOptions>['cell'];
|
|
35
31
|
header?: TableRenderer<TOptions>['header'];
|
|
32
|
+
footer?: TableRenderer<TOptions>['footer'];
|
|
36
33
|
config?: TableRenderer<TOptions>['config'];
|
|
37
34
|
columnDefOverrides?: TableRenderer<TOptions>['columnDefOverrides'];
|
|
38
35
|
}>): TableRenderer<TOptions>;
|
|
@@ -6,11 +6,12 @@ export function defineTableRenderer(id, shape, impl) {
|
|
|
6
6
|
id,
|
|
7
7
|
optionsSchema,
|
|
8
8
|
parseOptions: (input) => {
|
|
9
|
-
const normalized = input
|
|
9
|
+
const normalized = input === null || input === void 0 ? {} : input;
|
|
10
10
|
return optionsSchema.parse(normalized);
|
|
11
11
|
},
|
|
12
12
|
cell: impl.cell,
|
|
13
13
|
header: impl.header,
|
|
14
|
+
footer: impl.footer,
|
|
14
15
|
config: impl.config,
|
|
15
16
|
columnDefOverrides: impl.columnDefOverrides
|
|
16
17
|
};
|