@globalbrain/sefirot 4.14.1 → 4.15.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.
Files changed (37) hide show
  1. package/lib/components/SButton.vue +2 -2
  2. package/lib/components/SControlActionBarButton.vue +1 -1
  3. package/lib/components/SControlActionBarClose.vue +1 -1
  4. package/lib/components/SControlActionBarCollapse.vue +1 -1
  5. package/lib/components/SControlButton.vue +1 -1
  6. package/lib/components/SControlInputSearch.vue +4 -4
  7. package/lib/components/SControlPagination.vue +2 -2
  8. package/lib/components/SDropdownSectionDateRangeDateFromTo.vue +1 -1
  9. package/lib/components/SDropdownSectionDateRangeYear.vue +1 -1
  10. package/lib/components/SDropdownSectionDateRangeYearHalf.vue +1 -1
  11. package/lib/components/SDropdownSectionDateRangeYearQuarter.vue +1 -1
  12. package/lib/components/SErrorBoundary.vue +1 -1
  13. package/lib/components/SInputAddon.vue +1 -1
  14. package/lib/components/SInputCheckbox.vue +2 -2
  15. package/lib/components/SInputCheckboxes.vue +2 -2
  16. package/lib/components/SInputDate.vue +1 -1
  17. package/lib/components/SInputFile.vue +2 -2
  18. package/lib/components/SInputFileUploadItem.vue +1 -1
  19. package/lib/components/SInputHMS.vue +2 -2
  20. package/lib/components/SInputImage.vue +2 -2
  21. package/lib/components/SInputRadio.vue +2 -2
  22. package/lib/components/SInputRadios.vue +2 -2
  23. package/lib/components/SInputSegments.vue +2 -2
  24. package/lib/components/SInputSegmentsOption.vue +1 -1
  25. package/lib/components/SInputSelect.vue +2 -2
  26. package/lib/components/SInputSwitch.vue +2 -2
  27. package/lib/components/SInputSwitches.vue +1 -1
  28. package/lib/components/SInputYMD.vue +2 -2
  29. package/lib/components/SMarkdown.vue +1 -1
  30. package/lib/components/SModal.vue +1 -1
  31. package/lib/components/SPagination.vue +2 -2
  32. package/lib/components/SPill.vue +1 -1
  33. package/lib/components/STable.vue +95 -74
  34. package/lib/components/STableColumn.vue +1 -1
  35. package/lib/composables/Table.ts +1 -0
  36. package/lib/support/Reactivity.ts +11 -0
  37. package/package.json +1 -1
@@ -51,8 +51,8 @@ const props = defineProps<{
51
51
  }>()
52
52
 
53
53
  const emit = defineEmits<{
54
- (e: 'click'): void
55
- (e: 'disabled-click'): void
54
+ 'click': []
55
+ 'disabled-click': []
56
56
  }>()
57
57
 
58
58
  const _leadIcon = computed(() => props.leadIcon ?? props.icon)
@@ -12,7 +12,7 @@ defineProps<{
12
12
  }>()
13
13
 
14
14
  defineEmits<{
15
- (e: 'click'): void
15
+ click: []
16
16
  }>()
17
17
 
18
18
  const size = useControlSize()
@@ -7,7 +7,7 @@ defineProps<{
7
7
  }>()
8
8
 
9
9
  defineEmits<{
10
- (e: 'click'): void
10
+ click: []
11
11
  }>()
12
12
  </script>
13
13
 
@@ -11,7 +11,7 @@ const props = defineProps<{
11
11
  }>()
12
12
 
13
13
  defineEmits<{
14
- (e: 'click'): void
14
+ click: []
15
15
  }>()
16
16
 
17
17
  const { isCollapsed, setCollapse, toggleCollapse } = useCardState()
@@ -20,7 +20,7 @@ defineProps<{
20
20
  }>()
21
21
 
22
22
  defineEmits<{
23
- (e: 'click'): void
23
+ click: []
24
24
  }>()
25
25
 
26
26
  const size = useControlSize()
@@ -19,10 +19,10 @@ const props = defineProps<{
19
19
  }>()
20
20
 
21
21
  defineEmits<{
22
- (e: 'update:model-value', value: string | null): void
23
- (e: 'input', value: string | null): void
24
- (e: 'blur', value: string | null): void
25
- (e: 'enter', value: string | null): void
22
+ 'update:model-value': [value: string | null]
23
+ 'input': [value: string | null]
24
+ 'blur': [value: string | null]
25
+ 'enter': [value: string | null]
26
26
  }>()
27
27
 
28
28
  const { t } = useTrans({
@@ -10,8 +10,8 @@ defineProps<{
10
10
  }>()
11
11
 
12
12
  defineEmits<{
13
- (e: 'prev'): void
14
- (e: 'next'): void
13
+ prev: []
14
+ next: []
15
15
  }>()
16
16
 
17
17
  const size = useControlSize()
@@ -10,7 +10,7 @@ const props = defineProps<{
10
10
  }>()
11
11
 
12
12
  const emit = defineEmits<{
13
- (e: 'change', value: DateFromTo): void
13
+ change: [value: DateFromTo]
14
14
  }>()
15
15
 
16
16
  const { validation } = useValidation(() => ({
@@ -9,7 +9,7 @@ const props = defineProps<{
9
9
  }>()
10
10
 
11
11
  const emit = defineEmits<{
12
- (e: 'change', value: Year): void
12
+ change: [value: Year]
13
13
  }>()
14
14
 
15
15
  const { validation } = useValidation(() => ({
@@ -10,7 +10,7 @@ const props = defineProps<{
10
10
  }>()
11
11
 
12
12
  const emit = defineEmits<{
13
- (e: 'change', value: YearHalf): void
13
+ change: [value: YearHalf]
14
14
  }>()
15
15
 
16
16
  const { validation } = useValidation(() => ({
@@ -10,7 +10,7 @@ const props = defineProps<{
10
10
  }>()
11
11
 
12
12
  const emit = defineEmits<{
13
- (e: 'change', value: YearQuarter): void
13
+ change: [value: YearQuarter]
14
14
  }>()
15
15
 
16
16
  const { validation } = useValidation(() => ({
@@ -3,7 +3,7 @@ import { onErrorCaptured, shallowRef } from 'vue'
3
3
  import { useRouter } from 'vue-router'
4
4
 
5
5
  const emit = defineEmits<{
6
- (e: 'error', value: any): void
6
+ error: [value: any]
7
7
  }>()
8
8
 
9
9
  const error = shallowRef<Error>()
@@ -24,7 +24,7 @@ const props = withDefaults(defineProps<{
24
24
  })
25
25
 
26
26
  const emit = defineEmits<{
27
- (e: 'click'): void
27
+ click: []
28
28
  }>()
29
29
 
30
30
  const container = ref<any>(null)
@@ -29,8 +29,8 @@ const props = withDefaults(defineProps<{
29
29
  })
30
30
 
31
31
  const emit = defineEmits<{
32
- (e: 'update:model-value', value: boolean): void
33
- (e: 'change', value: boolean): void
32
+ 'update:model-value': [value: boolean]
33
+ 'change': [value: boolean]
34
34
  }>()
35
35
 
36
36
  const classes = computed(() => [
@@ -37,8 +37,8 @@ const props = withDefaults(defineProps<{
37
37
  })
38
38
 
39
39
  const emit = defineEmits<{
40
- (e: 'update:model-value', value: Value[]): void
41
- (e: 'change', value: Value[]): void
40
+ 'update:model-value': [value: Value[]]
41
+ 'change': [value: Value[]]
42
42
  }>()
43
43
 
44
44
  const _value = computed(() => {
@@ -26,7 +26,7 @@ const props = defineProps<{
26
26
  }>()
27
27
 
28
28
  const emit = defineEmits<{
29
- (e: 'update:model-value', value: Day | null): void
29
+ 'update:model-value': [value: Day | null]
30
30
  }>()
31
31
 
32
32
  const classes = computed(() => [
@@ -26,8 +26,8 @@ const props = defineProps<{
26
26
  }>()
27
27
 
28
28
  const emit = defineEmits<{
29
- (e: 'update:model-value', file: File | File[] | null): void
30
- (e: 'change', file: File | File[] | null): void
29
+ 'update:model-value': [file: File | File[] | null]
30
+ 'change': [file: File | File[] | null]
31
31
  }>()
32
32
 
33
33
  const _value = computed(() => {
@@ -32,7 +32,7 @@ const props = defineProps<{
32
32
  }>()
33
33
 
34
34
  defineEmits<{
35
- 'remove': []
35
+ remove: []
36
36
  }>()
37
37
 
38
38
  const _file = computed(() => ({
@@ -41,8 +41,8 @@ const props = defineProps<{
41
41
  }>()
42
42
 
43
43
  const emit = defineEmits<{
44
- (e: 'update:model-value', value: Value): void
45
- (e: 'change', value: Value): void
44
+ 'update:model-value': [value: Value]
45
+ 'change': [value: Value]
46
46
  }>()
47
47
 
48
48
  const _value = computed(() => {
@@ -42,8 +42,8 @@ const props = withDefaults(defineProps<{
42
42
  })
43
43
 
44
44
  const emit = defineEmits<{
45
- (e: 'update:model-value', value: File | null): void
46
- (e: 'change', value: File | null): void
45
+ 'update:model-value': [file: File | null]
46
+ 'change': [file: File | null]
47
47
  }>()
48
48
 
49
49
  const fileInput = ref<HTMLInputElement | null>(null)
@@ -24,8 +24,8 @@ const props = defineProps<{
24
24
  }>()
25
25
 
26
26
  const emit = defineEmits<{
27
- (e: 'update:model-value', value: boolean): void
28
- (e: 'change', value: boolean): void
27
+ 'update:model-value': [value: boolean]
28
+ 'change': [value: boolean]
29
29
  }>()
30
30
 
31
31
  const classes = computed(() => [
@@ -47,8 +47,8 @@ const props = withDefaults(defineProps<{
47
47
  })
48
48
 
49
49
  const emit = defineEmits<{
50
- (e: 'update:model-value', value: ValueType | NullValue): void
51
- (e: 'change', value: ValueType | NullValue): void
50
+ 'update:model-value': [value: ValueType | NullValue]
51
+ 'change': [value: ValueType | NullValue]
52
52
  }>()
53
53
 
54
54
  const _value = computed(() => {
@@ -35,8 +35,8 @@ const props = defineProps<{
35
35
  }>()
36
36
 
37
37
  const emit = defineEmits<{
38
- (e: 'update:model-value', value: T): void
39
- (e: 'change', value: T): void
38
+ 'update:model-value': [value: T]
39
+ 'change': [value: T]
40
40
  }>()
41
41
 
42
42
  const _value = computed(() => {
@@ -12,7 +12,7 @@ const props = defineProps<{
12
12
  }>()
13
13
 
14
14
  const emit = defineEmits<{
15
- (e: 'click'): void
15
+ click: []
16
16
  }>()
17
17
 
18
18
  function onClick() {
@@ -38,8 +38,8 @@ const props = withDefaults(defineProps<{
38
38
  })
39
39
 
40
40
  const emit = defineEmits<{
41
- (e: 'update:model-value', value: Value): void
42
- (e: 'change', value: Value): void
41
+ 'update:model-value': [value: Value]
42
+ 'change': [value: Value]
43
43
  }>()
44
44
 
45
45
  const _value = computed(() => {
@@ -30,8 +30,8 @@ const props = withDefaults(defineProps<{
30
30
  })
31
31
 
32
32
  const emit = defineEmits<{
33
- (e: 'update:model-value', value: boolean): void
34
- (e: 'change', value: boolean): void
33
+ 'update:model-value': [value: boolean]
34
+ 'change': [value: boolean]
35
35
  }>()
36
36
 
37
37
  const _value = computed(() => {
@@ -30,7 +30,7 @@ const props = defineProps<{
30
30
  }>()
31
31
 
32
32
  const emit = defineEmits<{
33
- (e: 'update:modelValue', value: any[]): void
33
+ 'update:modelValue': [value: any[]]
34
34
  }>()
35
35
 
36
36
  const classes = computed(() => [
@@ -42,8 +42,8 @@ const props = defineProps<{
42
42
  }>()
43
43
 
44
44
  const emit = defineEmits<{
45
- (e: 'update:model-value', value: Value): void
46
- (e: 'change', value: Value): void
45
+ 'update:model-value': [value: Value]
46
+ 'change': [value: Value]
47
47
  }>()
48
48
 
49
49
  const _value = computed(() => {
@@ -10,7 +10,7 @@ const props = defineProps<{
10
10
  }>()
11
11
 
12
12
  const emit = defineEmits<{
13
- (e: 'clicked', payload: LinkSubscriberPayload): void
13
+ clicked: [payload: LinkSubscriberPayload]
14
14
  }>()
15
15
 
16
16
  const container = shallowRef<Element | null>(null)
@@ -11,7 +11,7 @@ const props = withDefaults(defineProps<Props>(), {
11
11
  })
12
12
 
13
13
  const emit = defineEmits<{
14
- (e: 'close'): void
14
+ close: []
15
15
  }>()
16
16
 
17
17
  const el = ref<any>(null)
@@ -21,8 +21,8 @@ const props = withDefaults(defineProps<{
21
21
  })
22
22
 
23
23
  const emit = defineEmits<{
24
- (e: 'prev'): void
25
- (e: 'next'): void
24
+ prev: []
25
+ next: []
26
26
  }>()
27
27
 
28
28
  const { t } = useTrans({
@@ -15,7 +15,7 @@ const props = defineProps<{
15
15
  }>()
16
16
 
17
17
  const emit = defineEmits<{
18
- (e: 'click'): void
18
+ click: []
19
19
  }>()
20
20
 
21
21
  const classes = computed(() => [
@@ -1,18 +1,10 @@
1
- <script setup lang="ts" generic="S extends any[] | any | undefined = undefined">
1
+ <script setup lang="ts" generic="S extends any = undefined">
2
2
  import { useVirtualizer } from '@tanstack/vue-virtual'
3
3
  import { useResizeObserver } from '@vueuse/core'
4
4
  import xor from 'lodash-es/xor'
5
- import {
6
- computed,
7
- nextTick,
8
- reactive,
9
- ref,
10
- shallowRef,
11
- toValue,
12
- unref,
13
- watch
14
- } from 'vue'
5
+ import { computed, nextTick, reactive, ref, shallowRef, toValue, unref, watch } from 'vue'
15
6
  import { type Table } from '../composables/Table'
7
+ import { smartComputed } from '../support/Reactivity'
16
8
  import { getTextWidth } from '../support/Text'
17
9
  import SInputCheckbox from './SInputCheckbox.vue'
18
10
  import SInputRadio from './SInputRadio.vue'
@@ -23,28 +15,24 @@ import STableFooter from './STableFooter.vue'
23
15
  import STableHeader from './STableHeader.vue'
24
16
  import STableItem from './STableItem.vue'
25
17
 
26
- const props = defineProps<{
27
- options: Table
28
- selected?: S
29
- }>()
30
-
31
- const emit = defineEmits<{
32
- (e: 'update:selected', value: S): void
33
- }>()
18
+ const props = defineProps<{ options: Table }>()
19
+ const selected = defineModel<S>('selected')
34
20
 
35
21
  const head = shallowRef<HTMLElement | null>(null)
36
22
  const body = shallowRef<HTMLElement | null>(null)
37
23
  const block = shallowRef<HTMLElement | null>(null)
38
24
  const row = shallowRef<HTMLElement | null>(null)
39
25
 
40
- const ordersToShow = computed(() => {
26
+ const ordersToShow = smartComputed(() => {
41
27
  const orders = unref(props.options.orders).filter((key) => {
42
28
  const show = unref(props.options.columns)[key]?.show
43
29
  return toValue(show) !== false
44
30
  })
45
- if (props.selected === undefined) {
31
+
32
+ if (selected.value === undefined) {
46
33
  return orders
47
34
  }
35
+
48
36
  return ['__select', ...orders]
49
37
  })
50
38
 
@@ -126,51 +114,45 @@ const recordsWithSummary = computed(() => {
126
114
  return summary ? [...records, summary] : records
127
115
  })
128
116
 
129
- const indexes = computed(() => {
130
- if (props.selected === undefined) {
117
+ const indexes = smartComputed(() => {
118
+ if (selected.value === undefined) {
131
119
  return []
132
120
  }
121
+
133
122
  const records = unref(props.options.records) ?? []
134
123
  const indexField = unref(props.options.indexField)
135
124
 
136
- return records.map((record, i) => indexField ? record[indexField] : i)
125
+ return records.map((record, i) => (indexField ? record[indexField] : i))
137
126
  })
138
127
 
139
- const selectedIndexes = reactive(new Set(Array.isArray(props.selected) ? props.selected : []))
140
-
141
128
  const control = computed({
142
129
  get() {
143
- if (Array.isArray(props.selected)) {
144
- return props.selected.length === indexes.value.length
145
- ? true
146
- : props.selected.length ? 'indeterminate' : false
130
+ if (Array.isArray(selected.value)) {
131
+ if (!selected.value.length) {
132
+ return false
133
+ }
134
+
135
+ if (selected.value.length === indexes.value.length) {
136
+ return true
137
+ }
147
138
  }
148
139
 
149
- return 'indeterminate' // doesn't matter
140
+ return 'indeterminate'
150
141
  },
151
142
 
152
143
  set(newValue) {
153
144
  if (newValue === false) {
154
- selectedIndexes.clear()
145
+ updateSelected([])
155
146
  } else if (newValue === true) {
156
- indexes.value.forEach((index) => {
157
- selectedIndexes.add(index)
158
- })
147
+ updateSelected(indexes.value)
159
148
  }
160
149
  }
161
150
  })
162
151
 
163
152
  watch(indexes, (newValue, oldValue) => {
164
- if (Array.isArray(props.selected)) {
165
- xor(newValue, oldValue).forEach((index) => {
166
- selectedIndexes.delete(index)
167
- })
168
- }
169
- })
170
-
171
- watch(selectedIndexes, (newValue) => {
172
- if (Array.isArray(props.selected)) {
173
- updateSelected(Array.from(newValue))
153
+ if (Array.isArray(selected.value)) {
154
+ const removed = xor(newValue, oldValue)
155
+ updateSelected(selected.value.filter((item) => !removed.includes(item)))
174
156
  }
175
157
  })
176
158
 
@@ -202,6 +184,21 @@ watch(() => unref(props.options.records), () => {
202
184
  isSyncingBody = false
203
185
  }, { flush: 'post' })
204
186
 
187
+ const frozenColumns = smartComputed(() => {
188
+ const columns = unref(props.options.columns)
189
+ const keys = Object.keys(columns).filter((key) => columns[key].freeze)
190
+ if (selected.value !== undefined && keys.length) {
191
+ keys.unshift('__select')
192
+ }
193
+ return keys.filter((key) => ordersToShow.value.includes(key))
194
+ })
195
+
196
+ const frozenColWidths = smartComputed(() => {
197
+ // eslint-disable-next-line no-void
198
+ void blockWidth.value
199
+ return frozenColumns.value.map((key) => getColWidth(key))
200
+ })
201
+
205
202
  useResizeObserver(block, ([entry]) => {
206
203
  blockWidth.value = entry.contentRect.width
207
204
  })
@@ -256,10 +253,9 @@ watch(actionsColumnWidth, (newValue) => {
256
253
 
257
254
  function stopObserving() {
258
255
  const orders = ordersToShow.value
259
- const lastOrder
260
- = orders[orders.length - 1] === 'actions'
261
- ? orders[orders.length - 2]
262
- : orders[orders.length - 1]
256
+ const lastOrder = orders[orders.length - 1] === 'actions'
257
+ ? orders[orders.length - 2]
258
+ : orders[orders.length - 1]
263
259
  colWidths[lastOrder] = 'auto'
264
260
  resizeObserver.stop()
265
261
  }
@@ -284,10 +280,7 @@ async function handleResize() {
284
280
  }
285
281
 
286
282
  const availableFill = row.value.getBoundingClientRect().width - totalWidth
287
- updateColWidth(
288
- nameOfColToGrow.value,
289
- `calc(${availableFill}px + ${initialWidth})`
290
- )
283
+ updateColWidth(nameOfColToGrow.value, `calc(${availableFill}px + ${initialWidth})`)
291
284
  }
292
285
 
293
286
  function syncHeadScroll() {
@@ -341,16 +334,50 @@ function getCell(key: string, index: number) {
341
334
  return { type: 'custom' }
342
335
  }
343
336
  const col = unref(props.options.columns)[key]
344
- return (isSummary(index) && col?.summaryCell) ? col?.summaryCell : col?.cell
337
+ return isSummary(index) && col?.summaryCell ? col?.summaryCell : col?.cell
345
338
  }
346
339
 
347
- function updateSelected(selected: any) {
348
- if (Array.isArray(props.selected)) {
349
- if (xor(selected, props.selected ?? []).length) {
350
- emit('update:selected', selected)
351
- }
340
+ function updateSelected(items: any) {
341
+ if (Array.isArray(selected.value)) {
342
+ selected.value = [...items] as any
352
343
  } else {
353
- emit('update:selected', selected)
344
+ selected.value = items
345
+ }
346
+ }
347
+
348
+ function addSelected(item: any) {
349
+ updateSelected([...(selected.value as any), item])
350
+ }
351
+
352
+ function removeSelected(item: any) {
353
+ updateSelected((selected.value as any[]).filter((i) => i !== item))
354
+ }
355
+
356
+ function getColWidth(key: string) {
357
+ if (key === '__select') {
358
+ return '48px + var(--table-padding-left, 0)'
359
+ }
360
+ const adjustedWidth = colWidths[key]
361
+ if (adjustedWidth && adjustedWidth !== 'auto') {
362
+ return adjustedWidth
363
+ }
364
+ const el = row.value?.children?.[ordersToShow.value.indexOf(key)]
365
+ if (!el) {
366
+ return '0px'
367
+ }
368
+ return `${el.getBoundingClientRect().width}px`
369
+ }
370
+
371
+ function getStyles(key: string) {
372
+ const length = frozenColumns.value.length
373
+ if (length === 0) { return }
374
+ const i = frozenColumns.value.indexOf(key)
375
+ if (i < 0) { return }
376
+ const widthSum = frozenColWidths.value.slice(0, i).join(' + ')
377
+ return {
378
+ '--table-col-position': 'sticky',
379
+ '--table-col-z-index': length - i, // left to right decreasing
380
+ '--table-col-left': widthSum ? `calc(${widthSum})` : '0px'
354
381
  }
355
382
  }
356
383
  </script>
@@ -369,11 +396,7 @@ function updateSelected(selected: any) {
369
396
  />
370
397
 
371
398
  <div class="table" role="grid">
372
- <div
373
- class="container head"
374
- ref="head"
375
- @scroll="syncHeadScroll"
376
- >
399
+ <div class="container head" ref="head" @scroll="syncHeadScroll">
377
400
  <div class="block" ref="block">
378
401
  <div class="row" ref="row">
379
402
  <STableItem
@@ -381,6 +404,7 @@ function updateSelected(selected: any) {
381
404
  :key="key"
382
405
  :name="key"
383
406
  :class-name="unref(options.columns)[key]?.className"
407
+ :style="getStyles(key)"
384
408
  :width="colWidths[key]"
385
409
  >
386
410
  <STableColumn
@@ -421,10 +445,7 @@ function updateSelected(selected: any) {
421
445
  position: 'relative'
422
446
  }"
423
447
  >
424
- <div
425
- v-for="{ index, key: __key, size, start } in virtualItems"
426
- :key="__key"
427
- >
448
+ <div v-for="{ index, key: __key, size, start } in virtualItems" :key="__key">
428
449
  <div
429
450
  class="row"
430
451
  :class="isSummaryOrLastClass(index)"
@@ -442,6 +463,7 @@ function updateSelected(selected: any) {
442
463
  :key="key"
443
464
  :name="key"
444
465
  :class-name="unref(options.columns)[key]?.className"
466
+ :style="getStyles(key)"
445
467
  :width="colWidths[key]"
446
468
  >
447
469
  <STableCell
@@ -456,14 +478,14 @@ function updateSelected(selected: any) {
456
478
  <template v-if="key === '__select' && !isSummary(index)">
457
479
  <SInputCheckbox
458
480
  v-if="Array.isArray(selected)"
459
- :model-value="selectedIndexes.has(indexes[index])"
460
- @update:model-value="c => selectedIndexes[c ? 'add' : 'delete'](indexes[index])"
481
+ :model-value="selected.includes(indexes[index])"
482
+ @update:model-value="(c) => (c ? addSelected : removeSelected)(indexes[index])"
461
483
  :disabled="options.disableSelection?.(recordsWithSummary[index]) === true"
462
484
  />
463
485
  <SInputRadio
464
486
  v-else
465
487
  :model-value="selected === indexes[index]"
466
- @update:model-value="c => updateSelected(c ? indexes[index] : null)"
488
+ @update:model-value="(c) => updateSelected(c ? indexes[index] : null)"
467
489
  :disabled="options.disableSelection?.(recordsWithSummary[index]) === true"
468
490
  />
469
491
  </template>
@@ -609,8 +631,7 @@ function updateSelected(selected: any) {
609
631
  }
610
632
 
611
633
  .STable .col-__select {
612
- --table-padding-left: 0;
613
- --table-col-width: 48px;
634
+ --table-col-width: calc(48px + var(--table-padding-left, 0));
614
635
 
615
636
  :deep(.input) {
616
637
  align-items: center;
@@ -17,7 +17,7 @@ const props = withDefaults(defineProps<{
17
17
  })
18
18
 
19
19
  const emit = defineEmits<{
20
- (e: 'resize', value: string): void
20
+ resize: [value: string]
21
21
  }>()
22
22
 
23
23
  const { container, isOpen, toggle } = useFlyout()
@@ -44,6 +44,7 @@ export interface TableColumn<V, R, SV, SR> {
44
44
  label?: string
45
45
  className?: string
46
46
  dropdown?: DropdownSection[]
47
+ freeze?: boolean
47
48
  grow?: boolean
48
49
  resizable?: boolean
49
50
  cell?: TableCell<V, R> | TableColumnCellFn<V, R>
@@ -0,0 +1,11 @@
1
+ import { type ComputedRef, computed } from 'vue'
2
+
3
+ export function smartComputed<T>(
4
+ getter: () => T,
5
+ comparator = (oldValue: T, newValue: T) => JSON.stringify(oldValue) === JSON.stringify(newValue)
6
+ ): ComputedRef<T> {
7
+ return computed((oldValue) => {
8
+ const newValue = getter()
9
+ return oldValue === undefined || !comparator(oldValue, newValue) ? newValue : oldValue
10
+ })
11
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@globalbrain/sefirot",
3
3
  "type": "module",
4
- "version": "4.14.1",
4
+ "version": "4.15.0",
5
5
  "packageManager": "pnpm@9.15.4",
6
6
  "description": "Vue Components for Global Brain Design System.",
7
7
  "author": "Kia Ishii <ka.ishii@globalbrains.com>",