Vulture/VApp/node_modules/vuetify/lib/components/VSelectionControl/VSelectionControl.mjs

208 lines
7.0 KiB
JavaScript
Raw Normal View History

import { withDirectives as _withDirectives, resolveDirective as _resolveDirective, Fragment as _Fragment, createVNode as _createVNode, mergeProps as _mergeProps } from "vue";
// Styles
import "./VSelectionControl.css";
// Components
import { VIcon } from "../VIcon/index.mjs";
import { VLabel } from "../VLabel/index.mjs";
import { makeSelectionControlGroupProps, VSelectionControlGroupSymbol } from "../VSelectionControlGroup/VSelectionControlGroup.mjs"; // Composables
import { useBackgroundColor, useTextColor } from "../../composables/color.mjs";
import { makeComponentProps } from "../../composables/component.mjs";
import { useDensity } from "../../composables/density.mjs";
import { useProxiedModel } from "../../composables/proxiedModel.mjs"; // Directives
import { Ripple } from "../../directives/ripple/index.mjs"; // Utilities
import { computed, inject, nextTick, ref, shallowRef } from 'vue';
import { filterInputAttrs, genericComponent, getUid, matchesSelector, propsFactory, useRender, wrapInArray } from "../../util/index.mjs"; // Types
export const makeVSelectionControlProps = propsFactory({
label: String,
baseColor: String,
trueValue: null,
falseValue: null,
value: null,
...makeComponentProps(),
...makeSelectionControlGroupProps()
}, 'VSelectionControl');
export function useSelectionControl(props) {
const group = inject(VSelectionControlGroupSymbol, undefined);
const {
densityClasses
} = useDensity(props);
const modelValue = useProxiedModel(props, 'modelValue');
const trueValue = computed(() => props.trueValue !== undefined ? props.trueValue : props.value !== undefined ? props.value : true);
const falseValue = computed(() => props.falseValue !== undefined ? props.falseValue : false);
const isMultiple = computed(() => !!props.multiple || props.multiple == null && Array.isArray(modelValue.value));
const model = computed({
get() {
const val = group ? group.modelValue.value : modelValue.value;
return isMultiple.value ? wrapInArray(val).some(v => props.valueComparator(v, trueValue.value)) : props.valueComparator(val, trueValue.value);
},
set(val) {
if (props.readonly) return;
const currentValue = val ? trueValue.value : falseValue.value;
let newVal = currentValue;
if (isMultiple.value) {
newVal = val ? [...wrapInArray(modelValue.value), currentValue] : wrapInArray(modelValue.value).filter(item => !props.valueComparator(item, trueValue.value));
}
if (group) {
group.modelValue.value = newVal;
} else {
modelValue.value = newVal;
}
}
});
const {
textColorClasses,
textColorStyles
} = useTextColor(computed(() => {
if (props.error || props.disabled) return undefined;
return model.value ? props.color : props.baseColor;
}));
const {
backgroundColorClasses,
backgroundColorStyles
} = useBackgroundColor(computed(() => {
return model.value && !props.error && !props.disabled ? props.color : undefined;
}));
const icon = computed(() => model.value ? props.trueIcon : props.falseIcon);
return {
group,
densityClasses,
trueValue,
falseValue,
model,
textColorClasses,
textColorStyles,
backgroundColorClasses,
backgroundColorStyles,
icon
};
}
export const VSelectionControl = genericComponent()({
name: 'VSelectionControl',
directives: {
Ripple
},
inheritAttrs: false,
props: makeVSelectionControlProps(),
emits: {
'update:modelValue': value => true
},
setup(props, _ref) {
let {
attrs,
slots
} = _ref;
const {
group,
densityClasses,
icon,
model,
textColorClasses,
textColorStyles,
backgroundColorClasses,
backgroundColorStyles,
trueValue
} = useSelectionControl(props);
const uid = getUid();
const isFocused = shallowRef(false);
const isFocusVisible = shallowRef(false);
const input = ref();
const id = computed(() => props.id || `input-${uid}`);
const isInteractive = computed(() => !props.disabled && !props.readonly);
group?.onForceUpdate(() => {
if (input.value) {
input.value.checked = model.value;
}
});
function onFocus(e) {
if (!isInteractive.value) return;
isFocused.value = true;
if (matchesSelector(e.target, ':focus-visible') !== false) {
isFocusVisible.value = true;
}
}
function onBlur() {
isFocused.value = false;
isFocusVisible.value = false;
}
function onClickLabel(e) {
e.stopPropagation();
}
function onInput(e) {
if (!isInteractive.value) return;
if (props.readonly && group) {
nextTick(() => group.forceUpdate());
}
model.value = e.target.checked;
}
useRender(() => {
const label = slots.label ? slots.label({
label: props.label,
props: {
for: id.value
}
}) : props.label;
const [rootAttrs, inputAttrs] = filterInputAttrs(attrs);
const inputNode = _createVNode("input", _mergeProps({
"ref": input,
"checked": model.value,
"disabled": !!props.disabled,
"id": id.value,
"onBlur": onBlur,
"onFocus": onFocus,
"onInput": onInput,
"aria-disabled": !!props.disabled,
"type": props.type,
"value": trueValue.value,
"name": props.name,
"aria-checked": props.type === 'checkbox' ? model.value : undefined
}, inputAttrs), null);
return _createVNode("div", _mergeProps({
"class": ['v-selection-control', {
'v-selection-control--dirty': model.value,
'v-selection-control--disabled': props.disabled,
'v-selection-control--error': props.error,
'v-selection-control--focused': isFocused.value,
'v-selection-control--focus-visible': isFocusVisible.value,
'v-selection-control--inline': props.inline
}, densityClasses.value, props.class]
}, rootAttrs, {
"style": props.style
}), [_createVNode("div", {
"class": ['v-selection-control__wrapper', textColorClasses.value],
"style": textColorStyles.value
}, [slots.default?.({
backgroundColorClasses,
backgroundColorStyles
}), _withDirectives(_createVNode("div", {
"class": ['v-selection-control__input']
}, [slots.input?.({
model,
textColorClasses,
textColorStyles,
backgroundColorClasses,
backgroundColorStyles,
inputNode,
icon: icon.value,
props: {
onFocus,
onBlur,
id: id.value
}
}) ?? _createVNode(_Fragment, null, [icon.value && _createVNode(VIcon, {
"key": "icon",
"icon": icon.value
}, null), inputNode])]), [[_resolveDirective("ripple"), props.ripple && [!props.disabled && !props.readonly, null, ['center', 'circle']]]])]), label && _createVNode(VLabel, {
"for": id.value,
"onClick": onClickLabel
}, {
default: () => [label]
})]);
});
return {
isFocused,
input
};
}
});
//# sourceMappingURL=VSelectionControl.mjs.map