@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.
Files changed (33) hide show
  1. package/docs/pages/component/datepicker/usage.vue +1 -0
  2. package/docs/pages/component/select/multiple.vue +4 -2
  3. package/docs/pages/component/select/usage.vue +1 -0
  4. package/docs/pages/component/table/usage.vue +1 -1
  5. package/lib/components/datepicker/Datepicker.vue.d.ts +12 -12
  6. package/lib/components/datepicker/Datepicker.vue.js +6 -6
  7. package/lib/components/select/Select.vue.d.ts +5 -1
  8. package/lib/components/select/Select.vue.js +262 -245
  9. package/lib/components/select/theme/Select.base.theme.js +11 -10
  10. package/lib/components/table/Table.vue.d.ts +1 -0
  11. package/lib/components/table/Table.vue.js +51 -50
  12. package/lib/components/table/TableHeader.vue.d.ts +3 -0
  13. package/lib/components/table/TableHeader.vue.js +58 -49
  14. package/lib/components/table/theme/TableHead.base.theme.js +1 -1
  15. package/lib/components/table/theme/TableHeader.base.theme.js +3 -3
  16. package/lib/components/table/theme/TableRow.base.theme.js +1 -1
  17. package/lib/index.js +1 -1
  18. package/lib/index.umd.js +4 -4
  19. 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
  20. package/lib/version.d.ts +1 -1
  21. package/lib/version.js +1 -1
  22. package/package.json +2 -2
  23. package/src/components/datepicker/Datepicker.vue +1 -1
  24. package/src/components/select/Select.vue +27 -8
  25. package/src/components/select/theme/Select.base.theme.ts +17 -6
  26. package/src/components/table/Table.vue +2 -0
  27. package/src/components/table/TableHeader.vue +36 -28
  28. package/src/components/table/theme/TableHead.base.theme.ts +1 -1
  29. package/src/components/table/theme/TableHeader.base.theme.ts +1 -1
  30. package/src/components/table/theme/TableRow.base.theme.ts +1 -1
  31. package/src/version.ts +1 -1
  32. 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
  33. /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.12.1";
1
+ declare const _default: "1.13.1";
2
2
  export default _default;
package/lib/version.js CHANGED
@@ -1,4 +1,4 @@
1
- const e = "1.12.1";
1
+ const e = "1.13.1";
2
2
  export {
3
3
  e as default
4
4
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@indielayer/ui",
3
- "version": "1.12.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.1",
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
- .dp__clear_icon {
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 = 0
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 (totalWidth < maxWidth) tagsCount++
439
- else tag.style.display = 'none'
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="[classes.icon]"
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 pr-8 outline-transparent outline outline-2 outline-offset-[-1px] transition-all duration-150 ease-in-out rounded-md shadow-sm']
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: 'pointer-events-none absolute inset-y-0 right-0 flex items-center px-2',
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-6 w-6')
45
- else if (props.size === 'xl') classes.push('h-7 w-7')
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
- <slot></slot>
43
+ <div class="flex items-center gap-1 select-none">
44
+ <slot></slot>
42
45
 
43
- <svg
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
- <template v-else-if="sort === 1">
64
- <line x1="12" y1="19" x2="12" y2="5"/>
65
- <polyline points="5 12 12 5 19 12" />
66
- </template>
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
- <template v-else>
69
- <path d="m3 9l4-4l4 4M7 5v14m14-4l-4 4l-4-4m4 4V5"/>
70
- </template>
71
- </svg>
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-50 dark:bg-secondary-700']
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
 
@@ -16,7 +16,7 @@ const theme: TableHeaderTheme = {
16
16
  },
17
17
 
18
18
  sortIcon: ({ props }) => {
19
- const classes = ['absolute stroke-2 w-3 h-3 top-3.5 right-0.5']
19
+ const classes = ['stroke-2 w-3 h-3']
20
20
 
21
21
  return classes
22
22
  },
@@ -6,7 +6,7 @@ const theme: TableRowTheme = {
6
6
  const classes = []
7
7
 
8
8
  if (props.selected) {
9
- classes.push('shadow-[inset_3px_0] shadow-primary-500')
9
+ classes.push('shadow-[inset_2px_0] shadow-primary-500')
10
10
  }
11
11
 
12
12
  if (props.striped) {
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export default '1.12.1'
1
+ export default '1.13.1'