@kikiloaw/simple-table 1.0.5 → 1.1.0

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/README.md CHANGED
@@ -6,6 +6,8 @@
6
6
  [![Vue 3](https://img.shields.io/badge/Vue-3.x-brightgreen.svg)](https://vuejs.org/)
7
7
  [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)
8
8
 
9
+ > **🚀 Explore the Demo**: Check out the [SimpleTable Demo Repository](https://github.com/kikiloaw/simple-table-demo.git) for a complete documentation site with live server-side examples, seeding, and source code.
10
+
9
11
  ---
10
12
 
11
13
  ## ✨ Why SimpleTable?
@@ -475,7 +477,7 @@ SimpleTable supports three data modes:
475
477
  label: 'Name', // Required: Column header text
476
478
  sortable: true, // Optional: Enable sorting
477
479
  width: '200px', // Optional: Fixed column width
478
- fixed: true, // Optional: Sticky column (useful for actions)
480
+ fixed: true, // Optional: Sticky column (left for first, right for last, others left). **Requires `width` to be set.**
479
481
  class: 'text-center' // Optional: Additional CSS classes
480
482
  }
481
483
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kikiloaw/simple-table",
3
- "version": "1.0.5",
3
+ "version": "1.1.0",
4
4
  "description": "A lightweight, dependency-light DataTable component for Vue 3 with Tailwind CSS",
5
5
  "main": "src/index.js",
6
6
  "module": "src/index.js",
@@ -67,6 +67,8 @@ const props = withDefaults(defineProps<Props>(), {
67
67
  hoverColor: 'hover:bg-stone-200'
68
68
  })
69
69
 
70
+
71
+
70
72
  // ...
71
73
 
72
74
  // -- Computed: Page Sizes Normalization --
@@ -163,7 +165,7 @@ const densityConfig = computed(() => {
163
165
  </div>
164
166
  */
165
167
 
166
- const emit = defineEmits(['update:search', 'update:sort', 'page-change'])
168
+ const emit = defineEmits(['update:search', 'update:sort', 'page-change', 'fetched'])
167
169
 
168
170
  // -- State --
169
171
  const searchQuery = ref('')
@@ -464,6 +466,7 @@ async function fetchData(params: any = {}) {
464
466
  }
465
467
 
466
468
  internalData.value = data
469
+ emit('fetched', data)
467
470
 
468
471
  // Store in cache if enabled
469
472
  if (props.enableCache) {
@@ -644,6 +647,8 @@ defineExpose({
644
647
  clearCache // expose cache clearing method
645
648
  })
646
649
 
650
+
651
+
647
652
  // -- Helper Styles --
648
653
  function getCellClass(col: any, index: number, totalCols: number, rowIndex: number = -1) {
649
654
  let classes = col.class || ''
@@ -653,15 +658,13 @@ function getCellClass(col: any, index: number, totalCols: number, rowIndex: numb
653
658
 
654
659
  if (col.fixed) {
655
660
  // Sticky logic
656
- const isLast = index === totalCols - 1
657
-
658
- let stickyClass = ''
659
- if (isLast) {
660
- // Right sticky: Stronger shadow to the left, and a left border
661
- stickyClass = ' sticky right-0 z-10 shadow-[-4px_0_8px_-2px_rgba(0,0,0,0.1)] border-l border-border/50'
661
+ let stickyClass = ' whitespace-nowrap' // Prevent content wrapping in sticky columns
662
+ if (index === totalCols - 1) {
663
+ // Last Column -> Right Sticky
664
+ stickyClass = ' sticky right-0 z-10 shadow-[-4px_0_8px_-2px_rgba(0,0,0,0.1)] border-l border-stone-300'
662
665
  } else {
663
- // Left sticky: Stronger shadow to the right, and a right border
664
- stickyClass = ' sticky left-0 z-10 shadow-[4px_0_8px_-2px_rgba(0,0,0,0.1)] border-r border-border/50'
666
+ // All other fixed columns -> Left Sticky
667
+ stickyClass = ' sticky left-0 z-10 shadow-[4px_0_8px_-2px_rgba(0,0,0,0.1)] border-r border-stone-300'
665
668
  }
666
669
 
667
670
  // Determine background
@@ -670,8 +673,8 @@ function getCellClass(col: any, index: number, totalCols: number, rowIndex: numb
670
673
 
671
674
  if (rowIndex !== -1) {
672
675
  // Body Row
673
- const isEven = rowIndex % 2 === 0
674
- bgClass = isEven ? props.evenRowColor : props.oddRowColor
676
+ const isOdd = rowIndex % 2 === 0
677
+ bgClass = isOdd ? props.oddRowColor : props.evenRowColor
675
678
 
676
679
  // Should also match hover
677
680
  // If the row has a hover class (like hover:bg-muted), the sticky cell needs group-hover:bg-muted to match.
@@ -702,6 +705,10 @@ function getCellStyle(col: any) {
702
705
  if (col.width) {
703
706
  return { width: col.width, minWidth: col.width, maxWidth: col.width }
704
707
  }
708
+ // Smart default: If fixed but no width, force a safe width (e.g. 100px) to ensure background covers content
709
+ if (col.fixed) {
710
+ return { width: '100px', minWidth: '100px' }
711
+ }
705
712
  return {}
706
713
  }
707
714
 
@@ -753,7 +760,7 @@ function getCellStyle(col: any) {
753
760
  <!-- Table -->
754
761
  <div class="border bg-background overflow-x-auto relative">
755
762
  <!-- We add min-w-full to Table to ensure it stretches -->
756
- <Table class="min-w-full table-fixed">
763
+ <Table class="min-w-full table-auto">
757
764
  <TableHeader>
758
765
  <TableRow :style="{ height: densityConfig.cellHeight }">
759
766
  <TableHead
@@ -797,7 +804,12 @@ function getCellStyle(col: any) {
797
804
  <!-- Group Header Row: Single cell spanning all columns -->
798
805
  <template v-if="row._isGroupHeader">
799
806
  <TableCell :colspan="columns.length" class="border-b border-gray-200">
800
- <div :class="['px-2', densityConfig.groupHeaderPadding, 'font-semibold text-gray-700 text-sm uppercase tracking-wide']">
807
+ <div :class="[
808
+ 'px-2',
809
+ densityConfig.groupHeaderPadding,
810
+ 'font-semibold text-sm uppercase tracking-wide',
811
+ row._groupTitleClass || 'text-gray-700'
812
+ ]">
801
813
  {{ row._groupTitle }}
802
814
  </div>
803
815
  </TableCell>
@@ -16,7 +16,7 @@ const delegatedProps = computed(() => {
16
16
  <template>
17
17
  <div class="relative w-full overflow-auto">
18
18
  <table
19
- :class="cn('w-full caption-bottom text-sm', props.class)"
19
+ :class="cn('w-full caption-bottom text-sm border-separate border-spacing-0', props.class)"
20
20
  v-bind="delegatedProps"
21
21
  >
22
22
  <slot />
@@ -7,6 +7,7 @@ const props = defineProps<{
7
7
  style?: any
8
8
  padding?: string
9
9
  height?: string
10
+ colspan?: number | string
10
11
  }>()
11
12
 
12
13
  const delegatedProps = computed(() => {
@@ -25,7 +26,7 @@ const cellStyle = computed(() => {
25
26
 
26
27
  <template>
27
28
  <td
28
- :class="cn(props.padding || 'p-2', 'align-middle [&:has([role=checkbox])]:pr-0', props.class)"
29
+ :class="cn(props.padding || 'p-2', 'border-b border-stone-300 align-middle [&:has([role=checkbox])]:pr-0', props.class)"
29
30
  :style="cellStyle"
30
31
  v-bind="delegatedProps"
31
32
  >
@@ -21,7 +21,7 @@ const delegatedProps = computed(() => {
21
21
  cn(
22
22
  props.height || 'h-[38px]',
23
23
  props.padding || 'px-2',
24
- 'text-left align-middle font-bold text-muted-foreground [&:has([role=checkbox])]:pr-0',
24
+ 'border-b border-stone-300 text-left align-middle font-bold text-muted-foreground [&:has([role=checkbox])]:pr-0',
25
25
  props.class,
26
26
  )
27
27
  "
@@ -17,7 +17,7 @@ const delegatedProps = computed(() => {
17
17
  <tr
18
18
  :class="
19
19
  cn(
20
- 'border-b border-stone-300 transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted',
20
+ 'transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted',
21
21
  props.class,
22
22
  )
23
23
  "