@demos-europe/demosplan-ui 0.0.1
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/LICENSE +21 -0
- package/buildTokens.js +59 -0
- package/components/DpButton/DpButton.stories.mdx +136 -0
- package/components/DpButton/DpButton.vue +118 -0
- package/components/DpDetails/DpDetails.stories.mdx +55 -0
- package/components/DpDetails/DpDetails.vue +58 -0
- package/components/DpIcon/DpIcon.stories.mdx +396 -0
- package/components/DpIcon/DpIcon.vue +51 -0
- package/components/DpIcon/util/iconVariables.js +148 -0
- package/components/DpInput/DpInput.stories.mdx +127 -0
- package/components/DpInput/DpInput.vue +284 -0
- package/components/DpLabel/DpLabel.stories.mdx +103 -0
- package/components/DpLabel/DpLabel.vue +112 -0
- package/components/DpLoading/DpLoading.stories.mdx +63 -0
- package/components/DpLoading/DpLoading.vue +63 -0
- package/components/core/DpAccordion.vue +108 -0
- package/components/core/DpAnonymizeText.vue +136 -0
- package/components/core/DpAutocomplete.vue +133 -0
- package/components/core/DpBulkEditHeader.vue +53 -0
- package/components/core/DpButtonIcon.vue +47 -0
- package/components/core/DpButtonRow.vue +155 -0
- package/components/core/DpCard.vue +54 -0
- package/components/core/DpChangeStateAtDate.vue +223 -0
- package/components/core/DpCheckboxGroup.vue +93 -0
- package/components/core/DpContextualHelp.vue +54 -0
- package/components/core/DpCopyPasteButton.vue +47 -0
- package/components/core/DpDashboardTaskCard.vue +123 -0
- package/components/core/DpDataTable/DataTableSearch.js +44 -0
- package/components/core/DpDataTable/DpColumnSelector.vue +133 -0
- package/components/core/DpDataTable/DpDataTable.vue +647 -0
- package/components/core/DpDataTable/DpDataTableExtended.vue +377 -0
- package/components/core/DpDataTable/DpResizeHandle.vue +37 -0
- package/components/core/DpDataTable/DpSelectPageItemCount.vue +70 -0
- package/components/core/DpDataTable/DpTableHeader.vue +197 -0
- package/components/core/DpDataTable/DpTableRow.vue +355 -0
- package/components/core/DpDataTable/DpWrapTrigger.vue +48 -0
- package/components/core/DpDataTable/lib/ResizableColumns.js +83 -0
- package/components/core/DpEditableList.vue +161 -0
- package/components/core/DpEditor/DpBoilerPlate.vue +140 -0
- package/components/core/DpEditor/DpBoilerPlateModal.vue +166 -0
- package/components/core/DpEditor/DpEditor.vue +1281 -0
- package/components/core/DpEditor/DpLinkModal.vue +117 -0
- package/components/core/DpEditor/DpRecommendationModal/DpInsertableRecommendation.vue +137 -0
- package/components/core/DpEditor/DpRecommendationModal.vue +283 -0
- package/components/core/DpEditor/DpResizableImage.vue +121 -0
- package/components/core/DpEditor/DpUploadModal.vue +121 -0
- package/components/core/DpEditor/libs/Decoration.js +66 -0
- package/components/core/DpEditor/libs/SegmentRangeChangePlugin.js +35 -0
- package/components/core/DpEditor/libs/editorAnonymize.js +66 -0
- package/components/core/DpEditor/libs/editorBuildSuggestion.js +269 -0
- package/components/core/DpEditor/libs/editorCustomDelete.js +32 -0
- package/components/core/DpEditor/libs/editorCustomImage.js +100 -0
- package/components/core/DpEditor/libs/editorCustomInsert.js +32 -0
- package/components/core/DpEditor/libs/editorCustomLink.js +46 -0
- package/components/core/DpEditor/libs/editorCustomMark.js +32 -0
- package/components/core/DpEditor/libs/editorInsertAtCursorPos.js +41 -0
- package/components/core/DpEditor/libs/editorObscure.js +60 -0
- package/components/core/DpEditor/libs/editorUnAnonymize.js +56 -0
- package/components/core/DpEditor/libs/handleWordPaste.js +360 -0
- package/components/core/DpEditor/libs/preventDrop.js +31 -0
- package/components/core/DpEditor/libs/preventKeyboardInput.js +27 -0
- package/components/core/DpEditor/libs/preventPaste.js +28 -0
- package/components/core/DpFlyout.vue +119 -0
- package/components/core/DpInlineNotification.vue +116 -0
- package/components/core/DpModal.vue +208 -0
- package/components/core/DpObscure.vue +29 -0
- package/components/core/DpPager.vue +139 -0
- package/components/core/DpProgressBar.vue +67 -0
- package/components/core/DpRegisterFlyout.vue +58 -0
- package/components/core/DpResettableInput.vue +140 -0
- package/components/core/DpSkeletonBox.vue +32 -0
- package/components/core/DpSlidebar.vue +86 -0
- package/components/core/DpSlidingPagination.vue +45 -0
- package/components/core/DpSplitButton.vue +77 -0
- package/components/core/DpSwitcher.vue +62 -0
- package/components/core/DpTableCardList/DpTableCard.vue +61 -0
- package/components/core/DpTableCardList/DpTableCardListHeader.vue +83 -0
- package/components/core/DpTabs/DpTab.vue +52 -0
- package/components/core/DpTabs/DpTabs.vue +165 -0
- package/components/core/DpTextWrapper.vue +65 -0
- package/components/core/DpToggleForm.vue +72 -0
- package/components/core/DpTooltipIcon.vue +52 -0
- package/components/core/DpTransitionExpand.vue +87 -0
- package/components/core/DpTreeList/DpTreeList.vue +334 -0
- package/components/core/DpTreeList/DpTreeListCheckbox.vue +79 -0
- package/components/core/DpTreeList/DpTreeListNode.vue +348 -0
- package/components/core/DpTreeList/DpTreeListToggle.vue +71 -0
- package/components/core/DpTreeList/utils/constants.js +14 -0
- package/components/core/DpUpload/DpUpload.vue +223 -0
- package/components/core/DpUpload/DpUploadFiles.vue +269 -0
- package/components/core/DpUpload/DpUploadedFile.vue +80 -0
- package/components/core/DpUpload/DpUploadedFileList.vue +56 -0
- package/components/core/DpUpload/utils/GetFileIdsByHash.js +42 -0
- package/components/core/DpUpload/utils/UppyTranslations.js +31 -0
- package/components/core/DpVideoPlayer.vue +115 -0
- package/components/core/HeightLimit.vue +121 -0
- package/components/core/MultistepNav.vue +89 -0
- package/components/core/form/DpCheckbox.vue +108 -0
- package/components/core/form/DpDateRangePicker.vue +186 -0
- package/components/core/form/DpDatepicker.vue +160 -0
- package/components/core/form/DpDatetimePicker.vue +194 -0
- package/components/core/form/DpFormRow.vue +79 -0
- package/components/core/form/DpMultiselect.vue +164 -0
- package/components/core/form/DpRadio.vue +128 -0
- package/components/core/form/DpSearchField.vue +110 -0
- package/components/core/form/DpSelect.vue +149 -0
- package/components/core/form/DpTextArea.vue +152 -0
- package/components/core/form/DpTimePicker.vue +374 -0
- package/components/core/form/DpToggle.vue +78 -0
- package/components/core/index.js +132 -0
- package/components/core/notify/DpNotifyContainer.vue +122 -0
- package/components/core/notify/DpNotifyMessage.vue +95 -0
- package/components/core/shared/DpStickyElement.vue +95 -0
- package/components/index.js +24 -0
- package/components/shared/translations.js +15 -0
- package/directives/CleanHtml/CleanHtml.js +50 -0
- package/directives/CleanHtml/CleanHtml.stories.mdx +64 -0
- package/directives/Tooltip/Tooltip.js +40 -0
- package/directives/Tooltip/Tooltip.stories.mdx +42 -0
- package/directives/index.js +17 -0
- package/lib/index.js +14 -0
- package/lib/prefixClass.js +47 -0
- package/mixins/index.js +14 -0
- package/mixins/prefixClassMixin.js +22 -0
- package/package.json +52 -0
- package/shared/props.js +86 -0
- package/style/index.css +7 -0
- package/tailwind.config.js +24 -0
- package/tokens/color.json +358 -0
- package/tokens/color.stories.mdx +45 -0
- package/tokens/fontSize.json +100 -0
- package/tokens/space.json +33 -0
- package/utils/lengthHint.js +69 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
<license>
|
|
2
|
+
(c) 2010-present DEMOS E-Partizipation GmbH.
|
|
3
|
+
|
|
4
|
+
This file is part of the package @demos-europe/demosplan-ui,
|
|
5
|
+
for more information see the license file.
|
|
6
|
+
|
|
7
|
+
All rights reserved
|
|
8
|
+
</license>
|
|
9
|
+
|
|
10
|
+
<template>
|
|
11
|
+
<div>
|
|
12
|
+
<ul
|
|
13
|
+
class="flex space-inline-m list-style-none border--bottom"
|
|
14
|
+
role="tablist">
|
|
15
|
+
<li
|
|
16
|
+
v-for="(tab, idx) in tabs"
|
|
17
|
+
:key="`tab:${idx}`"
|
|
18
|
+
:class="{ 'is-active': tab.isActive }"
|
|
19
|
+
style="margin-bottom: -1px;">
|
|
20
|
+
<button
|
|
21
|
+
role="tab"
|
|
22
|
+
class="btn--blank o-link--default u-pb-0_5 border--bottom"
|
|
23
|
+
:class="[
|
|
24
|
+
tab.isActive ? 'color-ui-interactive border-interactive' : 'border--none color-ui-dimmed-text',
|
|
25
|
+
tabSize === 'large' ? 'font-size-larger' : 'font-size-large'
|
|
26
|
+
]"
|
|
27
|
+
:aria-selected="tab.isActive"
|
|
28
|
+
:aria-controls="tab.id"
|
|
29
|
+
:data-cy="tab.id"
|
|
30
|
+
@click.prevent="handleTabClick(tab.id)">
|
|
31
|
+
{{ tab.label }}
|
|
32
|
+
<span
|
|
33
|
+
v-if="tab.suffix"
|
|
34
|
+
v-cleanhtml="tab.suffix" />
|
|
35
|
+
</button>
|
|
36
|
+
</li>
|
|
37
|
+
</ul>
|
|
38
|
+
<div>
|
|
39
|
+
<slot />
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
</template>
|
|
43
|
+
|
|
44
|
+
<script>
|
|
45
|
+
import { CleanHtml } from 'demosplan-ui/directives'
|
|
46
|
+
|
|
47
|
+
export default {
|
|
48
|
+
name: 'DpTabs',
|
|
49
|
+
|
|
50
|
+
directives: {
|
|
51
|
+
cleanhtml: CleanHtml
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
model: {
|
|
55
|
+
prop: 'activeId',
|
|
56
|
+
event: 'change'
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
props: {
|
|
60
|
+
activeId: {
|
|
61
|
+
type: String,
|
|
62
|
+
required: false,
|
|
63
|
+
default: null
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
tabSize: {
|
|
67
|
+
type: String,
|
|
68
|
+
required: false,
|
|
69
|
+
default: 'large',
|
|
70
|
+
validator: (prop) => ['medium', 'large'].includes(prop)
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Active tab state may be persisted via an Url fragment. Also, ab clicks are pushed
|
|
75
|
+
* to the browser history to enable state change when browser navigation is used.
|
|
76
|
+
*/
|
|
77
|
+
useUrlFragment: {
|
|
78
|
+
type: Boolean,
|
|
79
|
+
required: false,
|
|
80
|
+
default: false
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
data: () => ({
|
|
85
|
+
tabs: []
|
|
86
|
+
}),
|
|
87
|
+
|
|
88
|
+
computed: {
|
|
89
|
+
tabIds () {
|
|
90
|
+
return this.tabs.map(tab => tab.id)
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
methods: {
|
|
95
|
+
/**
|
|
96
|
+
* When users click the back button, the tabs should behave accordingly.
|
|
97
|
+
*/
|
|
98
|
+
handleHashChange () {
|
|
99
|
+
const hash = window.location.hash.slice(1)
|
|
100
|
+
|
|
101
|
+
if (this.isTabId(hash)) {
|
|
102
|
+
this.setActiveTab(hash)
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
handleTabClick (id) {
|
|
107
|
+
this.$emit('change', id)
|
|
108
|
+
this.setActiveTab(id)
|
|
109
|
+
|
|
110
|
+
if (this.useUrlFragment) {
|
|
111
|
+
history.pushState(null, null, `#${id}`)
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Check if a given string is a valid tab id.
|
|
117
|
+
* @param id
|
|
118
|
+
* @return {boolean}
|
|
119
|
+
*/
|
|
120
|
+
isTabId (id) {
|
|
121
|
+
return this.tabs.map(tab => tab.id).includes(id)
|
|
122
|
+
},
|
|
123
|
+
|
|
124
|
+
setActiveTab (id) {
|
|
125
|
+
this.tabs.forEach(tab => {
|
|
126
|
+
tab.isActive = (tab.id === id)
|
|
127
|
+
})
|
|
128
|
+
},
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* If a hash specifies a tab, activate it. If a tab is activated
|
|
132
|
+
* via prop, activate that tab. Fallback to the first tab.
|
|
133
|
+
*/
|
|
134
|
+
setInitialTab () {
|
|
135
|
+
const hash = window.location.hash.slice(1)
|
|
136
|
+
|
|
137
|
+
if (this.useUrlFragment && this.isTabId(hash)) {
|
|
138
|
+
this.setActiveTab(hash)
|
|
139
|
+
} else if (this.activeId) {
|
|
140
|
+
this.setActiveTab(this.activeId)
|
|
141
|
+
} else {
|
|
142
|
+
this.tabs[0].isActive = true
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
|
|
147
|
+
created () {
|
|
148
|
+
this.tabs = this.$children
|
|
149
|
+
},
|
|
150
|
+
|
|
151
|
+
mounted () {
|
|
152
|
+
this.setInitialTab()
|
|
153
|
+
|
|
154
|
+
if (this.useUrlFragment) {
|
|
155
|
+
window.addEventListener('hashchange', this.handleHashChange)
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
|
|
159
|
+
beforeDestroy () {
|
|
160
|
+
if (this.useUrlFragment) {
|
|
161
|
+
window.removeEventListener('hashchange', this.handleHashChange)
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
</script>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<license>
|
|
2
|
+
(c) 2010-present DEMOS E-Partizipation GmbH.
|
|
3
|
+
|
|
4
|
+
This file is part of the package @demos-europe/demosplan-ui,
|
|
5
|
+
for more information see the license file.
|
|
6
|
+
|
|
7
|
+
All rights reserved
|
|
8
|
+
</license>
|
|
9
|
+
|
|
10
|
+
<script>
|
|
11
|
+
import { DpLoading } from 'demosplan-ui/components'
|
|
12
|
+
|
|
13
|
+
export default {
|
|
14
|
+
name: 'DpTextWrapper',
|
|
15
|
+
|
|
16
|
+
functional: true,
|
|
17
|
+
|
|
18
|
+
props: {
|
|
19
|
+
text: {
|
|
20
|
+
type: String,
|
|
21
|
+
default: ''
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
data: {
|
|
25
|
+
type: Object,
|
|
26
|
+
default: () => ({})
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
/**
|
|
30
|
+
* Rendering dynamic elements is done by tricking the renderer into
|
|
31
|
+
* rendering the content of a made up template.
|
|
32
|
+
*
|
|
33
|
+
* This works because vue recreates components on the fly if they are
|
|
34
|
+
* not globally registered. Thus, creating the minicomponent `immediateComponent`
|
|
35
|
+
* causes its template (the passed text) to be reinterpreted every time.
|
|
36
|
+
*
|
|
37
|
+
* Since any component will rerender if any of its props is changed,
|
|
38
|
+
* changing the text property on a <dp-text-wrapper>-Instance will
|
|
39
|
+
* cause it to re-evaluate its contents.
|
|
40
|
+
*
|
|
41
|
+
* CAVEATS:
|
|
42
|
+
*
|
|
43
|
+
* While this is technically able to re-evaluate any html code inside text
|
|
44
|
+
* and on that way instantiate any Vue component inside, this will - as it
|
|
45
|
+
* is set up right now - only work for components which are registered to
|
|
46
|
+
* the global Vue object or to the currently calling parent component.
|
|
47
|
+
*
|
|
48
|
+
* @param h
|
|
49
|
+
* @param context
|
|
50
|
+
* @return {*}
|
|
51
|
+
*/
|
|
52
|
+
render (h, context) {
|
|
53
|
+
const immediateComponent = {
|
|
54
|
+
template: `<div class='text-wrapper width-fit-content' data-cy='textWrapper'>${context.props.text}</div>`,
|
|
55
|
+
data () {
|
|
56
|
+
return context.props.data
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return (context.props.text)
|
|
61
|
+
? h(immediateComponent)
|
|
62
|
+
: h(DpLoading, { props: { isLoading: true } })
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
</script>
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
<license>
|
|
2
|
+
(c) 2010-present DEMOS E-Partizipation GmbH.
|
|
3
|
+
|
|
4
|
+
This file is part of the package @demos-europe/demosplan-ui,
|
|
5
|
+
for more information see the license file.
|
|
6
|
+
|
|
7
|
+
All rights reserved
|
|
8
|
+
</license>
|
|
9
|
+
|
|
10
|
+
<template>
|
|
11
|
+
<dp-accordion
|
|
12
|
+
ref="accordion"
|
|
13
|
+
:title="title">
|
|
14
|
+
<!-- this is where the form fields go -->
|
|
15
|
+
<slot />
|
|
16
|
+
|
|
17
|
+
<slot name="buttons">
|
|
18
|
+
<dp-button-row
|
|
19
|
+
primary
|
|
20
|
+
secondary
|
|
21
|
+
@primary-action="dpValidateAction(formId, save, false)"
|
|
22
|
+
@secondary-action="abort" />
|
|
23
|
+
</slot>
|
|
24
|
+
</dp-accordion>
|
|
25
|
+
</template>
|
|
26
|
+
|
|
27
|
+
<script>
|
|
28
|
+
import DpAccordion from './DpAccordion'
|
|
29
|
+
import { dpValidateMixin } from 'demosplan-utils/mixins'
|
|
30
|
+
|
|
31
|
+
export default {
|
|
32
|
+
name: 'DpToggleForm',
|
|
33
|
+
|
|
34
|
+
components: {
|
|
35
|
+
DpAccordion,
|
|
36
|
+
DpButtonRow: () => import('./DpButtonRow')
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
mixins: [dpValidateMixin],
|
|
40
|
+
|
|
41
|
+
props: {
|
|
42
|
+
formId: {
|
|
43
|
+
type: String,
|
|
44
|
+
default: ''
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
title: {
|
|
48
|
+
type: String,
|
|
49
|
+
default: ''
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
methods: {
|
|
54
|
+
abort () {
|
|
55
|
+
if (this.formId !== '') {
|
|
56
|
+
document.querySelector(`form#${this.formId}`).reset()
|
|
57
|
+
} else {
|
|
58
|
+
this.$emit('form-abort')
|
|
59
|
+
}
|
|
60
|
+
this.$refs.accordion.toggle()
|
|
61
|
+
},
|
|
62
|
+
|
|
63
|
+
save () {
|
|
64
|
+
if (this.formId !== '') {
|
|
65
|
+
document.querySelector(`form#${this.formId}`).submit()
|
|
66
|
+
} else {
|
|
67
|
+
this.$emit('form-save')
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
</script>
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<license>
|
|
2
|
+
(c) 2010-present DEMOS E-Partizipation GmbH.
|
|
3
|
+
|
|
4
|
+
This file is part of the package @demos-europe/demosplan-ui,
|
|
5
|
+
for more information see the license file.
|
|
6
|
+
|
|
7
|
+
All rights reserved
|
|
8
|
+
</license>
|
|
9
|
+
|
|
10
|
+
<documentation>
|
|
11
|
+
<!--
|
|
12
|
+
It renders an fontawesome Icon with a tooltip
|
|
13
|
+
-->
|
|
14
|
+
<usage>
|
|
15
|
+
<dp-tooltip-icon
|
|
16
|
+
icon="fa-trash"
|
|
17
|
+
text="some translated String"
|
|
18
|
+
large="true|false (adds the class fa-lg)"
|
|
19
|
+
></dp-tooltip-icon>
|
|
20
|
+
</usage>
|
|
21
|
+
</documentation>
|
|
22
|
+
|
|
23
|
+
<template>
|
|
24
|
+
<i
|
|
25
|
+
class="fa"
|
|
26
|
+
:class="[icon, large ? 'fa-lg' : '']"
|
|
27
|
+
v-tooltip="text" />
|
|
28
|
+
</template>
|
|
29
|
+
|
|
30
|
+
<script>
|
|
31
|
+
export default {
|
|
32
|
+
name: 'DpTooltipIcon',
|
|
33
|
+
|
|
34
|
+
props: {
|
|
35
|
+
icon: {
|
|
36
|
+
required: true,
|
|
37
|
+
type: String
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
text: {
|
|
41
|
+
required: true,
|
|
42
|
+
type: String
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
large: {
|
|
46
|
+
required: false,
|
|
47
|
+
type: Boolean,
|
|
48
|
+
default: false
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
</script>
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
<license>
|
|
2
|
+
(c) 2010-present DEMOS E-Partizipation GmbH.
|
|
3
|
+
|
|
4
|
+
This file is part of the package @demos-europe/demosplan-ui,
|
|
5
|
+
for more information see the license file.
|
|
6
|
+
|
|
7
|
+
All rights reserved
|
|
8
|
+
</license>
|
|
9
|
+
|
|
10
|
+
<script>
|
|
11
|
+
export default {
|
|
12
|
+
name: 'DpTransitionExpand',
|
|
13
|
+
|
|
14
|
+
functional: true,
|
|
15
|
+
|
|
16
|
+
render (createElement, context) {
|
|
17
|
+
const data = {
|
|
18
|
+
props: {
|
|
19
|
+
name: 'expand'
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
on: {
|
|
23
|
+
afterEnter (element) {
|
|
24
|
+
element.style.height = 'auto'
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
enter (element) {
|
|
28
|
+
element.style.width = getComputedStyle(element).width
|
|
29
|
+
element.style.position = 'absolute'
|
|
30
|
+
element.style.visibility = 'hidden'
|
|
31
|
+
element.style.height = 'auto'
|
|
32
|
+
|
|
33
|
+
const height = getComputedStyle(element).height
|
|
34
|
+
|
|
35
|
+
element.style.width = null
|
|
36
|
+
element.style.position = null
|
|
37
|
+
element.style.visibility = null
|
|
38
|
+
element.style.height = 0
|
|
39
|
+
|
|
40
|
+
/*
|
|
41
|
+
* Force repaint to make sure the
|
|
42
|
+
* animation is triggered correctly.
|
|
43
|
+
*/
|
|
44
|
+
/* eslint-disable no-unused-expressions */
|
|
45
|
+
getComputedStyle(element).height
|
|
46
|
+
|
|
47
|
+
/*
|
|
48
|
+
* Trigger the animation.
|
|
49
|
+
* We use `requestAnimationFrame` because we need
|
|
50
|
+
* to make sure the browser has finished
|
|
51
|
+
* painting after setting the `height`
|
|
52
|
+
* to `0` in the line above.
|
|
53
|
+
*/
|
|
54
|
+
requestAnimationFrame(() => {
|
|
55
|
+
element.style.height = height
|
|
56
|
+
})
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
leave (element) {
|
|
60
|
+
element.style.height = getComputedStyle(element).height
|
|
61
|
+
|
|
62
|
+
getComputedStyle(element).height
|
|
63
|
+
|
|
64
|
+
requestAnimationFrame(() => {
|
|
65
|
+
element.style.height = 0
|
|
66
|
+
})
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return createElement('transition', data, context.children)
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
</script>
|
|
75
|
+
|
|
76
|
+
<!--
|
|
77
|
+
This is currently not supported but will accelerate the animation
|
|
78
|
+
once the <style> part of Vue single file templates is also included in the build.
|
|
79
|
+
-->
|
|
80
|
+
<style scoped>
|
|
81
|
+
* {
|
|
82
|
+
will-change: height;
|
|
83
|
+
transform: translateZ(0);
|
|
84
|
+
backface-visibility: hidden;
|
|
85
|
+
perspective: 1000px;
|
|
86
|
+
}
|
|
87
|
+
</style>
|