diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/tools/benchmark-builder/benchmark-builder.vue | 24 | ||||
-rw-r--r-- | src/tools/crontab-generator/crontab-generator.vue | 30 | ||||
-rw-r--r-- | src/ui/c-table/c-table.demo.vue | 20 | ||||
-rw-r--r-- | src/ui/c-table/c-table.types.ts | 4 | ||||
-rw-r--r-- | src/ui/c-table/c-table.vue | 65 |
5 files changed, 94 insertions, 49 deletions
diff --git a/src/tools/benchmark-builder/benchmark-builder.vue b/src/tools/benchmark-builder/benchmark-builder.vue index 7922791..9391142 100644 --- a/src/tools/benchmark-builder/benchmark-builder.vue +++ b/src/tools/benchmark-builder/benchmark-builder.vue @@ -51,11 +51,11 @@ const results = computed(() => { const { copy } = useCopy({ createToast: false }); const header = { + position: 'Position', title: 'Suite', size: 'Samples', mean: 'Mean', variance: 'Variance', - position: 'Position', }; function copyAsMarkdown() { @@ -131,26 +131,8 @@ function copyAsBulletList() { </c-button> </div> - <n-table> - <thead> - <tr> - <th>{{ header.position }}</th> - <th>{{ header.title }}</th> - <th>{{ header.size }}</th> - <th>{{ header.mean }}</th> - <th>{{ header.variance }}</th> - </tr> - </thead> - <tbody> - <tr v-for="{ title, size, mean, variance, position } of results" :key="title"> - <td>{{ position }}</td> - <td>{{ title }}</td> - <td>{{ size }}</td> - <td>{{ mean }}</td> - <td>{{ variance }}</td> - </tr> - </tbody> - </n-table> + <c-table :data="results" :headers="header" /> + <div mt-5 flex justify-center gap-3> <c-button @click="copyAsMarkdown()"> Copy as markdown table diff --git a/src/tools/crontab-generator/crontab-generator.vue b/src/tools/crontab-generator/crontab-generator.vue index 28683ce..97503e7 100644 --- a/src/tools/crontab-generator/crontab-generator.vue +++ b/src/tools/crontab-generator/crontab-generator.vue @@ -167,34 +167,8 @@ const cronValidationRules = [ </div> </c-card> </div> - <n-table v-else size="small"> - <thead> - <tr> - <th class="text-left" scope="col"> - Symbol - </th> - <th class="text-left" scope="col"> - Meaning - </th> - <th class="text-left" scope="col"> - Example - </th> - <th class="text-left" scope="col"> - Equivalent - </th> - </tr> - </thead> - <tbody> - <tr v-for="{ symbol, meaning, example, equivalent } in helpers" :key="symbol"> - <td>{{ symbol }}</td> - <td>{{ meaning }}</td> - <td> - <code>{{ example }}</code> - </td> - <td>{{ equivalent }}</td> - </tr> - </tbody> - </n-table> + + <c-table v-else :data="helpers" /> </c-card> </template> diff --git a/src/ui/c-table/c-table.demo.vue b/src/ui/c-table/c-table.demo.vue new file mode 100644 index 0000000..b2cf8a7 --- /dev/null +++ b/src/ui/c-table/c-table.demo.vue @@ -0,0 +1,20 @@ +<script lang="ts" setup> +const data = ref([ + { name: 'John', age: 20 }, + { name: 'Jane', age: 24 }, + { name: 'Joe', age: 30 }, +]); +</script> + +<template> + <c-table :data="data" mb-2 /> + <c-table :data="data" hide-headers mb-2 /> + <c-table :data="data" :headers="['age', 'name']" mb-2 /> + <c-table :data="data" :headers="['age', { key: 'name', label: 'Full name' }]" mb-2 /> + <c-table :data="data" :headers="{ name: 'full name' }" mb-2 /> + <c-table :data="data" :headers="['age', 'name']"> + <template #age="{ value }"> + {{ value }}yo + </template> + </c-table> +</template> diff --git a/src/ui/c-table/c-table.types.ts b/src/ui/c-table/c-table.types.ts new file mode 100644 index 0000000..6c658f3 --- /dev/null +++ b/src/ui/c-table/c-table.types.ts @@ -0,0 +1,4 @@ +export type HeaderConfiguration = (string | { + key: string + label?: string +})[] | Record<string, string>; diff --git a/src/ui/c-table/c-table.vue b/src/ui/c-table/c-table.vue new file mode 100644 index 0000000..9f734a9 --- /dev/null +++ b/src/ui/c-table/c-table.vue @@ -0,0 +1,65 @@ +<script lang="ts" setup> +import _ from 'lodash'; +import type { HeaderConfiguration } from './c-table.types'; + +const props = withDefaults(defineProps<{ data?: Record<string, unknown>[]; headers?: HeaderConfiguration ; hideHeaders?: boolean }>(), { data: () => [], headers: undefined, hideHeaders: false }); +const { data, headers: rawHeaders, hideHeaders } = toRefs(props); + +const headers = computed(() => { + if (rawHeaders.value) { + if (Array.isArray(rawHeaders.value)) { + return rawHeaders.value.map((value) => { + if (typeof value === 'string') { + return { key: value, label: value }; + } + + const { key, label } = value; + + return { + key, + label: label ?? key, + }; + }); + } + + return _.map(rawHeaders.value, (value, key) => ({ + key, label: value, + })); + } + + return _.chain(data.value) + .map(row => Object.keys(row)) + .flatten() + .uniq() + .map(key => ({ key, label: key })) + .value(); +}); +</script> + +<template> + <div class="relative overflow-x-auto rounded"> + <table class="w-full border-collapse text-left text-sm text-gray-500 dark:text-gray-400"> + <thead v-if="!hideHeaders" class="bg-#ffffff uppercase text-gray-700 dark:bg-#333333 dark:text-gray-400"> + <tr> + <th v-for="header in headers" :key="header.key" scope="col" class="px-6 py-3 text-xs"> + {{ header.label }} + </th> + </tr> + </thead> + <tbody> + <tr + v-for="(row, i) in data" :key="i" border-b="1px solid dark:#282828 #efeff5" class="bg-white dark:bg-#232323" + :class="{ + 'important:border-b-none': i === data.length - 1, + }" + > + <td v-for="header in headers" :key="header.key" class="px-6 py-4"> + <slot :name="header" :row="row" :headers="headers" :value="row[header.key]"> + {{ row[header.key] }} + </slot> + </td> + </tr> + </tbody> + </table> + </div> +</template> |