vuetify
Version:
Vue Material Component Framework
1,571 lines (1,487 loc) • 578 kB
JavaScript
/*!
* Vuetify v3.1.7
* Forged by John Leider
* Released under the MIT License.
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('vue')) :
typeof define === 'function' && define.amd ? define(['exports', 'vue'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Vuetify = {}, global.Vue));
})(this, (function (exports, vue) { 'use strict';
const IN_BROWSER = typeof window !== 'undefined';
const SUPPORTS_INTERSECTION = IN_BROWSER && 'IntersectionObserver' in window;
const SUPPORTS_TOUCH = IN_BROWSER && ('ontouchstart' in window || window.navigator.maxTouchPoints > 0);
const SUPPORTS_FOCUS_VISIBLE = IN_BROWSER && typeof CSS !== 'undefined' && CSS.supports('selector(:focus-visible)');
// Utilities
function useResizeObserver(callback) {
const resizeRef = vue.ref();
const contentRect = vue.ref();
if (IN_BROWSER) {
const observer = new ResizeObserver(entries => {
callback?.(entries, observer);
if (!entries.length) return;
contentRect.value = entries[0].contentRect;
});
vue.onBeforeUnmount(() => {
observer.disconnect();
});
vue.watch(resizeRef, (newValue, oldValue) => {
if (oldValue) {
observer.unobserve(oldValue);
contentRect.value = undefined;
}
if (newValue) observer.observe(newValue);
}, {
flush: 'post'
});
}
return {
resizeRef,
contentRect: vue.readonly(contentRect)
};
}
function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); }
function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
function _classPrivateFieldSet(receiver, privateMap, value) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "set"); _classApplyDescriptorSet(receiver, descriptor, value); return value; }
function _classApplyDescriptorSet(receiver, descriptor, value) { if (descriptor.set) { descriptor.set.call(receiver, value); } else { if (!descriptor.writable) { throw new TypeError("attempted to set read only private field"); } descriptor.value = value; } }
function _classPrivateFieldGet(receiver, privateMap) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "get"); return _classApplyDescriptorGet(receiver, descriptor); }
function _classExtractFieldDescriptor(receiver, privateMap, action) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to " + action + " private field on non-instance"); } return privateMap.get(receiver); }
function _classApplyDescriptorGet(receiver, descriptor) { if (descriptor.get) { return descriptor.get.call(receiver); } return descriptor.value; }
// Types
function getNestedValue(obj, path, fallback) {
const last = path.length - 1;
if (last < 0) return obj === undefined ? fallback : obj;
for (let i = 0; i < last; i++) {
if (obj == null) {
return fallback;
}
obj = obj[path[i]];
}
if (obj == null) return fallback;
return obj[path[last]] === undefined ? fallback : obj[path[last]];
}
function deepEqual(a, b) {
if (a === b) return true;
if (a instanceof Date && b instanceof Date && a.getTime() !== b.getTime()) {
// If the values are Date, compare them as timestamps
return false;
}
if (a !== Object(a) || b !== Object(b)) {
// If the values aren't objects, they were already checked for equality
return false;
}
const props = Object.keys(a);
if (props.length !== Object.keys(b).length) {
// Different number of props, don't bother to check
return false;
}
return props.every(p => deepEqual(a[p], b[p]));
}
function getObjectValueByPath(obj, path, fallback) {
// credit: http://stackoverflow.com/questions/6491463/accessing-nested-javascript-objects-with-string-key#comment55278413_6491621
if (obj == null || !path || typeof path !== 'string') return fallback;
if (obj[path] !== undefined) return obj[path];
path = path.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties
path = path.replace(/^\./, ''); // strip a leading dot
return getNestedValue(obj, path.split('.'), fallback);
}
function getPropertyFromItem(item, property, fallback) {
if (property == null) return item === undefined ? fallback : item;
if (item !== Object(item)) {
if (typeof property !== 'function') return fallback;
const value = property(item, fallback);
return typeof value === 'undefined' ? fallback : value;
}
if (typeof property === 'string') return getObjectValueByPath(item, property, fallback);
if (Array.isArray(property)) return getNestedValue(item, property, fallback);
if (typeof property !== 'function') return fallback;
const value = property(item, fallback);
return typeof value === 'undefined' ? fallback : value;
}
function createRange(length) {
let start = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
return Array.from({
length
}, (v, k) => start + k);
}
function convertToUnit(str) {
let unit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'px';
if (str == null || str === '') {
return undefined;
} else if (isNaN(+str)) {
return String(str);
} else if (!isFinite(+str)) {
return undefined;
} else {
return `${Number(str)}${unit}`;
}
}
function isObject(obj) {
return obj !== null && typeof obj === 'object' && !Array.isArray(obj);
}
function isComponentInstance(obj) {
return obj?.$el;
}
// KeyboardEvent.keyCode aliases
const keyCodes = Object.freeze({
enter: 13,
tab: 9,
delete: 46,
esc: 27,
space: 32,
up: 38,
down: 40,
left: 37,
right: 39,
end: 35,
home: 36,
del: 46,
backspace: 8,
insert: 45,
pageup: 33,
pagedown: 34,
shift: 16
});
const keyValues = Object.freeze({
enter: 'Enter',
tab: 'Tab',
delete: 'Delete',
esc: 'Escape',
space: 'Space',
up: 'ArrowUp',
down: 'ArrowDown',
left: 'ArrowLeft',
right: 'ArrowRight',
end: 'End',
home: 'Home',
del: 'Delete',
backspace: 'Backspace',
insert: 'Insert',
pageup: 'PageUp',
pagedown: 'PageDown',
shift: 'Shift'
});
function keys(o) {
return Object.keys(o);
}
function pick(obj, paths) {
const found = Object.create(null);
const rest = Object.create(null);
for (const key in obj) {
if (paths.some(path => path instanceof RegExp ? path.test(key) : path === key)) {
found[key] = obj[key];
} else {
rest[key] = obj[key];
}
}
return [found, rest];
}
function omit(obj, exclude) {
const clone = {
...obj
};
exclude.forEach(prop => delete clone[prop]);
return clone;
}
/**
* Filter attributes that should be applied to
* the root element of a an input component. Remaining
* attributes should be passed to the <input> element inside.
*/
function filterInputAttrs(attrs) {
return pick(attrs, ['class', 'style', 'id', /^data-/]);
}
function wrapInArray(v) {
return v == null ? [] : Array.isArray(v) ? v : [v];
}
function clamp(value) {
let min = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
let max = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
return Math.max(min, Math.min(max, value));
}
function padEnd(str, length) {
let char = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '0';
return str + char.repeat(Math.max(0, length - str.length));
}
function chunk(str) {
let size = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
const chunked = [];
let index = 0;
while (index < str.length) {
chunked.push(str.substr(index, size));
index += size;
}
return chunked;
}
function humanReadableFileSize(bytes) {
let base = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1000;
if (bytes < base) {
return `${bytes} B`;
}
const prefix = base === 1024 ? ['Ki', 'Mi', 'Gi'] : ['k', 'M', 'G'];
let unit = -1;
while (Math.abs(bytes) >= base && unit < prefix.length - 1) {
bytes /= base;
++unit;
}
return `${bytes.toFixed(1)} ${prefix[unit]}B`;
}
function mergeDeep() {
let source = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
let target = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
let arrayFn = arguments.length > 2 ? arguments[2] : undefined;
const out = {};
for (const key in source) {
out[key] = source[key];
}
for (const key in target) {
const sourceProperty = source[key];
const targetProperty = target[key];
// Only continue deep merging if
// both properties are objects
if (isObject(sourceProperty) && isObject(targetProperty)) {
out[key] = mergeDeep(sourceProperty, targetProperty, arrayFn);
continue;
}
if (Array.isArray(sourceProperty) && Array.isArray(targetProperty) && arrayFn) {
out[key] = arrayFn(sourceProperty, targetProperty);
continue;
}
out[key] = targetProperty;
}
return out;
}
function toKebabCase() {
let str = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
if (toKebabCase.cache.has(str)) return toKebabCase.cache.get(str);
const kebab = str.replace(/[^a-z]/gi, '-').replace(/\B([A-Z])/g, '-$1').toLowerCase();
toKebabCase.cache.set(str, kebab);
return kebab;
}
toKebabCase.cache = new Map();
function findChildrenWithProvide(key, vnode) {
if (!vnode || typeof vnode !== 'object') return [];
if (Array.isArray(vnode)) {
return vnode.map(child => findChildrenWithProvide(key, child)).flat(1);
} else if (Array.isArray(vnode.children)) {
return vnode.children.map(child => findChildrenWithProvide(key, child)).flat(1);
} else if (vnode.component) {
if (Object.getOwnPropertySymbols(vnode.component.provides).includes(key)) {
return [vnode.component];
} else if (vnode.component.subTree) {
return findChildrenWithProvide(key, vnode.component.subTree).flat(1);
}
}
return [];
}
var _arr = /*#__PURE__*/new WeakMap();
var _pointer = /*#__PURE__*/new WeakMap();
class CircularBuffer {
constructor(size) {
_classPrivateFieldInitSpec(this, _arr, {
writable: true,
value: []
});
_classPrivateFieldInitSpec(this, _pointer, {
writable: true,
value: 0
});
this.size = size;
}
push(val) {
_classPrivateFieldGet(this, _arr)[_classPrivateFieldGet(this, _pointer)] = val;
_classPrivateFieldSet(this, _pointer, (_classPrivateFieldGet(this, _pointer) + 1) % this.size);
}
values() {
return _classPrivateFieldGet(this, _arr).slice(_classPrivateFieldGet(this, _pointer)).concat(_classPrivateFieldGet(this, _arr).slice(0, _classPrivateFieldGet(this, _pointer)));
}
}
function getEventCoordinates(e) {
if ('touches' in e) {
return {
clientX: e.touches[0].clientX,
clientY: e.touches[0].clientY
};
}
return {
clientX: e.clientX,
clientY: e.clientY
};
}
// Only allow a single return type
function destructComputed(getter) {
const refs = vue.reactive({});
const base = vue.computed(getter);
vue.watchEffect(() => {
for (const key in base.value) {
refs[key] = base.value[key];
}
}, {
flush: 'sync'
});
return vue.toRefs(refs);
}
/** Array.includes but value can be any type */
function includes(arr, val) {
return arr.includes(val);
}
const onRE = /^on[^a-z]/;
const isOn = key => onRE.test(key);
const EventProp = [Function, Array];
function hasEvent(props, name) {
name = 'on' + vue.capitalize(name);
return !!(props[name] || props[`${name}Once`] || props[`${name}Capture`] || props[`${name}OnceCapture`] || props[`${name}CaptureOnce`]);
}
function callEvent(handler) {
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
args[_key2 - 1] = arguments[_key2];
}
if (Array.isArray(handler)) {
for (const h of handler) {
h(...args);
}
} else if (typeof handler === 'function') {
handler(...args);
}
}
const block = ['top', 'bottom'];
const inline = ['start', 'end', 'left', 'right'];
/** Parse a raw anchor string into an object */
function parseAnchor(anchor, isRtl) {
let [side, align] = anchor.split(' ');
if (!align) {
align = includes(block, side) ? 'start' : includes(inline, side) ? 'top' : 'center';
}
return {
side: toPhysical(side, isRtl),
align: toPhysical(align, isRtl)
};
}
function toPhysical(str, isRtl) {
if (str === 'start') return isRtl ? 'right' : 'left';
if (str === 'end') return isRtl ? 'left' : 'right';
return str;
}
function flipSide(anchor) {
return {
side: {
center: 'center',
top: 'bottom',
bottom: 'top',
left: 'right',
right: 'left'
}[anchor.side],
align: anchor.align
};
}
function flipAlign(anchor) {
return {
side: anchor.side,
align: {
center: 'center',
top: 'bottom',
bottom: 'top',
left: 'right',
right: 'left'
}[anchor.align]
};
}
function flipCorner(anchor) {
return {
side: anchor.align,
align: anchor.side
};
}
function getAxis(anchor) {
return includes(block, anchor.side) ? 'y' : 'x';
}
class Box {
constructor(_ref) {
let {
x,
y,
width,
height
} = _ref;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
get top() {
return this.y;
}
get bottom() {
return this.y + this.height;
}
get left() {
return this.x;
}
get right() {
return this.x + this.width;
}
}
function getOverflow(a, b) {
return {
x: {
before: Math.max(0, b.left - a.left),
after: Math.max(0, a.right - b.right)
},
y: {
before: Math.max(0, b.top - a.top),
after: Math.max(0, a.bottom - b.bottom)
}
};
}
/** @see https://stackoverflow.com/a/57876601/2074736 */
function nullifyTransforms(el) {
const rect = el.getBoundingClientRect();
const style = getComputedStyle(el);
const tx = style.transform;
if (tx) {
let ta, sx, sy, dx, dy;
if (tx.startsWith('matrix3d(')) {
ta = tx.slice(9, -1).split(/, /);
sx = +ta[0];
sy = +ta[5];
dx = +ta[12];
dy = +ta[13];
} else if (tx.startsWith('matrix(')) {
ta = tx.slice(7, -1).split(/, /);
sx = +ta[0];
sy = +ta[3];
dx = +ta[4];
dy = +ta[5];
} else {
return new Box(rect);
}
const to = style.transformOrigin;
const x = rect.x - dx - (1 - sx) * parseFloat(to);
const y = rect.y - dy - (1 - sy) * parseFloat(to.slice(to.indexOf(' ') + 1));
const w = sx ? rect.width / sx : el.offsetWidth + 1;
const h = sy ? rect.height / sy : el.offsetHeight + 1;
return new Box({
x,
y,
width: w,
height: h
});
} else {
return new Box(rect);
}
}
function animate(el, keyframes, options) {
if (typeof el.animate === 'undefined') return {
finished: Promise.resolve()
};
const animation = el.animate(keyframes, options);
if (typeof animation.finished === 'undefined') {
animation.finished = new Promise(resolve => {
animation.onfinish = () => {
resolve(animation);
};
});
}
return animation;
}
/* eslint-disable no-console */
// import Vuetify from '../framework'
function createMessage(message, vm, parent) {
// if (Vuetify.config.silent) return
if (parent) {
vm = {
__isVue: true,
$parent: parent,
$options: vm
};
}
if (vm) {
// Only show each message once per instance
vm.$_alreadyWarned = vm.$_alreadyWarned || [];
if (vm.$_alreadyWarned.includes(message)) return;
vm.$_alreadyWarned.push(message);
}
return `[Vuetify] ${message}` + (vm ? generateComponentTrace(vm) : '');
}
function consoleWarn(message, vm, parent) {
const newMessage = createMessage(message, vm, parent);
newMessage != null && console.warn(newMessage);
}
function consoleError(message, vm, parent) {
const newMessage = createMessage(message, vm, parent);
newMessage != null && console.error(newMessage);
}
/**
* Shamelessly stolen from vuejs/vue/blob/dev/src/core/util/debug.js
*/
const classifyRE = /(?:^|[-_])(\w)/g;
const classify = str => str.replace(classifyRE, c => c.toUpperCase()).replace(/[-_]/g, '');
function formatComponentName(vm, includeFile) {
if (vm.$root === vm) {
return '<Root>';
}
const options = typeof vm === 'function' && vm.cid != null ? vm.options : vm.__isVue ? vm.$options || vm.constructor.options : vm || {};
let name = options.name || options._componentTag;
const file = options.__file;
if (!name && file) {
const match = file.match(/([^/\\]+)\.vue$/);
name = match?.[1];
}
return (name ? `<${classify(name)}>` : `<Anonymous>`) + (file && includeFile !== false ? ` at ${file}` : '');
}
function generateComponentTrace(vm) {
if (vm.__isVue && vm.$parent) {
const tree = [];
let currentRecursiveSequence = 0;
while (vm) {
if (tree.length > 0) {
const last = tree[tree.length - 1];
if (last.constructor === vm.constructor) {
currentRecursiveSequence++;
vm = vm.$parent;
continue;
} else if (currentRecursiveSequence > 0) {
tree[tree.length - 1] = [last, currentRecursiveSequence];
currentRecursiveSequence = 0;
}
}
tree.push(vm);
vm = vm.$parent;
}
return '\n\nfound in\n\n' + tree.map((vm, i) => `${i === 0 ? '---> ' : ' '.repeat(5 + i * 2)}${Array.isArray(vm)
// eslint-disable-next-line sonarjs/no-nested-template-literals
? `${formatComponentName(vm[0])}... (${vm[1]} recursive calls)` : formatComponentName(vm)}`).join('\n');
} else {
return `\n\n(found in ${formatComponentName(vm)})`;
}
}
// For converting XYZ to sRGB
const srgbForwardMatrix = [[3.2406, -1.5372, -0.4986], [-0.9689, 1.8758, 0.0415], [0.0557, -0.2040, 1.0570]];
// Forward gamma adjust
const srgbForwardTransform = C => C <= 0.0031308 ? C * 12.92 : 1.055 * C ** (1 / 2.4) - 0.055;
// For converting sRGB to XYZ
const srgbReverseMatrix = [[0.4124, 0.3576, 0.1805], [0.2126, 0.7152, 0.0722], [0.0193, 0.1192, 0.9505]];
// Reverse gamma adjust
const srgbReverseTransform = C => C <= 0.04045 ? C / 12.92 : ((C + 0.055) / 1.055) ** 2.4;
function fromXYZ$1(xyz) {
const rgb = Array(3);
const transform = srgbForwardTransform;
const matrix = srgbForwardMatrix;
// Matrix transform, then gamma adjustment
for (let i = 0; i < 3; ++i) {
// Rescale back to [0, 255]
rgb[i] = Math.round(clamp(transform(matrix[i][0] * xyz[0] + matrix[i][1] * xyz[1] + matrix[i][2] * xyz[2])) * 255);
}
return {
r: rgb[0],
g: rgb[1],
b: rgb[2]
};
}
function toXYZ$1(_ref) {
let {
r,
g,
b
} = _ref;
const xyz = [0, 0, 0];
const transform = srgbReverseTransform;
const matrix = srgbReverseMatrix;
// Rescale from [0, 255] to [0, 1] then adjust sRGB gamma to linear RGB
r = transform(r / 255);
g = transform(g / 255);
b = transform(b / 255);
// Matrix color space transform
for (let i = 0; i < 3; ++i) {
xyz[i] = matrix[i][0] * r + matrix[i][1] * g + matrix[i][2] * b;
}
return xyz;
}
const delta = 0.20689655172413793; // 6÷29
const cielabForwardTransform = t => t > delta ** 3 ? Math.cbrt(t) : t / (3 * delta ** 2) + 4 / 29;
const cielabReverseTransform = t => t > delta ? t ** 3 : 3 * delta ** 2 * (t - 4 / 29);
function fromXYZ(xyz) {
const transform = cielabForwardTransform;
const transformedY = transform(xyz[1]);
return [116 * transformedY - 16, 500 * (transform(xyz[0] / 0.95047) - transformedY), 200 * (transformedY - transform(xyz[2] / 1.08883))];
}
function toXYZ(lab) {
const transform = cielabReverseTransform;
const Ln = (lab[0] + 16) / 116;
return [transform(Ln + lab[1] / 500) * 0.95047, transform(Ln), transform(Ln - lab[2] / 200) * 1.08883];
}
// Utilities
// Types
function isCssColor(color) {
return !!color && /^(#|var\(--|(rgb|hsl)a?\()/.test(color);
}
function parseColor$1(color) {
if (typeof color === 'number') {
if (isNaN(color) || color < 0 || color > 0xFFFFFF) {
// int can't have opacity
consoleWarn(`'${color}' is not a valid hex color`);
}
return {
r: (color & 0xFF0000) >> 16,
g: (color & 0xFF00) >> 8,
b: color & 0xFF
};
} else if (typeof color === 'string') {
let hex = color.startsWith('#') ? color.slice(1) : color;
if ([3, 4].includes(hex.length)) {
hex = hex.split('').map(char => char + char).join('');
} else if (![6, 8].includes(hex.length)) {
consoleWarn(`'${color}' is not a valid hex(a) color`);
}
const int = parseInt(hex, 16);
if (isNaN(int) || int < 0 || int > 0xFFFFFFFF) {
consoleWarn(`'${color}' is not a valid hex(a) color`);
}
return HexToRGB(hex);
} else {
throw new TypeError(`Colors can only be numbers or strings, recieved ${color == null ? color : color.constructor.name} instead`);
}
}
/** Converts HSVA to RGBA. Based on formula from https://en.wikipedia.org/wiki/HSL_and_HSV */
function HSVtoRGB(hsva) {
const {
h,
s,
v,
a
} = hsva;
const f = n => {
const k = (n + h / 60) % 6;
return v - v * s * Math.max(Math.min(k, 4 - k, 1), 0);
};
const rgb = [f(5), f(3), f(1)].map(v => Math.round(v * 255));
return {
r: rgb[0],
g: rgb[1],
b: rgb[2],
a
};
}
/** Converts RGBA to HSVA. Based on formula from https://en.wikipedia.org/wiki/HSL_and_HSV */
function RGBtoHSV(rgba) {
if (!rgba) return {
h: 0,
s: 1,
v: 1,
a: 1
};
const r = rgba.r / 255;
const g = rgba.g / 255;
const b = rgba.b / 255;
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
let h = 0;
if (max !== min) {
if (max === r) {
h = 60 * (0 + (g - b) / (max - min));
} else if (max === g) {
h = 60 * (2 + (b - r) / (max - min));
} else if (max === b) {
h = 60 * (4 + (r - g) / (max - min));
}
}
if (h < 0) h = h + 360;
const s = max === 0 ? 0 : (max - min) / max;
const hsv = [h, s, max];
return {
h: hsv[0],
s: hsv[1],
v: hsv[2],
a: rgba.a
};
}
function HSVtoHSL(hsva) {
const {
h,
s,
v,
a
} = hsva;
const l = v - v * s / 2;
const sprime = l === 1 || l === 0 ? 0 : (v - l) / Math.min(l, 1 - l);
return {
h,
s: sprime,
l,
a
};
}
function HSLtoHSV(hsl) {
const {
h,
s,
l,
a
} = hsl;
const v = l + s * Math.min(l, 1 - l);
const sprime = v === 0 ? 0 : 2 - 2 * l / v;
return {
h,
s: sprime,
v,
a
};
}
function RGBtoCSS(_ref) {
let {
r,
g,
b,
a
} = _ref;
return a === undefined ? `rgb(${r}, ${g}, ${b})` : `rgba(${r}, ${g}, ${b}, ${a})`;
}
function HSVtoCSS(hsva) {
return RGBtoCSS(HSVtoRGB(hsva));
}
function toHex(v) {
const h = Math.round(v).toString(16);
return ('00'.substr(0, 2 - h.length) + h).toUpperCase();
}
function RGBtoHex(_ref2) {
let {
r,
g,
b,
a
} = _ref2;
return `#${[toHex(r), toHex(g), toHex(b), a !== undefined ? toHex(Math.round(a * 255)) : ''].join('')}`;
}
function HexToRGB(hex) {
hex = parseHex(hex);
let [r, g, b, a] = chunk(hex, 2).map(c => parseInt(c, 16));
a = a === undefined ? a : a / 255;
return {
r,
g,
b,
a
};
}
function HexToHSV(hex) {
const rgb = HexToRGB(hex);
return RGBtoHSV(rgb);
}
function HSVtoHex(hsva) {
return RGBtoHex(HSVtoRGB(hsva));
}
function parseHex(hex) {
if (hex.startsWith('#')) {
hex = hex.slice(1);
}
hex = hex.replace(/([^0-9a-f])/gi, 'F');
if (hex.length === 3 || hex.length === 4) {
hex = hex.split('').map(x => x + x).join('');
}
if (hex.length !== 6) {
hex = padEnd(padEnd(hex, 6), 8, 'F');
}
return hex;
}
function lighten(value, amount) {
const lab = fromXYZ(toXYZ$1(value));
lab[0] = lab[0] + amount * 10;
return fromXYZ$1(toXYZ(lab));
}
function darken(value, amount) {
const lab = fromXYZ(toXYZ$1(value));
lab[0] = lab[0] - amount * 10;
return fromXYZ$1(toXYZ(lab));
}
/**
* Calculate the relative luminance of a given color
* @see https://www.w3.org/TR/WCAG20/#relativeluminancedef
*/
function getLuma(color) {
const rgb = parseColor$1(color);
return toXYZ$1(rgb)[1];
}
/**
* Returns the contrast ratio (1-21) between two colors.
* @see https://www.w3.org/TR/WCAG20/#contrast-ratiodef
*/
function getContrast(first, second) {
const l1 = getLuma(first);
const l2 = getLuma(second);
const light = Math.max(l1, l2);
const dark = Math.min(l1, l2);
return (light + 0.05) / (dark + 0.05);
}
// Utilities
function getCurrentInstance(name, message) {
const vm = vue.getCurrentInstance();
if (!vm) {
throw new Error(`[Vuetify] ${name} ${message || 'must be called from inside a setup function'}`);
}
return vm;
}
function getCurrentInstanceName() {
let name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'composables';
const vm = getCurrentInstance(name).type;
return toKebabCase(vm?.aliasName || vm?.name);
}
let _uid = 0;
let _map = new WeakMap();
function getUid() {
const vm = getCurrentInstance('getUid');
if (_map.has(vm)) return _map.get(vm);else {
const uid = _uid++;
_map.set(vm, uid);
return uid;
}
}
getUid.reset = () => {
_uid = 0;
_map = new WeakMap();
};
function injectSelf(key) {
const {
provides
} = getCurrentInstance('injectSelf');
if (provides && key in provides) {
// TS doesn't allow symbol as index type
return provides[key];
}
}
/**
* Creates a factory function for props definitions.
* This is used to define props in a composable then override
* default values in an implementing component.
*
* @example Simplified signature
* (props: Props) => (defaults?: Record<keyof props, any>) => Props
*
* @example Usage
* const makeProps = propsFactory({
* foo: String,
* })
*
* defineComponent({
* props: {
* ...makeProps({
* foo: 'a',
* }),
* },
* setup (props) {
* // would be "string | undefined", now "string" because a default has been provided
* props.foo
* },
* }
*/
function propsFactory(props, source) {
return defaults => {
return Object.keys(props).reduce((obj, prop) => {
const isObjectDefinition = typeof props[prop] === 'object' && props[prop] != null && !Array.isArray(props[prop]);
const definition = isObjectDefinition ? props[prop] : {
type: props[prop]
};
if (defaults && prop in defaults) {
obj[prop] = {
...definition,
default: defaults[prop]
};
} else {
obj[prop] = definition;
}
if (source && !obj[prop].source) {
obj[prop].source = source;
}
return obj;
}, {});
};
}
// Utilities
// Types
const DefaultsSymbol = Symbol.for('vuetify:defaults');
function createDefaults(options) {
return vue.ref(options);
}
function useDefaults() {
const defaults = vue.inject(DefaultsSymbol);
if (!defaults) throw new Error('[Vuetify] Could not find defaults instance');
return defaults;
}
function provideDefaults(defaults, options) {
const injectedDefaults = useDefaults();
const providedDefaults = vue.ref(defaults);
const newDefaults = vue.computed(() => {
const scoped = vue.unref(options?.scoped);
const reset = vue.unref(options?.reset);
const root = vue.unref(options?.root);
let properties = mergeDeep(providedDefaults.value, {
prev: injectedDefaults.value
});
if (scoped) return properties;
if (reset || root) {
const len = Number(reset || Infinity);
for (let i = 0; i <= len; i++) {
if (!properties || !('prev' in properties)) {
break;
}
properties = properties.prev;
}
return properties;
}
return mergeDeep(properties.prev, properties);
});
vue.provide(DefaultsSymbol, newDefaults);
return newDefaults;
}
function useToggleScope(source, fn) {
let scope;
function start() {
scope = vue.effectScope();
scope.run(() => fn.length ? fn(() => {
scope?.stop();
start();
}) : fn());
}
vue.watch(source, active => {
if (active && !scope) {
start();
} else if (!active) {
scope?.stop();
scope = undefined;
}
}, {
immediate: true
});
vue.onScopeDispose(() => {
scope?.stop();
});
}
// Utils
// Types
function propIsDefined(vnode, prop) {
return typeof vnode.props?.[prop] !== 'undefined' || typeof vnode.props?.[toKebabCase(prop)] !== 'undefined';
}
const defineComponent = function defineComponent(options) {
options._setup = options._setup ?? options.setup;
if (!options.name) {
consoleWarn('The component is missing an explicit name, unable to generate default prop value');
return options;
}
if (options._setup) {
options.props = options.props ?? {};
options.props = propsFactory(options.props, toKebabCase(options.name))();
options.props._as = String;
options.setup = function setup(props, ctx) {
const defaults = useDefaults();
// Skip props proxy if defaults are not provided
if (!defaults.value) return options._setup(props, ctx);
const vm = vue.getCurrentInstance();
const componentDefaults = vue.computed(() => defaults.value[props._as ?? options.name]);
const _props = new Proxy(props, {
get(target, prop) {
if (typeof prop === 'string' && !propIsDefined(vm.vnode, prop)) {
return componentDefaults.value?.[prop] ?? defaults.value.global?.[prop] ?? target[prop];
}
return Reflect.get(target, prop);
}
});
const _subcomponentDefaults = vue.shallowRef();
vue.watchEffect(() => {
if (componentDefaults.value) {
const subComponents = Object.entries(componentDefaults.value).filter(_ref => {
let [key] = _ref;
return key.startsWith(key[0].toUpperCase());
});
if (subComponents.length) _subcomponentDefaults.value = Object.fromEntries(subComponents);
}
});
const setupBindings = options._setup(_props, ctx);
// If subcomponent defaults are provided, override any
// subcomponents provided by the component's setup function.
// This uses injectSelf so must be done after the original setup to work.
useToggleScope(_subcomponentDefaults, () => {
provideDefaults(mergeDeep(injectSelf(DefaultsSymbol)?.value ?? {}, _subcomponentDefaults.value));
});
return setupBindings;
};
}
return options;
};
// Implementation
function genericComponent() {
let exposeDefaults = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
return options => (exposeDefaults ? defineComponent : vue.defineComponent)(options);
}
function createSimpleFunctional(klass) {
let tag = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'div';
let name = arguments.length > 2 ? arguments[2] : undefined;
return genericComponent()({
name: name ?? vue.capitalize(vue.camelize(klass.replace(/__/g, '-'))),
props: {
tag: {
type: String,
default: tag
}
},
setup(props, _ref) {
let {
slots
} = _ref;
return () => vue.h(props.tag, {
class: klass
}, slots.default?.());
}
});
}
/**
* Returns:
* - 'null' if the node is not attached to the DOM
* - the root node (HTMLDocument | ShadowRoot) otherwise
*/
function attachedRoot(node) {
/* istanbul ignore next */
if (typeof node.getRootNode !== 'function') {
// Shadow DOM not supported (IE11), lets find the root of this node
while (node.parentNode) node = node.parentNode;
// The root parent is the document if the node is attached to the DOM
if (node !== document) return null;
return document;
}
const root = node.getRootNode();
// The composed root node is the document if the node is attached to the DOM
if (root !== document && root.getRootNode({
composed: true
}) !== document) return null;
return root;
}
const standardEasing = 'cubic-bezier(0.4, 0, 0.2, 1)';
const deceleratedEasing = 'cubic-bezier(0.0, 0, 0.2, 1)'; // Entering
const acceleratedEasing = 'cubic-bezier(0.4, 0, 1, 1)'; // Leaving
function getScrollParent(el) {
while (el) {
if (hasScrollbar(el)) return el;
el = el.parentElement;
}
return document.scrollingElement;
}
function getScrollParents(el, stopAt) {
const elements = [];
if (stopAt && el && !stopAt.contains(el)) return elements;
while (el) {
if (hasScrollbar(el)) elements.push(el);
if (el === stopAt) break;
el = el.parentElement;
}
return elements;
}
function hasScrollbar(el) {
if (!el || el.nodeType !== Node.ELEMENT_NODE) return false;
const style = window.getComputedStyle(el);
return style.overflowY === 'scroll' || style.overflowY === 'auto' && el.scrollHeight > el.clientHeight;
}
function isFixedPosition(el) {
while (el) {
if (window.getComputedStyle(el).position === 'fixed') {
return true;
}
el = el.offsetParent;
}
return false;
}
// Utilities
// Types
function useRender(render) {
const vm = getCurrentInstance('useRender');
vm.render = render;
}
// Composables
// Types
const VuetifyLayoutKey = Symbol.for('vuetify:layout');
const VuetifyLayoutItemKey = Symbol.for('vuetify:layout-item');
const ROOT_ZINDEX = 1000;
const makeLayoutProps = propsFactory({
overlaps: {
type: Array,
default: () => []
},
fullHeight: Boolean
}, 'layout');
// Composables
const makeLayoutItemProps = propsFactory({
name: {
type: String
},
order: {
type: [Number, String],
default: 0
},
absolute: Boolean
}, 'layout-item');
function useLayout() {
const layout = vue.inject(VuetifyLayoutKey);
if (!layout) throw new Error('[Vuetify] Could not find injected layout');
return {
getLayoutItem: layout.getLayoutItem,
mainRect: layout.mainRect,
mainStyles: layout.mainStyles
};
}
function useLayoutItem(options) {
const layout = vue.inject(VuetifyLayoutKey);
if (!layout) throw new Error('[Vuetify] Could not find injected layout');
const id = options.id ?? `layout-item-${getUid()}`;
const vm = getCurrentInstance('useLayoutItem');
vue.provide(VuetifyLayoutItemKey, {
id
});
const isKeptAlive = vue.ref(false);
vue.onDeactivated(() => isKeptAlive.value = true);
vue.onActivated(() => isKeptAlive.value = false);
const {
layoutItemStyles,
layoutItemScrimStyles
} = layout.register(vm, {
...options,
active: vue.computed(() => isKeptAlive.value ? false : options.active.value),
id
});
vue.onBeforeUnmount(() => layout.unregister(id));
return {
layoutItemStyles,
layoutRect: layout.layoutRect,
layoutItemScrimStyles
};
}
const generateLayers = (layout, positions, layoutSizes, activeItems) => {
let previousLayer = {
top: 0,
left: 0,
right: 0,
bottom: 0
};
const layers = [{
id: '',
layer: {
...previousLayer
}
}];
for (const id of layout) {
const position = positions.get(id);
const amount = layoutSizes.get(id);
const active = activeItems.get(id);
if (!position || !amount || !active) continue;
const layer = {
...previousLayer,
[position.value]: parseInt(previousLayer[position.value], 10) + (active.value ? parseInt(amount.value, 10) : 0)
};
layers.push({
id,
layer
});
previousLayer = layer;
}
return layers;
};
function createLayout(props) {
const parentLayout = vue.inject(VuetifyLayoutKey, null);
const rootZIndex = vue.computed(() => parentLayout ? parentLayout.rootZIndex.value - 100 : ROOT_ZINDEX);
const registered = vue.ref([]);
const positions = vue.reactive(new Map());
const layoutSizes = vue.reactive(new Map());
const priorities = vue.reactive(new Map());
const activeItems = vue.reactive(new Map());
const disabledTransitions = vue.reactive(new Map());
const {
resizeRef,
contentRect: layoutRect
} = useResizeObserver();
const computedOverlaps = vue.computed(() => {
const map = new Map();
const overlaps = props.overlaps ?? [];
for (const overlap of overlaps.filter(item => item.includes(':'))) {
const [top, bottom] = overlap.split(':');
if (!registered.value.includes(top) || !registered.value.includes(bottom)) continue;
const topPosition = positions.get(top);
const bottomPosition = positions.get(bottom);
const topAmount = layoutSizes.get(top);
const bottomAmount = layoutSizes.get(bottom);
if (!topPosition || !bottomPosition || !topAmount || !bottomAmount) continue;
map.set(bottom, {
position: topPosition.value,
amount: parseInt(topAmount.value, 10)
});
map.set(top, {
position: bottomPosition.value,
amount: -parseInt(bottomAmount.value, 10)
});
}
return map;
});
const layers = vue.computed(() => {
const uniquePriorities = [...new Set([...priorities.values()].map(p => p.value))].sort((a, b) => a - b);
const layout = [];
for (const p of uniquePriorities) {
const items = registered.value.filter(id => priorities.get(id)?.value === p);
layout.push(...items);
}
return generateLayers(layout, positions, layoutSizes, activeItems);
});
const transitionsEnabled = vue.computed(() => {
return !Array.from(disabledTransitions.values()).some(ref => ref.value);
});
const mainRect = vue.computed(() => {
return layers.value[layers.value.length - 1].layer;
});
const mainStyles = vue.computed(() => {
return {
'--v-layout-left': convertToUnit(mainRect.value.left),
'--v-layout-right': convertToUnit(mainRect.value.right),
'--v-layout-top': convertToUnit(mainRect.value.top),
'--v-layout-bottom': convertToUnit(mainRect.value.bottom),
...(transitionsEnabled.value ? undefined : {
transition: 'none'
})
};
});
const items = vue.computed(() => {
return layers.value.slice(1).map((_ref, index) => {
let {
id
} = _ref;
const {
layer
} = layers.value[index];
const size = layoutSizes.get(id);
const position = positions.get(id);
return {
id,
...layer,
size: Number(size.value),
position: position.value
};
});
});
const getLayoutItem = id => {
return items.value.find(item => item.id === id);
};
const rootVm = getCurrentInstance('createLayout');
const isMounted = vue.ref(false);
vue.onMounted(() => {
isMounted.value = true;
});
vue.provide(VuetifyLayoutKey, {
register: (vm, _ref2) => {
let {
id,
order,
position,
layoutSize,
elementSize,
active,
disableTransitions,
absolute
} = _ref2;
priorities.set(id, order);
positions.set(id, position);
layoutSizes.set(id, layoutSize);
activeItems.set(id, active);
disableTransitions && disabledTransitions.set(id, disableTransitions);
const instances = findChildrenWithProvide(VuetifyLayoutItemKey, rootVm?.vnode);
const instanceIndex = instances.indexOf(vm);
if (instanceIndex > -1) registered.value.splice(instanceIndex, 0, id);else registered.value.push(id);
const index = vue.computed(() => items.value.findIndex(i => i.id === id));
const zIndex = vue.computed(() => rootZIndex.value + layers.value.length * 2 - index.value * 2);
const layoutItemStyles = vue.computed(() => {
const isHorizontal = position.value === 'left' || position.value === 'right';
const isOppositeHorizontal = position.value === 'right';
const isOppositeVertical = position.value === 'bottom';
const styles = {
[position.value]: 0,
zIndex: zIndex.value,
transform: `translate${isHorizontal ? 'X' : 'Y'}(${(active.value ? 0 : -110) * (isOppositeHorizontal || isOppositeVertical ? -1 : 1)}%)`,
position: absolute.value || rootZIndex.value !== ROOT_ZINDEX ? 'absolute' : 'fixed',
...(transitionsEnabled.value ? undefined : {
transition: 'none'
})
};
if (!isMounted.value) return styles;
const item = items.value[index.value];
if (!item) throw new Error(`[Vuetify] Could not find layout item "${id}"`);
const overlap = computedOverlaps.value.get(id);
if (overlap) {
item[overlap.position] += overlap.amount;
}
return {
...styles,
height: isHorizontal ? `calc(100% - ${item.top}px - ${item.bottom}px)` : elementSize.value ? `${elementSize.value}px` : undefined,
left: isOppositeHorizontal ? undefined : `${item.left}px`,
right: isOppositeHorizontal ? `${item.right}px` : undefined,
top: position.value !== 'bottom' ? `${item.top}px` : undefined,
bottom: position.value !== 'top' ? `${item.bottom}px` : undefined,
width: !isHorizontal ? `calc(100% - ${item.left}px - ${item.right}px)` : elementSize.value ? `${elementSize.value}px` : undefined
};
});
const layoutItemScrimStyles = vue.computed(() => ({
zIndex: zIndex.value - 1
}));
return {
layoutItemStyles,
layoutItemScrimStyles,
zIndex
};
},
unregister: id => {
priorities.delete(id);
positions.delete(id);
layoutSizes.delete(id);
activeItems.delete(id);
disabledTransitions.delete(id);
registered.value = registered.value.filter(v => v !== id);
},
mainRect,
mainStyles,
getLayoutItem,
items,
layoutRect,
rootZIndex
});
const layoutClasses = vue.computed(() => ['v-layout', {
'v-layout--full-height': props.fullHeight
}]);
const layoutStyles = vue.computed(() => ({
zIndex: rootZIndex.value,
position: parentLayout ? 'relative' : undefined,
overflow: parentLayout ? 'hidden' : undefined
}));
return {
layoutClasses,
layoutStyles,
getLayoutItem,
items,
layoutRect,
layoutRef: resizeRef
};
}
/**
* WCAG 3.0 APCA perceptual contrast algorithm from https://github.com/Myndex/SAPC-APCA
* @licence https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
* @see https://www.w3.org/WAI/GL/task-forces/silver/wiki/Visual_Contrast_of_Text_Subgroup
*/
// MAGICAL NUMBERS
// sRGB Conversion to Relative Luminance (Y)
// Transfer Curve (aka "Gamma") for sRGB linearization
// Simple power curve vs piecewise described in docs
// Essentially, 2.4 best models actual display
// characteristics in combination with the total method
const mainTRC = 2.4;
const Rco = 0.2126729; // sRGB Red Coefficient (from matrix)
const Gco = 0.7151522; // sRGB Green Coefficient (from matrix)
const Bco = 0.0721750; // sRGB Blue Coefficient (from matrix)
// For Finding Raw SAPC Contrast from Relative Luminance (Y)
// Constants for SAPC Power Curve Exponents
// One pair for normal text, and one for reverse
// These are the "beating heart" of SAPC
const normBG = 0.55;
const normTXT = 0.58;
const revTXT = 0.57;
const revBG = 0.62;
// For Clamping and Scaling Values
const blkThrs = 0.03; // Level that triggers the soft black clamp
const blkClmp = 1.45; // Exponent for the soft black clamp curve
const deltaYmin = 0.0005; // Lint trap
const scaleBoW = 1.25; // Scaling for dark text on light
const scaleWoB = 1.25; // Scaling for light text on dark
const loConThresh = 0.078; // Threshold for new simple offset scale
const loConFactor = 12.82051282051282; // = 1/0.078,
const loConOffset = 0.06; // The simple offset
const loClip = 0.001; // Output clip (lint trap #2)
function APCAcontrast(text, background) {
// Linearize sRGB
const Rtxt = (text.r / 255) ** mainTRC;
const Gtxt = (text.g / 255) ** mainTRC;
const Btxt = (text.b / 255) ** mainTRC;
const Rbg = (background.r / 255) ** mainTRC;
const Gbg = (background.g / 255) ** mainTRC;
const Bbg = (background.b / 255) ** mainTRC;
// Apply the standard coefficients and sum to Y
let Ytxt = Rtxt * Rco + Gtxt * Gco + Btxt * Bco;
let Ybg = Rbg * Rco + Gbg * Gco + Bbg * Bco;
// Soft clamp Y when near black.
// Now clamping all colors to prevent crossover errors
if (Ytxt <= blkThrs) Ytxt += (blkThrs - Ytxt) ** blkClmp;
if (Ybg <= blkThrs) Ybg += (blkThrs - Ybg) ** blkClmp;
// Return 0 Early for extremely low ∆Y (lint trap #1)
if (Math.abs(Ybg - Ytxt) < deltaYmin) return 0.0;
// SAPC CONTRAST
let outputContrast; // For weighted final values
if (Ybg > Ytxt) {
// For normal polarity, black text on white
// Calculate the SAPC contrast value and scale
const SAPC = (Ybg ** normBG - Ytxt ** normTXT) * scaleBoW;
// NEW! SAPC SmoothScale™
// Low Contrast Smooth Scale Rollout to prevent polarity reversal
// and also a low clip for very low contrasts (lint trap #2)
// much of this is for very low contrasts, less than 10
// therefore for most reversing needs, only loConOffset is important
outputContrast = SAPC < loClip ? 0.0 : SAPC < loConThresh ? SAPC - SAPC * loConFactor * loConOffset : SAPC - loConOffset;
} else {
// For reverse polarity, light text on dark
// WoB should always return negative value.
const SAPC = (Ybg ** revBG - Ytxt ** revTXT) * scaleWoB;
outputContrast = SAPC > -loClip ? 0.0 : SAPC > -loConThresh ? SAPC - SAPC * loConFactor * loConOffset : SAPC + loConOffset;
}
return outputContrast * 100;
}
// Utilities
// Types
const ThemeSymbol = Symbol.for('vuetify:theme');
const makeThemeProps = propsFactory({
theme: String
}, 'theme');
const defaultThemeOptions = {
defaultTheme: 'light',
variations: {
colors: [],
lighten: 0,
darken: 0
},
themes: {
light: {
dark: false,
colors: {
background: '#FFFFFF',
surface: '#FFFFFF',
'surface-variant': '#424242',
'on-surface-variant': '#EEEEEE',
primary: '#6200EE',
'primary-darken-1': '#3700B3',
secondary: '#03DAC6',
'secondary-darken-1': '#018786',
error: '#B00020',
info: '#2196F3',
success: '#4CAF50',
warning: '#FB8C00'
},
variables: {
'border-color': '#000000',
'border-opacity': 0.12,
'high-emphasis-opacity': 0.87,
'medium-emphasis-opacity': 0.60,
'disabled-opacity': 0.38,
'idle-opacity': 0.04,
'hover-opacity': 0.04,
'focus-opacity': 0.12,
'selected-opacity': 0.08,
'activated-opacity': 0.12,
'pressed-opacity': 0.12,
'dragged-opacity': 0.08,
'theme-kbd': '#212529',
'theme-on-kbd': '#FFFFFF',
'theme-code': '#F5F5F5',
'theme-on-code': '#000000'
}
},
dark: {
dark: true,
colors: {
background: '#121212',
surface: '#212121',