@citizenplane/pimp 18.12.2 → 18.12.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/biome.json +10 -0
- package/dist/components/CpMultiselect.vue.d.ts.map +1 -1
- package/dist/components/CpTabs.vue.d.ts.map +1 -1
- package/dist/components/CpTransitionCounter.vue.d.ts.map +1 -1
- package/dist/components/CpTransitionExpand.vue.d.ts.map +1 -1
- package/dist/components/CpTransitionSize.vue.d.ts.map +1 -1
- package/dist/components/CpTransitionTabContent.vue.d.ts.map +1 -1
- package/dist/components/icons/IconBank.vue.d.ts +3 -0
- package/dist/components/icons/IconBank.vue.d.ts.map +1 -0
- package/dist/components/index.d.ts +2 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/composables/useReducedMotion.d.ts +2 -0
- package/dist/composables/useReducedMotion.d.ts.map +1 -0
- package/dist/constants/CpCustomIcons.d.ts +1 -0
- package/dist/constants/CpCustomIcons.d.ts.map +1 -1
- package/dist/constants/index.d.ts +1 -0
- package/dist/constants/index.d.ts.map +1 -1
- package/dist/pimp.es.js +3293 -3263
- package/dist/pimp.umd.js +30 -30
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/assets/css/reduced-motion.css +73 -0
- package/src/assets/main.css +1 -0
- package/src/components/CpMultiselect.vue +1 -0
- package/src/components/CpTabs.vue +4 -1
- package/src/components/CpTransitionCounter.vue +6 -1
- package/src/components/CpTransitionExpand.vue +16 -0
- package/src/components/CpTransitionSize.vue +23 -8
- package/src/components/CpTransitionTabContent.vue +8 -1
- package/src/components/icons/IconBank.vue +5 -0
- package/src/components/index.ts +2 -0
- package/src/composables/useReducedMotion.ts +13 -0
- package/src/constants/CpCustomIcons.ts +2 -0
- package/src/constants/index.ts +2 -0
package/package.json
CHANGED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
@media (prefers-reduced-motion: reduce) {
|
|
2
|
+
*,
|
|
3
|
+
*::before,
|
|
4
|
+
*::after {
|
|
5
|
+
scroll-behavior: auto !important;
|
|
6
|
+
transition-delay: 0ms !important;
|
|
7
|
+
transition-duration: 1ms !important;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
[class$="-enter-from"],
|
|
11
|
+
[class*="-enter-from "],
|
|
12
|
+
[class$="-leave-to"],
|
|
13
|
+
[class*="-leave-to "] {
|
|
14
|
+
transform: none !important;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
:where([class$="-enter-from"], [class*="-enter-from "], [class$="-leave-to"], [class*="-leave-to "]) {
|
|
18
|
+
rotate: none !important;
|
|
19
|
+
scale: 1 !important;
|
|
20
|
+
translate: none !important;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
[class$="-enter-active"],
|
|
24
|
+
[class*="-enter-active "],
|
|
25
|
+
[class$="-leave-active"],
|
|
26
|
+
[class*="-leave-active "] {
|
|
27
|
+
transition: opacity 120ms linear !important;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.dialog-enter-from dialog main,
|
|
31
|
+
.dialog-leave-to dialog main {
|
|
32
|
+
transform: none !important;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.cpDialog__container,
|
|
36
|
+
.cpDialog__overlay,
|
|
37
|
+
.cpMenu__menuContent,
|
|
38
|
+
.cpTable__overlay,
|
|
39
|
+
.v-popper__wrapper {
|
|
40
|
+
transition: opacity 120ms linear !important;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.v-popper__popper--hidden .v-popper__wrapper {
|
|
44
|
+
scale: 1 !important;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.drawer-enter-from,
|
|
48
|
+
.drawer-leave-to {
|
|
49
|
+
opacity: 0 !important;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.counter-up-enter-active,
|
|
53
|
+
.counter-up-leave-active,
|
|
54
|
+
.counter-down-enter-active,
|
|
55
|
+
.counter-down-leave-active,
|
|
56
|
+
.expand-enter-active,
|
|
57
|
+
.expand-leave-active {
|
|
58
|
+
transition: none !important;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.counter-up-leave-to,
|
|
62
|
+
.counter-down-leave-to {
|
|
63
|
+
filter: none !important;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
:not([data-motion="essential"], [data-motion="essential"] *),
|
|
67
|
+
:not([data-motion="essential"], [data-motion="essential"] *)::before,
|
|
68
|
+
:not([data-motion="essential"], [data-motion="essential"] *)::after {
|
|
69
|
+
animation-delay: 0ms !important;
|
|
70
|
+
animation-duration: 1ms !important;
|
|
71
|
+
animation-iteration-count: 1 !important;
|
|
72
|
+
}
|
|
73
|
+
}
|
package/src/assets/main.css
CHANGED
|
@@ -347,6 +347,7 @@ onMounted(() => overrideAlignOverlay())
|
|
|
347
347
|
justify-content: space-between;
|
|
348
348
|
padding: var(--cp-spacing-md);
|
|
349
349
|
border-radius: var(--cp-radius-md);
|
|
350
|
+
background-color: var(--cp-background-primary);
|
|
350
351
|
box-shadow:
|
|
351
352
|
var(--cp-shadows-3xs-inset),
|
|
352
353
|
0 0 0 var(--cp-dimensions-0_25) var(--cp-border-soft);
|
|
@@ -30,6 +30,8 @@
|
|
|
30
30
|
<script setup lang="ts">
|
|
31
31
|
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
|
32
32
|
|
|
33
|
+
import { useReducedMotion } from '@/composables/useReducedMotion'
|
|
34
|
+
|
|
33
35
|
import CpText from '@/components/CpText.vue'
|
|
34
36
|
|
|
35
37
|
import { capitalizeFirstLetter } from '@/helpers'
|
|
@@ -64,6 +66,7 @@ const cpTabsElement = ref<HTMLElement | null>(null)
|
|
|
64
66
|
const activeUnderline = ref<HTMLElement | null>(null)
|
|
65
67
|
const activeTabIndex = ref<number | null>(props.defaultActiveIndex)
|
|
66
68
|
const suppressUnderlineTransition = ref(false)
|
|
69
|
+
const prefersReducedMotion = useReducedMotion()
|
|
67
70
|
|
|
68
71
|
const textSize = computed(() => {
|
|
69
72
|
switch (props.size) {
|
|
@@ -204,7 +207,7 @@ const scrollToActiveElement = (behavior: ScrollBehavior = 'smooth') => {
|
|
|
204
207
|
const activeTabElement = getActiveTabElement()
|
|
205
208
|
if (!activeTabElement) return
|
|
206
209
|
|
|
207
|
-
return activeTabElement.scrollIntoView({ block: 'nearest', behavior })
|
|
210
|
+
return activeTabElement.scrollIntoView({ block: 'nearest', behavior: prefersReducedMotion.value ? 'instant' : behavior })
|
|
208
211
|
}
|
|
209
212
|
|
|
210
213
|
onBeforeUnmount(() => window.removeEventListener('resize', setUnderlineStyle))
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="cpTransitionCounter">
|
|
3
|
-
<transition :duration="
|
|
3
|
+
<transition :duration="resolvedDuration" mode="out-in" :name="formattedTransitionName">
|
|
4
4
|
<span :key="counterNumber">
|
|
5
5
|
<slot />
|
|
6
6
|
</span>
|
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
<script setup lang="ts">
|
|
12
12
|
import { computed, ref, watch } from 'vue'
|
|
13
13
|
|
|
14
|
+
import { useReducedMotion } from '@/composables/useReducedMotion'
|
|
15
|
+
|
|
14
16
|
interface Props {
|
|
15
17
|
counterNumber?: number
|
|
16
18
|
duration?: number
|
|
@@ -30,6 +32,9 @@ const direction = ref<Directions>(Directions.UP)
|
|
|
30
32
|
|
|
31
33
|
const formattedTransitionName = computed(() => `counter-${direction.value}`)
|
|
32
34
|
|
|
35
|
+
const prefersReducedMotion = useReducedMotion()
|
|
36
|
+
const resolvedDuration = computed(() => (prefersReducedMotion.value ? 0 : props.duration))
|
|
37
|
+
|
|
33
38
|
watch(
|
|
34
39
|
() => props.counterNumber,
|
|
35
40
|
(newValue: number, oldValue: number) => {
|
|
@@ -5,6 +5,10 @@
|
|
|
5
5
|
</template>
|
|
6
6
|
|
|
7
7
|
<script setup lang="ts">
|
|
8
|
+
import { useReducedMotion } from '@/composables/useReducedMotion'
|
|
9
|
+
|
|
10
|
+
const prefersReducedMotion = useReducedMotion()
|
|
11
|
+
|
|
8
12
|
const afterEnter = (element: Element) => {
|
|
9
13
|
const el = element as HTMLElement
|
|
10
14
|
el.style.height = `auto`
|
|
@@ -12,6 +16,12 @@ const afterEnter = (element: Element) => {
|
|
|
12
16
|
|
|
13
17
|
const enter = (element: Element) => {
|
|
14
18
|
const el = element as HTMLElement
|
|
19
|
+
|
|
20
|
+
if (prefersReducedMotion.value) {
|
|
21
|
+
el.style.height = 'auto'
|
|
22
|
+
return
|
|
23
|
+
}
|
|
24
|
+
|
|
15
25
|
const { width } = getComputedStyle(el)
|
|
16
26
|
|
|
17
27
|
el.style.width = width
|
|
@@ -37,6 +47,12 @@ const enter = (element: Element) => {
|
|
|
37
47
|
|
|
38
48
|
const leave = (element: Element): void => {
|
|
39
49
|
const el = element as HTMLElement
|
|
50
|
+
|
|
51
|
+
if (prefersReducedMotion.value) {
|
|
52
|
+
el.style.height = '0'
|
|
53
|
+
return
|
|
54
|
+
}
|
|
55
|
+
|
|
40
56
|
const { height } = getComputedStyle(el)
|
|
41
57
|
|
|
42
58
|
el.style.height = height
|
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
</template>
|
|
6
6
|
|
|
7
7
|
<script setup lang="ts">
|
|
8
|
-
import { computed, nextTick, onBeforeUnmount, onMounted, ref, useId } from 'vue'
|
|
8
|
+
import { computed, nextTick, onBeforeUnmount, onMounted, ref, useId, watch } from 'vue'
|
|
9
|
+
|
|
10
|
+
import { useReducedMotion } from '@/composables/useReducedMotion'
|
|
9
11
|
|
|
10
12
|
interface Props {
|
|
11
13
|
type?: 'width' | 'height'
|
|
@@ -13,6 +15,8 @@ interface Props {
|
|
|
13
15
|
|
|
14
16
|
const props = withDefaults(defineProps<Props>(), { type: 'width' })
|
|
15
17
|
|
|
18
|
+
const prefersReducedMotion = useReducedMotion()
|
|
19
|
+
|
|
16
20
|
const slotWrapper = ref()
|
|
17
21
|
const slotContent = computed<HTMLElement | null>(() => slotWrapper.value?.children[0])
|
|
18
22
|
|
|
@@ -52,22 +56,33 @@ const updateWrapperSize = async () => {
|
|
|
52
56
|
|
|
53
57
|
const observer = ref<MutationObserver>()
|
|
54
58
|
|
|
55
|
-
const
|
|
59
|
+
const startObserving = () => {
|
|
60
|
+
if (!slotContent.value || observer.value) return
|
|
61
|
+
|
|
56
62
|
observer.value = new MutationObserver(updateWrapperSize)
|
|
57
63
|
observer.value.observe(slotContent.value as HTMLElement, { childList: true, subtree: false })
|
|
58
64
|
|
|
59
65
|
updateWrapperSize()
|
|
60
66
|
}
|
|
61
67
|
|
|
68
|
+
const stopObserving = () => {
|
|
69
|
+
observer.value?.disconnect()
|
|
70
|
+
observer.value = undefined
|
|
71
|
+
|
|
72
|
+
if (!slotWrapper.value) return
|
|
73
|
+
|
|
74
|
+
slotWrapper.value.style.width = ''
|
|
75
|
+
slotWrapper.value.style.height = ''
|
|
76
|
+
slotWrapper.value.style.minHeight = ''
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
watch(prefersReducedMotion, (isReduced) => (isReduced ? stopObserving() : startObserving()))
|
|
80
|
+
|
|
62
81
|
onMounted(() => {
|
|
63
|
-
if (
|
|
64
|
-
initObserver()
|
|
65
|
-
}
|
|
82
|
+
if (!prefersReducedMotion.value) startObserving()
|
|
66
83
|
})
|
|
67
84
|
|
|
68
|
-
onBeforeUnmount(() =>
|
|
69
|
-
if (observer.value) observer.value.disconnect()
|
|
70
|
-
})
|
|
85
|
+
onBeforeUnmount(() => observer.value?.disconnect())
|
|
71
86
|
</script>
|
|
72
87
|
|
|
73
88
|
<style lang="scss">
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<transition :duration="
|
|
2
|
+
<transition :duration="resolvedDuration" mode="out-in" :name="formattedTransitionName" @after-enter="emit('onAfterEnter')">
|
|
3
3
|
<slot />
|
|
4
4
|
</transition>
|
|
5
5
|
</template>
|
|
@@ -7,6 +7,10 @@
|
|
|
7
7
|
<script setup lang="ts">
|
|
8
8
|
import { computed } from 'vue'
|
|
9
9
|
|
|
10
|
+
import { useReducedMotion } from '@/composables/useReducedMotion'
|
|
11
|
+
|
|
12
|
+
import { REDUCED_MOTION_FADE_MS } from '@/constants'
|
|
13
|
+
|
|
10
14
|
type Direction = 'forward' | 'backward'
|
|
11
15
|
|
|
12
16
|
type EmitType = {
|
|
@@ -26,6 +30,9 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
26
30
|
const emit = defineEmits<EmitType>()
|
|
27
31
|
|
|
28
32
|
const formattedTransitionName = computed(() => `tab-content-${props.direction}`)
|
|
33
|
+
|
|
34
|
+
const prefersReducedMotion = useReducedMotion()
|
|
35
|
+
const resolvedDuration = computed(() => (prefersReducedMotion.value ? REDUCED_MOTION_FADE_MS : props.duration))
|
|
29
36
|
</script>
|
|
30
37
|
|
|
31
38
|
<style lang="scss">
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
|
|
3
|
+
<path d="M11.3389 2.36384C11.6929 2.05223 12.2131 2.0327 12.5879 2.30525L12.6602 2.36384L21.4629 10.1119L20.8027 10.8609V10.8629L21.4629 10.1119C21.7752 10.3867 21.885 10.8262 21.7383 11.2154C21.5914 11.6046 21.2187 11.8627 20.8027 11.8629H20.208V19.6871H20.8027C21.3548 19.6873 21.8026 20.135 21.8027 20.6871C21.8027 21.2392 21.3548 21.6869 20.8027 21.6871H3.19727C2.64509 21.687 2.19731 21.2393 2.19727 20.6871C2.19736 20.1349 2.64512 19.6872 3.19727 19.6871H4.0127V11.8629H3.19727C2.78126 11.8628 2.40861 11.6046 2.26172 11.2154C2.11501 10.8263 2.22413 10.3867 2.53613 10.1119L11.3389 2.36384ZM6.0127 19.6871H8.74414V11.8629H6.0127V19.6871ZM10.7441 19.6871H13.4766V11.8629H10.7441V19.6871ZM15.4766 19.6871H18.208V11.8629H15.4766V19.6871ZM5.84668 9.86286H18.1533L11.999 4.44685L5.84668 9.86286Z" />
|
|
4
|
+
</svg>
|
|
5
|
+
</template>
|
package/src/components/index.ts
CHANGED
|
@@ -13,6 +13,7 @@ import type { App, Plugin } from 'vue'
|
|
|
13
13
|
import { BindOnceDirective } from 'vue-bind-once'
|
|
14
14
|
import VueTelInput from 'vue-tel-input'
|
|
15
15
|
|
|
16
|
+
import { useReducedMotion } from '../composables/useReducedMotion'
|
|
16
17
|
import ClickOutside from '../directives/ClickOutside'
|
|
17
18
|
import CpCoreDatepicker from '../libs/CoreDatepicker.vue'
|
|
18
19
|
import CpAccordion from './CpAccordion.vue'
|
|
@@ -265,6 +266,7 @@ export {
|
|
|
265
266
|
IconSupplier,
|
|
266
267
|
IconThirdParty,
|
|
267
268
|
IconTooltip,
|
|
269
|
+
useReducedMotion,
|
|
268
270
|
}
|
|
269
271
|
|
|
270
272
|
export default Pimp
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { usePreferredReducedMotion } from '@vueuse/core'
|
|
2
|
+
import { computed, getCurrentInstance, onMounted, ref } from 'vue'
|
|
3
|
+
|
|
4
|
+
export const useReducedMotion = () => {
|
|
5
|
+
const preference = usePreferredReducedMotion()
|
|
6
|
+
|
|
7
|
+
const isMounted = ref(!getCurrentInstance())
|
|
8
|
+
if (!isMounted.value) {
|
|
9
|
+
onMounted(() => (isMounted.value = true))
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return computed(() => isMounted.value && preference.value === 'reduce')
|
|
13
|
+
}
|
|
@@ -18,6 +18,7 @@ import IconBaggageCheckedNone from '@/components/icons/IconBaggageCheckedNone.vu
|
|
|
18
18
|
import IconBaggagePersonalNone from '@/components/icons/IconBaggagePersonalNone.vue'
|
|
19
19
|
import IconBaggageSet from '@/components/icons/IconBaggageSet.vue'
|
|
20
20
|
import IconBaggageSetPlus from '@/components/icons/IconBaggageSetPlus.vue'
|
|
21
|
+
import IconBank from '@/components/icons/IconBank.vue'
|
|
21
22
|
import IconBomb from '@/components/icons/IconBomb.vue'
|
|
22
23
|
import IconBottle from '@/components/icons/IconBottle.vue'
|
|
23
24
|
import IconBroadcast from '@/components/icons/IconBroadcast.vue'
|
|
@@ -155,6 +156,7 @@ export const CustomCpIcons = {
|
|
|
155
156
|
'baggage-set': IconBaggageSet,
|
|
156
157
|
'baggage-battery': IconBaggageBattery,
|
|
157
158
|
'baggage-set-plus': IconBaggageSetPlus,
|
|
159
|
+
bank: IconBank,
|
|
158
160
|
'car-battery': IconCarBattery,
|
|
159
161
|
bomb: IconBomb,
|
|
160
162
|
bottle: IconBottle,
|