import type { VNode } from 'vue'; import type { DropdownButtonItemArgs } from '../dropdown-button/dropdown-button-item'; import type { FormItemWrapperArgs, MarginType } from '../form/form-item-wrapper'; import { Prop, toNative } from 'vue-facing-decorator'; import TsxComponent, { Component } from '../../app/vuetsx'; import { PortalUtils } from '../../common/utils/utils'; import FormItemWrapper from '../form/form-item-wrapper'; import HtmlLiteral from '../html-literal/html-literal'; import './css/checkbox.css'; interface CheckBoxArgs extends Omit { name?: string; value: boolean; checkboxLabelHtml?: string; customRenderOption?: (h, state: CheckBoxDisplayArgs) => any; skin?: CheckBoxSkin; size?: CheckBoxSize; disabled?: boolean; changed?: (newValue: boolean) => void; } export enum CheckBoxSkin { NowUi = 0, Material = 1, // default MinusVariant = 2, } export enum CheckBoxSize { Small = 'sm', Medium = 'md', } interface CheckBoxDisplayArgs { checked: boolean; disabled: boolean; } @Component class CheckBoxComponent extends TsxComponent implements CheckBoxArgs { @Prop() name?: string; @Prop() label!: string | VNode; @Prop() labelButtons!: DropdownButtonItemArgs[]; @Prop() cssClass!: string; @Prop() subtitle!: string; @Prop() checkboxLabelHtml!: string; @Prop() customRenderOption?: (h, state: CheckBoxDisplayArgs) => any; @Prop() value!: boolean; @Prop() mandatory!: boolean; @Prop() wrap!: boolean; @Prop() maxWidth?: number; @Prop() skin!: CheckBoxSkin; @Prop() size?: CheckBoxSize; @Prop() disabled?: boolean; @Prop() marginType?: MarginType; @Prop() hint: string; @Prop() appendIcon: string; @Prop() prependIcon: string; @Prop() appendClicked: () => void; @Prop() prependClicked: () => void; @Prop() changed: (newValue: boolean) => void; uuid: string = null; private get errorId(): string { return `checkbox-error-${this.$.uid}`; } getCustomRenderedLabel(h) { if (this.customRenderOption != null) { const displayArgs: CheckBoxDisplayArgs = { checked: this.value, disabled: this.disabled ?? false, }; return this.customRenderOption(h, displayArgs); } return null; } raiseChangeEvent(e) { this.populateValidationDeclaration(); const val = e.target.checked; if (this.changed != null) { this.changed(val); } } render(h) { return ( {this.renderCheckboxBasedOnSkin(h)} ); } renderCheckboxBasedOnSkin(h) { if (this.skin == CheckBoxSkin.NowUi) { return this.renderCheckboxNowUi(h); } else if (this.skin == CheckBoxSkin.MinusVariant) { return this.renderCheckboxMaterialMinus(h); } // default -> CheckBoxSkin.Material return this.renderCheckboxMaterial(h); } renderCheckboxNowUi(h) { const checkboxClass = `form-check ${this.wrap ? 'ui-checkbox-wrapped' : 'ui-checkbox-nonwrapped' }${this.size === CheckBoxSize.Small ? ' ui-checkbox-sm' : ''}`; return (
); } renderCheckboxMaterial(h) { if (this.uuid == null) { this.uuid = PortalUtils.randomString(12); } const checkboxClass = `inv-md-checkbox${this.size === CheckBoxSize.Small ? ' inv-md-checkbox-sm' : ''}`; return (
this.raiseChangeEvent(e)} name={this.name} aria-invalid={this.hasValidationError ? 'true' : undefined} aria-describedby={this.hasValidationError ? this.errorId : undefined} aria-required={this.mandatory ? 'true' : undefined} />
); } renderCheckboxMaterialMinus(h) { if (this.uuid == null) { this.uuid = PortalUtils.randomString(12); } const checkboxClass = `inv-md-checkbox${this.size === CheckBoxSize.Small ? ' inv-md-checkbox-sm' : '' }${this.skin === CheckBoxSkin.MinusVariant ? ' inv-md-checkbox-minus' : ''}`; return (
this.raiseChangeEvent(e)} name={this.name} aria-invalid={this.hasValidationError ? 'true' : undefined} aria-describedby={this.hasValidationError ? this.errorId : undefined} aria-required={this.mandatory ? 'true' : undefined} />
); } } const CheckBox = toNative(CheckBoxComponent); export default CheckBox;