Skip to content

Commit 4e69e86

Browse files
committed
feat: opaque table
1 parent 7c8a04b commit 4e69e86

File tree

15 files changed

+328
-148
lines changed

15 files changed

+328
-148
lines changed

packages/components-vue/src/components/base/Box.vue

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
stateClasses,
88
themeClasses,
99
GMC(button ?? false, { modifier: 'button' }),
10+
{ ' --opaque': opaque },
11+
{ ' --square': square },
1012
{ ' --bdr-dashed': dashed },
1113
{ ' --bdr-solid': solid && !dashed },
1214
{ '--bgColor-none': transparent },
@@ -42,6 +44,12 @@
4244
solid?: boolean;
4345
transparent?: boolean;
4446
withColor?: boolean;
47+
/** Prefer an opaque background */
48+
opaque?: boolean;
49+
/**
50+
* Square shape
51+
*/
52+
square?: boolean;
4553
}
4654
4755
/**
@@ -62,7 +70,11 @@
6270
const { themeClasses, themeValues } = useTheme(props);
6371
6472
const colorClasses = computed(() => {
65-
const classes = GMC([themeValues.value[0]], { modifier: "txtColor", divider: "-" });
73+
const [theme, themeWithColor] = themeValues.value;
74+
const classes = GMC([props.opaque ? themeWithColor : theme], {
75+
modifier: "txtColor",
76+
divider: "-",
77+
});
6678
6779
return props.withColor ? classes : [];
6880
});

packages/components-vue/src/components/box/Action.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
:aria-label="label"
66
button
77
>
8-
<div v-if="icon || src" :class="innerThemeClasses" class="box --square">
8+
<BaseBox v-if="icon || src" :class="innerThemeClasses" square opaque>
99
<IconFa v-if="icon" v-bind="{ size: 35, ...iconProps, name: icon }" />
1010
<BaseImg
1111
v-else-if="src"
@@ -14,7 +14,7 @@
1414
:alt="label"
1515
:placeholder="imagePlaceholder"
1616
/>
17-
</div>
17+
</BaseBox>
1818
<p>
1919
<!-- Since we only accept label there is no room for slot here -->
2020
<b>{{ label }}</b>

packages/components-vue/src/components/pagination/Content.vue

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
v-if="!hideControls"
2929
v-model="pagination"
3030
v-bind="{ currentPage: content, withRoute, theme }"
31+
:class="paginationClass"
3132
/>
3233
</LoaderContentFetch>
3334
</template>
@@ -102,6 +103,12 @@
102103
* Whether to fetch data on client side only
103104
*/
104105
client?: boolean;
106+
/**
107+
* Additional class for the pagination
108+
*
109+
* @example --txtColor
110+
*/
111+
paginationClass?: string | string[] | Record<string, boolean>;
105112
}
106113
107114
/**

packages/components-vue/src/components/pagination/ContentTable.vue

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
<PaginationContent
1212
v-slot="{ content }"
1313
v-bind="{ page, url, noContentMessage, preventAutoload, theme, client, defaults }"
14-
class="flx --flxColumn --flx-start-end"
14+
pagination-class="flx --flxRow-wrap --flx-end-center --gap-5 --gap-10:sm --gap:md"
15+
class="flx --flxColumn --flx-start-stretch"
1516
with-route
1617
@refresh="emittedRefresh = $event"
1718
@has-content="hasContent = $event"
@@ -22,8 +23,8 @@
2223
:refresh="refreshData"
2324
:class="tableClass"
2425
v-bind="{
25-
...tableProps,
2626
theme,
27+
...tableProps,
2728
modalProps: {
2829
invertTheme: true,
2930
class: modalClass ?? tableClass,

packages/components-vue/src/components/pagination/Simple.vue

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
<template>
22
<ul
33
v-if="currentPage && modelValue"
4-
class="flx --flxRow-wrap --flx-center --gap-5 --gap-10:sm --gap:md --width-fit"
4+
:class="
5+
$attrs.class ||
6+
'flx --flxRow-wrap --flx-center --gap-5 --gap-10:sm --gap:md --width-fit'
7+
"
58
>
69
<li v-if="modelValue.first">
710
<p class="--txtSize-sm">
Lines changed: 9 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<template>
2+
<!-- Action bar -->
23
<thead>
3-
<!-- Action bar -->
44
<tr
55
v-if="(!isReadOnly && nodes.length > 1) || withDefaultSlot || $slots.headActions"
66
class="no--hover"
@@ -12,7 +12,8 @@
1212
<tr class="no--hover">
1313
<th
1414
v-if="withDefaultSlot || $slots.headActions"
15-
class="--sticky --pBottom-10"
15+
class="--sticky"
16+
:class="{ '--pBottom-10': !nested }"
1617
>
1718
<div
1819
class="flx --flxRow --flx-start-center --gap-10 --gap:md --flx"
@@ -56,13 +57,14 @@
5657
</div>
5758
</th>
5859
<td
59-
class="--pBottom-10"
60+
:class="{ '--pBottom-10': !nested }"
6061
:colspan="propertiesMeta.length"
6162
width="99%"
6263
></td>
6364
<th
6465
v-if="!isReadOnly && nodes.length > 1 && deleteNode"
65-
class="--sticky --pBottom-10"
66+
class="--sticky"
67+
:class="{ '--pBottom-10': !nested }"
6668
colspan="0"
6769
width="1px"
6870
>
@@ -92,100 +94,15 @@
9294
</table>
9395
</td>
9496
</tr>
95-
<!-- Table header -->
96-
<tr v-if="nodes.length" class="--txtAlign" :class="`--txtSize-${size}`">
97-
<!-- TODO: define filters, filter table contents -->
98-
<th
99-
v-if="nodes.length > 1 || withDefaultSlot"
100-
class="--sticky"
101-
:class="{ ['is--selected']: sort && !!ordering['id'] }"
102-
data-column-name="id"
103-
data-column="id"
104-
>
105-
<div class="flx --flxRow --flx-start-center --gap-10">
106-
<InputToggle
107-
v-if="!isReadOnly"
108-
:id="tableId + 'select-all'"
109-
:theme="theme || themeValues"
110-
:title="t('table_select_all')"
111-
:checked="selectedNodes.every(([n]) => n)"
112-
:size="size"
113-
@update:model-value="toggleAll"
114-
/>
115-
<span v-if="!sort">#</span>
116-
<ActionLink
117-
v-else
118-
:theme="theme || themeValues"
119-
title="id"
120-
:tooltip="t('table_sort_by_name', { name: 'Id' })"
121-
tooltip-as-text
122-
tooltip-position="bottom"
123-
:size="size"
124-
@click="() => setOrdering('id')"
125-
>
126-
<span>#</span>
127-
<template v-if="!!ordering['id']">
128-
<IconFa v-if="ordering['id'] === 'asc'" name="arrow-down" />
129-
<IconFa v-else name="arrow-up" />
130-
</template>
131-
</ActionLink>
132-
</div>
133-
</th>
134-
<template v-for="(meta, metaIndex) in propertiesMeta" :key="metaIndex">
135-
<td
136-
v-if="!meta.hidden"
137-
class="--maxWidth-440"
138-
:class="[
139-
`--txtSize-${size}`,
140-
{ ['is--selected']: meta.canSort && !!ordering[meta.value] },
141-
]"
142-
:data-column-name="meta.value"
143-
:data-column="meta.alias"
144-
:width="nested && metaIndex === propertiesMeta.length - 1 ? '99%' : 'auto'"
145-
>
146-
<span v-if="!meta.canSort" :title="meta.value">
147-
{{ meta.alias }}
148-
</span>
149-
<ActionLink
150-
v-else
151-
:theme="theme || themeValues"
152-
:title="meta.value"
153-
:tooltip="t('table_sort_by_name', { name: meta.alias })"
154-
tooltip-as-text
155-
tooltip-position="bottom"
156-
:size="size"
157-
@click="() => setOrdering(meta.value)"
158-
>
159-
<span>{{ meta.alias }}</span>
160-
<template v-if="!!ordering[meta.value]">
161-
<IconFa v-if="ordering[meta.value] === 'asc'" name="arrow-down" />
162-
<IconFa v-else name="arrow-up" />
163-
</template>
164-
</ActionLink>
165-
</td>
166-
</template>
167-
<th
168-
v-if="!isReadOnly && (!!updateNode || !!deleteNode || !!cloneNode)"
169-
class="--sticky --txtAlign-center"
170-
data-column-name="modify"
171-
data-column="modify"
172-
>
173-
<span>
174-
{{ t("table_modify") }}
175-
</span>
176-
</th>
177-
</tr>
17897
</thead>
17998
</template>
18099

181100
<script setup lang="ts" generic="T extends Record<string, any>">
182101
import { useI18n } from "@open-xamu-co/ui-common-helpers";
183102
184103
import IconFa from "../icon/Fa.vue";
185-
import ActionLink from "../action/Link.vue";
186104
import ActionButton from "../action/Button.vue";
187105
import ActionButtonLink from "../action/ButtonLink.vue";
188-
import InputToggle from "../input/Toggle.vue";
189106
190107
import type { iTableChildProps } from "../../types/props";
191108
import useTheme from "../../composables/theme";
@@ -196,15 +113,15 @@
196113
}
197114
198115
/**
199-
* Table head
116+
* Table head actions
200117
*
201118
* @component
202119
*/
203120
204-
defineOptions({ name: "TableHead", inheritAttrs: false });
121+
defineOptions({ name: "TableHeadActions", inheritAttrs: false });
205122
206123
const props = defineProps<iTableHeadProps<T>>();
207124
208125
const { t } = useHelpers(useI18n);
209-
const { themeClasses, themeValues, dangerThemeValues } = useTheme(props);
126+
const { themeClasses, dangerThemeValues } = useTheme(props);
210127
</script>
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
<template>
2+
<!-- Table header -->
3+
<thead>
4+
<tr v-if="nodes.length" class="--txtAlign" :class="`--txtSize-${size}`">
5+
<!-- TODO: define filters, filter table contents -->
6+
<th
7+
v-if="nodes.length > 1 || withDefaultSlot"
8+
class="--sticky"
9+
:class="{ ['is--selected']: sort && !!ordering['id'] }"
10+
data-column-name="id"
11+
data-column="id"
12+
>
13+
<div class="flx --flxRow --flx-start-center --gap-10">
14+
<InputToggle
15+
v-if="!isReadOnly"
16+
:id="tableId + 'select-all'"
17+
:theme="theme || themeValues"
18+
:title="t('table_select_all')"
19+
:checked="selectedNodes.every(([n]) => n)"
20+
:size="size"
21+
@update:model-value="toggleAll"
22+
/>
23+
<span v-if="!sort">#</span>
24+
<ActionLink
25+
v-else
26+
:theme="theme || themeValues"
27+
title="id"
28+
:tooltip="t('table_sort_by_name', { name: 'Id' })"
29+
tooltip-as-text
30+
tooltip-position="bottom"
31+
:size="size"
32+
@click="() => setOrdering('id')"
33+
>
34+
<span>#</span>
35+
<template v-if="!!ordering['id']">
36+
<IconFa v-if="ordering['id'] === 'asc'" name="arrow-down" />
37+
<IconFa v-else name="arrow-up" />
38+
</template>
39+
</ActionLink>
40+
</div>
41+
</th>
42+
<template v-for="(meta, metaIndex) in propertiesMeta" :key="metaIndex">
43+
<td
44+
v-if="!meta.hidden"
45+
class="--maxWidth-440"
46+
:class="[
47+
`--txtSize-${size}`,
48+
{ ['is--selected']: meta.canSort && !!ordering[meta.value] },
49+
]"
50+
:data-column-name="meta.value"
51+
:data-column="meta.alias"
52+
:width="nested && metaIndex === propertiesMeta.length - 1 ? '99%' : 'auto'"
53+
>
54+
<span v-if="!meta.canSort" :title="meta.value">
55+
{{ meta.alias }}
56+
</span>
57+
<ActionLink
58+
v-else
59+
:theme="theme || themeValues"
60+
:title="meta.value"
61+
:tooltip="t('table_sort_by_name', { name: meta.alias })"
62+
tooltip-as-text
63+
tooltip-position="bottom"
64+
:size="size"
65+
@click="() => setOrdering(meta.value)"
66+
>
67+
<span>{{ meta.alias }}</span>
68+
<template v-if="!!ordering[meta.value]">
69+
<IconFa v-if="ordering[meta.value] === 'asc'" name="arrow-down" />
70+
<IconFa v-else name="arrow-up" />
71+
</template>
72+
</ActionLink>
73+
</td>
74+
</template>
75+
<th
76+
v-if="!isReadOnly && (!!updateNode || !!deleteNode || !!cloneNode)"
77+
class="--sticky --txtAlign-center"
78+
data-column-name="modify"
79+
data-column="modify"
80+
>
81+
<span>
82+
{{ t("table_modify") }}
83+
</span>
84+
</th>
85+
</tr>
86+
</thead>
87+
</template>
88+
89+
<script setup lang="ts" generic="T extends Record<string, any>">
90+
import { useI18n } from "@open-xamu-co/ui-common-helpers";
91+
92+
import IconFa from "../icon/Fa.vue";
93+
import ActionLink from "../action/Link.vue";
94+
95+
import type { iTableChildProps } from "../../types/props";
96+
import useTheme from "../../composables/theme";
97+
import { useHelpers } from "../../composables/utils";
98+
99+
export interface iTableHeadProps<Ti extends Record<string, any>> extends iTableChildProps<Ti> {
100+
withDefaultSlot: boolean;
101+
}
102+
103+
/**
104+
* Table head content
105+
*
106+
* @component
107+
*/
108+
109+
defineOptions({ name: "TableHeadContent", inheritAttrs: false });
110+
111+
const props = defineProps<iTableHeadProps<T>>();
112+
113+
const { t } = useHelpers(useI18n);
114+
const { themeValues } = useTheme(props);
115+
</script>

0 commit comments

Comments
 (0)