@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.
- package/dist/@pocketprep/ui-kit.css +1 -1
- package/dist/@pocketprep/ui-kit.js +14469 -17731
- package/dist/@pocketprep/ui-kit.js.map +1 -1
- package/dist/@pocketprep/ui-kit.umd.cjs +19 -29
- package/dist/@pocketprep/ui-kit.umd.cjs.map +1 -1
- package/eslint.config.ts +38 -11
- package/lib/SVGDefinitions.vue +32 -35
- package/lib/components/Banners/Banner.vue +10 -14
- package/lib/components/Blobs/Blob.vue +6 -14
- package/lib/components/Blobs/BlobEmptyState.vue +9 -8
- package/lib/components/Blobs/blob.d.ts +1 -1
- package/lib/components/BundleIcons/BundleIcon.vue +36 -63
- package/lib/components/BundleIcons/bundleIcon.d.ts +1 -1
- package/lib/components/Bundles/BundleList.vue +71 -59
- package/lib/components/Bundles/BundleSearch.vue +93 -117
- package/lib/components/Bundles/PremiumPill.vue +6 -12
- package/lib/components/Buttons/Button.vue +32 -35
- package/lib/components/Buttons/Link.vue +32 -31
- package/lib/components/Buttons/Tab.vue +14 -17
- package/lib/components/Calendar/Calendar.vue +87 -85
- package/lib/components/Charts/Bar.vue +192 -263
- package/lib/components/Charts/Pie.vue +55 -61
- package/lib/components/Charts/highcharts-wrap.ts +81 -0
- package/lib/components/Controls/SegmentControl.vue +26 -24
- package/lib/components/Controls/Slider.vue +51 -47
- package/lib/components/Controls/ToggleSwitch.vue +33 -31
- package/lib/components/EmptyStates/EmptyState.vue +69 -73
- package/lib/components/Exams/ExamCard.vue +59 -47
- package/lib/components/Exams/ExamMenuCard.vue +30 -28
- package/lib/components/Filters/FilterDropdown.vue +83 -86
- package/lib/components/Filters/FilterOptions.vue +83 -88
- package/lib/components/Forms/Checkbox.vue +27 -27
- package/lib/components/Forms/CheckboxOption.vue +30 -30
- package/lib/components/Forms/Errors.vue +21 -24
- package/lib/components/Forms/Input.vue +71 -59
- package/lib/components/Forms/Radio.vue +2 -2
- package/lib/components/Forms/RadioButton.vue +8 -8
- package/lib/components/Forms/Select.vue +265 -257
- package/lib/components/Forms/Textarea.vue +49 -35
- package/lib/components/Icons/IconAccordionArrow.vue +7 -9
- package/lib/components/Icons/IconActivity.vue +7 -9
- package/lib/components/Icons/IconAdd.vue +7 -11
- package/lib/components/Icons/IconAddCircle.vue +7 -9
- package/lib/components/Icons/IconArrow.vue +7 -9
- package/lib/components/Icons/IconBarChart.vue +7 -9
- package/lib/components/Icons/IconCalendar.vue +7 -9
- package/lib/components/Icons/IconCalendarPicker.vue +7 -9
- package/lib/components/Icons/IconChat.vue +7 -9
- package/lib/components/Icons/IconCheck.vue +7 -9
- package/lib/components/Icons/IconClose.vue +7 -9
- package/lib/components/Icons/IconConcept.vue +1 -1
- package/lib/components/Icons/IconCorrect.vue +7 -9
- package/lib/components/Icons/IconEdit.vue +7 -11
- package/lib/components/Icons/IconExam.vue +7 -9
- package/lib/components/Icons/IconExternalLink.vue +7 -9
- package/lib/components/Icons/IconEyeHide.vue +7 -9
- package/lib/components/Icons/IconEyeShow.vue +7 -9
- package/lib/components/Icons/IconFilter.vue +7 -9
- package/lib/components/Icons/IconFilterActive.vue +7 -9
- package/lib/components/Icons/IconFlag.vue +7 -9
- package/lib/components/Icons/IconFlagContent.vue +8 -9
- package/lib/components/Icons/IconFlagFeedback.vue +8 -10
- package/lib/components/Icons/IconFlagFilled.vue +7 -9
- package/lib/components/Icons/IconFullView.vue +7 -9
- package/lib/components/Icons/IconFullViewActive.vue +7 -9
- package/lib/components/Icons/IconGridDrag.vue +2 -2
- package/lib/components/Icons/IconHandle.vue +7 -9
- package/lib/components/Icons/IconHeart.vue +7 -9
- package/lib/components/Icons/IconHelp.vue +7 -9
- package/lib/components/Icons/IconHighlight.vue +2 -2
- package/lib/components/Icons/IconHourglass.vue +7 -9
- package/lib/components/Icons/IconImage.vue +7 -9
- package/lib/components/Icons/IconIncorrect.vue +7 -9
- package/lib/components/Icons/IconInfo.vue +7 -9
- package/lib/components/Icons/IconKeyboard.vue +7 -9
- package/lib/components/Icons/IconLaunch.vue +7 -9
- package/lib/components/Icons/IconLevelUp.vue +7 -9
- package/lib/components/Icons/IconLightbulb.vue +7 -9
- package/lib/components/Icons/IconLightning.vue +7 -9
- package/lib/components/Icons/IconLink.vue +7 -9
- package/lib/components/Icons/IconList.vue +7 -9
- package/lib/components/Icons/IconLoading.vue +7 -9
- package/lib/components/Icons/IconLoading2.vue +11 -11
- package/lib/components/Icons/IconLock.vue +7 -9
- package/lib/components/Icons/IconMissedQuestions.vue +7 -9
- package/lib/components/Icons/IconMoon.vue +7 -9
- package/lib/components/Icons/IconPaginationArrow.vue +7 -9
- package/lib/components/Icons/IconPaginationArrowDouble.vue +7 -9
- package/lib/components/Icons/IconPassage.vue +7 -9
- package/lib/components/Icons/IconPencil.vue +7 -9
- package/lib/components/Icons/IconPeople.vue +7 -9
- package/lib/components/Icons/IconPercent.vue +7 -9
- package/lib/components/Icons/IconPerson.vue +8 -9
- package/lib/components/Icons/IconPresent.vue +7 -9
- package/lib/components/Icons/IconPreview.vue +7 -9
- package/lib/components/Icons/IconQuestions.vue +7 -9
- package/lib/components/Icons/IconQuick10.vue +7 -9
- package/lib/components/Icons/IconQuickActions.vue +2 -2
- package/lib/components/Icons/IconRecommendedFilter.vue +1 -1
- package/lib/components/Icons/IconRemoveCircle.vue +7 -9
- package/lib/components/Icons/IconReviewFlag.vue +7 -9
- package/lib/components/Icons/IconSearch.vue +7 -9
- package/lib/components/Icons/IconShare.vue +7 -9
- package/lib/components/Icons/IconSideBar.vue +7 -9
- package/lib/components/Icons/IconSideBarActive.vue +7 -9
- package/lib/components/Icons/IconStar.vue +1 -1
- package/lib/components/Icons/IconStopwatch.vue +7 -9
- package/lib/components/Icons/IconStrike.vue +7 -9
- package/lib/components/Icons/IconSubject.vue +7 -9
- package/lib/components/Icons/IconText.vue +7 -9
- package/lib/components/Icons/IconTimer.vue +8 -9
- package/lib/components/Icons/IconWarning.vue +7 -9
- package/lib/components/Icons/icon.d.ts +1 -1
- package/lib/components/Loaders/SkeletonLoader.vue +1 -5
- package/lib/components/Modal/Modal.vue +23 -29
- package/lib/components/Modal/ModalContainer.vue +135 -133
- package/lib/components/Onboarding/EmailAuth.vue +66 -70
- package/lib/components/Onboarding/MagicCodeEntry.vue +88 -83
- package/lib/components/Pagination/QuestionReviewPagination.vue +3 -3
- package/lib/components/Pagination/TablePagination.vue +47 -44
- package/lib/components/PhonePerson/PhonePerson.vue +18 -18
- package/lib/components/PhonePerson/phonePerson.d.ts +1 -1
- package/lib/components/Quiz/FlagToggle.vue +45 -44
- package/lib/components/Quiz/GlobalMetricsToggle.vue +29 -28
- package/lib/components/Quiz/KeyboardShortcutsButton.vue +16 -23
- package/lib/components/Quiz/KeyboardShortcutsModal.vue +36 -37
- package/lib/components/Quiz/Question/BuildListChoicesContainer.vue +65 -65
- package/lib/components/Quiz/Question/ChoicesContainer.vue +5 -5
- package/lib/components/Quiz/Question/DropdownExplanation.vue +5 -5
- package/lib/components/Quiz/Question/Explanation.vue +6 -6
- package/lib/components/Quiz/Question/MPMCChoicesContainer.vue +17 -17
- package/lib/components/Quiz/Question/MPMCRadioGroup.vue +2 -2
- package/lib/components/Quiz/Question/MatrixChoicesContainer.vue +39 -39
- package/lib/components/Quiz/Question/MatrixRadioGroup.vue +6 -6
- package/lib/components/Quiz/Question/MobileMatrixChoicesContainer.vue +27 -28
- package/lib/components/Quiz/Question/MobileMatrixRadioGroup.vue +2 -2
- package/lib/components/Quiz/Question/PassageAndImage.vue +3 -3
- package/lib/components/Quiz/Question/PassageAndImageDropdown.vue +7 -7
- package/lib/components/Quiz/Question/Paywall.vue +2 -2
- package/lib/components/Quiz/Question/QuestionContext.vue +1 -1
- package/lib/components/Quiz/Question/StatsSummary.vue +2 -2
- package/lib/components/Quiz/Question/Summary.vue +11 -11
- package/lib/components/Quiz/Question.vue +90 -82
- package/lib/components/Quiz/QuizContainer.vue +1 -1
- package/lib/components/Quiz/QuizProgressBar.vue +23 -23
- package/lib/components/Quiz/question.d.ts +3 -3
- package/lib/components/Search/Pill.vue +16 -19
- package/lib/components/Search/Search.vue +52 -47
- package/lib/components/SidePanels/SidePanel.vue +168 -174
- package/lib/components/Tables/Table.vue +135 -122
- package/lib/components/Tables/TableActions.vue +81 -76
- package/lib/components/Tables/table.d.ts +1 -1
- package/lib/components/Tags/Tag.vue +49 -39
- package/lib/components/Toasts/Toast.vue +44 -42
- package/lib/components/Tooltips/OverflowTooltip.vue +39 -45
- package/lib/components/Tooltips/Tooltip.vue +69 -70
- package/lib/directives.ts +4 -4
- package/lib/utils.ts +13 -12
- package/package.json +27 -28
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
<slot />
|
|
30
30
|
</div>
|
|
31
31
|
<div
|
|
32
|
-
v-if="$slots.subtext
|
|
32
|
+
v-if="$slots.subtext"
|
|
33
33
|
v-dark="isDarkMode"
|
|
34
34
|
class="toast__content-subtext"
|
|
35
35
|
>
|
|
@@ -39,57 +39,59 @@
|
|
|
39
39
|
</div>
|
|
40
40
|
</template>
|
|
41
41
|
|
|
42
|
-
<script lang="ts">
|
|
43
|
-
import { Vue, Component, Prop, Emit } from 'vue-facing-decorator'
|
|
42
|
+
<script setup lang="ts">
|
|
44
43
|
import Icon from '../Icons/Icon.vue'
|
|
45
|
-
import { dark } from '../../directives'
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
44
|
+
import { dark as vDark } from '../../directives'
|
|
45
|
+
import { onMounted, ref, useTemplateRef } from 'vue'
|
|
46
|
+
|
|
47
|
+
const props = withDefaults(defineProps<{
|
|
48
|
+
showCloseButton?: boolean
|
|
49
|
+
isDarkMode?: boolean
|
|
50
|
+
right?: boolean
|
|
51
|
+
}>(), {
|
|
52
|
+
showCloseButton: true,
|
|
53
|
+
isDarkMode: false,
|
|
54
|
+
right: false,
|
|
54
55
|
})
|
|
55
|
-
export default class Toast extends Vue {
|
|
56
|
-
@Prop({ default: true }) showCloseButton!: boolean
|
|
57
|
-
@Prop({ default: false }) isDarkMode!: boolean
|
|
58
|
-
@Prop({ default: false }) right!: boolean
|
|
59
56
|
|
|
60
|
-
|
|
57
|
+
const emit = defineEmits<{
|
|
58
|
+
'close': []
|
|
59
|
+
}>()
|
|
61
60
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const toastEl = this.$refs['toast'] as HTMLElement
|
|
61
|
+
const closeTimeout = ref<NodeJS.Timeout | null>(null)
|
|
62
|
+
const toastEl = useTemplateRef<HTMLElement>('toast')
|
|
65
63
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}, 1)
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
setCloseTimeout () {
|
|
72
|
-
this.closeTimeout = setTimeout(() => {
|
|
73
|
-
const toastEl = this.$refs['toast'] as HTMLElement
|
|
74
|
-
toastEl?.classList.add('toast--closing')
|
|
64
|
+
onMounted(() => {
|
|
65
|
+
setCloseTimeout()
|
|
75
66
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
67
|
+
setTimeout(() => {
|
|
68
|
+
if (toastEl.value) {
|
|
69
|
+
toastEl.value.classList.add(`toast--visible${props.right ? '--right' : ''}`)
|
|
70
|
+
}
|
|
71
|
+
}, 1)
|
|
72
|
+
})
|
|
81
73
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
74
|
+
const setCloseTimeout = () => {
|
|
75
|
+
closeTimeout.value = setTimeout(() => {
|
|
76
|
+
if (toastEl.value) {
|
|
77
|
+
toastEl.value.classList.add('toast--closing')
|
|
85
78
|
}
|
|
86
|
-
}
|
|
87
79
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
80
|
+
setTimeout(() => {
|
|
81
|
+
emitClose()
|
|
82
|
+
}, 300)
|
|
83
|
+
}, 5000)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const clearCloseTimeout = () => {
|
|
87
|
+
if (closeTimeout.value) {
|
|
88
|
+
clearTimeout(closeTimeout.value)
|
|
91
89
|
}
|
|
92
90
|
}
|
|
91
|
+
|
|
92
|
+
const emitClose = () => {
|
|
93
|
+
emit('close')
|
|
94
|
+
}
|
|
93
95
|
</script>
|
|
94
96
|
|
|
95
97
|
<style lang="scss" scoped>
|
|
@@ -230,4 +232,4 @@ export default class Toast extends Vue {
|
|
|
230
232
|
}
|
|
231
233
|
}
|
|
232
234
|
}
|
|
233
|
-
</style>
|
|
235
|
+
</style>
|
|
@@ -27,57 +27,51 @@
|
|
|
27
27
|
</div>
|
|
28
28
|
</template>
|
|
29
29
|
|
|
30
|
-
<script lang="ts">
|
|
31
|
-
import {
|
|
30
|
+
<script setup lang="ts">
|
|
31
|
+
import { nextTick, onMounted, onUnmounted, ref, useTemplateRef } from 'vue'
|
|
32
32
|
import Tooltip from '../Tooltips/Tooltip.vue'
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
uid = Math.floor(Math.random() * 1e9)
|
|
44
|
-
intersectionObserver: IntersectionObserver | null = null
|
|
45
|
-
isVisible = false
|
|
34
|
+
const showTooltip = ref(false)
|
|
35
|
+
const textOverflows = ref(false)
|
|
36
|
+
const measurementComplete = ref(false)
|
|
37
|
+
const uid = Math.floor(Math.random() * 1e9)
|
|
38
|
+
const intersectionObserver = ref<IntersectionObserver | null>(null)
|
|
39
|
+
const isVisible = ref(false)
|
|
40
|
+
const containerEl = useTemplateRef<HTMLDivElement>('uikit-overflow-tooltip')
|
|
41
|
+
const contentEl = useTemplateRef<HTMLElement>(`content_${uid}`)
|
|
42
|
+
const contentFullWidthEl = useTemplateRef<HTMLElement>(`content_fullwidth_${uid}`)
|
|
46
43
|
|
|
47
|
-
|
|
48
|
-
|
|
44
|
+
onMounted(() => {
|
|
45
|
+
checkTextOverflows()
|
|
49
46
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
this.intersectionObserver.observe(containerEl)
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
unmounted () {
|
|
67
|
-
this.intersectionObserver?.disconnect()
|
|
47
|
+
// Watch for changes in the element's visibility to recalculate whether the text overflows
|
|
48
|
+
if (containerEl.value) {
|
|
49
|
+
intersectionObserver.value = new IntersectionObserver(entries => {
|
|
50
|
+
if (!isVisible.value && entries[0]?.isIntersecting) {
|
|
51
|
+
measurementComplete.value = false
|
|
52
|
+
nextTick(() => {
|
|
53
|
+
isVisible.value = true
|
|
54
|
+
checkTextOverflows()
|
|
55
|
+
})
|
|
56
|
+
}
|
|
57
|
+
})
|
|
58
|
+
intersectionObserver.value.observe(containerEl.value)
|
|
68
59
|
}
|
|
60
|
+
})
|
|
69
61
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
62
|
+
onUnmounted(() => {
|
|
63
|
+
intersectionObserver.value?.disconnect()
|
|
64
|
+
})
|
|
73
65
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
66
|
+
const checkTextOverflows = () => {
|
|
67
|
+
nextTick(() => {
|
|
68
|
+
if (contentEl.value && contentFullWidthEl.value) {
|
|
69
|
+
const truncatedWidth = contentEl.value.getBoundingClientRect().width
|
|
70
|
+
const fullWidth = contentFullWidthEl.value.getBoundingClientRect().width
|
|
71
|
+
textOverflows.value = truncatedWidth < fullWidth
|
|
72
|
+
measurementComplete.value = true
|
|
73
|
+
}
|
|
74
|
+
})
|
|
81
75
|
}
|
|
82
76
|
</script>
|
|
83
77
|
|
|
@@ -105,4 +99,4 @@ export default class OverflowTooltip extends Vue {
|
|
|
105
99
|
top: calc(-100% - 14px);
|
|
106
100
|
}
|
|
107
101
|
}
|
|
108
|
-
</style>
|
|
102
|
+
</style>
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
:id="`tooltip-${tooltipId}`"
|
|
8
8
|
v-dark="isDarkMode"
|
|
9
9
|
class="uikit-tooltip-popup"
|
|
10
|
-
:class="{
|
|
10
|
+
:class="{
|
|
11
11
|
'uikit-tooltip-popup--rightalign': theme === 'rightalign',
|
|
12
12
|
'uikit-tooltip-popup--leftalign': theme === 'leftalign'
|
|
13
13
|
}"
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
<div
|
|
16
16
|
v-dark="isDarkMode"
|
|
17
17
|
class="uikit-tooltip-popup__triangle"
|
|
18
|
-
:class="{
|
|
18
|
+
:class="{
|
|
19
19
|
'uikit-tooltip-popup__triangle--rightalign': theme === 'rightalign',
|
|
20
20
|
'uikit-tooltip-popup__triangle--leftalign': theme === 'leftalign',
|
|
21
21
|
'uikit-tooltip-popup__triangle--offset': theme === 'offset'
|
|
@@ -28,78 +28,77 @@
|
|
|
28
28
|
</div>
|
|
29
29
|
</template>
|
|
30
30
|
|
|
31
|
-
<script lang="ts">
|
|
32
|
-
import {
|
|
33
|
-
import { dark } from '../../directives'
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
31
|
+
<script setup lang="ts">
|
|
32
|
+
import { nextTick, onMounted, onUnmounted } from 'vue'
|
|
33
|
+
import { dark as vDark } from '../../directives'
|
|
34
|
+
|
|
35
|
+
const props = withDefaults(defineProps<{
|
|
36
|
+
theme?: 'leftalign' | 'rightalign' | 'offset' | ''
|
|
37
|
+
styles?: Record<string, string> | null
|
|
38
|
+
isDarkMode?: boolean
|
|
39
|
+
}>(), {
|
|
40
|
+
theme: '',
|
|
41
|
+
styles: null,
|
|
42
|
+
isDarkMode: false,
|
|
39
43
|
})
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
if (
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
const triangleEl = document.querySelector(
|
|
74
|
-
`.uikit-tooltip-popup#tooltip-${this.tooltipId} .uikit-tooltip-popup__triangle`
|
|
75
|
-
) as HTMLElement
|
|
76
|
-
triangleEl.style.borderColor = `${tooltipEl.style.backgroundColor} transparent transparent`
|
|
77
|
-
}
|
|
44
|
+
|
|
45
|
+
const tooltipId = Math.floor(Math.random() * 1000000)
|
|
46
|
+
|
|
47
|
+
onMounted(() => {
|
|
48
|
+
nextTick(() => {
|
|
49
|
+
const tooltipEl = document.querySelector(`.uikit-tooltip-popup#tooltip-${tooltipId}`) as HTMLElement
|
|
50
|
+
const body = document.querySelector('body') as HTMLElement
|
|
51
|
+
|
|
52
|
+
// Get original positioning before adding element to body
|
|
53
|
+
const clientRectTop = tooltipEl.getBoundingClientRect().top
|
|
54
|
+
const clientRectLeft = tooltipEl.getBoundingClientRect().left
|
|
55
|
+
const computedStyle = getComputedStyle(tooltipEl)
|
|
56
|
+
const singleLineTooltipHeight = parseInt(computedStyle.lineHeight)
|
|
57
|
+
+ parseInt(computedStyle.paddingTop)
|
|
58
|
+
+ parseInt(computedStyle.paddingBottom)
|
|
59
|
+
|
|
60
|
+
// Move element to body
|
|
61
|
+
tooltipEl.parentNode?.removeChild(tooltipEl)
|
|
62
|
+
body.appendChild(tooltipEl)
|
|
63
|
+
tooltipEl.style.position = 'absolute'
|
|
64
|
+
tooltipEl.style.zIndex = '1002'
|
|
65
|
+
|
|
66
|
+
// Apply Prop styles
|
|
67
|
+
const propStyle = props.styles
|
|
68
|
+
if (propStyle) {
|
|
69
|
+
Object.keys(propStyle).forEach(styleProp => {
|
|
70
|
+
tooltipEl.style[styleProp as 'color'] = propStyle[styleProp] || ''
|
|
71
|
+
})
|
|
72
|
+
if (tooltipEl.style.backgroundColor) {
|
|
73
|
+
const triangleEl = document.querySelector(
|
|
74
|
+
`.uikit-tooltip-popup#tooltip-${tooltipId} .uikit-tooltip-popup__triangle`
|
|
75
|
+
) as HTMLElement
|
|
76
|
+
triangleEl.style.borderColor = `${tooltipEl.style.backgroundColor} transparent transparent`
|
|
78
77
|
}
|
|
78
|
+
}
|
|
79
79
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
80
|
+
// Apply horizontal positioning before vertical positioning (because the height depends on text wrap)
|
|
81
|
+
const tooltipWidth = tooltipEl.clientWidth
|
|
82
|
+
const leftOffset = props.theme === 'rightalign'
|
|
83
|
+
? 20
|
|
84
|
+
: props.theme === 'leftalign'
|
|
85
|
+
? tooltipWidth - 20
|
|
86
|
+
: Math.floor(tooltipWidth / 2)
|
|
87
|
+
const left = Math.round(clientRectLeft + window.pageXOffset - leftOffset)
|
|
88
|
+
tooltipEl.style.left = `${left}px`
|
|
89
|
+
|
|
90
|
+
// Apply vertical positioning
|
|
91
|
+
const top = Math.round(clientRectTop + window.pageYOffset)
|
|
92
|
+
- tooltipEl.clientHeight
|
|
93
|
+
+ singleLineTooltipHeight
|
|
94
|
+
tooltipEl.style.top = `${top}px`
|
|
95
|
+
})
|
|
96
|
+
})
|
|
97
97
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
}
|
|
98
|
+
onUnmounted(() => {
|
|
99
|
+
const tooltipEl = document.querySelector(`.uikit-tooltip-popup#tooltip-${tooltipId}`) as HTMLElement
|
|
100
|
+
tooltipEl.remove()
|
|
101
|
+
})
|
|
103
102
|
</script>
|
|
104
103
|
|
|
105
104
|
<style lang="scss">
|
package/lib/directives.ts
CHANGED
|
@@ -207,15 +207,15 @@ export const breakpoint: Directive<HTMLElement, {
|
|
|
207
207
|
updateBreakpointClasses(el, binding.value, getCustomContainer(binding))
|
|
208
208
|
})
|
|
209
209
|
},
|
|
210
|
-
unmounted:
|
|
210
|
+
unmounted: el => {
|
|
211
211
|
removeBreakpointListeners(el)
|
|
212
212
|
},
|
|
213
213
|
}
|
|
214
214
|
|
|
215
215
|
export const dark: Directive<HTMLElement> = (el, { value }: { value?: boolean }) => {
|
|
216
216
|
const isDarkMode = !!value
|
|
217
|
-
const classes = (typeof el.className === 'string'
|
|
218
|
-
? el.className
|
|
217
|
+
const classes = (typeof el.className === 'string'
|
|
218
|
+
? el.className
|
|
219
219
|
: (el.className as unknown as { baseVal: string }).baseVal).split(' ')
|
|
220
220
|
if (isDarkMode) {
|
|
221
221
|
if (classes.find(c => c.endsWith('--dark'))) {
|
|
@@ -231,4 +231,4 @@ export const dark: Directive<HTMLElement> = (el, { value }: { value?: boolean })
|
|
|
231
231
|
}
|
|
232
232
|
})
|
|
233
233
|
}
|
|
234
|
-
}
|
|
234
|
+
}
|
package/lib/utils.ts
CHANGED
|
@@ -99,8 +99,8 @@ export const highlightKeywordsInText = (params: {
|
|
|
99
99
|
|
|
100
100
|
// Create an array for all matching keywords and substrings with their start and end indexes
|
|
101
101
|
const allMatches: { start: number; end: number; keyword: string; keywordMatch: string }[] = []
|
|
102
|
-
|
|
103
|
-
sortedKeywords.forEach(
|
|
102
|
+
|
|
103
|
+
sortedKeywords.forEach(keyword => {
|
|
104
104
|
const escapedKeyword = escapeRegex(keyword)
|
|
105
105
|
const regex = new RegExp(`\\b${escapedKeyword}\\b`, 'gi')
|
|
106
106
|
|
|
@@ -108,7 +108,7 @@ export const highlightKeywordsInText = (params: {
|
|
|
108
108
|
// This will include keyword matches that are substrings of other keywords
|
|
109
109
|
// ie: keyword 'stakeholder' will match in a keyword string 'key stakeholder'
|
|
110
110
|
const matches = Array.from(params.text.matchAll(regex))
|
|
111
|
-
matches.forEach(
|
|
111
|
+
matches.forEach(match => {
|
|
112
112
|
allMatches.push({
|
|
113
113
|
start: match.index,
|
|
114
114
|
end: match.index + match[0].length,
|
|
@@ -117,7 +117,7 @@ export const highlightKeywordsInText = (params: {
|
|
|
117
117
|
})
|
|
118
118
|
})
|
|
119
119
|
})
|
|
120
|
-
|
|
120
|
+
|
|
121
121
|
// Sort all matches by start index
|
|
122
122
|
allMatches.sort((a, b) => a.start - b.start)
|
|
123
123
|
|
|
@@ -127,27 +127,28 @@ export const highlightKeywordsInText = (params: {
|
|
|
127
127
|
// Create an array to track non-overlapping keyword matches
|
|
128
128
|
const nonOverlappingMatches: { start: number; end: number; keyword: string; keywordMatch: string }[] = []
|
|
129
129
|
// Do not include any matches that are substrings of other matches
|
|
130
|
-
allMatches.forEach(
|
|
131
|
-
const overlaps = highlightedRanges.some(range =>
|
|
130
|
+
allMatches.forEach(match => {
|
|
131
|
+
const overlaps = highlightedRanges.some(range =>
|
|
132
132
|
(match.start < range.end && match.end > range.start)
|
|
133
133
|
)
|
|
134
|
-
|
|
134
|
+
|
|
135
135
|
if (!overlaps) {
|
|
136
136
|
nonOverlappingMatches.push(match)
|
|
137
137
|
highlightedRanges.push({ start: match.start, end: match.end })
|
|
138
138
|
}
|
|
139
139
|
})
|
|
140
|
-
|
|
140
|
+
|
|
141
141
|
// Sort by start position again and process in reverse order to maintain positions
|
|
142
142
|
nonOverlappingMatches.sort((a, b) => b.start - a.start)
|
|
143
143
|
|
|
144
144
|
let result = params.text
|
|
145
145
|
|
|
146
|
-
nonOverlappingMatches.forEach(
|
|
146
|
+
nonOverlappingMatches.forEach(match => {
|
|
147
147
|
const beforeMatch = result.substring(0, match.start)
|
|
148
148
|
const afterMatch = result.substring(match.end)
|
|
149
|
-
const highlightedMatch = `<span class="keyword-highlight${params.isDarkMode
|
|
150
|
-
? ' keyword-highlight--dark'
|
|
149
|
+
const highlightedMatch = `<span class="keyword-highlight${params.isDarkMode
|
|
150
|
+
? ' keyword-highlight--dark'
|
|
151
|
+
: ''}" data-location="${
|
|
151
152
|
params.location}" role="button" tabindex="0" aria-label="${
|
|
152
153
|
match.keywordMatch}, Instruction. Click for definition" aria-haspopup="dialog" aria-expanded="false">
|
|
153
154
|
<span style="pointer-events: none;">${match.keywordMatch}</span></span>`
|
|
@@ -164,4 +165,4 @@ export const stripHtmlTags = (string?: string) => {
|
|
|
164
165
|
return div.textContent || ''
|
|
165
166
|
}
|
|
166
167
|
return ''
|
|
167
|
-
}
|
|
168
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pocketprep/ui-kit",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.9.0",
|
|
4
4
|
"description": "Pocket Prep UI Kit",
|
|
5
5
|
"author": "pocketprep",
|
|
6
6
|
"scripts": {
|
|
@@ -77,34 +77,33 @@
|
|
|
77
77
|
"highcharts": "10.3.3",
|
|
78
78
|
"litepicker": "2.0.12",
|
|
79
79
|
"resize-observer": "1.0.4",
|
|
80
|
-
"vue": "3.5.
|
|
81
|
-
"vue-
|
|
82
|
-
"vue-router": "4.5.0"
|
|
80
|
+
"vue": "3.5.27",
|
|
81
|
+
"vue-router": "4.6.4"
|
|
83
82
|
},
|
|
84
83
|
"devDependencies": {
|
|
85
|
-
"@pocketprep/types": "1.
|
|
86
|
-
"@stylistic/eslint-plugin
|
|
87
|
-
"@tsconfig/
|
|
88
|
-
"@types/node": "
|
|
89
|
-
"@vitejs/plugin-vue": "
|
|
90
|
-
"@vue/eslint-config-typescript": "14.
|
|
91
|
-
"@vue/tsconfig": "0.
|
|
92
|
-
"cypress": "
|
|
93
|
-
"eslint": "9.
|
|
94
|
-
"eslint-plugin-cypress": "
|
|
95
|
-
"eslint-plugin-vue": "10.
|
|
84
|
+
"@pocketprep/types": "1.16.22",
|
|
85
|
+
"@stylistic/eslint-plugin": "5.7.1",
|
|
86
|
+
"@tsconfig/node24": "24.0.4",
|
|
87
|
+
"@types/node": "24.10.4",
|
|
88
|
+
"@vitejs/plugin-vue": "6.0.3",
|
|
89
|
+
"@vue/eslint-config-typescript": "14.6.0",
|
|
90
|
+
"@vue/tsconfig": "0.8.1",
|
|
91
|
+
"cypress": "15.9.0",
|
|
92
|
+
"eslint": "9.39.2",
|
|
93
|
+
"eslint-plugin-cypress": "5.2.1",
|
|
94
|
+
"eslint-plugin-vue": "10.7.0",
|
|
96
95
|
"jiti": "2.4.2",
|
|
97
|
-
"npm-run-all2": "
|
|
98
|
-
"postcss-html": "1.8.
|
|
99
|
-
"sass": "1.
|
|
100
|
-
"start-server-and-test": "2.
|
|
101
|
-
"stylelint": "16.
|
|
102
|
-
"stylelint-config-recommended-scss": "
|
|
103
|
-
"stylelint-config-recommended-vue": "1.6.
|
|
104
|
-
"stylelint-config-standard-scss": "
|
|
105
|
-
"typescript": "5.
|
|
106
|
-
"vite": "
|
|
107
|
-
"vite-plugin-vue-devtools": "
|
|
96
|
+
"npm-run-all2": "8.0.4",
|
|
97
|
+
"postcss-html": "1.8.1",
|
|
98
|
+
"sass": "1.97.3",
|
|
99
|
+
"start-server-and-test": "2.1.3",
|
|
100
|
+
"stylelint": "16.26.1",
|
|
101
|
+
"stylelint-config-recommended-scss": "16.0.2",
|
|
102
|
+
"stylelint-config-recommended-vue": "1.6.1",
|
|
103
|
+
"stylelint-config-standard-scss": "16.0.0",
|
|
104
|
+
"typescript": "5.9.3",
|
|
105
|
+
"vite": "7.3.1",
|
|
106
|
+
"vite-plugin-vue-devtools": "8.0.5",
|
|
108
107
|
"vue-tsc": "2.2.8",
|
|
109
108
|
"yorkie": "2.0.0"
|
|
110
109
|
},
|
|
@@ -124,7 +123,7 @@
|
|
|
124
123
|
"url": "git+https://github.com/Pocket-Prep/ui-kit.git"
|
|
125
124
|
},
|
|
126
125
|
"engines": {
|
|
127
|
-
"node": "
|
|
128
|
-
"npm": "
|
|
126
|
+
"node": "24.12.0",
|
|
127
|
+
"npm": "11.6.2"
|
|
129
128
|
}
|
|
130
129
|
}
|