@pocketprep/ui-kit 3.8.4 → 3.9.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 (159) hide show
  1. package/dist/@pocketprep/ui-kit.css +1 -1
  2. package/dist/@pocketprep/ui-kit.js +14469 -17731
  3. package/dist/@pocketprep/ui-kit.js.map +1 -1
  4. package/dist/@pocketprep/ui-kit.umd.cjs +19 -29
  5. package/dist/@pocketprep/ui-kit.umd.cjs.map +1 -1
  6. package/eslint.config.ts +38 -11
  7. package/lib/SVGDefinitions.vue +32 -35
  8. package/lib/components/Banners/Banner.vue +10 -14
  9. package/lib/components/Blobs/Blob.vue +6 -14
  10. package/lib/components/Blobs/BlobEmptyState.vue +9 -8
  11. package/lib/components/Blobs/blob.d.ts +1 -1
  12. package/lib/components/BundleIcons/BundleIcon.vue +36 -63
  13. package/lib/components/BundleIcons/bundleIcon.d.ts +1 -1
  14. package/lib/components/Bundles/BundleList.vue +71 -59
  15. package/lib/components/Bundles/BundleSearch.vue +93 -117
  16. package/lib/components/Bundles/PremiumPill.vue +6 -12
  17. package/lib/components/Buttons/Button.vue +32 -35
  18. package/lib/components/Buttons/Link.vue +32 -31
  19. package/lib/components/Buttons/Tab.vue +14 -17
  20. package/lib/components/Calendar/Calendar.vue +87 -85
  21. package/lib/components/Charts/Bar.vue +192 -263
  22. package/lib/components/Charts/Pie.vue +55 -61
  23. package/lib/components/Charts/highcharts-wrap.ts +81 -0
  24. package/lib/components/Controls/SegmentControl.vue +26 -24
  25. package/lib/components/Controls/Slider.vue +51 -47
  26. package/lib/components/Controls/ToggleSwitch.vue +33 -31
  27. package/lib/components/EmptyStates/EmptyState.vue +69 -73
  28. package/lib/components/Exams/ExamCard.vue +59 -47
  29. package/lib/components/Exams/ExamMenuCard.vue +30 -28
  30. package/lib/components/Filters/FilterDropdown.vue +83 -86
  31. package/lib/components/Filters/FilterOptions.vue +83 -88
  32. package/lib/components/Forms/Checkbox.vue +27 -27
  33. package/lib/components/Forms/CheckboxOption.vue +30 -30
  34. package/lib/components/Forms/Errors.vue +21 -24
  35. package/lib/components/Forms/Input.vue +71 -59
  36. package/lib/components/Forms/Radio.vue +2 -2
  37. package/lib/components/Forms/RadioButton.vue +8 -8
  38. package/lib/components/Forms/Select.vue +265 -257
  39. package/lib/components/Forms/Textarea.vue +49 -35
  40. package/lib/components/Icons/IconAccordionArrow.vue +7 -9
  41. package/lib/components/Icons/IconActivity.vue +7 -9
  42. package/lib/components/Icons/IconAdd.vue +7 -11
  43. package/lib/components/Icons/IconAddCircle.vue +7 -9
  44. package/lib/components/Icons/IconArrow.vue +7 -9
  45. package/lib/components/Icons/IconBarChart.vue +7 -9
  46. package/lib/components/Icons/IconCalendar.vue +7 -9
  47. package/lib/components/Icons/IconCalendarPicker.vue +7 -9
  48. package/lib/components/Icons/IconChat.vue +7 -9
  49. package/lib/components/Icons/IconCheck.vue +7 -9
  50. package/lib/components/Icons/IconClose.vue +7 -9
  51. package/lib/components/Icons/IconConcept.vue +1 -1
  52. package/lib/components/Icons/IconCorrect.vue +7 -9
  53. package/lib/components/Icons/IconEdit.vue +7 -11
  54. package/lib/components/Icons/IconExam.vue +7 -9
  55. package/lib/components/Icons/IconExternalLink.vue +7 -9
  56. package/lib/components/Icons/IconEyeHide.vue +7 -9
  57. package/lib/components/Icons/IconEyeShow.vue +7 -9
  58. package/lib/components/Icons/IconFilter.vue +7 -9
  59. package/lib/components/Icons/IconFilterActive.vue +7 -9
  60. package/lib/components/Icons/IconFlag.vue +7 -9
  61. package/lib/components/Icons/IconFlagContent.vue +8 -9
  62. package/lib/components/Icons/IconFlagFeedback.vue +8 -10
  63. package/lib/components/Icons/IconFlagFilled.vue +7 -9
  64. package/lib/components/Icons/IconFullView.vue +7 -9
  65. package/lib/components/Icons/IconFullViewActive.vue +7 -9
  66. package/lib/components/Icons/IconGridDrag.vue +2 -2
  67. package/lib/components/Icons/IconHandle.vue +7 -9
  68. package/lib/components/Icons/IconHeart.vue +7 -9
  69. package/lib/components/Icons/IconHelp.vue +7 -9
  70. package/lib/components/Icons/IconHighlight.vue +2 -2
  71. package/lib/components/Icons/IconHourglass.vue +7 -9
  72. package/lib/components/Icons/IconImage.vue +7 -9
  73. package/lib/components/Icons/IconIncorrect.vue +7 -9
  74. package/lib/components/Icons/IconInfo.vue +7 -9
  75. package/lib/components/Icons/IconKeyboard.vue +7 -9
  76. package/lib/components/Icons/IconLaunch.vue +7 -9
  77. package/lib/components/Icons/IconLevelUp.vue +7 -9
  78. package/lib/components/Icons/IconLightbulb.vue +7 -9
  79. package/lib/components/Icons/IconLightning.vue +7 -9
  80. package/lib/components/Icons/IconLink.vue +7 -9
  81. package/lib/components/Icons/IconList.vue +7 -9
  82. package/lib/components/Icons/IconLoading.vue +7 -9
  83. package/lib/components/Icons/IconLoading2.vue +11 -11
  84. package/lib/components/Icons/IconLock.vue +7 -9
  85. package/lib/components/Icons/IconMissedQuestions.vue +7 -9
  86. package/lib/components/Icons/IconMoon.vue +7 -9
  87. package/lib/components/Icons/IconPaginationArrow.vue +7 -9
  88. package/lib/components/Icons/IconPaginationArrowDouble.vue +7 -9
  89. package/lib/components/Icons/IconPassage.vue +7 -9
  90. package/lib/components/Icons/IconPencil.vue +7 -9
  91. package/lib/components/Icons/IconPeople.vue +7 -9
  92. package/lib/components/Icons/IconPercent.vue +7 -9
  93. package/lib/components/Icons/IconPerson.vue +8 -9
  94. package/lib/components/Icons/IconPresent.vue +7 -9
  95. package/lib/components/Icons/IconPreview.vue +7 -9
  96. package/lib/components/Icons/IconQuestions.vue +7 -9
  97. package/lib/components/Icons/IconQuick10.vue +7 -9
  98. package/lib/components/Icons/IconQuickActions.vue +2 -2
  99. package/lib/components/Icons/IconRecommendedFilter.vue +1 -1
  100. package/lib/components/Icons/IconRemoveCircle.vue +7 -9
  101. package/lib/components/Icons/IconReviewFlag.vue +7 -9
  102. package/lib/components/Icons/IconSearch.vue +7 -9
  103. package/lib/components/Icons/IconShare.vue +7 -9
  104. package/lib/components/Icons/IconSideBar.vue +7 -9
  105. package/lib/components/Icons/IconSideBarActive.vue +7 -9
  106. package/lib/components/Icons/IconStar.vue +1 -1
  107. package/lib/components/Icons/IconStopwatch.vue +7 -9
  108. package/lib/components/Icons/IconStrike.vue +7 -9
  109. package/lib/components/Icons/IconSubject.vue +7 -9
  110. package/lib/components/Icons/IconText.vue +7 -9
  111. package/lib/components/Icons/IconTimer.vue +8 -9
  112. package/lib/components/Icons/IconWarning.vue +7 -9
  113. package/lib/components/Icons/icon.d.ts +1 -1
  114. package/lib/components/Loaders/SkeletonLoader.vue +1 -5
  115. package/lib/components/Modal/Modal.vue +23 -29
  116. package/lib/components/Modal/ModalContainer.vue +135 -133
  117. package/lib/components/Onboarding/EmailAuth.vue +66 -70
  118. package/lib/components/Onboarding/MagicCodeEntry.vue +88 -83
  119. package/lib/components/Pagination/QuestionReviewPagination.vue +3 -3
  120. package/lib/components/Pagination/TablePagination.vue +47 -44
  121. package/lib/components/PhonePerson/PhonePerson.vue +18 -18
  122. package/lib/components/PhonePerson/phonePerson.d.ts +1 -1
  123. package/lib/components/Quiz/FlagToggle.vue +45 -44
  124. package/lib/components/Quiz/GlobalMetricsToggle.vue +29 -28
  125. package/lib/components/Quiz/KeyboardShortcutsButton.vue +16 -23
  126. package/lib/components/Quiz/KeyboardShortcutsModal.vue +36 -37
  127. package/lib/components/Quiz/Question/BuildListChoicesContainer.vue +65 -65
  128. package/lib/components/Quiz/Question/ChoicesContainer.vue +5 -5
  129. package/lib/components/Quiz/Question/DropdownExplanation.vue +5 -5
  130. package/lib/components/Quiz/Question/Explanation.vue +6 -6
  131. package/lib/components/Quiz/Question/MPMCChoicesContainer.vue +17 -17
  132. package/lib/components/Quiz/Question/MPMCRadioGroup.vue +2 -2
  133. package/lib/components/Quiz/Question/MatrixChoicesContainer.vue +39 -39
  134. package/lib/components/Quiz/Question/MatrixRadioGroup.vue +6 -6
  135. package/lib/components/Quiz/Question/MobileMatrixChoicesContainer.vue +27 -28
  136. package/lib/components/Quiz/Question/MobileMatrixRadioGroup.vue +2 -2
  137. package/lib/components/Quiz/Question/PassageAndImage.vue +3 -3
  138. package/lib/components/Quiz/Question/PassageAndImageDropdown.vue +7 -7
  139. package/lib/components/Quiz/Question/Paywall.vue +2 -2
  140. package/lib/components/Quiz/Question/QuestionContext.vue +1 -1
  141. package/lib/components/Quiz/Question/StatsSummary.vue +2 -2
  142. package/lib/components/Quiz/Question/Summary.vue +11 -11
  143. package/lib/components/Quiz/Question.vue +90 -82
  144. package/lib/components/Quiz/QuizContainer.vue +1 -1
  145. package/lib/components/Quiz/QuizProgressBar.vue +23 -23
  146. package/lib/components/Quiz/question.d.ts +3 -3
  147. package/lib/components/Search/Pill.vue +16 -19
  148. package/lib/components/Search/Search.vue +52 -47
  149. package/lib/components/SidePanels/SidePanel.vue +168 -174
  150. package/lib/components/Tables/Table.vue +135 -122
  151. package/lib/components/Tables/TableActions.vue +81 -76
  152. package/lib/components/Tables/table.d.ts +1 -1
  153. package/lib/components/Tags/Tag.vue +49 -39
  154. package/lib/components/Toasts/Toast.vue +44 -42
  155. package/lib/components/Tooltips/OverflowTooltip.vue +39 -45
  156. package/lib/components/Tooltips/Tooltip.vue +69 -70
  157. package/lib/directives.ts +4 -4
  158. package/lib/utils.ts +13 -12
  159. package/package.json +27 -28
@@ -45,7 +45,7 @@
45
45
  <th
46
46
  :key="`column-label--${column.propName}`"
47
47
  class="uikit-table__column-label"
48
- :style="{
48
+ :style="{
49
49
  ...tableColumnLabelStyles,
50
50
  ...column.styles,
51
51
  ...column.labelStyles,
@@ -53,12 +53,12 @@
53
53
  scope="col"
54
54
  role="columnheader"
55
55
  :aria-sort="
56
- (!currentSort.column
57
- || currentSort.column.propName !== column.propName
56
+ (!currentSort.column
57
+ || currentSort.column.propName !== column.propName
58
58
  || currentSort.direction === 0)
59
59
  ? 'none'
60
- : currentSort.direction === -1
61
- ? 'ascending'
60
+ : currentSort.direction === -1
61
+ ? 'ascending'
62
62
  : 'descending'"
63
63
  >
64
64
  <slot name="tableColumnLabelContent" :column="column">
@@ -71,11 +71,11 @@
71
71
  }"
72
72
  :role="column.isSortDisabled ? 'presentation' : 'button'"
73
73
  :aria-label="
74
- (!currentSort.column
75
- || currentSort.column.propName !== column.propName
74
+ (!currentSort.column
75
+ || currentSort.column.propName !== column.propName
76
76
  || currentSort.direction === 0)
77
77
  ? `${column.name || column.propName} (sortable)`
78
- : currentSort.direction === -1
78
+ : currentSort.direction === -1
79
79
  ? `${column.name || column.propName} (sorted ascending)`
80
80
  : `${column.name || column.propName} (sorted descending)`"
81
81
  :tabindex="column.isSortDisabled ? -1 : 0"
@@ -94,9 +94,9 @@
94
94
  v-dark="isDarkMode"
95
95
  class="uikit-table__sort-icon"
96
96
  :class="{
97
- 'uikit-table__sort-icon--visible':
97
+ 'uikit-table__sort-icon--visible':
98
98
  currentSort.column
99
- && currentSort.column.propName
99
+ && currentSort.column.propName
100
100
  === column.propName
101
101
  && currentSort.direction !== 0,
102
102
  'uikit-table__sort-icon--up': currentSort
@@ -131,7 +131,7 @@
131
131
  role="row"
132
132
  :tabIndex="row.tabIndex === 0 ? 0 : -1"
133
133
  :class="{
134
- 'uikit-table__row--hover-focus': row.tabIndex === 0
134
+ 'uikit-table__row--hover-focus': row.tabIndex === 0
135
135
  }"
136
136
  :style="{
137
137
  ...gridStyles,
@@ -175,13 +175,13 @@
175
175
  </tr>
176
176
  <template v-for="subrow in row.subrows">
177
177
  <slot name="tableSubrow" :subrow="subrow">
178
- <tr
178
+ <tr
179
179
  :key="`subrow--${subrow.id}`"
180
180
  v-dark="isDarkMode"
181
181
  role="subrow"
182
182
  :tabIndex="row.tabIndex === 0 ? 0 : -1"
183
183
  :class="{
184
- 'uikit-table__subrow--hover-focus': row.tabIndex === 0
184
+ 'uikit-table__subrow--hover-focus': row.tabIndex === 0
185
185
  }"
186
186
  class="uikit-table__subrow"
187
187
  :style="{
@@ -237,144 +237,157 @@
237
237
  </div>
238
238
  </template>
239
239
 
240
- <script lang="ts">
241
- import { Component, Emit, Prop, Vue, Watch } from 'vue-facing-decorator'
240
+ <script setup lang="ts">
242
241
  import Icon from '../Icons/Icon.vue'
243
242
  import OverflowTooltip from '../Tooltips/OverflowTooltip.vue'
244
- import { dark } from '../../directives'
243
+ import { dark as vDark } from '../../directives'
245
244
  import type { ITableColumn, TTableRow, TSortDirection, ITableSortSettings } from './table'
246
-
247
- @Component({
248
- directives: {
249
- dark,
250
- },
251
- components: {
252
- Icon,
253
- OverflowTooltip,
254
- },
255
- })
256
- export default class Table extends Vue {
257
- @Prop() columns!: ITableColumn[]
258
- @Prop() rows!: TTableRow[]
259
- @Prop({ default: true }) showHeader!: boolean
260
- @Prop({ default: 'Results' }) name!: string // Used in the header by default
261
- @Prop() count?: string
262
- @Prop() grid?: Record<string, string>
263
- @Prop({ default: () => [ 1, -1, 0 ] }) sortToggleOrder!: TSortDirection[]
264
- @Prop() defaultSort?: ITableSortSettings
265
- @Prop({ default: false }) isDarkMode!: boolean
266
-
267
- /******* Element-specific style props *******/
245
+ import { ref, watch } from 'vue'
246
+
247
+ const {
248
+ columns,
249
+ rows,
250
+ showHeader = true,
251
+ name = 'Results',
252
+ count = undefined,
253
+ grid = undefined,
254
+ sortToggleOrder = [ 1, -1 ],
255
+ defaultSort = undefined,
256
+ isDarkMode = false,
257
+ tableContainerStyles = undefined,
258
+ tableStyles = undefined,
259
+ tableHeaderStyles = undefined,
260
+ tableNameStyles = undefined,
261
+ tableCountStyles = undefined,
262
+ tableContentStyles = undefined,
263
+ tableColumnLabelsStyles = undefined,
264
+ tableColumnLabelStyles = undefined,
265
+ tableSortIconStyles = undefined,
266
+ tableRowsStyles = undefined,
267
+ tableRowStyles = undefined,
268
+ tableCellStyles = undefined,
269
+ tableSubrowsStyles = undefined,
270
+ } = defineProps<{
271
+ columns: ITableColumn[]
272
+ rows: TTableRow[]
273
+ showHeader?: boolean
274
+ name?: string
275
+ count?: string | number
276
+ grid?: Record<string, string>
277
+ sortToggleOrder?: TSortDirection[]
278
+ defaultSort?: ITableSortSettings
279
+ isDarkMode?: boolean
280
+ /** ***** Element-specific style props ***** **/
268
281
  // .table__container
269
- @Prop() tableContainerStyles!: Record<string, string>
282
+ tableContainerStyles?: Record<string, string>
270
283
  // .table
271
- @Prop() tableStyles!: Record<string, string>
284
+ tableStyles?: Record<string, string>
272
285
  // .table__header
273
- @Prop() tableHeaderStyles!: Record<string, string>
286
+ tableHeaderStyles?: Record<string, string>
274
287
  // .table__name
275
- @Prop() tableNameStyles!: Record<string, string>
288
+ tableNameStyles?: Record<string, string>
276
289
  // .table__count
277
- @Prop() tableCountStyles!: Record<string, string>
290
+ tableCountStyles?: Record<string, string>
278
291
  // .table__content
279
- @Prop() tableContentStyles!: Record<string, string>
292
+ tableContentStyles?: Record<string, string>
280
293
  // .table__column-labels
281
- @Prop() tableColumnLabelsStyles!: Record<string, string>
294
+ tableColumnLabelsStyles?: Record<string, string>
282
295
  // .table__column-label
283
- @Prop() tableColumnLabelStyles!: Record<string, string>
296
+ tableColumnLabelStyles?: Record<string, string>
284
297
  // .table__sort-icon
285
- @Prop() tableSortIconStyles!: Record<string, string>
298
+ tableSortIconStyles?: Record<string, string>
286
299
  // .table__rows
287
- @Prop() tableRowsStyles!: Record<string, string>
300
+ tableRowsStyles?: Record<string, string>
288
301
  // .table__row
289
- @Prop() tableRowStyles!: Record<string, string>
302
+ tableRowStyles?: Record<string, string>
290
303
  // .table__cell
291
- @Prop() tableCellStyles!: Record<string, string>
304
+ tableCellStyles?: Record<string, string>
292
305
  // .table__subrow
293
- @Prop() tableSubrowsStyles!: Record<string, string>
294
-
295
- gridStyles: Record<string, string> = {}
296
- currentSort: ITableSortSettings = {
297
- column: null,
298
- direction: this.sortToggleOrder?.[0] !== undefined ? this.sortToggleOrder[0] : -1,
299
- }
306
+ tableSubrowsStyles?: Record<string, string>
307
+ }>()
308
+
309
+ const emit = defineEmits<{
310
+ 'sort': [sortSettings: ITableSortSettings]
311
+ 'rowClicked': [row: TTableRow]
312
+ 'rowEnter': [row: TTableRow]
313
+ 'rowLeave': [row: TTableRow]
314
+ 'cellClicked': [rowAndColumn: { row: TTableRow; column: ITableColumn }]
315
+ }>()
316
+
317
+ const gridStyles = ref<Record<string, string>>({})
318
+ const currentSort = ref<ITableSortSettings>({
319
+ column: null,
320
+ direction: sortToggleOrder?.[0] !== undefined ? sortToggleOrder[0] : -1,
321
+ })
300
322
 
301
- created () {
302
- // Use default sort, if provided
303
- if (this.defaultSort) {
304
- this.currentSort = JSON.parse(JSON.stringify(this.defaultSort))
305
- }
323
+ // Use default sort, if provided
324
+ if (defaultSort) {
325
+ currentSort.value = JSON.parse(JSON.stringify(defaultSort))
326
+ }
306
327
 
307
- // Allow custom grid styles, otherwise use default based on number of columns
308
- if (this.grid) {
309
- this.gridStyles = this.grid
310
- } else {
311
- const numColumns = this.columns.length
312
- this.gridStyles = {
313
- 'grid-template-columns': `repeat(${numColumns}, 1fr)`,
314
- }
315
- }
328
+ // Allow custom grid styles, otherwise use default based on number of columns
329
+ if (grid) {
330
+ gridStyles.value = grid
331
+ } else {
332
+ const numColumns = columns.length
333
+ gridStyles.value = {
334
+ 'grid-template-columns': `repeat(${numColumns}, 1fr)`,
316
335
  }
336
+ }
317
337
 
318
- columnLabelClicked (column: ITableColumn) {
319
- // Do nothing if the column has disabled sort
320
- if (column.isSortDisabled) {
321
- return
322
- }
323
-
324
- // Sort by the current column, or change directions if already sorting by current column
325
- if (!this.currentSort.column || this.currentSort.column.propName !== column.propName) {
326
- this.currentSort.column = column
327
- } else {
328
- const currentSortDirIndex = this.sortToggleOrder.indexOf(this.currentSort.direction)
329
- const newSortDirection = this.sortToggleOrder[
330
- (currentSortDirIndex + 1) % this.sortToggleOrder.length
331
- ]
332
- this.currentSort.direction = newSortDirection !== undefined ? newSortDirection : -1
333
- }
334
- this.emitSort()
338
+ const columnLabelClicked = (column: ITableColumn) => {
339
+ // Do nothing if the column has disabled sort
340
+ if (column.isSortDisabled) {
341
+ return
335
342
  }
336
343
 
337
- @Watch('defaultSort')
338
- defaultSortChanged () {
339
- if (!this.defaultSort) {
340
- return
341
- }
342
- const defaultSort = JSON.stringify(this.defaultSort)
343
- const currentSort = JSON.stringify(this.currentSort)
344
-
345
- if (defaultSort !== currentSort) {
346
- this.currentSort = JSON.parse(defaultSort)
347
- this.emitSort()
348
- }
344
+ // Sort by the current column, or change directions if already sorting by current column
345
+ if (currentSort.value.column?.propName !== column.propName) {
346
+ currentSort.value.column = column
347
+ } else {
348
+ const currentSortDirIndex = sortToggleOrder.indexOf(currentSort.value.direction)
349
+ const newSortDirection = sortToggleOrder[
350
+ (currentSortDirIndex + 1) % sortToggleOrder.length
351
+ ]
352
+ currentSort.value.direction = newSortDirection !== undefined ? newSortDirection : -1
349
353
  }
354
+ emitSort()
355
+ }
350
356
 
351
- @Emit('sort')
352
- emitSort (): ITableSortSettings {
353
- return this.currentSort
357
+ watch(() => defaultSort, () => {
358
+ if (!defaultSort) {
359
+ return
354
360
  }
361
+ const defaultSortStr = JSON.stringify(defaultSort)
362
+ const currentSortStr = JSON.stringify(currentSort)
355
363
 
356
- @Emit('rowClicked')
357
- emitRowClicked (row: TTableRow) {
358
- return row
364
+ if (defaultSortStr !== currentSortStr) {
365
+ currentSort.value = JSON.parse(defaultSortStr)
366
+ emitSort()
359
367
  }
368
+ })
360
369
 
361
- @Emit('rowEnter')
362
- emitRowEnter (row: TTableRow) {
363
- return row
364
- }
370
+ const emitSort = () => {
371
+ emit('sort', currentSort.value)
372
+ }
365
373
 
366
- @Emit('rowLeave')
367
- emitRowLeave (row: TTableRow) {
368
- return row
369
- }
374
+ const emitRowClicked = (row: TTableRow) => {
375
+ emit('rowClicked', row)
376
+ }
370
377
 
371
- @Emit('cellClicked')
372
- emitCellClicked (row: TTableRow, column: ITableColumn) {
373
- return {
374
- row,
375
- column,
376
- }
377
- }
378
+ const emitRowEnter = (row: TTableRow) => {
379
+ emit('rowEnter', row)
380
+ }
381
+
382
+ const emitRowLeave = (row: TTableRow) => {
383
+ emit('rowLeave', row)
384
+ }
385
+
386
+ const emitCellClicked = (row: TTableRow, column: ITableColumn) => {
387
+ emit('cellClicked', {
388
+ row,
389
+ column,
390
+ })
378
391
  }
379
392
  </script>
380
393
 
@@ -614,4 +627,4 @@ export default class Table extends Vue {
614
627
  }
615
628
  }
616
629
  }
617
- </style>
630
+ </style>
@@ -32,7 +32,8 @@
32
32
  <div
33
33
  v-for="subAction in action.menu"
34
34
  :key="subAction.id"
35
- :ref="`${name}ActionMenu-${action.id}`"
35
+ :ref="`${name}ActionMenu`"
36
+ :data-action-id="action.id"
36
37
  class="uikit-table-actions__action-menu-option"
37
38
  tabindex="0"
38
39
  @mousedown.prevent.stop="actionClicked(subAction)"
@@ -46,95 +47,99 @@
46
47
  </div>
47
48
  </template>
48
49
 
49
- <script lang="ts">
50
- import { Component, Vue, Prop, Emit } from 'vue-facing-decorator'
50
+ <script setup lang="ts">
51
51
  import type { ITableAction, ITableSubAction } from './table'
52
52
  import Icon from '../Icons/Icon.vue'
53
53
  import Tooltip from '../Tooltips/Tooltip.vue'
54
+ import { ref, useTemplateRef } from 'vue'
55
+
56
+ const {
57
+ name = undefined,
58
+ actions = [],
59
+ } = defineProps<{
60
+ name?: string
61
+ actions?: ITableAction[]
62
+ }>()
63
+
64
+ const emit = defineEmits<{
65
+ 'actionClicked': [action: ITableAction | ITableSubAction]
66
+ }>()
67
+
68
+ const visibleMenuActionId = ref<string | number>('')
69
+ const hoveringMenuActionId = ref<number | string | null>(null)
70
+ const focusedMenuOptionIndex = ref<number | null>(null)
71
+
72
+ const actionRefs = useTemplateRef<HTMLElement[]>(`${name}Actions`)
73
+ const actionMenuRefs = useTemplateRef<HTMLElement[]>(`${name}ActionMenu`)
74
+
75
+ const blurActions = () => {
76
+ visibleMenuActionId.value = ''
77
+ hoveringMenuActionId.value = null
78
+ focusedMenuOptionIndex.value = null
79
+ actionRefs.value?.forEach(actionElement => {
80
+ actionElement.blur()
81
+ })
82
+ }
54
83
 
55
- @Component({
56
- components: {
57
- Icon,
58
- Tooltip,
59
- },
60
- })
61
- export default class TableActions extends Vue {
62
- @Prop() name!: string
63
- @Prop({ default: () => [] }) actions!: ITableAction[]
64
-
65
- visibleMenuActionId: string | number = ''
66
- hoveringMenuActionId: number | string | null = null
67
- focusedMenuOptionIndex: number | null = null
68
-
69
- blurActions () {
70
- this.visibleMenuActionId = ''
71
- this.hoveringMenuActionId = null
72
- this.focusedMenuOptionIndex = null
73
- const actionElements = this.$refs[`${this.name}Actions`] as HTMLElement[]
74
- actionElements?.forEach(actionElement => {
75
- actionElement.blur()
76
- })
77
- }
78
-
79
- actionClicked (action: ITableAction | ITableSubAction) {
80
- if ('menu' in action && action.menu?.length) {
81
- if (this.visibleMenuActionId !== action.id) {
82
- this.focusedMenuOptionIndex = null
83
- this.visibleMenuActionId = action.id
84
- } else {
85
- this.blurActions()
86
- }
84
+ const actionClicked = (action: ITableAction | ITableSubAction) => {
85
+ if ('menu' in action && action.menu?.length) {
86
+ if (visibleMenuActionId.value !== action.id) {
87
+ focusedMenuOptionIndex.value = null
88
+ visibleMenuActionId.value = action.id
87
89
  } else {
88
- this.blurActions()
89
- this.emitActionClicked(action)
90
+ blurActions()
90
91
  }
92
+ } else {
93
+ blurActions()
94
+ emitActionClicked(action)
91
95
  }
96
+ }
92
97
 
93
- scrollActionMenu (action: ITableAction, event: KeyboardEvent) {
94
- if (
95
- ![ 'ArrowUp', 'ArrowDown' ].includes(event.key) // ArrowUp, ArrowDown
96
- || !('menu' in action)
97
- || this.visibleMenuActionId !== action.id
98
- ) {
99
- return
100
- }
98
+ const scrollActionMenu = (action: ITableAction, event: KeyboardEvent) => {
99
+ if (
100
+ ![ 'ArrowUp', 'ArrowDown' ].includes(event.key) // ArrowUp, ArrowDown
101
+ || !('menu' in action)
102
+ || visibleMenuActionId.value !== action.id
103
+ ) {
104
+ return
105
+ }
101
106
 
102
- const currentIndex = this.focusedMenuOptionIndex
103
- const menuElements = this.$refs[`${this.name}ActionMenu-${action.id}`] as HTMLElement[] | undefined
104
-
105
- if (menuElements && event.key === 'ArrowUp') {
106
- // Up arrow
107
- if (currentIndex === 0) {
108
- const parentActionElement = menuElements[currentIndex]?.parentElement?.parentElement
109
- if (parentActionElement) {
110
- parentActionElement.focus()
111
- this.visibleMenuActionId = ''
112
- }
113
- } else {
114
- const nextIndex = currentIndex === null
115
- ? menuElements.length - 1
116
- : currentIndex - 1
117
- menuElements[nextIndex]?.focus()
118
- this.focusedMenuOptionIndex = nextIndex
119
- this.visibleMenuActionId = action.id
107
+ const currentIndex = focusedMenuOptionIndex.value
108
+ const menuElements = actionMenuRefs.value?.filter(actionMenuEl =>
109
+ actionMenuEl.getAttribute('data-action-id') === action.id
110
+ )
111
+
112
+ if (menuElements && event.key === 'ArrowUp') {
113
+ // Up arrow
114
+ if (currentIndex === 0) {
115
+ const parentActionElement = menuElements[currentIndex]?.parentElement?.parentElement
116
+ if (parentActionElement) {
117
+ parentActionElement.focus()
118
+ visibleMenuActionId.value = ''
120
119
  }
121
- } else if (menuElements && event.key === 'ArrowDown') {
122
- // Down arrow
123
- const nextIndex = currentIndex === null || currentIndex === menuElements.length - 1
124
- ? 0
125
- : currentIndex + 1
120
+ } else {
121
+ const nextIndex = currentIndex === null
122
+ ? menuElements.length - 1
123
+ : currentIndex - 1
126
124
  menuElements[nextIndex]?.focus()
127
- this.focusedMenuOptionIndex = nextIndex
128
- this.visibleMenuActionId = action.id
125
+ focusedMenuOptionIndex.value = nextIndex
126
+ visibleMenuActionId.value = action.id
129
127
  }
130
- event.preventDefault()
131
- event.stopPropagation()
128
+ } else if (menuElements && event.key === 'ArrowDown') {
129
+ // Down arrow
130
+ const nextIndex = currentIndex === null || currentIndex === menuElements.length - 1
131
+ ? 0
132
+ : currentIndex + 1
133
+ menuElements[nextIndex]?.focus()
134
+ focusedMenuOptionIndex.value = nextIndex
135
+ visibleMenuActionId.value = action.id
132
136
  }
137
+ event.preventDefault()
138
+ event.stopPropagation()
139
+ }
133
140
 
134
- @Emit('actionClicked')
135
- emitActionClicked (action: ITableAction | ITableSubAction) {
136
- return action
137
- }
141
+ const emitActionClicked = (action: ITableAction | ITableSubAction) => {
142
+ emit('actionClicked', action)
138
143
  }
139
144
  </script>
140
145
 
@@ -41,7 +41,7 @@ export type TTableRow = {
41
41
  }
42
42
 
43
43
  export interface ITableSortSettings {
44
- column: ITableColumn | null
44
+ column?: ITableColumn | null
45
45
  direction: TSortDirection
46
46
  }
47
47
 
@@ -22,9 +22,9 @@
22
22
  </div>
23
23
  </template>
24
24
 
25
- <script lang="ts">
26
- import { Vue, Component, Prop } from 'vue-facing-decorator'
27
- import { dark } from '../../directives'
25
+ <script setup lang="ts">
26
+ import { computed } from 'vue'
27
+ import { dark as vDark } from '../../directives'
28
28
 
29
29
  type TTagStyles = {
30
30
  background?: string
@@ -32,44 +32,54 @@ type TTagStyles = {
32
32
  border?: string
33
33
  }
34
34
 
35
- @Component({
36
- directives: {
37
- dark,
38
- },
39
- })
40
- export default class Tag extends Vue {
41
- @Prop({ default: false }) isBetaTag!: boolean
42
- @Prop({ default: false }) isLearningTag!: boolean
43
- @Prop({ default: false }) isActiveTag!: boolean
44
- @Prop({ default: false }) isPendingTag!: boolean
45
- @Prop({ default: false }) isArchivedTag!: boolean
46
- @Prop({ default: false }) isDraftTag!: boolean
47
- @Prop({ default: false }) isAvailableTag!: boolean
48
- @Prop({ default: false }) isUpcomingTag!: boolean
49
- @Prop({ default: false }) isClosedTag!: boolean
50
- @Prop({ default: 'large' }) size!: 'small' | 'medium' | 'large'
51
- @Prop({ default: false }) isDarkMode!: boolean
52
- @Prop({ default: undefined }) backgroundColor!: string | undefined
53
- @Prop({ default: undefined }) textColor!: string | undefined
54
- @Prop({ default: undefined }) tagBorder!: string | undefined
55
-
56
- get tagStyles () {
57
- const tagStylesObj: TTagStyles = {}
58
- if (this.backgroundColor) {
59
- tagStylesObj['background'] = this.backgroundColor
60
- }
61
-
62
- if (this.textColor) {
63
- tagStylesObj['color'] = this.textColor
64
- }
35
+ const {
36
+ isBetaTag = false,
37
+ isLearningTag = false,
38
+ isActiveTag = false,
39
+ isPendingTag = false,
40
+ isArchivedTag = false,
41
+ isDraftTag = false,
42
+ isAvailableTag = false,
43
+ isUpcomingTag = false,
44
+ isClosedTag = false,
45
+ size = 'large',
46
+ isDarkMode = false,
47
+ backgroundColor = undefined,
48
+ textColor = undefined,
49
+ tagBorder = undefined,
50
+ } = defineProps<{
51
+ isBetaTag?: boolean
52
+ isLearningTag?: boolean
53
+ isActiveTag?: boolean
54
+ isPendingTag?: boolean
55
+ isArchivedTag?: boolean
56
+ isDraftTag?: boolean
57
+ isAvailableTag?: boolean
58
+ isUpcomingTag?: boolean
59
+ isClosedTag?: boolean
60
+ size?: 'small' | 'medium' | 'large'
61
+ isDarkMode?: boolean
62
+ backgroundColor?: string
63
+ textColor?: string
64
+ tagBorder?: string
65
+ }>()
66
+
67
+ const tagStyles = computed(() => {
68
+ const tagStylesObj: TTagStyles = {}
69
+ if (backgroundColor) {
70
+ tagStylesObj['background'] = backgroundColor
71
+ }
65
72
 
66
- if (this.tagBorder) {
67
- tagStylesObj['border'] = this.tagBorder
68
- }
73
+ if (textColor) {
74
+ tagStylesObj['color'] = textColor
75
+ }
69
76
 
70
- return Object.keys(tagStylesObj).length !== 0 ? tagStylesObj : undefined
77
+ if (tagBorder) {
78
+ tagStylesObj['border'] = tagBorder
71
79
  }
72
- }
80
+
81
+ return Object.keys(tagStylesObj).length !== 0 ? tagStylesObj : undefined
82
+ })
73
83
  </script>
74
84
 
75
85
  <style lang="scss">
@@ -209,4 +219,4 @@ export default class Tag extends Vue {
209
219
  }
210
220
  }
211
221
  }
212
- </style>
222
+ </style>