@indielayer/ui 1.12.1 → 1.13.1
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/docs/pages/component/datepicker/usage.vue +1 -0
- package/docs/pages/component/select/multiple.vue +4 -2
- package/docs/pages/component/select/usage.vue +1 -0
- package/docs/pages/component/table/usage.vue +1 -1
- package/lib/components/datepicker/Datepicker.vue.d.ts +12 -12
- package/lib/components/datepicker/Datepicker.vue.js +6 -6
- package/lib/components/select/Select.vue.d.ts +5 -1
- package/lib/components/select/Select.vue.js +262 -245
- package/lib/components/select/theme/Select.base.theme.js +11 -10
- package/lib/components/table/Table.vue.d.ts +1 -0
- package/lib/components/table/Table.vue.js +51 -50
- package/lib/components/table/TableHeader.vue.d.ts +3 -0
- package/lib/components/table/TableHeader.vue.js +58 -49
- package/lib/components/table/theme/TableHead.base.theme.js +1 -1
- package/lib/components/table/theme/TableHeader.base.theme.js +3 -3
- package/lib/components/table/theme/TableRow.base.theme.js +1 -1
- package/lib/index.js +1 -1
- package/lib/index.umd.js +4 -4
- package/lib/node_modules/.pnpm/@vuepic_vue-datepicker@11.0.2_vue@3.5.10_typescript@5.2.2_/node_modules/@vuepic/vue-datepicker/dist/vue-datepicker.js +5210 -0
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +2 -2
- package/src/components/datepicker/Datepicker.vue +1 -1
- package/src/components/select/Select.vue +27 -8
- package/src/components/select/theme/Select.base.theme.ts +17 -6
- package/src/components/table/Table.vue +2 -0
- package/src/components/table/TableHeader.vue +36 -28
- package/src/components/table/theme/TableHead.base.theme.ts +1 -1
- package/src/components/table/theme/TableHeader.base.theme.ts +1 -1
- package/src/components/table/theme/TableRow.base.theme.ts +1 -1
- package/src/version.ts +1 -1
- package/lib/node_modules/.pnpm/@vuepic_vue-datepicker@11.0.1_vue@3.5.10_typescript@5.2.2_/node_modules/@vuepic/vue-datepicker/dist/vue-datepicker.js +0 -5199
- /package/lib/node_modules/.pnpm/{@vuepic_vue-datepicker@11.0.1_vue@3.5.10_typescript@5.2.2_ → @vuepic_vue-datepicker@11.0.2_vue@3.5.10_typescript@5.2.2_}/node_modules/@vuepic/vue-datepicker/dist/main.css.js +0 -0
package/lib/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: "1.
|
|
1
|
+
declare const _default: "1.13.1";
|
|
2
2
|
export default _default;
|
package/lib/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@indielayer/ui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.13.1",
|
|
4
4
|
"description": "Indielayer UI Components with Tailwind CSS build for Vue 3",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "João Teixeira",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"@vitejs/plugin-vue-jsx": "^3.0.1",
|
|
58
58
|
"@vue/test-utils": "^2.4.0",
|
|
59
59
|
"@vue/tsconfig": "^0.4.0",
|
|
60
|
-
"@vuepic/vue-datepicker": "^11.0.
|
|
60
|
+
"@vuepic/vue-datepicker": "^11.0.2",
|
|
61
61
|
"@vueuse/core": "^11.1.0",
|
|
62
62
|
"autoprefixer": "^10.4.0",
|
|
63
63
|
"c8": "^7.12.0",
|
|
@@ -335,7 +335,7 @@ const { styles, classes, className } = useTheme('Datepicker', {}, props)
|
|
|
335
335
|
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
|
336
336
|
}
|
|
337
337
|
|
|
338
|
-
.
|
|
338
|
+
.dp--clear-btn {
|
|
339
339
|
top: 2.75rem !important;
|
|
340
340
|
}
|
|
341
341
|
|
|
@@ -12,6 +12,7 @@ const selectProps = {
|
|
|
12
12
|
flat: Boolean,
|
|
13
13
|
native: Boolean,
|
|
14
14
|
filterable: Boolean,
|
|
15
|
+
clearable: Boolean,
|
|
15
16
|
filterPlaceholder: {
|
|
16
17
|
type: String,
|
|
17
18
|
default: 'Filter by...',
|
|
@@ -42,7 +43,7 @@ export type SelectOption = {
|
|
|
42
43
|
|
|
43
44
|
export type SelectProps = ExtractPublicPropTypes<typeof selectProps>
|
|
44
45
|
|
|
45
|
-
type InternalClasses = 'wrapper' | 'box' | 'truncateCounter' | 'content' | 'search' | 'contentBody' | 'iconWrapper' | 'icon'
|
|
46
|
+
type InternalClasses = 'wrapper' | 'box' | 'truncateCounter' | 'content' | 'search' | 'contentBody' | 'iconWrapper' | 'clearButton' | 'icon'
|
|
46
47
|
type InternalExtraData = { errorInternal: Ref<boolean>; }
|
|
47
48
|
export interface SelectTheme extends ThemeComponent<SelectProps, InternalClasses, InternalExtraData> {}
|
|
48
49
|
|
|
@@ -63,7 +64,7 @@ import { useInputtable } from '../../composables/useInputtable'
|
|
|
63
64
|
import { useInteractive } from '../../composables/useInteractive'
|
|
64
65
|
import { useTheme, type ThemeComponent } from '../../composables/useTheme'
|
|
65
66
|
import { useVirtualList } from '../../composables/useVirtualList'
|
|
66
|
-
import { checkIcon, selectIcon } from '../../common/icons'
|
|
67
|
+
import { checkIcon, selectIcon, closeIcon } from '../../common/icons'
|
|
67
68
|
|
|
68
69
|
import XLabel from '../label/Label.vue'
|
|
69
70
|
import XTag from '../tag/Tag.vue'
|
|
@@ -85,12 +86,14 @@ const elRef = ref<HTMLElement | null>(null)
|
|
|
85
86
|
const labelRef = ref<InstanceType<typeof XLabel> | null>(null)
|
|
86
87
|
const itemsRef = ref<InstanceType<typeof XMenuItem>[] | null>(null)
|
|
87
88
|
const popoverRef = ref<InstanceType<typeof XPopover> | null>(null)
|
|
89
|
+
const hiddenTagsCounterRef = ref<HTMLElement | null>(null)
|
|
88
90
|
const selectedIndex = ref<number | undefined>()
|
|
89
91
|
|
|
90
92
|
const filter = defineModel('filter', { default : '' })
|
|
91
93
|
const filterRef = ref<InstanceType<typeof XInput> | null>(null)
|
|
92
94
|
|
|
93
95
|
const isDisabled = computed(() => props.disabled || props.loading || props.readonly)
|
|
96
|
+
const isClearIconVisible = computed(() => !props.loading && !props.readonly && !props.disabled && props.clearable && !isEmpty(selected.value))
|
|
94
97
|
|
|
95
98
|
const selected = computed<any | any[]>({
|
|
96
99
|
get() {
|
|
@@ -424,7 +427,7 @@ function calcMaxTags() {
|
|
|
424
427
|
const tagsArray = Array.from(tags)
|
|
425
428
|
|
|
426
429
|
let totalWidth = 0
|
|
427
|
-
let tagsCount =
|
|
430
|
+
let tagsCount = 1
|
|
428
431
|
|
|
429
432
|
const maxWidth = tagsRef.value.offsetWidth - 30
|
|
430
433
|
|
|
@@ -435,8 +438,10 @@ function calcMaxTags() {
|
|
|
435
438
|
|
|
436
439
|
totalWidth += tag.offsetWidth
|
|
437
440
|
|
|
438
|
-
if (
|
|
439
|
-
|
|
441
|
+
if (i > 0) {
|
|
442
|
+
if (totalWidth < maxWidth) tagsCount++
|
|
443
|
+
else tag.style.display = 'none'
|
|
444
|
+
}
|
|
440
445
|
}
|
|
441
446
|
|
|
442
447
|
return tagsCount
|
|
@@ -504,12 +509,13 @@ defineExpose({ focus, blur, reset, validate, setError, filterRef })
|
|
|
504
509
|
}"
|
|
505
510
|
>
|
|
506
511
|
<x-tag
|
|
507
|
-
v-for="value in selected"
|
|
512
|
+
v-for="(value, valueIndex) in selected"
|
|
508
513
|
:key="value"
|
|
509
514
|
size="xs"
|
|
510
515
|
removable
|
|
511
516
|
:outlined="!(isDisabled || options?.find((i) => i.value === value)?.disabled)"
|
|
512
517
|
:disabled="isDisabled || options?.find((i) => i.value === value)?.disabled"
|
|
518
|
+
:style="{ 'max-width': valueIndex === 0 && hiddenTagsCounterRef ? `calc(100% - ${hiddenTagsCounterRef.offsetWidth + 6 + 'px'})` : undefined }"
|
|
513
519
|
@remove="(e: Event) => { handleRemove(e, value) }"
|
|
514
520
|
>
|
|
515
521
|
<template #prefix>
|
|
@@ -520,6 +526,7 @@ defineExpose({ focus, blur, reset, validate, setError, filterRef })
|
|
|
520
526
|
|
|
521
527
|
<div
|
|
522
528
|
v-if="showCountTag"
|
|
529
|
+
ref="hiddenTagsCounterRef"
|
|
523
530
|
:class="classes.truncateCounter"
|
|
524
531
|
@click.stop="multipleHiddenRef?.toggle()"
|
|
525
532
|
>+{{ hiddenTags }}</div>
|
|
@@ -638,17 +645,29 @@ defineExpose({ focus, blur, reset, validate, setError, filterRef })
|
|
|
638
645
|
</template>
|
|
639
646
|
</select>
|
|
640
647
|
|
|
648
|
+
<button
|
|
649
|
+
v-if="isClearIconVisible"
|
|
650
|
+
type="button"
|
|
651
|
+
aria-label="Clean value"
|
|
652
|
+
:class="classes.clearButton"
|
|
653
|
+
@click="reset"
|
|
654
|
+
>
|
|
655
|
+
<x-icon
|
|
656
|
+
:icon="closeIcon"
|
|
657
|
+
:class="[classes.icon, 'cursor-pointer']"
|
|
658
|
+
/>
|
|
659
|
+
</button>
|
|
660
|
+
|
|
641
661
|
<div v-if="!$slots.input" :class="classes.iconWrapper">
|
|
642
662
|
<x-spinner v-if="loading" :size="size" />
|
|
643
663
|
<slot v-else name="icon">
|
|
644
664
|
<x-icon
|
|
645
665
|
:icon="selectIcon"
|
|
646
|
-
:class="
|
|
666
|
+
:class="classes.icon"
|
|
647
667
|
/>
|
|
648
668
|
</slot>
|
|
649
669
|
</div>
|
|
650
670
|
</div>
|
|
651
|
-
|
|
652
671
|
<x-input-footer v-if="!hideFooterInternal" :error="errorInternal" :helper="helper"/>
|
|
653
672
|
</x-label>
|
|
654
673
|
</template>
|
|
@@ -5,7 +5,7 @@ const theme: SelectTheme = {
|
|
|
5
5
|
wrapper: '',
|
|
6
6
|
|
|
7
7
|
box: ({ props, data }) => {
|
|
8
|
-
const classes = ['w-full border border-secondary-300 dark:border-secondary-700
|
|
8
|
+
const classes = ['w-full border border-secondary-300 dark:border-secondary-700 outline-transparent outline outline-2 outline-offset-[-1px] transition-all duration-150 ease-in-out rounded-md shadow-sm']
|
|
9
9
|
|
|
10
10
|
if (!data.errorInternal && !props.disabled) classes.push('hover:border-secondary-400 dark:hover:border-secondary-500')
|
|
11
11
|
|
|
@@ -24,6 +24,16 @@ const theme: SelectTheme = {
|
|
|
24
24
|
classes.push('group-focus:outline-[color:var(--x-select-border)]')
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
if (!props.multiple && !props.multipleCheckbox) {
|
|
28
|
+
classes.push('truncate')
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (props.clearable) {
|
|
32
|
+
classes.push('pr-14')
|
|
33
|
+
} else {
|
|
34
|
+
classes.push('pr-8')
|
|
35
|
+
}
|
|
36
|
+
|
|
27
37
|
return classes
|
|
28
38
|
},
|
|
29
39
|
|
|
@@ -35,15 +45,16 @@ const theme: SelectTheme = {
|
|
|
35
45
|
|
|
36
46
|
contentBody: 'overflow-y-auto max-h-64 min-w-[280px]',
|
|
37
47
|
|
|
38
|
-
iconWrapper: '
|
|
48
|
+
iconWrapper: 'absolute inset-y-0 right-0 flex items-center px-2 pointer-events-none',
|
|
49
|
+
|
|
50
|
+
clearButton: 'absolute top-1/2 -translate-y-1/2 right-5 flex items-center p-2',
|
|
39
51
|
|
|
40
52
|
icon: ({ props }) => {
|
|
41
|
-
const classes = [
|
|
53
|
+
const classes = []
|
|
42
54
|
|
|
43
55
|
if (props.size === 'sm' || props.size === 'xs') classes.push('h-3 w-3')
|
|
44
|
-
else if (props.size === 'lg') classes.push('h-
|
|
45
|
-
else
|
|
46
|
-
else classes.push('h-5 w-5')
|
|
56
|
+
else if (props.size === 'lg' || props.size === 'xl') classes.push('h-5 w-5')
|
|
57
|
+
else classes.push('h-4 w-4')
|
|
47
58
|
|
|
48
59
|
if (props.disabled) classes.push('text-secondary-300 dark:text-secondary-500')
|
|
49
60
|
else classes.push('text-secondary-500 dark:text-secondary-400')
|
|
@@ -55,6 +55,7 @@ export type TableHeader = {
|
|
|
55
55
|
width?: string | number;
|
|
56
56
|
truncate?: boolean;
|
|
57
57
|
skeletonShape?: SkeletonShape;
|
|
58
|
+
tooltip?: string;
|
|
58
59
|
}
|
|
59
60
|
|
|
60
61
|
export type TableProps = ExtractPublicPropTypes<typeof tableProps>
|
|
@@ -208,6 +209,7 @@ const { styles, classes, className } = useTheme('Table', {}, props)
|
|
|
208
209
|
:sort="getSort(header.value, sort)"
|
|
209
210
|
:sortable="header.sortable"
|
|
210
211
|
:width="header.width"
|
|
212
|
+
:tooltip="header.tooltip"
|
|
211
213
|
@click="header.sortable ? sortHeader(header) : null"
|
|
212
214
|
>
|
|
213
215
|
<slot :name="`header-${header.value}`" :header="header">
|
|
@@ -15,6 +15,7 @@ const tableHeaderProps = {
|
|
|
15
15
|
default: 'left',
|
|
16
16
|
validator: (value: string) => validators.textAlign.includes(value as any),
|
|
17
17
|
},
|
|
18
|
+
tooltip: String,
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
export type TableHeaderSort = typeof validators.sort[number]
|
|
@@ -30,6 +31,7 @@ export default { name: 'XTableHeader', validators }
|
|
|
30
31
|
<script setup lang="ts">
|
|
31
32
|
import type { ExtractPublicPropTypes, PropType } from 'vue'
|
|
32
33
|
import { useTheme, type ThemeComponent } from '../../composables/useTheme'
|
|
34
|
+
import XToggleTip from '../tooltip/ToggleTip.vue'
|
|
33
35
|
|
|
34
36
|
const props = defineProps(tableHeaderProps)
|
|
35
37
|
|
|
@@ -38,36 +40,42 @@ const { styles, classes, className } = useTheme('TableHeader', {}, props)
|
|
|
38
40
|
|
|
39
41
|
<template>
|
|
40
42
|
<th :style="styles" :class="[className, classes.th, 'group/th']">
|
|
41
|
-
<
|
|
43
|
+
<div class="flex items-center gap-1 select-none">
|
|
44
|
+
<slot></slot>
|
|
42
45
|
|
|
43
|
-
|
|
44
|
-
v-if="sortable"
|
|
45
|
-
:class="[
|
|
46
|
-
classes.sortIcon,
|
|
47
|
-
[sort && [1, -1].includes(sort) ? '' : 'invisible group-hover/th:visible']
|
|
48
|
-
]"
|
|
49
|
-
width="24"
|
|
50
|
-
height="24"
|
|
51
|
-
viewBox="0 0 24 24"
|
|
52
|
-
stroke="currentColor"
|
|
53
|
-
stroke-linejoin="round"
|
|
54
|
-
stroke-linecap="round"
|
|
55
|
-
fill="none"
|
|
56
|
-
role="presentation"
|
|
57
|
-
>
|
|
58
|
-
<template v-if="sort === -1">
|
|
59
|
-
<line x1="12" y1="5" x2="12" y2="19"/>
|
|
60
|
-
<polyline points="19 12 12 19 5 12" />
|
|
61
|
-
</template>
|
|
46
|
+
<x-toggle-tip v-if="tooltip" :content="tooltip"/>
|
|
62
47
|
|
|
63
|
-
<
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
48
|
+
<svg
|
|
49
|
+
v-if="sortable"
|
|
50
|
+
class="shrink-0"
|
|
51
|
+
:class="[
|
|
52
|
+
classes.sortIcon,
|
|
53
|
+
[sort && [1, -1].includes(sort) ? '' : 'invisible group-hover/th:visible'],
|
|
54
|
+
[sort !== -1 && sort !== 1 ? 'text-secondary-400' : 'text-primary-700']
|
|
55
|
+
]"
|
|
56
|
+
width="24"
|
|
57
|
+
height="24"
|
|
58
|
+
viewBox="0 0 24 24"
|
|
59
|
+
stroke="currentColor"
|
|
60
|
+
stroke-linejoin="round"
|
|
61
|
+
stroke-linecap="round"
|
|
62
|
+
fill="none"
|
|
63
|
+
role="presentation"
|
|
64
|
+
>
|
|
65
|
+
<template v-if="sort === -1">
|
|
66
|
+
<line x1="12" y1="5" x2="12" y2="19"/>
|
|
67
|
+
<polyline points="19 12 12 19 5 12" />
|
|
68
|
+
</template>
|
|
67
69
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
<template v-else-if="sort === 1">
|
|
71
|
+
<line x1="12" y1="19" x2="12" y2="5"/>
|
|
72
|
+
<polyline points="5 12 12 5 19 12" />
|
|
73
|
+
</template>
|
|
74
|
+
|
|
75
|
+
<template v-else>
|
|
76
|
+
<path d="m3 9l4-4l4 4M7 5v14m14-4l-4 4l-4-4m4 4V5"/>
|
|
77
|
+
</template>
|
|
78
|
+
</svg>
|
|
79
|
+
</div>
|
|
72
80
|
</th>
|
|
73
81
|
</template>
|
|
@@ -3,7 +3,7 @@ import type { TableHeadTheme } from '../TableHead.vue'
|
|
|
3
3
|
const theme: TableHeadTheme = {
|
|
4
4
|
classes: {
|
|
5
5
|
thead: ({ props }) => {
|
|
6
|
-
const classes = ['align-bottom bg-secondary-
|
|
6
|
+
const classes = ['align-bottom bg-secondary-100 dark:bg-secondary-700']
|
|
7
7
|
|
|
8
8
|
if (props.stickyHeader) classes.push('sticky top-0 z-10')
|
|
9
9
|
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export default '1.
|
|
1
|
+
export default '1.13.1'
|