@propelinc/citrus-ui 1.0.5 → 1.3.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/README.md +39 -14
- package/dist/citrus-ui.cdn.css +1 -0
- package/dist/citrus-ui.css +1 -0
- package/dist/colors/colors.d.ts +31 -0
- package/dist/colors/theme.d.ts +3 -0
- package/dist/colors/util-classes.d.ts +11 -0
- package/dist/components/CAccordion.vue.d.ts +34 -0
- package/dist/components/CAccordionItem.vue.d.ts +39 -0
- package/dist/components/CAppBar.vue.d.ts +59 -0
- package/dist/components/CBadge.vue.d.ts +35 -0
- package/dist/components/CBottomSheet.vue.d.ts +90 -0
- package/dist/components/CButton/CButton.vue.d.ts +97 -0
- package/dist/components/CButton/types.d.ts +5 -0
- package/dist/components/CButtonStack.vue.d.ts +27 -0
- package/dist/components/CCard.vue.d.ts +53 -0
- package/dist/components/CCardFooter.vue.d.ts +20 -0
- package/dist/components/CCardHeader.vue.d.ts +22 -0
- package/dist/components/CCardSection.vue.d.ts +26 -0
- package/dist/components/CCheckbox.vue.d.ts +62 -0
- package/dist/components/CCol.vue.d.ts +30 -0
- package/dist/components/CDivider.vue.d.ts +9 -0
- package/dist/components/CDobField.vue.d.ts +60 -0
- package/dist/components/CDobSelect.vue.d.ts +50 -0
- package/dist/components/CEmailField.vue.d.ts +48 -0
- package/dist/components/CExpandTransition.vue.d.ts +29 -0
- package/dist/components/CFadeTransition.vue.d.ts +20 -0
- package/dist/components/CFileInput.vue.d.ts +50 -0
- package/dist/components/CFixedPageFooter.vue.d.ts +153 -0
- package/dist/components/CForm.vue.d.ts +44 -0
- package/dist/components/CFormFieldCounter.vue.d.ts +15 -0
- package/dist/components/CIconButton.vue.d.ts +97 -0
- package/dist/components/CLabel.vue.d.ts +36 -0
- package/dist/components/CListItem.vue.d.ts +56 -0
- package/dist/components/CListItemContent.vue.d.ts +27 -0
- package/dist/components/CListItemIcon.vue.d.ts +28 -0
- package/dist/components/CLoader.vue.d.ts +23 -0
- package/dist/components/CLogo.vue.d.ts +9 -0
- package/dist/components/CMaskedTextField.vue.d.ts +511 -0
- package/dist/components/CMenu.vue.d.ts +17 -0
- package/dist/components/CMenuItem.vue.d.ts +37 -0
- package/dist/components/CMenuLabel.vue.d.ts +20 -0
- package/dist/components/CModal.vue.d.ts +59 -0
- package/dist/components/CModalLoading.vue.d.ts +36 -0
- package/dist/components/CNotification.vue.d.ts +64 -0
- package/dist/components/CPhoneField.vue.d.ts +792 -0
- package/dist/components/CPill.vue.d.ts +41 -0
- package/dist/components/CPillGroup.vue.d.ts +39 -0
- package/dist/components/CPopup.vue.d.ts +37 -0
- package/dist/components/CProgressLinear.vue.d.ts +21 -0
- package/dist/components/CProgressRing.vue.d.ts +48 -0
- package/dist/components/CRadio.vue.d.ts +40 -0
- package/dist/components/CRadioGroup.vue.d.ts +54 -0
- package/dist/components/CRebrand.vue.d.ts +28 -0
- package/dist/components/CRow.vue.d.ts +41 -0
- package/dist/components/CSafeArea.vue.d.ts +18 -0
- package/dist/components/CSectionHeader.vue.d.ts +29 -0
- package/dist/components/CSelect.vue.d.ts +96 -0
- package/dist/components/CSkeleton.vue.d.ts +3 -0
- package/dist/components/CSkeletonLoaderCard.vue.d.ts +9 -0
- package/dist/components/CSkeletonLoaderCircle.vue.d.ts +3 -0
- package/dist/components/CSkeletonLoaderText.vue.d.ts +16 -0
- package/dist/components/CSlideFadeTransition.vue.d.ts +36 -0
- package/dist/components/CSplitInput.vue.d.ts +56 -0
- package/dist/components/CSquaredIcon.vue.d.ts +33 -0
- package/dist/components/CSsnField.vue.d.ts +798 -0
- package/dist/components/CStatusDot.vue.d.ts +10 -0
- package/dist/components/CSwitch.vue.d.ts +39 -0
- package/dist/components/CSwitchListItem.vue.d.ts +48 -0
- package/dist/components/CTextArea.vue.d.ts +96 -0
- package/dist/components/CTextField.vue.d.ts +129 -0
- package/dist/components/CTextLink.vue.d.ts +36 -0
- package/dist/components/CThirdPartyLogo.vue.d.ts +22 -0
- package/dist/components/CTimeago.vue.d.ts +12 -0
- package/dist/components/CToast.vue.d.ts +69 -0
- package/dist/components/CToastsList.vue.d.ts +3 -0
- package/dist/components/CValidationMessage.vue.d.ts +37 -0
- package/dist/components/CZipcodeField.vue.d.ts +796 -0
- package/dist/components/index.d.ts +66 -0
- package/dist/components/internal/CCloseButton.vue.d.ts +14 -0
- package/dist/composables/accessibility.d.ts +1 -0
- package/dist/composables/animation.d.ts +12 -0
- package/dist/composables/binding.d.ts +19 -0
- package/dist/composables/colors.d.ts +13 -0
- package/dist/composables/elements.d.ts +3 -0
- package/dist/composables/fields.d.ts +10 -0
- package/dist/composables/gestures.d.ts +53 -0
- package/dist/composables/i18n.d.ts +3 -0
- package/dist/composables/id.d.ts +11 -0
- package/dist/composables/input-mask.d.ts +18 -0
- package/dist/composables/router.d.ts +30 -0
- package/dist/composables/slots.d.ts +2 -0
- package/dist/composables/toast.d.ts +21 -0
- package/dist/composables/validations.d.ts +77 -0
- package/dist/icons.cdn.mjs +3 -0
- package/dist/icons.cdn.mjs.map +1 -0
- package/dist/icons.d.ts +1 -0
- package/dist/icons.mjs +6 -0
- package/dist/icons.mjs.map +1 -0
- package/dist/index.cdn.mjs +9328 -12875
- package/dist/index.cdn.mjs.map +1 -1
- package/dist/index.cdn2.mjs +55255 -0
- package/dist/index.cdn2.mjs.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.mjs +3946 -0
- package/dist/index.mjs.map +1 -0
- package/dist/plugin.d.ts +3 -0
- package/dist/services/animation.d.ts +17 -0
- package/dist/services/directives/index.d.ts +2 -0
- package/dist/services/directives/scroll-into-view.d.ts +7 -0
- package/dist/services/directives/tap-animation.d.ts +6 -0
- package/dist/services/id.d.ts +22 -0
- package/dist/services/injections/accordions.d.ts +3 -0
- package/dist/services/injections/animations.d.ts +2 -0
- package/dist/services/injections/buttons.d.ts +4 -0
- package/dist/services/injections/forms.d.ts +6 -0
- package/dist/services/injections/icon-buttons.d.ts +3 -0
- package/dist/services/injections/pills.d.ts +4 -0
- package/dist/services/injections/radio.d.ts +10 -0
- package/dist/{styles/main.css → styles.css} +8 -6
- package/dist/theme/icons.d.ts +36 -0
- package/dist/types/CForm.d.ts +12 -0
- package/dist/types/font-awesome.d.ts +5 -0
- package/dist/types.d.ts +13 -0
- package/package.json +8 -3
- package/src/colors/colors.ts +8 -3
- package/src/components/CAccordion.vue +31 -24
- package/src/components/CAccordionItem.vue +46 -45
- package/src/components/CAppBar.vue +108 -101
- package/src/components/CBadge.vue +33 -25
- package/src/components/CBottomSheet.vue +212 -199
- package/src/components/CButton/CButton.vue +135 -147
- package/src/components/CButtonStack.vue +21 -13
- package/src/components/CCard.vue +72 -69
- package/src/components/CCardFooter.vue +5 -5
- package/src/components/CCardHeader.vue +9 -7
- package/src/components/CCardSection.vue +15 -8
- package/src/components/CCheckbox.vue +68 -69
- package/src/components/CCol.vue +21 -22
- package/src/components/CDivider.vue +9 -8
- package/src/components/CDobField.vue +114 -105
- package/src/components/CDobSelect.vue +162 -164
- package/src/components/CEmailField.vue +39 -27
- package/src/components/CExpandTransition.vue +14 -17
- package/src/components/CFadeTransition.vue +3 -3
- package/src/components/CFileInput.vue +57 -50
- package/src/components/CFixedPageFooter.vue +23 -17
- package/src/components/CForm.vue +67 -60
- package/src/components/CFormFieldCounter.vue +25 -28
- package/src/components/CIconButton.vue +84 -65
- package/src/components/CLabel.vue +19 -13
- package/src/components/CListItem.vue +67 -66
- package/src/components/CListItemContent.vue +14 -16
- package/src/components/CListItemIcon.vue +18 -14
- package/src/components/CLoader.vue +47 -56
- package/src/components/CLogo.vue +13 -12
- package/src/components/CMaskedTextField.vue +80 -64
- package/src/components/CMenu.vue +14 -6
- package/src/components/CMenuItem.vue +28 -22
- package/src/components/CMenuLabel.vue +6 -5
- package/src/components/CModal.vue +76 -71
- package/src/components/CModalLoading.vue +24 -15
- package/src/components/CNotification.vue +77 -28
- package/src/components/CPhoneField.vue +34 -25
- package/src/components/CPill.vue +92 -88
- package/src/components/CPillGroup.vue +30 -21
- package/src/components/CPopup.vue +46 -37
- package/src/components/CProgressLinear.vue +17 -11
- package/src/components/CProgressRing.vue +33 -33
- package/src/components/CRadio.vue +57 -57
- package/src/components/CRadioGroup.vue +85 -72
- package/src/components/CRow.vue +22 -20
- package/src/components/CSectionHeader.vue +20 -12
- package/src/components/CSelect.vue +89 -73
- package/src/components/CSkeletonLoaderCard.vue +9 -15
- package/src/components/CSkeletonLoaderCircle.vue +1 -9
- package/src/components/CSkeletonLoaderText.vue +17 -18
- package/src/components/CSlideFadeTransition.vue +12 -34
- package/src/components/CSplitInput.vue +46 -45
- package/src/components/CSquaredIcon.vue +39 -29
- package/src/components/CSsnField.vue +48 -36
- package/src/components/CStatusDot.vue +16 -16
- package/src/components/CSwitch.vue +31 -22
- package/src/components/CSwitchListItem.vue +27 -28
- package/src/components/CTextArea.vue +116 -83
- package/src/components/CTextField.vue +194 -198
- package/src/components/CTextLink.vue +28 -25
- package/src/components/CThirdPartyLogo.vue +30 -59
- package/src/components/CToast.vue +135 -132
- package/src/components/CToastsList.vue +2 -15
- package/src/components/CValidationMessage.vue +31 -24
- package/src/components/CZipcodeField.vue +40 -27
- package/src/composables/elements.ts +1 -1
- package/src/composables/fields.ts +4 -4
- package/src/composables/router.ts +6 -5
- package/src/icons.ts +6 -0
- package/src/services/injections/buttons.ts +1 -1
- package/src/styles/_core.scss +1 -2
- package/src/styles/_reset.scss +1 -1
- package/src/types.ts +2 -0
- package/dist/index.cdn.css +0 -1
- package/dist/styles/utils.css +0 -2709
|
@@ -66,14 +66,13 @@
|
|
|
66
66
|
</sl-drawer>
|
|
67
67
|
</template>
|
|
68
68
|
|
|
69
|
-
<script lang="ts">
|
|
70
|
-
import { faXmark } from '@fortawesome/pro-regular-svg-icons';
|
|
69
|
+
<script setup lang="ts">
|
|
71
70
|
import '@shoelace-style/shoelace/dist/components/drawer/drawer.js';
|
|
72
71
|
import type SlDrawer from '@shoelace-style/shoelace/dist/components/drawer/drawer.js';
|
|
73
72
|
import type { ElementAnimation } from '@shoelace-style/shoelace/dist/utilities/animation-registry.js';
|
|
74
73
|
import { setAnimation } from '@shoelace-style/shoelace/dist/utilities/animation-registry.js';
|
|
75
|
-
import type { Ref } from 'vue';
|
|
76
|
-
import { computed,
|
|
74
|
+
import type { Ref, VNode } from 'vue';
|
|
75
|
+
import { computed, nextTick, onMounted, ref, toRef } from 'vue';
|
|
77
76
|
|
|
78
77
|
import CButtonStack from '@propelinc/citrus-ui/src/components/CButtonStack.vue';
|
|
79
78
|
import CCloseButton from '@propelinc/citrus-ui/src/components/internal/CCloseButton.vue';
|
|
@@ -122,217 +121,231 @@ function setCustomAnimation(
|
|
|
122
121
|
setAnimation(el.value, name, animation);
|
|
123
122
|
}
|
|
124
123
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
props: {
|
|
124
|
+
const props = withDefaults(
|
|
125
|
+
defineProps<{
|
|
128
126
|
/** Aria label for the bottom sheet. This is required if title is hidden */
|
|
129
|
-
ariaLabel
|
|
127
|
+
ariaLabel?: string;
|
|
130
128
|
/** Background color of the bottom sheet */
|
|
131
|
-
backgroundColor
|
|
129
|
+
backgroundColor?: string;
|
|
130
|
+
/** If true, the bottom sheet will be contained within the viewport. */
|
|
131
|
+
contained?: boolean;
|
|
132
132
|
/** Prefix for test selectors */
|
|
133
|
-
dataTest
|
|
133
|
+
dataTest?: string;
|
|
134
134
|
/** Disables the dismiss button */
|
|
135
|
-
disableDismiss
|
|
135
|
+
disableDismiss?: boolean;
|
|
136
136
|
/** Divided into header, body, and footer slots */
|
|
137
|
-
divided
|
|
137
|
+
divided?: boolean;
|
|
138
138
|
/** Fixed size, in CSS units. By default the drawer sizes itself to its contents. */
|
|
139
|
-
fixedSize
|
|
139
|
+
fixedSize?: string;
|
|
140
140
|
/** Hides the dismiss 'x' button */
|
|
141
|
-
hideDismiss
|
|
141
|
+
hideDismiss?: boolean;
|
|
142
142
|
/** Allows for hiding the entire title bar, both the title and the dismiss 'x' button */
|
|
143
|
-
hideTitle
|
|
144
|
-
/**
|
|
145
|
-
*
|
|
146
|
-
|
|
147
|
-
|
|
143
|
+
hideTitle?: boolean;
|
|
144
|
+
/**
|
|
145
|
+
* Toggles the background behind the sheet. If there's no overlay, the sheet
|
|
146
|
+
* stays open as the user interacts with background content.
|
|
147
|
+
*/
|
|
148
|
+
overlay?: boolean;
|
|
149
|
+
/**
|
|
150
|
+
* Prevents the sheet from being dismissed when tapping on the overlay. If
|
|
148
151
|
* there is no overlay then this property is ignored, as the sheet always
|
|
149
|
-
* stays open.
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
contained: { type: Boolean, default: false },
|
|
152
|
+
* stays open.
|
|
153
|
+
*/
|
|
154
|
+
persistent?: boolean;
|
|
153
155
|
/** Do not animate in the bottom sheet if it starts open. */
|
|
154
|
-
skipInitialAnimation
|
|
156
|
+
skipInitialAnimation?: boolean;
|
|
155
157
|
/** The title of the bottom sheet */
|
|
156
|
-
title
|
|
158
|
+
title?: string;
|
|
157
159
|
/** Controls whether or not the bottom sheet is showing */
|
|
158
|
-
value
|
|
159
|
-
},
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
const onAfterClose = (): void => {
|
|
222
|
-
// Reset the exit animations in case they were changed in a drag event
|
|
223
|
-
setCustomAnimation(sheet, 'drawer.hideBottom', slideDown());
|
|
224
|
-
setCustomAnimation(sheet, 'drawer.overlay.hide', fadeOut());
|
|
225
|
-
emit('closed');
|
|
226
|
-
};
|
|
160
|
+
value?: boolean;
|
|
161
|
+
}>(),
|
|
162
|
+
{
|
|
163
|
+
ariaLabel: '',
|
|
164
|
+
backgroundColor: '',
|
|
165
|
+
dataTest: 'bottom-sheet',
|
|
166
|
+
disableDismiss: false,
|
|
167
|
+
divided: false,
|
|
168
|
+
fixedSize: '',
|
|
169
|
+
hideDismiss: false,
|
|
170
|
+
hideTitle: false,
|
|
171
|
+
overlay: true,
|
|
172
|
+
persistent: false,
|
|
173
|
+
contained: false,
|
|
174
|
+
skipInitialAnimation: false,
|
|
175
|
+
title: '',
|
|
176
|
+
value: false,
|
|
177
|
+
}
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
const emit = defineEmits<{
|
|
181
|
+
input: [value: boolean];
|
|
182
|
+
opened: [];
|
|
183
|
+
closed: [];
|
|
184
|
+
}>();
|
|
185
|
+
|
|
186
|
+
defineSlots<{
|
|
187
|
+
header?: () => VNode[];
|
|
188
|
+
image?: () => VNode[];
|
|
189
|
+
body?: () => VNode[];
|
|
190
|
+
footer?: () => VNode[];
|
|
191
|
+
}>();
|
|
192
|
+
|
|
193
|
+
// NOTE(slanden): Temporarily disabling because it's causing a lot of errors
|
|
194
|
+
// in the console - uses from CMS aren't specifying aria-label.
|
|
195
|
+
// watchEffect(() => {
|
|
196
|
+
// if (props.hideTitle && !props.ariaLabel) {
|
|
197
|
+
// console.error('CBottomSheet: aria-label is required when title is hidden');
|
|
198
|
+
// }
|
|
199
|
+
// });
|
|
200
|
+
|
|
201
|
+
// value: Value provided using props which can open/close the bottom sheet.
|
|
202
|
+
// internalValue: Tracks the open/closed state and lets the bottom sheet open and close even if
|
|
203
|
+
// the external value doesn't change.
|
|
204
|
+
// animatedValue: Same as internalValue but starts at false so the bottom sheet animates if it
|
|
205
|
+
// starts in an open state.
|
|
206
|
+
const valueRef = toRef(props, 'value');
|
|
207
|
+
const internalValue = useInternalValue(valueRef, { onChange: (value) => emit('input', value) });
|
|
208
|
+
const mounted = ref(false);
|
|
209
|
+
const animatedValue = computed(() => {
|
|
210
|
+
// To animate in the bottom sheet we mount the component with the sheet closed.
|
|
211
|
+
if (!props.skipInitialAnimation && !mounted.value) {
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
return internalValue.value;
|
|
215
|
+
});
|
|
216
|
+
const { cssColor: backgroundCssColor } = useCssColor(() => props.backgroundColor);
|
|
217
|
+
onMounted(async () => {
|
|
218
|
+
// The bottom sheet does not animate unless we wait a tick. We don't know exactly why this
|
|
219
|
+
// is necessary.
|
|
220
|
+
await nextTick();
|
|
221
|
+
mounted.value = true;
|
|
222
|
+
});
|
|
227
223
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
);
|
|
260
|
-
handleDismiss();
|
|
261
|
-
} else {
|
|
262
|
-
/**
|
|
263
|
-
* This is when the user's drag event fails to trigger a dismissal
|
|
264
|
-
* We need to restore the sheet to its original position
|
|
265
|
-
*/
|
|
266
|
-
const start = 1 - getTransformDistanceRatio(dragDistance.value!.y);
|
|
267
|
-
const slideUpAnimation = slideUp({ start });
|
|
268
|
-
const fadeInAnimation = fadeIn({ start });
|
|
269
|
-
|
|
270
|
-
// Here we imperatively animate the sheet and overlay back to their original positions
|
|
271
|
-
panel.value?.animate(slideUpAnimation.keyframes, slideUpAnimation.options);
|
|
272
|
-
overlay.value?.animate(fadeInAnimation.keyframes, fadeInAnimation.options);
|
|
273
|
-
}
|
|
274
|
-
},
|
|
275
|
-
});
|
|
224
|
+
const sheet = ref<SlDrawer | null>(null);
|
|
225
|
+
const {
|
|
226
|
+
panel,
|
|
227
|
+
overlay: overlayPart,
|
|
228
|
+
body: bodyPart,
|
|
229
|
+
} = useShoelaceShadowParts(sheet, ['panel', 'overlay', 'body']);
|
|
230
|
+
useScrollBoundary(bodyPart);
|
|
231
|
+
|
|
232
|
+
// NOTE(mohan): There are three parts to the bottom sheet animation:
|
|
233
|
+
// 1. CSS variables. These are used when we want to set the exact height and
|
|
234
|
+
// opacity, i.e. when the user is actively moving the sheet.
|
|
235
|
+
// 2. The built-in Shoelace show and hide animations. If a user has swiped
|
|
236
|
+
// the sheet away, we calculate the exact animation that will smoothly
|
|
237
|
+
// continue the swipe and then dismiss the shoelace drawer.
|
|
238
|
+
// 3. Manually-called web animations. These are used when the sheet is being
|
|
239
|
+
// restored to its original position after a drag that was not fast or
|
|
240
|
+
// long enough to count as a swipe.
|
|
241
|
+
setCustomAnimation(sheet, 'drawer.showBottom', slideUp());
|
|
242
|
+
setCustomAnimation(sheet, 'drawer.overlay.show', fadeIn());
|
|
243
|
+
setCustomAnimation(sheet, 'drawer.hideBottom', slideDown());
|
|
244
|
+
setCustomAnimation(sheet, 'drawer.overlay.hide', fadeOut());
|
|
245
|
+
|
|
246
|
+
const handleDismiss = (): void => {
|
|
247
|
+
internalValue.value = false;
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
const onRequestClose = (event: Event): void => {
|
|
251
|
+
if (props.persistent) {
|
|
252
|
+
event.preventDefault();
|
|
253
|
+
}
|
|
254
|
+
};
|
|
276
255
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
onAfterClose,
|
|
331
|
-
sheet,
|
|
332
|
-
transformDistance,
|
|
333
|
-
};
|
|
256
|
+
const onAfterClose = (): void => {
|
|
257
|
+
// Reset the exit animations in case they were changed in a drag event
|
|
258
|
+
setCustomAnimation(sheet, 'drawer.hideBottom', slideDown());
|
|
259
|
+
setCustomAnimation(sheet, 'drawer.overlay.hide', fadeOut());
|
|
260
|
+
emit('closed');
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Helper function to calculate the distance ratio of the sheet's transform.
|
|
265
|
+
*/
|
|
266
|
+
const getTransformDistanceRatio = (distance: number): number => {
|
|
267
|
+
return distance / (panel.value?.clientHeight ?? SHEET_HEIGHT_FALLBACK);
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
const { dragDistance } = useDragListener(panel, {
|
|
271
|
+
onDragEnd: async ({ distance, velocity }) => {
|
|
272
|
+
const shouldDismiss =
|
|
273
|
+
!props.persistent && (distance.y > MIN_SWIPE_DISTANCE || velocity.y > MIN_SWIPE_VELOCITY);
|
|
274
|
+
|
|
275
|
+
if (shouldDismiss) {
|
|
276
|
+
const remainingDismissDistance = panel.value!.clientHeight - dragDistance.value!.y;
|
|
277
|
+
const dismissDuration = Math.max(
|
|
278
|
+
remainingDismissDistance / Math.max(velocity.y, MIN_DISMISS_VELOCITY),
|
|
279
|
+
MIN_DISMISS_DURATION
|
|
280
|
+
);
|
|
281
|
+
const dismissStart = getTransformDistanceRatio(distance.y);
|
|
282
|
+
|
|
283
|
+
// Here we set the custom animations to complete the dismissal animation smoothly
|
|
284
|
+
// from the point where the user ended their drag event.
|
|
285
|
+
setCustomAnimation(
|
|
286
|
+
sheet,
|
|
287
|
+
'drawer.hideBottom',
|
|
288
|
+
slideDown({ start: dismissStart, duration: dismissDuration })
|
|
289
|
+
);
|
|
290
|
+
setCustomAnimation(
|
|
291
|
+
sheet,
|
|
292
|
+
'drawer.overlay.hide',
|
|
293
|
+
fadeOut({ start: dismissStart, duration: dismissDuration })
|
|
294
|
+
);
|
|
295
|
+
handleDismiss();
|
|
296
|
+
} else {
|
|
297
|
+
/**
|
|
298
|
+
* This is when the user's drag event fails to trigger a dismissal
|
|
299
|
+
* We need to restore the sheet to its original position
|
|
300
|
+
*/
|
|
301
|
+
const start = 1 - getTransformDistanceRatio(dragDistance.value!.y);
|
|
302
|
+
const slideUpAnimation = slideUp({ start });
|
|
303
|
+
const fadeInAnimation = fadeIn({ start });
|
|
304
|
+
|
|
305
|
+
// Here we imperatively animate the sheet and overlay back to their original positions
|
|
306
|
+
panel.value?.animate(slideUpAnimation.keyframes, slideUpAnimation.options);
|
|
307
|
+
overlayPart.value?.animate(fadeInAnimation.keyframes, fadeInAnimation.options);
|
|
308
|
+
}
|
|
334
309
|
},
|
|
335
310
|
});
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* The distance that the sheet has been currently dragged
|
|
314
|
+
*/
|
|
315
|
+
const transformDistance = useElasticClamp(
|
|
316
|
+
computed(() => dragDistance.value?.y ?? 0),
|
|
317
|
+
computed(() => ({
|
|
318
|
+
min: -DRAG_CLAMP_DISTANCE,
|
|
319
|
+
max: props.persistent ? DRAG_CLAMP_DISTANCE : undefined,
|
|
320
|
+
}))
|
|
321
|
+
);
|
|
322
|
+
|
|
323
|
+
const transformDistanceRatio = computed(() => getTransformDistanceRatio(transformDistance.value));
|
|
324
|
+
|
|
325
|
+
const panelTransform = computed(() => `translateY(${transformDistance.value}px)`);
|
|
326
|
+
|
|
327
|
+
const overlayOpacity = computed(() => {
|
|
328
|
+
const result = 1 - transformDistanceRatio.value;
|
|
329
|
+
|
|
330
|
+
if (isNaN(result)) {
|
|
331
|
+
return 1;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
return result;
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
// NOTE(mohan): We show data-test attributes only when the sheet is open.
|
|
338
|
+
// This helps simplify testing assertions.
|
|
339
|
+
const getDataTestAttr = (suffix?: string): string | null => {
|
|
340
|
+
const dataTest = suffix ? `${props.dataTest}-${suffix}` : props.dataTest;
|
|
341
|
+
return internalValue.value ? dataTest : null;
|
|
342
|
+
};
|
|
343
|
+
|
|
344
|
+
const footerHasContent = useSlotHasContent('footer');
|
|
345
|
+
|
|
346
|
+
const isDismissVisible = computed(
|
|
347
|
+
() => (!props.persistent && !props.hideDismiss) || props.disableDismiss
|
|
348
|
+
);
|
|
336
349
|
</script>
|
|
337
350
|
|
|
338
351
|
<style lang="scss" scoped>
|