routie dev init since i didn't adhere to any proper guidance up until now
This commit is contained in:
+221
@@ -0,0 +1,221 @@
|
||||
@layer vuetify-components {
|
||||
.v-snackbar {
|
||||
justify-content: center;
|
||||
z-index: 10000;
|
||||
margin: 8px;
|
||||
margin-inline-end: calc(8px + var(--v-scrollbar-offset));
|
||||
padding: var(--v-layout-top) var(--v-layout-right) var(--v-layout-bottom) var(--v-layout-left);
|
||||
--v-snackbar-current-offset: var(--v-snackbar-offset);
|
||||
transform: translateY(calc(var(--v-snackbar-direction) * (var(--v-snackbar-current-offset) + var(--v-snackbar-mobile-notch, 0px))));
|
||||
transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
.v-snackbar:not(.v-snackbar--center):not(.v-snackbar--top) {
|
||||
align-items: flex-end;
|
||||
}
|
||||
.v-snackbar__wrapper {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
max-width: 672px;
|
||||
min-height: 48px;
|
||||
min-width: 344px;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
transition: 0.35s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
transition-property: height, width;
|
||||
}
|
||||
.v-snackbar__wrapper {
|
||||
border-radius: 4px;
|
||||
}
|
||||
.v-snackbar--variant-plain, .v-snackbar--variant-outlined, .v-snackbar--variant-text, .v-snackbar--variant-tonal {
|
||||
background: transparent;
|
||||
color: inherit;
|
||||
}
|
||||
.v-snackbar--variant-plain {
|
||||
opacity: 0.62;
|
||||
}
|
||||
.v-snackbar--variant-plain:focus, .v-snackbar--variant-plain:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
.v-snackbar--variant-plain .v-snackbar__overlay {
|
||||
display: none;
|
||||
}
|
||||
.v-snackbar--variant-elevated, .v-snackbar--variant-flat {
|
||||
background: rgb(var(--v-theme-surface-variant));
|
||||
color: rgb(var(--v-theme-on-surface-variant));
|
||||
}
|
||||
.v-snackbar--variant-elevated {
|
||||
box-shadow: 0px 1px 2px 0px rgba(var(--v-shadow-color), var(--v-shadow-key-opacity, 0.3)), 0px 2px 6px 2px rgba(var(--v-shadow-color), var(--v-shadow-ambient-opacity, 0.15));
|
||||
--v-elevation-overlay: color-mix(in srgb, var(--v-elevation-overlay-color) 4%, transparent);
|
||||
}
|
||||
.v-snackbar--variant-flat {
|
||||
box-shadow: 0px 0px 0px 0px rgba(var(--v-shadow-color), var(--v-shadow-key-opacity, 0.3)), 0px 0px 0px 0px rgba(var(--v-shadow-color), var(--v-shadow-ambient-opacity, 0.15));
|
||||
--v-elevation-overlay: color-mix(in srgb, var(--v-elevation-overlay-color) 0%, transparent);
|
||||
}
|
||||
.v-snackbar--variant-outlined {
|
||||
border: thin solid currentColor;
|
||||
}
|
||||
.v-snackbar--variant-text .v-snackbar__overlay {
|
||||
background: currentColor;
|
||||
}
|
||||
.v-snackbar--variant-tonal .v-snackbar__underlay {
|
||||
background: currentColor;
|
||||
opacity: var(--v-activated-opacity);
|
||||
border-radius: inherit;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
.v-snackbar .v-snackbar__underlay {
|
||||
position: absolute;
|
||||
}
|
||||
.v-snackbar--variant-outlined, .v-snackbar--variant-tonal {
|
||||
background: rgb(var(--v-theme-surface));
|
||||
}
|
||||
@media (forced-colors: active) {
|
||||
.v-snackbar__wrapper {
|
||||
border: thick solid;
|
||||
}
|
||||
}
|
||||
.v-snackbar__header {
|
||||
flex-basis: 100%;
|
||||
}
|
||||
.v-snackbar__header:after {
|
||||
content: "";
|
||||
display: block;
|
||||
flex-basis: 100%;
|
||||
}
|
||||
.v-snackbar__prepend {
|
||||
align-self: center;
|
||||
display: flex;
|
||||
margin-inline: 16px 12px;
|
||||
}
|
||||
.v-snackbar__prepend + .v-snackbar__content {
|
||||
padding-inline-start: 0;
|
||||
}
|
||||
.v-snackbar__title {
|
||||
font-weight: 700;
|
||||
}
|
||||
.v-snackbar__content {
|
||||
flex: 1 1;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 400;
|
||||
letter-spacing: 0.0178571429em;
|
||||
line-height: 1.4285714286;
|
||||
margin-right: auto;
|
||||
padding: 14px 16px;
|
||||
text-align: initial;
|
||||
}
|
||||
.v-snackbar__actions {
|
||||
align-items: center;
|
||||
align-self: center;
|
||||
display: flex;
|
||||
margin-inline-end: 8px;
|
||||
}
|
||||
.v-snackbar__actions > .v-btn {
|
||||
padding: 0 8px;
|
||||
min-width: auto;
|
||||
}
|
||||
.v-snackbar__timer {
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
}
|
||||
.v-snackbar__timer--top {
|
||||
top: 0;
|
||||
}
|
||||
.v-snackbar__timer--bottom {
|
||||
bottom: 0;
|
||||
}
|
||||
.v-snackbar__timer .v-progress-linear {
|
||||
transition: 0.2s linear;
|
||||
}
|
||||
.v-snackbar--absolute {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
}
|
||||
.v-snackbar--vertical .v-snackbar__actions {
|
||||
flex-basis: 100%;
|
||||
justify-content: end;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.v-snackbar--vertical .v-snackbar__actions:before {
|
||||
content: "";
|
||||
display: block;
|
||||
flex-basis: 100%;
|
||||
}
|
||||
.v-snackbar--center {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.v-snackbar--top {
|
||||
align-items: flex-start;
|
||||
}
|
||||
@media (max-width: 839.98px) {
|
||||
.v-snackbar--top {
|
||||
--v-snackbar-mobile-notch: max(env(safe-area-inset-top), 0px);
|
||||
}
|
||||
}
|
||||
.v-snackbar--bottom {
|
||||
align-items: flex-end;
|
||||
}
|
||||
@media (max-width: 839.98px) {
|
||||
.v-snackbar--bottom {
|
||||
--v-snackbar-mobile-notch: max(env(safe-area-inset-bottom), 0px);
|
||||
}
|
||||
}
|
||||
.v-snackbar--left, .v-snackbar--start {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
.v-snackbar--right, .v-snackbar--end {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.v-snackbar--collapsed {
|
||||
--v-snackbar-current-offset: calc(var(--v-snackbar-gap) * var(--v-snackbar-index, 0));
|
||||
}
|
||||
.v-snackbar--collapsed .v-snackbar__wrapper {
|
||||
min-width: 0;
|
||||
width: calc(var(--v-snackbar-collapsed-width) - 2 * var(--v-snackbar-gap) * var(--v-snackbar-index, 0));
|
||||
height: var(--v-snackbar-collapsed-height);
|
||||
}
|
||||
.v-snackbar--collapsed .v-snackbar__wrapper > * {
|
||||
opacity: 0;
|
||||
}
|
||||
.v-snackbar--collapsed.v-snackbar--start .v-snackbar__wrapper, .v-snackbar--collapsed.v-snackbar--left .v-snackbar__wrapper {
|
||||
transform: translateX(calc(var(--v-snackbar-gap) * var(--v-snackbar-index, 0)));
|
||||
}
|
||||
.v-snackbar--collapsed.v-snackbar--end .v-snackbar__wrapper, .v-snackbar--collapsed.v-snackbar--right .v-snackbar__wrapper {
|
||||
transform: translateX(calc(-1 * var(--v-snackbar-gap) * var(--v-snackbar-index, 0)));
|
||||
}
|
||||
.v-snackbar--collapsed .v-progress-linear {
|
||||
opacity: 0;
|
||||
}
|
||||
.v-snackbar .v-avatar {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
@layer vuetify-final.transitions {
|
||||
.v-snackbar-transition-enter-active, .v-snackbar-transition-leave-active {
|
||||
transition-duration: 0.15s;
|
||||
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
|
||||
}
|
||||
.v-snackbar-transition-enter-active {
|
||||
transition-property: opacity, transform;
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.v-snackbar-transition-enter-active {
|
||||
transition-property: opacity;
|
||||
}
|
||||
}
|
||||
.v-snackbar-transition-enter-from {
|
||||
opacity: 0;
|
||||
transform: scale(0.8);
|
||||
}
|
||||
.v-snackbar-transition-leave-active {
|
||||
transition-property: opacity;
|
||||
}
|
||||
.v-snackbar-transition-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
+2384
File diff suppressed because it is too large
Load Diff
+321
@@ -0,0 +1,321 @@
|
||||
import { createElementVNode as _createElementVNode, createVNode as _createVNode, normalizeClass as _normalizeClass, Fragment as _Fragment, mergeProps as _mergeProps } from "vue";
|
||||
// Styles
|
||||
import "./VSnackbar.css";
|
||||
|
||||
// Components
|
||||
import { VAvatar } from "../VAvatar/index.js";
|
||||
import { VDefaultsProvider } from "../VDefaultsProvider/index.js";
|
||||
import { VIcon } from "../VIcon/index.js";
|
||||
import { VOverlay } from "../VOverlay/index.js";
|
||||
import { makeVOverlayProps } from "../VOverlay/VOverlay.js";
|
||||
import { VProgressCircular } from "../VProgressCircular/index.js";
|
||||
import { VProgressLinear } from "../VProgressLinear/index.js";
|
||||
import { useSnackbarItem } from "../VSnackbarQueue/queue.js"; // Composables
|
||||
import { useLayout } from "../../composables/index.js";
|
||||
import { forwardRefs } from "../../composables/forwardRefs.js";
|
||||
import { IconValue } from "../../composables/icons.js";
|
||||
import { VuetifyLayoutKey } from "../../composables/layout.js";
|
||||
import { makeLocationProps } from "../../composables/location.js";
|
||||
import { makePositionProps, usePosition } from "../../composables/position.js";
|
||||
import { useProxiedModel } from "../../composables/proxiedModel.js";
|
||||
import { makeRoundedProps, useRounded } from "../../composables/rounded.js";
|
||||
import { useScopeId } from "../../composables/scopeId.js";
|
||||
import { makeThemeProps, provideTheme } from "../../composables/theme.js";
|
||||
import { useToggleScope } from "../../composables/toggleScope.js";
|
||||
import { genOverlays, makeVariantProps, useVariant } from "../../composables/variant.js"; // Utilities
|
||||
import { computed, inject, mergeProps, nextTick, onMounted, onScopeDispose, ref, shallowRef, watch, watchEffect } from 'vue';
|
||||
import { convertToUnit, genericComponent, omit, propsFactory, refElement, useRender } from "../../util/index.js"; // Types
|
||||
function useCountdown(milliseconds) {
|
||||
const time = shallowRef(milliseconds());
|
||||
let timer = -1;
|
||||
function clear() {
|
||||
clearInterval(timer);
|
||||
}
|
||||
function reset() {
|
||||
clear();
|
||||
nextTick(() => time.value = milliseconds());
|
||||
}
|
||||
function start(el) {
|
||||
const style = el ? getComputedStyle(el) : {
|
||||
transitionDuration: 0.2
|
||||
};
|
||||
const interval = parseFloat(style.transitionDuration) * 1000 || 200;
|
||||
clear();
|
||||
if (time.value <= 0) return;
|
||||
const startTime = performance.now();
|
||||
timer = window.setInterval(() => {
|
||||
const elapsed = performance.now() - startTime + interval;
|
||||
time.value = Math.max(milliseconds() - elapsed, 0);
|
||||
if (time.value <= 0) clear();
|
||||
}, interval);
|
||||
}
|
||||
onScopeDispose(clear);
|
||||
return {
|
||||
clear,
|
||||
time,
|
||||
start,
|
||||
reset
|
||||
};
|
||||
}
|
||||
export const makeVSnackbarProps = propsFactory({
|
||||
collapsed: Object,
|
||||
loading: Boolean,
|
||||
prependAvatar: String,
|
||||
prependIcon: IconValue,
|
||||
queueGap: Number,
|
||||
queueIndex: Number,
|
||||
title: String,
|
||||
text: String,
|
||||
reverseTimer: Boolean,
|
||||
timer: {
|
||||
type: [Boolean, String],
|
||||
default: false
|
||||
},
|
||||
timerColor: String,
|
||||
timeout: {
|
||||
type: [Number, String],
|
||||
default: 5000
|
||||
},
|
||||
vertical: Boolean,
|
||||
...makeLocationProps({
|
||||
location: 'bottom'
|
||||
}),
|
||||
...makePositionProps(),
|
||||
...makeRoundedProps(),
|
||||
...makeVariantProps(),
|
||||
...makeThemeProps(),
|
||||
...omit(makeVOverlayProps({
|
||||
closeOnBack: false,
|
||||
transition: 'v-snackbar-transition'
|
||||
}), ['persistent', 'noClickAnimation', 'offset', 'retainFocus', 'captureFocus', 'disableInitialFocus', 'scrim', 'scrollStrategy', 'stickToTarget', 'viewportMargin'])
|
||||
}, 'VSnackbar');
|
||||
export const VSnackbar = genericComponent()({
|
||||
name: 'VSnackbar',
|
||||
props: makeVSnackbarProps(),
|
||||
emits: {
|
||||
'update:modelValue': v => true
|
||||
},
|
||||
setup(props, {
|
||||
slots
|
||||
}) {
|
||||
const isActive = useProxiedModel(props, 'modelValue');
|
||||
const {
|
||||
positionClasses
|
||||
} = usePosition(props);
|
||||
const {
|
||||
scopeId
|
||||
} = useScopeId();
|
||||
const {
|
||||
themeClasses
|
||||
} = provideTheme(props);
|
||||
const {
|
||||
colorClasses,
|
||||
colorStyles,
|
||||
variantClasses
|
||||
} = useVariant(props);
|
||||
const {
|
||||
roundedClasses
|
||||
} = useRounded(props);
|
||||
const countdown = useCountdown(() => Number(props.timeout));
|
||||
const overlay = ref();
|
||||
const queueItem = useSnackbarItem(isActive, () => overlay.value?.contentEl);
|
||||
let _lastOffset;
|
||||
const timerRef = ref();
|
||||
const isHovering = shallowRef(false);
|
||||
const isFocused = shallowRef(false);
|
||||
const startY = shallowRef(0);
|
||||
const mainStyles = ref();
|
||||
const hasLayout = inject(VuetifyLayoutKey, undefined);
|
||||
useToggleScope(() => !!hasLayout, () => {
|
||||
const layout = useLayout();
|
||||
watchEffect(() => {
|
||||
mainStyles.value = layout.mainStyles.value;
|
||||
});
|
||||
});
|
||||
watch(isActive, startTimeout);
|
||||
watch(() => props.timeout, startTimeout);
|
||||
onMounted(() => {
|
||||
if (isActive.value) startTimeout();
|
||||
});
|
||||
let activeTimeout = -1;
|
||||
function startTimeout() {
|
||||
countdown.reset();
|
||||
window.clearTimeout(activeTimeout);
|
||||
const timeout = Number(props.timeout);
|
||||
if (!isActive.value || timeout === -1) return;
|
||||
const element = refElement(timerRef.value);
|
||||
nextTick(() => countdown.start(element));
|
||||
activeTimeout = window.setTimeout(() => {
|
||||
isActive.value = false;
|
||||
}, timeout);
|
||||
}
|
||||
function clearTimeout() {
|
||||
countdown.reset();
|
||||
window.clearTimeout(activeTimeout);
|
||||
}
|
||||
function onPointerenter() {
|
||||
isHovering.value = true;
|
||||
clearTimeout();
|
||||
}
|
||||
function onPointerleave() {
|
||||
isHovering.value = false;
|
||||
if (!isFocused.value) startTimeout();
|
||||
}
|
||||
function onFocusin() {
|
||||
isFocused.value = true;
|
||||
clearTimeout();
|
||||
}
|
||||
function onFocusout(event) {
|
||||
const contentEl = overlay.value?.contentEl;
|
||||
if (contentEl?.contains(event.relatedTarget)) {
|
||||
return;
|
||||
}
|
||||
isFocused.value = false;
|
||||
if (!isHovering.value) startTimeout();
|
||||
}
|
||||
function onTouchstart(event) {
|
||||
startY.value = event.touches[0].clientY;
|
||||
}
|
||||
function onTouchend(event) {
|
||||
if (Math.abs(startY.value - event.changedTouches[0].clientY) > 50) {
|
||||
isActive.value = false;
|
||||
}
|
||||
}
|
||||
function onAfterLeave() {
|
||||
if (isHovering.value) onPointerleave();
|
||||
isFocused.value = false;
|
||||
}
|
||||
const locationClasses = computed(() => {
|
||||
return props.location.split(' ').reduce((acc, loc) => {
|
||||
acc[`v-snackbar--${loc}`] = true;
|
||||
return acc;
|
||||
}, {});
|
||||
});
|
||||
const queueDirection = computed(() => {
|
||||
const [side, align] = props.location.split(' ');
|
||||
return side === 'bottom' || ['left', 'right'].includes(side) && align === 'end' ? -1 : 1;
|
||||
});
|
||||
const collapsedStyles = computed(() => {
|
||||
if (!props.collapsed) return null;
|
||||
return {
|
||||
'--v-snackbar-collapsed-height': convertToUnit(props.collapsed.height),
|
||||
'--v-snackbar-collapsed-width': convertToUnit(props.collapsed.width)
|
||||
};
|
||||
});
|
||||
const offset = computed(() => {
|
||||
if (!queueItem) return {};
|
||||
if (queueItem.offset.value === null) {
|
||||
return _lastOffset;
|
||||
}
|
||||
return _lastOffset = convertToUnit(queueItem.offset.value);
|
||||
});
|
||||
const transition = computed(() => {
|
||||
if (typeof props.transition !== 'string' || !props.transition.endsWith('-auto')) {
|
||||
return props.transition;
|
||||
}
|
||||
const prefix = props.transition.replace('-auto', '');
|
||||
const [side, align] = props.location.split(' ');
|
||||
const axis = ['start', 'end', 'left', 'right'].includes(align) || ['left', 'right'].includes(side) ? 'x' : 'y';
|
||||
const reverse = ['end', 'right'].includes(align) || !['start', 'left'].includes(align) && ['bottom', 'right'].includes(side) ? '-reverse' : '';
|
||||
return `${prefix}-${axis}${reverse}-transition`;
|
||||
});
|
||||
useRender(() => {
|
||||
const overlayProps = omit(VOverlay.filterProps(props), ['transition']);
|
||||
const hasPrependMedia = !!(props.prependAvatar || props.prependIcon);
|
||||
const hasPrepend = !!(hasPrependMedia || props.loading || slots.prepend);
|
||||
const hasContent = !!(slots.default || slots.text || slots.title || props.text || props.title);
|
||||
return _createVNode(VOverlay, _mergeProps({
|
||||
"ref": overlay,
|
||||
"class": ['v-snackbar', {
|
||||
'v-snackbar--active': isActive.value,
|
||||
'v-snackbar--collapsed': !!props.collapsed,
|
||||
'v-snackbar--timer': !!props.timer,
|
||||
'v-snackbar--vertical': props.vertical
|
||||
}, locationClasses.value, positionClasses.value, props.class],
|
||||
"style": [mainStyles.value, {
|
||||
'--v-snackbar-offset': offset.value,
|
||||
'--v-snackbar-gap': convertToUnit(props.queueGap),
|
||||
'--v-snackbar-index': props.queueIndex,
|
||||
'--v-snackbar-direction': queueDirection.value
|
||||
}, collapsedStyles.value, props.style]
|
||||
}, overlayProps, {
|
||||
"transition": transition.value,
|
||||
"modelValue": isActive.value,
|
||||
"onUpdate:modelValue": $event => isActive.value = $event,
|
||||
"contentProps": mergeProps({
|
||||
class: ['v-snackbar__wrapper', themeClasses.value, colorClasses.value, roundedClasses.value, variantClasses.value],
|
||||
style: [colorStyles.value],
|
||||
onPointerenter,
|
||||
onPointerleave,
|
||||
onFocusin,
|
||||
onFocusout
|
||||
}, overlayProps.contentProps),
|
||||
"persistent": true,
|
||||
"noClickAnimation": true,
|
||||
"scrim": false,
|
||||
"scrollStrategy": "none",
|
||||
"_disableGlobalStack": true,
|
||||
"onTouchstartPassive": onTouchstart,
|
||||
"onTouchend": onTouchend,
|
||||
"onAfterLeave": onAfterLeave
|
||||
}, scopeId), {
|
||||
default: () => [genOverlays(false, 'v-snackbar'), slots.header && _createElementVNode("div", {
|
||||
"class": "v-snackbar__header"
|
||||
}, [slots.header?.()]), props.timer && countdown.time.value > 0 && !isHovering.value && _createElementVNode("div", {
|
||||
"key": "timer",
|
||||
"class": _normalizeClass(['v-snackbar__timer', `v-snackbar__timer--${props.timer === 'bottom' ? 'bottom' : 'top'}`])
|
||||
}, [_createVNode(VProgressLinear, {
|
||||
"ref": timerRef,
|
||||
"color": props.timerColor ?? 'info',
|
||||
"max": props.timeout,
|
||||
"modelValue": props.reverseTimer ? Number(props.timeout) - countdown.time.value : countdown.time.value
|
||||
}, null)]), hasPrepend && _createVNode(VDefaultsProvider, {
|
||||
"key": "prepend-defaults",
|
||||
"disabled": !hasPrependMedia && !props.loading,
|
||||
"defaults": {
|
||||
VAvatar: {
|
||||
image: props.prependAvatar
|
||||
},
|
||||
VIcon: {
|
||||
icon: props.prependIcon
|
||||
},
|
||||
VProgressCircular: {
|
||||
indeterminate: true,
|
||||
size: 24,
|
||||
width: 3
|
||||
}
|
||||
}
|
||||
}, {
|
||||
default: () => [_createElementVNode("div", {
|
||||
"class": "v-snackbar__prepend"
|
||||
}, [slots.prepend ? slots.prepend() : _createElementVNode(_Fragment, null, [props.loading && _createVNode(VProgressCircular, null, null), !props.loading && props.prependAvatar && _createVNode(VAvatar, null, null), !props.loading && props.prependIcon && _createVNode(VIcon, null, null)])])]
|
||||
}), hasContent && _createElementVNode("div", {
|
||||
"key": "content",
|
||||
"class": "v-snackbar__content",
|
||||
"role": "status",
|
||||
"aria-live": "polite"
|
||||
}, [slots.title?.() ?? (props.title ? _createElementVNode("div", {
|
||||
"class": "v-snackbar__title",
|
||||
"key": "title"
|
||||
}, [props.title]) : ''), slots.text?.() ?? props.text, slots.default?.()]), slots.actions && _createVNode(VDefaultsProvider, {
|
||||
"defaults": {
|
||||
VBtn: {
|
||||
variant: 'text',
|
||||
ripple: false,
|
||||
slim: true
|
||||
}
|
||||
}
|
||||
}, {
|
||||
default: () => [_createElementVNode("div", {
|
||||
"class": "v-snackbar__actions"
|
||||
}, [slots.actions({
|
||||
isActive
|
||||
})])]
|
||||
})],
|
||||
activator: slots.activator
|
||||
});
|
||||
});
|
||||
return forwardRefs({}, overlay);
|
||||
}
|
||||
});
|
||||
//# sourceMappingURL=VSnackbar.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
+184
@@ -0,0 +1,184 @@
|
||||
@use 'sass:map'
|
||||
@use '../../styles/tools'
|
||||
@use '../../styles/settings'
|
||||
@use './variables' as *
|
||||
|
||||
@include tools.layer('components')
|
||||
.v-snackbar
|
||||
justify-content: center
|
||||
z-index: $snackbar-z-index
|
||||
margin: $snackbar-wrapper-margin
|
||||
margin-inline-end: calc(#{$snackbar-wrapper-margin} + var(--v-scrollbar-offset))
|
||||
padding: var(--v-layout-top) var(--v-layout-right) var(--v-layout-bottom) var(--v-layout-left)
|
||||
|
||||
--v-snackbar-current-offset: var(--v-snackbar-offset)
|
||||
transform: translateY(calc(var(--v-snackbar-direction) * (var(--v-snackbar-current-offset) + var(--v-snackbar-mobile-notch, 0px))))
|
||||
transition: transform .2s settings.$standard-easing
|
||||
|
||||
&:not(.v-snackbar--center):not(.v-snackbar--top)
|
||||
align-items: flex-end
|
||||
|
||||
&__wrapper
|
||||
align-items: center
|
||||
display: flex
|
||||
flex-wrap: wrap
|
||||
max-width: $snackbar-wrapper-max-width
|
||||
min-height: $snackbar-wrapper-min-height
|
||||
min-width: $snackbar-wrapper-min-width
|
||||
overflow: hidden
|
||||
padding: $snackbar-wrapper-padding
|
||||
|
||||
transition: .35s settings.$standard-easing
|
||||
transition-property: height, width
|
||||
|
||||
@include tools.rounded($snackbar-border-radius)
|
||||
|
||||
@at-root .v-snackbar
|
||||
@include tools.variant($snackbar-variants...)
|
||||
|
||||
&--variant-outlined,
|
||||
&--variant-tonal
|
||||
background: $snackbar-fallback-background
|
||||
|
||||
@media (forced-colors: active)
|
||||
border: thick solid
|
||||
|
||||
&__header
|
||||
flex-basis: 100%
|
||||
|
||||
&:after
|
||||
content: ''
|
||||
display: block
|
||||
flex-basis: 100%
|
||||
|
||||
&__prepend
|
||||
align-self: center
|
||||
display: flex
|
||||
margin-inline: $snackbar-prepend-margin-inline
|
||||
|
||||
&__prepend + &__content
|
||||
padding-inline-start: 0
|
||||
|
||||
&__title
|
||||
font-weight: $snackbar-title-font-weight
|
||||
|
||||
&__content
|
||||
flex: 1 1
|
||||
font-size: $snackbar-font-size
|
||||
font-weight: $snackbar-font-weight
|
||||
letter-spacing: $snackbar-letter-spacing
|
||||
line-height: $snackbar-line-height
|
||||
margin-right: auto
|
||||
padding: $snackbar-content-padding
|
||||
text-align: initial
|
||||
|
||||
&__actions
|
||||
align-items: center
|
||||
align-self: center
|
||||
display: flex
|
||||
margin-inline-end: $snackbar-action-margin
|
||||
|
||||
& > .v-btn
|
||||
padding: $snackbar-btn-padding
|
||||
min-width: auto
|
||||
|
||||
&__timer
|
||||
width: 100%
|
||||
position: absolute
|
||||
|
||||
&--top
|
||||
top: 0
|
||||
|
||||
&--bottom
|
||||
bottom: 0
|
||||
|
||||
.v-progress-linear
|
||||
transition: .2s linear
|
||||
|
||||
&--absolute
|
||||
position: absolute
|
||||
z-index: $snackbar-absolute-z-index
|
||||
|
||||
&--vertical .v-snackbar__actions
|
||||
flex-basis: 100%
|
||||
justify-content: end
|
||||
margin-bottom: $snackbar-vertical-action-margin-bottom
|
||||
|
||||
&:before
|
||||
content: ''
|
||||
display: block
|
||||
flex-basis: 100%
|
||||
|
||||
&--center
|
||||
align-items: center
|
||||
justify-content: center
|
||||
|
||||
&--top
|
||||
align-items: flex-start
|
||||
|
||||
@media #{map.get(settings.$display-breakpoints, 'sm-and-down')}
|
||||
--v-snackbar-mobile-notch: max(env(safe-area-inset-top), 0px)
|
||||
|
||||
&--bottom
|
||||
align-items: flex-end
|
||||
|
||||
@media #{map.get(settings.$display-breakpoints, 'sm-and-down')}
|
||||
--v-snackbar-mobile-notch: max(env(safe-area-inset-bottom), 0px)
|
||||
|
||||
&--left,
|
||||
&--start
|
||||
justify-content: flex-start
|
||||
|
||||
&--right,
|
||||
&--end
|
||||
justify-content: flex-end
|
||||
|
||||
&--collapsed
|
||||
--v-snackbar-current-offset: calc(var(--v-snackbar-gap) * var(--v-snackbar-index, 0))
|
||||
|
||||
.v-snackbar__wrapper
|
||||
min-width: 0
|
||||
width: calc(var(--v-snackbar-collapsed-width) - 2 * var(--v-snackbar-gap) * var(--v-snackbar-index, 0))
|
||||
height: var(--v-snackbar-collapsed-height)
|
||||
|
||||
> *
|
||||
opacity: 0
|
||||
|
||||
&.v-snackbar--start,
|
||||
&.v-snackbar--left
|
||||
.v-snackbar__wrapper
|
||||
transform: translateX(calc(var(--v-snackbar-gap) * var(--v-snackbar-index, 0)))
|
||||
|
||||
&.v-snackbar--end,
|
||||
&.v-snackbar--right
|
||||
.v-snackbar__wrapper
|
||||
transform: translateX(calc(-1 * var(--v-snackbar-gap) * var(--v-snackbar-index, 0)))
|
||||
|
||||
.v-progress-linear
|
||||
opacity: 0
|
||||
|
||||
.v-avatar
|
||||
background: transparent
|
||||
|
||||
@include tools.layer('transitions')
|
||||
.v-snackbar-transition
|
||||
&-enter-active,
|
||||
&-leave-active
|
||||
transition-duration: .15s
|
||||
transition-timing-function: settings.$decelerated-easing
|
||||
|
||||
&-enter-active
|
||||
transition-property: opacity, transform
|
||||
|
||||
@media (prefers-reduced-motion: reduce)
|
||||
transition-property: opacity
|
||||
|
||||
&-enter-from
|
||||
opacity: 0
|
||||
transform: scale($snackbar-transition-scale)
|
||||
|
||||
&-leave-active
|
||||
transition-property: opacity
|
||||
|
||||
&-leave-to
|
||||
opacity: 0
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
@use '../../styles/settings';
|
||||
@use '../../styles/tools';
|
||||
|
||||
// VSnackbar
|
||||
$snackbar-absolute-z-index: 1 !default;
|
||||
$snackbar-action-margin: 8px !default;
|
||||
$snackbar-border-radius: settings.$border-radius-root !default;
|
||||
$snackbar-plain-opacity: .62 !default;
|
||||
$snackbar-btn-padding: 0 8px !default;
|
||||
$snackbar-background: rgb(var(--v-theme-surface-variant)) !default;
|
||||
$snackbar-fallback-background: rgb(var(--v-theme-surface)) !default;
|
||||
$snackbar-color: rgb(var(--v-theme-on-surface-variant)) !default;
|
||||
$snackbar-font-size: tools.map-deep-get(settings.$typography, 'body-medium', 'size') !default;
|
||||
$snackbar-font-weight: tools.map-deep-get(settings.$typography, 'body-medium', 'weight') !default;
|
||||
$snackbar-letter-spacing: tools.map-deep-get(settings.$typography, 'body-medium', 'letter-spacing') !default;
|
||||
$snackbar-line-height: tools.map-deep-get(settings.$typography, 'body-medium', 'line-height') !default;
|
||||
$snackbar-title-font-weight: 700 !default;
|
||||
$snackbar-content-padding: 14px 16px !default;
|
||||
$snackbar-prepend-margin-inline: 16px 12px !default;
|
||||
$snackbar-elevation: 2 !default;
|
||||
$snackbar-transition-scale: .8 !default;
|
||||
$snackbar-vertical-action-margin-bottom: 8px !default;
|
||||
$snackbar-wrapper-margin: 8px !default;
|
||||
$snackbar-wrapper-max-width: 672px !default;
|
||||
$snackbar-wrapper-min-height: 48px !default;
|
||||
$snackbar-wrapper-min-width: 344px !default;
|
||||
$snackbar-wrapper-padding: 0 !default;
|
||||
$snackbar-z-index: 10000 !default;
|
||||
|
||||
// List
|
||||
$snackbar-variants: (
|
||||
$snackbar-background,
|
||||
$snackbar-color,
|
||||
$snackbar-elevation,
|
||||
$snackbar-plain-opacity,
|
||||
'v-snackbar'
|
||||
) !default;
|
||||
+1
@@ -0,0 +1 @@
|
||||
export { VSnackbar } from './VSnackbar.js';
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
export { VSnackbar } from "./VSnackbar.js";
|
||||
//# sourceMappingURL=index.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","names":["VSnackbar"],"sources":["../../../src/components/VSnackbar/index.ts"],"sourcesContent":["export { VSnackbar } from './VSnackbar'\n"],"mappings":"SAASA,SAAS","ignoreList":[]}
|
||||
Reference in New Issue
Block a user