@globalbrain/sefirot 4.31.0 → 4.32.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 (131) hide show
  1. package/client.d.ts +5 -0
  2. package/config/nuxt.d.ts +1 -0
  3. package/config/nuxt.js +1 -1
  4. package/config/vite.js +3 -2
  5. package/lib/components/SActionList.vue +2 -2
  6. package/lib/components/SActionMenu.vue +4 -4
  7. package/lib/components/SAvatar.vue +1 -1
  8. package/lib/components/SAvatarStack.vue +12 -12
  9. package/lib/components/SButton.vue +5 -7
  10. package/lib/components/SCard.vue +2 -2
  11. package/lib/components/SChartBar.vue +37 -12
  12. package/lib/components/SChartPie.vue +13 -7
  13. package/lib/components/SControlActionBarCollapse.vue +2 -4
  14. package/lib/components/SControlInputSearch.vue +7 -2
  15. package/lib/components/SDataListItem.vue +1 -3
  16. package/lib/components/SDescAvatar.vue +1 -1
  17. package/lib/components/SDescDay.vue +2 -2
  18. package/lib/components/SDescFile.vue +2 -4
  19. package/lib/components/SDescItem.vue +2 -1
  20. package/lib/components/SDescLabel.vue +1 -1
  21. package/lib/components/SDescLink.vue +2 -7
  22. package/lib/components/SDescPill.vue +2 -4
  23. package/lib/components/SDescText.vue +2 -2
  24. package/lib/components/SDropdown.vue +1 -1
  25. package/lib/components/SDropdownSectionFilter.vue +11 -11
  26. package/lib/components/SFragment.vue +1 -1
  27. package/lib/components/SInputAddon.vue +13 -11
  28. package/lib/components/SInputBase.vue +11 -11
  29. package/lib/components/SInputCheckbox.vue +6 -3
  30. package/lib/components/SInputCheckboxes.vue +7 -3
  31. package/lib/components/SInputDate.vue +3 -5
  32. package/lib/components/SInputDropdown.vue +26 -28
  33. package/lib/components/SInputDropdownItem.vue +21 -11
  34. package/lib/components/SInputFile.vue +9 -6
  35. package/lib/components/SInputFileUpload.vue +9 -11
  36. package/lib/components/SInputFileUploadItem.vue +8 -4
  37. package/lib/components/SInputHMS.vue +3 -1
  38. package/lib/components/SInputImage.vue +4 -2
  39. package/lib/components/SInputNumber.vue +9 -10
  40. package/lib/components/SInputRadio.vue +3 -2
  41. package/lib/components/SInputRadios.vue +6 -5
  42. package/lib/components/SInputSegments.vue +5 -7
  43. package/lib/components/SInputSegmentsOption.vue +1 -2
  44. package/lib/components/SInputSelect.vue +6 -4
  45. package/lib/components/SInputSwitch.vue +4 -1
  46. package/lib/components/SInputSwitches.vue +5 -3
  47. package/lib/components/SInputText.vue +16 -16
  48. package/lib/components/SInputTextarea.vue +7 -3
  49. package/lib/components/SInputYMD.vue +3 -1
  50. package/lib/components/SLink.vue +2 -2
  51. package/lib/components/SLocalNav.vue +1 -1
  52. package/lib/components/SLocalNavActions.vue +1 -1
  53. package/lib/components/SLocalNavMenu.vue +2 -2
  54. package/lib/components/SLoginPagePasswordDialog.vue +2 -2
  55. package/lib/components/SM.vue +1 -1
  56. package/lib/components/SMFade.vue +1 -1
  57. package/lib/components/SMarkdown.vue +3 -2
  58. package/lib/components/SModal.vue +2 -2
  59. package/lib/components/SSnackbar.vue +2 -2
  60. package/lib/components/SSteps.vue +6 -6
  61. package/lib/components/STable.vue +70 -27
  62. package/lib/components/STableCell.vue +14 -17
  63. package/lib/components/STableCellAvatars.vue +1 -1
  64. package/lib/components/STableCellDay.vue +12 -5
  65. package/lib/components/STableCellNumber.vue +2 -3
  66. package/lib/components/STableCellPath.vue +2 -2
  67. package/lib/components/STableCellText.vue +2 -3
  68. package/lib/components/STableColumn.vue +38 -16
  69. package/lib/components/STableFooter.vue +10 -2
  70. package/lib/components/STableHeader.vue +0 -1
  71. package/lib/components/STableHeaderMenu.vue +4 -4
  72. package/lib/components/STableHeaderMenuItem.vue +1 -1
  73. package/lib/components/STooltip.vue +3 -3
  74. package/lib/composables/Dropdown.ts +10 -1
  75. package/lib/composables/Error.ts +37 -37
  76. package/lib/composables/Grid.ts +1 -4
  77. package/lib/composables/Image.ts +2 -3
  78. package/lib/composables/Lang.ts +1 -1
  79. package/lib/composables/Markdown.ts +1 -1
  80. package/lib/composables/Table.ts +0 -2
  81. package/lib/composables/Theme.ts +1 -1
  82. package/lib/composables/Utils.ts +11 -4
  83. package/lib/composables/Validation.ts +1 -4
  84. package/lib/http/Http.ts +23 -17
  85. package/lib/styles/variables-deprecated.css +0 -1
  86. package/lib/styles/variables.css +16 -16
  87. package/lib/support/Chart.ts +0 -1
  88. package/lib/support/DateRange.ts +1 -1
  89. package/lib/support/Day.ts +12 -65
  90. package/lib/support/File.ts +7 -16
  91. package/lib/support/Utils.ts +7 -40
  92. package/lib/validation/Rule.ts +6 -21
  93. package/lib/validation/rules/decimal.ts +3 -3
  94. package/lib/validation/rules/email.ts +1 -1
  95. package/lib/validation/rules/index.ts +1 -1
  96. package/lib/validation/rules/negativeInteger.ts +1 -1
  97. package/lib/validation/rules/positiveInteger.ts +1 -1
  98. package/lib/validation/rules/requiredHms.ts +2 -2
  99. package/lib/validation/rules/requiredIf.ts +1 -4
  100. package/lib/validation/rules/requiredYmd.ts +2 -2
  101. package/lib/validation/rules/slackChannelName.ts +4 -1
  102. package/lib/validation/rules/zeroOrNegativeInteger.ts +1 -1
  103. package/lib/validation/rules/zeroOrPositiveInteger.ts +1 -1
  104. package/lib/validation/validators/after.ts +1 -5
  105. package/lib/validation/validators/afterOrEqual.ts +1 -5
  106. package/lib/validation/validators/before.ts +1 -4
  107. package/lib/validation/validators/beforeOrEqual.ts +1 -5
  108. package/lib/validation/validators/decimal.ts +7 -9
  109. package/lib/validation/validators/email.ts +4 -8
  110. package/lib/validation/validators/fileExtension.ts +7 -15
  111. package/lib/validation/validators/hms.ts +26 -15
  112. package/lib/validation/validators/index.ts +0 -2
  113. package/lib/validation/validators/maxFileSize.ts +3 -13
  114. package/lib/validation/validators/maxLength.ts +1 -7
  115. package/lib/validation/validators/maxTotalFileSize.ts +3 -26
  116. package/lib/validation/validators/maxValue.ts +2 -6
  117. package/lib/validation/validators/minLength.ts +1 -7
  118. package/lib/validation/validators/minValue.ts +2 -6
  119. package/lib/validation/validators/month.ts +1 -7
  120. package/lib/validation/validators/negativeInteger.ts +1 -7
  121. package/lib/validation/validators/positiveInteger.ts +1 -7
  122. package/lib/validation/validators/required.ts +5 -28
  123. package/lib/validation/validators/requiredHmsIf.ts +11 -13
  124. package/lib/validation/validators/requiredIf.ts +5 -11
  125. package/lib/validation/validators/requiredYmdIf.ts +11 -13
  126. package/lib/validation/validators/slackChannelName.ts +11 -11
  127. package/lib/validation/validators/url.ts +7 -5
  128. package/lib/validation/validators/ymd.ts +36 -30
  129. package/package.json +38 -38
  130. package/lib/validation/validators/requiredHms.ts +0 -9
  131. package/lib/validation/validators/requiredYmd.ts +0 -9
@@ -21,13 +21,10 @@ const props = defineProps<{
21
21
  cell?: any
22
22
  value: any
23
23
  record: any
24
- records: Record<string, any>
25
24
  }>()
26
25
 
27
26
  const computedCell = computed<TableCell | undefined>(() =>
28
- typeof props.cell === 'function'
29
- ? props.cell(props.value, props.record)
30
- : props.cell
27
+ typeof props.cell === 'function' ? props.cell(props.value, props.record) : props.cell
31
28
  )
32
29
  </script>
33
30
 
@@ -39,7 +36,7 @@ const computedCell = computed<TableCell | undefined>(() =>
39
36
  :record
40
37
  :align="computedCell?.align"
41
38
  :icon="computedCell?.icon"
42
- :text="computedCell?.value"
39
+ :text="computedCell?.value ?? value"
43
40
  :link="computedCell?.link"
44
41
  :color="computedCell?.color"
45
42
  :icon-color="computedCell?.iconColor"
@@ -51,7 +48,7 @@ const computedCell = computed<TableCell | undefined>(() =>
51
48
  :record
52
49
  :align="computedCell.align"
53
50
  :icon="computedCell.icon"
54
- :number="computedCell.value"
51
+ :number="computedCell.value ?? value"
55
52
  :separator="computedCell.separator"
56
53
  :link="computedCell.link"
57
54
  :color="computedCell.color"
@@ -60,47 +57,47 @@ const computedCell = computed<TableCell | undefined>(() =>
60
57
  />
61
58
  <STableCellPath
62
59
  v-else-if="computedCell.type === 'path'"
63
- :segments="computedCell.segments"
60
+ :segments="computedCell.segments ?? value"
64
61
  />
65
62
  <STableCellDay
66
63
  v-else-if="computedCell.type === 'day'"
67
64
  :align="computedCell.align"
68
- :day="computedCell.value"
65
+ :day="computedCell.value ?? value"
69
66
  :format="computedCell.format"
70
67
  :color="computedCell.color"
71
68
  />
72
69
  <STableCellPill
73
70
  v-else-if="computedCell.type === 'pill'"
74
- :pill="computedCell.value"
71
+ :pill="computedCell.value ?? value"
75
72
  :color="computedCell.color"
76
73
  />
77
74
  <STableCellPills
78
75
  v-else-if="computedCell.type === 'pills'"
79
- :pills="computedCell.pills"
76
+ :pills="computedCell.pills ?? value"
80
77
  />
81
78
  <STableCellState
82
79
  v-else-if="computedCell.type === 'state'"
83
- :state="computedCell.label"
80
+ :state="computedCell.label ?? value"
84
81
  :mode="computedCell.mode"
85
82
  />
86
83
  <STableCellIndicator
87
84
  v-else-if="computedCell.type === 'indicator'"
88
- :state="computedCell.state"
85
+ :state="computedCell.state ?? value"
89
86
  :label="computedCell.label"
90
87
  />
91
88
  <STableCellAvatar
92
89
  v-else-if="computedCell.type === 'avatar'"
93
90
  :value
94
91
  :record
95
- :image="computedCell.image"
96
- :name="computedCell.name"
92
+ :image="computedCell.image ?? (value as string).includes('/') ? value : null"
93
+ :name="computedCell.name ?? (value as string).includes('/') ? null : value"
97
94
  :link="computedCell.link"
98
95
  :color="computedCell.color"
99
96
  :on-click="computedCell.onClick"
100
97
  />
101
98
  <STableCellAvatars
102
99
  v-else-if="computedCell.type === 'avatars'"
103
- :avatars="computedCell.avatars"
100
+ :avatars="computedCell.avatars ?? value"
104
101
  :color="computedCell.color"
105
102
  :avatar-count="computedCell.avatarCount"
106
103
  :name-count="computedCell.nameCount"
@@ -109,7 +106,7 @@ const computedCell = computed<TableCell | undefined>(() =>
109
106
  <STableCellActions
110
107
  v-else-if="computedCell.type === 'actions'"
111
108
  :record
112
- :actions="computedCell.actions"
109
+ :actions="computedCell.actions ?? value"
113
110
  />
114
111
  <STableCellCustom
115
112
  v-else-if="computedCell.type === 'custom'"
@@ -120,8 +117,8 @@ const computedCell = computed<TableCell | undefined>(() =>
120
117
  v-else-if="computedCell.type === 'empty'"
121
118
  />
122
119
  <component
123
- v-else-if="computedCell.type === 'component'"
124
120
  :is="computedCell.component"
121
+ v-else-if="computedCell.type === 'component'"
125
122
  :value
126
123
  :record
127
124
  v-bind="computedCell.props"
@@ -48,7 +48,7 @@ const displayNames = computed(() => {
48
48
  <div class="STableCellAvatars" :class="[color]">
49
49
  <div class="container">
50
50
  <div v-if="displayAvatars.length" class="avatars">
51
- <div v-for="(avatar, index) in displayAvatars" :key="index" class="avatar">
51
+ <div v-for="(avatar, i) in displayAvatars" :key="i" class="avatar">
52
52
  <div class="avatar-box">
53
53
  <SAvatar size="mini" :avatar="avatar.image" :name="avatar.name" :tooltip />
54
54
  </div>
@@ -1,19 +1,26 @@
1
1
  <script setup lang="ts">
2
- import { type Day } from '../support/Day'
2
+ import { computed } from 'vue'
3
+ import { type Day, day } from '../support/Day'
3
4
 
4
- defineProps<{
5
+ const props = defineProps<{
5
6
  day?: Day | null
6
7
  align?: 'left' | 'center' | 'right'
7
8
  format?: string
8
9
  color?: 'neutral' | 'soft' | 'mute'
9
10
  }>()
11
+
12
+ const formatted = computed(() => {
13
+ if (props.day) {
14
+ return day(props.day).format(props.format ?? 'YYYY-MM-DD HH:mm:ss')
15
+ }
16
+
17
+ return null
18
+ })
10
19
  </script>
11
20
 
12
21
  <template>
13
22
  <div class="STableCellDay" :class="[align ?? 'left', color ?? 'neutral']">
14
- <div v-if="day" class="value">
15
- {{ day.format(format ?? 'YYYY-MM-DD HH:mm:ss') }}
16
- </div>
23
+ <div v-if="formatted" class="value">{{ formatted }}</div>
17
24
  </div>
18
25
  </template>
19
26
 
@@ -17,7 +17,6 @@ const props = defineProps<{
17
17
  onClick?(value: any, record: any): void
18
18
  }>()
19
19
 
20
- const _value = computed(() => props.number ?? props.value)
21
20
  const _color = computed(() => props.color ?? 'neutral')
22
21
  const _iconColor = computed(() => props.iconColor ?? _color.value)
23
22
 
@@ -31,7 +30,7 @@ const classes = computed(() => [
31
30
  <template>
32
31
  <div class="STableCellNumber" :class="classes">
33
32
  <SLink
34
- v-if="_value != null"
33
+ v-if="number != null"
35
34
  class="container"
36
35
  :href="link"
37
36
  :role="onClick ? 'button' : null"
@@ -41,7 +40,7 @@ const classes = computed(() => [
41
40
  <component :is="icon" class="svg" />
42
41
  </div>
43
42
  <div class="value" :class="_color">
44
- {{ separator ? format(_value) : _value }}
43
+ {{ separator ? format(number) : number }}
45
44
  </div>
46
45
  </SLink>
47
46
  </div>
@@ -16,8 +16,8 @@ function classes(item: TableCellPathSegment) {
16
16
 
17
17
  <template>
18
18
  <div class="STableCellPath">
19
- <template v-for="segment, index in segments" :key="index">
20
- <div v-if="index > 0" class="divider">/</div>
19
+ <template v-for="(segment, i) in segments" :key="i">
20
+ <div v-if="i > 0" class="divider">/</div>
21
21
  <SLink
22
22
  class="text"
23
23
  :class="classes(segment)"
@@ -15,7 +15,6 @@ const props = defineProps<{
15
15
  onClick?(value: any, record: any): void
16
16
  }>()
17
17
 
18
- const _value = computed(() => props.text ?? props.value)
19
18
  const _color = computed(() => props.color ?? 'neutral')
20
19
  const _iconColor = computed(() => props.iconColor ?? _color.value)
21
20
 
@@ -29,7 +28,7 @@ const classes = computed(() => [
29
28
  <template>
30
29
  <div class="STableCellText" :class="classes">
31
30
  <SLink
32
- v-if="_value != null"
31
+ v-if="text != null"
33
32
  class="container"
34
33
  :href="link"
35
34
  :role="onClick ? 'button' : null"
@@ -39,7 +38,7 @@ const classes = computed(() => [
39
38
  <component :is="icon" class="svg" />
40
39
  </div>
41
40
  <div class="text" :class="_color">
42
- {{ _value }}
41
+ {{ text }}
43
42
  </div>
44
43
  </SLink>
45
44
  </div>
@@ -17,13 +17,16 @@ const props = withDefaults(defineProps<{
17
17
  })
18
18
 
19
19
  const emit = defineEmits<{
20
- resize: [value: string]
20
+ 'resize-start': [data: { columnName: string; startX: number; initialX: number }]
21
+ 'resize-move': [data: { deltaX: number }]
22
+ 'resize-end': [data: { columnName: string; finalWidth: string }]
21
23
  }>()
22
24
 
23
25
  const { container, isOpen, toggle } = useFlyout()
24
26
 
25
27
  let startWidth = 0
26
28
  let startPoint = 0
29
+ let originalUserSelect = ''; let originalPointerEvents = ''
27
30
 
28
31
  const column = ref<HTMLElement | null>(null)
29
32
  const dialog = ref<HTMLElement | null>(null)
@@ -67,24 +70,43 @@ watch(isOpen, (value) => {
67
70
  value ? adjustDialogPosition() : stopDialogPositionListener()
68
71
  })
69
72
 
70
- function grip(e: any) {
73
+ function grip(e: MouseEvent) {
71
74
  startWidth = column.value?.offsetWidth ?? 0
72
75
  startPoint = e.pageX
73
76
 
77
+ emit('resize-start', {
78
+ columnName: props.name,
79
+ startX: e.pageX,
80
+ initialX: e.pageX
81
+ })
82
+
83
+ originalUserSelect = document.body.style.userSelect
84
+ originalPointerEvents = document.body.style.pointerEvents
85
+ document.body.style.userSelect = 'none'
86
+ document.body.style.pointerEvents = 'none'
74
87
  document.addEventListener('mousemove', resize)
75
88
  document.addEventListener('mouseup', stopResizeListener)
76
89
  }
77
90
 
78
91
  function resize(e: MouseEvent) {
79
- const movedWidth = e.pageX - startPoint
80
- const resized = startWidth + movedWidth
81
-
82
- emit('resize', resized > -1 ? `${resized}px` : 'var(--table-col-width)')
92
+ const deltaX = e.pageX - startPoint
93
+ emit('resize-move', { deltaX })
83
94
  }
84
95
 
85
- function stopResizeListener() {
96
+ function stopResizeListener(e: MouseEvent) {
86
97
  document.removeEventListener('mousemove', resize)
87
98
  document.removeEventListener('mouseup', stopResizeListener)
99
+ document.body.style.userSelect = originalUserSelect
100
+ document.body.style.pointerEvents = originalPointerEvents
101
+
102
+ const movedWidth = e.pageX - startPoint
103
+ const resized = startWidth + movedWidth
104
+ const finalWidth = resized > -1 ? `${resized}px` : 'var(--table-col-width)'
105
+
106
+ emit('resize-end', {
107
+ columnName: props.name,
108
+ finalWidth
109
+ })
88
110
  }
89
111
 
90
112
  async function adjustDialogPosition() {
@@ -99,14 +121,13 @@ async function adjustDialogPosition() {
99
121
  await nextTick()
100
122
 
101
123
  const dialogWidth = dialog.value?.offsetWidth ?? 0
102
- const position = (window.innerWidth - rect.right) > dialogWidth ? 'right' : 'left'
124
+ const position = window.innerWidth - rect.right > dialogWidth ? 'right' : 'left'
103
125
 
104
126
  top.value = `${rect.top + rect.height - 8}px`
105
- left.value
106
- = `${Math.max(
107
- 16,
108
- position === 'right' ? rect.left - 4 : rect.right - dialogWidth - 4
109
- )}px`
127
+ left.value = `${Math.max(
128
+ 16,
129
+ position === 'right' ? rect.left - 4 : rect.right - dialogWidth - 4
130
+ )}px`
110
131
  }
111
132
 
112
133
  function startDialogPositionListener() {
@@ -121,24 +142,25 @@ function stopDialogPositionListener() {
121
142
  </script>
122
143
 
123
144
  <template>
124
- <div class="STableColumn STableCell" :class="classes" ref="column">
145
+ <div ref="column" class="STableColumn STableCell" :class="classes">
125
146
  <div class="container">
126
147
  <slot>
127
148
  <p class="label">{{ label }}</p>
128
149
 
129
- <div v-if="dropdown" class="action" ref="container">
150
+ <div v-if="dropdown" ref="container" class="action">
130
151
  <button class="button" :class="{ active: buttonActive }" @click="toggle">
131
152
  <IconDotsThree class="icon" />
132
153
  </button>
133
154
 
134
155
  <transition name="fade">
135
- <div v-if="isOpen" class="dialog" :style="{ top, left }" ref="dialog">
156
+ <div v-if="isOpen" ref="dialog" class="dialog" :style="{ top, left }">
136
157
  <SDropdown :sections="dropdown" />
137
158
  </div>
138
159
  </transition>
139
160
  </div>
140
161
 
141
162
  <div v-if="resizable" class="grip" @mousedown="grip" />
163
+ <div v-if="resizable" class="resize-indicator" />
142
164
  </slot>
143
165
  </div>
144
166
  </div>
@@ -42,10 +42,18 @@ const hasNext = computed(() => {
42
42
  <p class="info">{{ format(from) }}–{{ format(to) }} of {{ format(_total) }}</p>
43
43
 
44
44
  <div v-if="onPrev && onNext" class="actions">
45
- <button class="button prev" :class="{ active: hasPrev }" @click="() => hasPrev && onPrev?.()">
45
+ <button
46
+ class="button prev"
47
+ :class="{ active: hasPrev }"
48
+ @click="() => hasPrev && onPrev?.()"
49
+ >
46
50
  <IconCaretLeft class="icon" />
47
51
  </button>
48
- <button class="button next" :class="{ active: hasNext }" @click="() => hasNext && onNext?.()">
52
+ <button
53
+ class="button next"
54
+ :class="{ active: hasNext }"
55
+ @click="() => hasNext && onNext?.()"
56
+ >
49
57
  <IconCaretRight class="icon" />
50
58
  </button>
51
59
  </div>
@@ -8,7 +8,6 @@ const props = defineProps<{
8
8
  total?: number | null
9
9
  menu?: TableMenu[] | TableMenu[][]
10
10
  borderless?: boolean
11
- onReset?(): void
12
11
  selected?: unknown[]
13
12
  }>()
14
13
 
@@ -9,15 +9,15 @@ const props = defineProps<{
9
9
 
10
10
  const normalizedMenu = computed(() => {
11
11
  return Array.isArray(props.menu[0])
12
- ? props.menu as TableMenu[][]
13
- : [props.menu] as TableMenu[][]
12
+ ? (props.menu as TableMenu[][])
13
+ : ([props.menu] as TableMenu[][])
14
14
  })
15
15
  </script>
16
16
 
17
17
  <template>
18
18
  <div class="STableHeaderMenu">
19
- <div v-for="items, index in normalizedMenu" :key="index" class="group">
20
- <div v-if="index > 0" class="divider" />
19
+ <div v-for="(items, i) in normalizedMenu" :key="i" class="group">
20
+ <div v-if="i > 0" class="divider" />
21
21
  <div v-for="item in items" :key="item.label" class="item">
22
22
  <STableHeaderMenuItem
23
23
  :label="item.label"
@@ -14,7 +14,7 @@ const { container, isOpen, toggle } = useFlyout()
14
14
  </script>
15
15
 
16
16
  <template>
17
- <div class="STableHeaderMenuItem" ref="container">
17
+ <div ref="container" class="STableHeaderMenuItem">
18
18
  <button class="button" :class="[state]" @click="toggle">
19
19
  <span class="label">{{ label }}</span>
20
20
  <span v-if="state !== 'indicate'" class="caret">
@@ -97,14 +97,14 @@ onBeforeUnmount(() => {
97
97
  </script>
98
98
 
99
99
  <template>
100
- <component ref="root" :is="tag" class="STooltip" :class="rootClasses" :tabindex>
101
- <component :is="triggerTag" class="trigger" ref="trigger">
100
+ <component :is="tag" ref="root" class="STooltip" :class="rootClasses" :tabindex>
101
+ <component :is="triggerTag" ref="trigger" class="trigger">
102
102
  <slot />
103
103
  </component>
104
104
 
105
105
  <Teleport to="#sefirot-modals">
106
106
  <Transition name="fade">
107
- <div v-show="on" class="container" :class="containerClasses" ref="content">
107
+ <div v-show="on" ref="content" class="container" :class="containerClasses">
108
108
  <div v-if="$slots.text" class="tip"><slot name="text" /></div>
109
109
  <div v-else-if="text" class="tip" v-html="text" />
110
110
  </div>
@@ -1,5 +1,14 @@
1
1
  import { useElementBounding, useWindowSize } from '@vueuse/core'
2
- import { type Component, type MaybeRef, type MaybeRefOrGetter, type Ref, computed, ref, toValue, unref } from 'vue'
2
+ import {
3
+ type Component,
4
+ type MaybeRef,
5
+ type MaybeRefOrGetter,
6
+ type Ref,
7
+ computed,
8
+ ref,
9
+ toValue,
10
+ unref
11
+ } from 'vue'
3
12
  import { type ActionList } from '../components/SActionList.vue'
4
13
  import { type DateRange } from '../support/DateRange'
5
14
 
@@ -1,20 +1,16 @@
1
1
  /**
2
2
  * Adapted from
3
- * @see https://github.com/vuejs/core/blob/1755ac0a108ba3486bd8397e56d3bdcd69196594/packages/runtime-core/src/component.ts
3
+ * @see https://github.com/vuejs/core/blob/b50eb68c50f3b94dca2e96f706c3e96ab864df24/packages/runtime-core/src/component.ts
4
4
  * @see https://github.com/vuejs/core/blob/ac9e7e8bfa55432a73a10864805fdf48bda2ff73/packages/runtime-core/src/warning.ts
5
- * @see https://github.com/getsentry/sentry-javascript/blob/04711c20246f7cdaac2305286fec783ab1859a18/packages/vue/src/errorhandler.ts
6
- * @see https://github.com/vercel/ai/blob/d544886d4f61440bacd6e44c86144bfac7c98282/packages/provider-utils/src/get-error-message.ts
5
+ * @see https://github.com/getsentry/sentry-javascript/blob/fbadeb81d23c03c3d852531c2deef59a3a992def/packages/vue/src/errorhandler.ts
7
6
  *
8
7
  * Original licenses:
9
8
  *
10
- * (c) 2018-present Yuxi (Evan) You and Vue contributors
9
+ * Copyright (c) 2018-present, Yuxi (Evan) You
11
10
  * @license MIT
12
11
  *
13
- * (c) 2012-2024 Functional Software, Inc. dba Sentry
12
+ * Copyright (c) 2019 Functional Software, Inc. dba Sentry
14
13
  * @license MIT
15
- *
16
- * (c) 2023 Vercel, Inc.
17
- * @license Apache-2.0
18
14
  */
19
15
 
20
16
  import * as Sentry from '@sentry/browser'
@@ -22,8 +18,8 @@ import { createSentryPiniaPlugin } from '@sentry/vue'
22
18
  import { pauseTracking, resetTracking } from '@vue/reactivity'
23
19
  import { getActivePinia } from 'pinia'
24
20
  import {
21
+ type Component,
25
22
  type ComponentInternalInstance,
26
- type ComponentOptions,
27
23
  type ComponentPublicInstance,
28
24
  type ConcreteComponent,
29
25
  type MaybeRefOrGetter,
@@ -31,7 +27,6 @@ import {
31
27
  toValue
32
28
  } from 'vue'
33
29
  import { useError } from '../stores/Error'
34
- import { isError } from '../support/Utils'
35
30
 
36
31
  export interface User {
37
32
  id?: string | number
@@ -43,7 +38,7 @@ type TraceEntry = { vnode: VNode; recurseCount: number }
43
38
 
44
39
  type ComponentTraceStack = TraceEntry[]
45
40
 
46
- const classifyRE = /(?:^|[-_])(\w)/g
41
+ const classifyRE = /(?:^|[-_])\w/g
47
42
  function classify(str: string): string {
48
43
  return str.replace(classifyRE, (c) => c.toUpperCase()).replace(/[-_]/g, '')
49
44
  }
@@ -70,19 +65,20 @@ function formatComponentName(instance: ComponentInternalInstance | null): string
70
65
  }
71
66
  }
72
67
 
73
- if (!name && instance && instance.parent) {
74
- const inferFromRegistry = (registry: Record<string, unknown> | undefined) => {
68
+ if (!name && instance) {
69
+ const inferFromRegistry = (registry?: Record<string, Component>) => {
75
70
  for (const key in registry) {
76
71
  if (registry[key] === Component) {
77
72
  return key
78
73
  }
79
74
  }
80
75
  }
81
- name
82
- = inferFromRegistry(
83
- // @ts-expect-error internal api
84
- instance.components || (instance.parent.type as ComponentOptions).components
85
- ) || inferFromRegistry(instance.appContext.components)
76
+ name =
77
+ // @ts-expect-error internal API
78
+ inferFromRegistry(instance.components)
79
+ // @ts-expect-error internal API
80
+ || inferFromRegistry(instance.parent?.type.components)
81
+ || inferFromRegistry(instance.appContext.components)
86
82
  }
87
83
 
88
84
  return name ? classify(name) : isRoot ? 'App' : 'Anonymous'
@@ -102,8 +98,8 @@ function getComponentTrace(currentVNode: VNode | null): ComponentTraceStack {
102
98
  } else {
103
99
  normalizedStack.push({ vnode: currentVNode, recurseCount: 0 })
104
100
  }
105
- const parentInstance: ComponentInternalInstance | null
106
- = currentVNode.component && currentVNode.component.parent
101
+ const parentInstance: ComponentInternalInstance | null =
102
+ currentVNode.component && currentVNode.component.parent
107
103
  currentVNode = parentInstance && parentInstance.vnode
108
104
  }
109
105
 
@@ -147,6 +143,26 @@ const ignoreErrors = [
147
143
  /\[Cloudflare Turnstile\] Error: (?:10[2-46]|1106[02]|[36]00)/
148
144
  ]
149
145
 
146
+ const stringifiers: readonly ((e: unknown) => string | false)[] = [
147
+ (e) => typeof e === 'string' && e,
148
+ (e) => e instanceof Error && (e.message || e.name),
149
+ (e) => {
150
+ const json = JSON.stringify(e)
151
+ return json !== '{}' && json
152
+ },
153
+ (e) => String(e)
154
+ ]
155
+
156
+ function getErrorMessage(error: unknown | undefined): string {
157
+ for (const stringify of stringifiers) {
158
+ try {
159
+ const s = stringify(error)
160
+ if (s) { return s }
161
+ } catch { /* continue */ }
162
+ }
163
+ return 'unknown error'
164
+ }
165
+
150
166
  export function useErrorHandler({
151
167
  dsn,
152
168
  environment,
@@ -204,7 +220,7 @@ export function useErrorHandler({
204
220
  componentName: formatComponentName($),
205
221
  lifecycleHook: info,
206
222
  trace: formatTrace($),
207
- propsData: $ && $.props
223
+ propsData: $.props
208
224
  }
209
225
 
210
226
  setTimeout(() => {
@@ -224,19 +240,3 @@ export function useErrorHandler({
224
240
  set(e)
225
241
  }
226
242
  }
227
-
228
- function getErrorMessage(error: unknown | undefined) {
229
- if (error == null) {
230
- return 'unknown error'
231
- }
232
-
233
- if (typeof error === 'string') {
234
- return error
235
- }
236
-
237
- if (isError(error)) {
238
- return error.message
239
- }
240
-
241
- return JSON.stringify(error)
242
- }
@@ -45,9 +45,7 @@ export function useGrid(options: UseGridOptions = {}): Grid {
45
45
  })
46
46
 
47
47
  function adjustSpacer() {
48
- container.value?.querySelectorAll(`${toClassSelector(spacerClass)}`)
49
- .forEach((n) => n.remove())
50
-
48
+ container.value?.querySelectorAll(`${toClassSelector(spacerClass)}`).forEach((n) => n.remove())
51
49
  const track = container.value?.firstElementChild
52
50
 
53
51
  const containerWidth = container.value?.clientWidth ?? 0
@@ -59,7 +57,6 @@ export function useGrid(options: UseGridOptions = {}): Grid {
59
57
  const lack = mod !== 0 ? perRow - mod : 0
60
58
 
61
59
  const fragment = createSpacers(lack, spacerTag, spacerClass, type)
62
-
63
60
  container.value?.appendChild(fragment)
64
61
  }
65
62
 
@@ -1,6 +1,5 @@
1
1
  import { isClient } from '@vueuse/core'
2
2
  import { type MaybeRefOrGetter, type Ref, ref, toValue, watchEffect } from 'vue'
3
- import { isFile, isString } from '../support/Utils'
4
3
 
5
4
  export interface ImageSrcFromFile {
6
5
  src: Ref<string | null>
@@ -34,12 +33,12 @@ export function useImageSrcFromFile(
34
33
  function read(): void {
35
34
  const f = toValue(file)
36
35
 
37
- if (isFile(f)) {
36
+ if (f instanceof Blob) {
38
37
  reader.readAsDataURL(f)
39
38
  return
40
39
  }
41
40
 
42
- if (isString(f)) {
41
+ if (typeof f === 'string') {
43
42
  src.value = f
44
43
  return
45
44
  }
@@ -8,7 +8,7 @@ export interface Trans<T> {
8
8
 
9
9
  export interface TransMessages<T> {
10
10
  en: T
11
- ja: T
11
+ ja: NoInfer<T>
12
12
  }
13
13
 
14
14
  export const SefirotLangKey: InjectionKey<Lang> = Symbol.for('sefirot-lang-key')
@@ -1,4 +1,4 @@
1
- import DOMPurify, { type Config } from 'dompurify'
1
+ import DOMPurify, { type Config } from 'isomorphic-dompurify'
2
2
  import MarkdownIt from 'markdown-it'
3
3
 
4
4
  export type UseMarkdown = (source: string, inline?: boolean) => string
@@ -25,11 +25,9 @@ export interface Table<
25
25
  total?: MaybeRef<number | null | undefined>
26
26
  page?: MaybeRef<number | null | undefined>
27
27
  perPage?: MaybeRef<number | null | undefined>
28
- reset?: MaybeRef<boolean | undefined>
29
28
  borderSize?: MaybeRef<number | undefined>
30
29
  onPrev?(): void
31
30
  onNext?(): void
32
- onReset?(): void
33
31
  }
34
32
 
35
33
  export type TableColumns<
@@ -7,7 +7,7 @@ export function useTheme(): WritableComputedRef<Theme> {
7
7
  const _isDark = useDark()
8
8
 
9
9
  return computed({
10
- get: () => _isDark.value ? 'dark' : 'light',
10
+ get: () => (_isDark.value ? 'dark' : 'light'),
11
11
  set: (v) => { _isDark.value = v === 'dark' }
12
12
  })
13
13
  }