import { defineComponent, ref, Transition as Trans } from "vue";
import type { VNode, PropType, InputHTMLAttributes } from "vue";
import { v4 as uuid } from "uuid";
import { COLOR_SCHEME } from "@darwin-studio/ui-codegen/dist/constants/color-scheme";
import { PADDING } from "@darwin-studio/ui-codegen/dist/constants/padding"; // TODO: shorter path, default export ???
import { SIZE } from "@darwin-studio/ui-codegen/dist/constants/size"; // TODO: shorter path, default export ???
import colorSchemeStyles from "@darwin-studio/ui-codegen/dist/styles/color-scheme.css?module"; // TODO: shorter path, default export ??? TODO: make it module ???
import useCaption from "@darwin-studio/vue-ui/src/compositions/caption";
import { EVENT_NAME } from "@darwin-studio/vue-ui/src/constants/event-name";
import type { Text } from "@darwin-studio/vue-ui/src/types/text";
import { DCaptionProps } from "@darwin-studio/vue-ui/src/components/atoms/d-caption/types";
import generateProp from "@darwin-studio/vue-ui/src/utils/generate-prop";
import generateClass from "@darwin-studio/vue-ui/src/utils/generate-class";
import config from "./config";
import styles from "./index.css?module";
/**
* Renders input element with type="checkbox", label, error and customizable ✓ icon.
*/
// TODO: indeterminate (or mixed) state
export default defineComponent({
name: config.name,
props: {
/**
* Defines id attr of the input element.
* If you don't want to specify it, it will be generated automatically.
*/
id: generateProp.text(() => uuid()),
/**
* Defines is the component is checked by default
*/
checked: Boolean,
/**
* Defines value of the input element
*/
value: generateProp.text(config.value),
/**
* Defines appearance of the component
*/
colorScheme: generateProp.colorScheme(COLOR_SCHEME.SECONDARY), // TODO: config
/**
* Defines corner rounding of the icon container element
*/
rounding: generateProp.rounding(),
/**
* Defines size of the component
*/
// TODO: fontSize and size separately ???
size: generateProp.size(SIZE.TINY),
/**
* Defines transition type of the component
*/
transition: generateProp.transition(),
/**
* You can pass own class name to the input element.
*/
inputClass: String,
/**
* You can pass any attributes to the input element.
*/
inputAttrs: generateProp.options(),
/**
* Defines content of the label element.
*/
label: generateProp.content(),
/**
* You can pass own class name to the label element.
*/
// TODO: move to labelOptions:
labelClass: String,
/**
* Defines font size of the label element. By default depends on props.size
*/
// TODO: move to labelOptions:
labelFont: generateProp.font(),
/**
* If not empty renders DCaption below the input element.
*/
caption: generateProp.content(),
/**
* Pass any DCaption.props to customize it, f.e. { type: "error" }
*/
captionOptions: generateProp.options(config.captionOptions),
/**
* Defines offset of DCaption
*/
captionOffset: generateProp.text(config.captionOffset), // TODO: move to captionOptions
/**
* You can pass own class name to the icon container element.
*/
// TODO: option ???
iconContainerClass: String,
/**
* Pass true to disable input element.
*/
disabled: Boolean,
/**
* Defines container element type of the component
*/
tag: generateProp.tag(),
/**
* Alternative way to catch change event
*/
whenChange: {
type: Function as PropType<
(checked?: boolean, value?: Text) => void | Promise
>,
},
/**
* Alternative way to catch input event
*/
whenInput: {
type: Function as PropType<(value?: Text) => void | Promise>,
},
},
setup(props, { slots }) {
const innerChecked = ref(props.checked); // TODO: what for, remove ???
const { renderCaption } = useCaption(props, slots, config.captionOptions);
return { innerChecked, renderCaption };
},
emits: [
EVENT_NAME.CHANGE,
EVENT_NAME.INPUT,
EVENT_NAME.UPDATE_CHECKED,
EVENT_NAME.UPDATE_VALUE,
],
computed: {
renderIcon(): VNode[] {
const iconContainerClasses = [
config.iconContainerClass,
generateClass.border(this.colorScheme, this.size),
generateClass.colorScheme(this.colorScheme),
...generateClass.padding(PADDING.EQUAL, this.size),
generateClass.rounding(this.rounding),
generateClass.size(this.size),
generateClass.transition(this.transition),
];
if (this.disabled) {
iconContainerClasses.push(colorSchemeStyles.__disabled);
}
if (this.iconContainerClass) {
iconContainerClasses.push(this.iconContainerClass);
}
// TODO: try not to use backdrop at all
return [
,