Implemented Checkbox
parent
e21ab4a480
commit
18848a9803
|
@ -22,6 +22,10 @@
|
|||
"name": "Components",
|
||||
"icon": "pi pi-compass",
|
||||
"children": [
|
||||
{
|
||||
"name": "Checkbox",
|
||||
"to": "/checkbox"
|
||||
},
|
||||
{
|
||||
"name": "InputMask",
|
||||
"to": "/inputmask"
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
<template>
|
||||
<DocSectionText v-bind="$attrs">
|
||||
<p>Binary checkbox is used with the <i>v-model</i> for two-way value binding and the <i>binary</i> property.</p>
|
||||
</DocSectionText>
|
||||
<div class="card flex justify-center">
|
||||
<Checkbox v-model="checked" binary />
|
||||
</div>
|
||||
<DocSectionCode :code="code" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Checkbox from '@/plex/checkbox';
|
||||
import { ref } from 'vue';
|
||||
|
||||
const checked = ref(false);
|
||||
|
||||
const code = ref(`
|
||||
<template>
|
||||
<div class="card flex justify-center">
|
||||
<Checkbox v-model="checked" binary />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Checkbox from '@/plex/checkbox';
|
||||
import { ref } from 'vue';
|
||||
|
||||
const checked = ref(false);
|
||||
<\/script>
|
||||
`);
|
||||
</script>
|
|
@ -0,0 +1,35 @@
|
|||
<template>
|
||||
<DocSectionText v-bind="$attrs">
|
||||
<p>When <i>disabled</i> is present, the element cannot be edited and focused.</p>
|
||||
</DocSectionText>
|
||||
<div class="card flex justify-center gap-2">
|
||||
<Checkbox v-model="checked1" binary disabled />
|
||||
<Checkbox v-model="checked2" binary disabled />
|
||||
</div>
|
||||
<DocSectionCode :code="code" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Checkbox from '@/plex/checkbox';
|
||||
import { ref } from 'vue';
|
||||
|
||||
const checked1 = ref(false);
|
||||
const checked2 = ref(true);
|
||||
|
||||
const code = ref(`
|
||||
<template>
|
||||
<div class="card flex justify-center gap-2">
|
||||
<Checkbox v-model="checked1" binary disabled />
|
||||
<Checkbox v-model="checked2" binary disabled />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Checkbox from '@/plex/checkbox';
|
||||
import { ref } from 'vue';
|
||||
|
||||
const checked1 = ref(false);
|
||||
const checked2 = ref(true);
|
||||
<\/script>
|
||||
`);
|
||||
</script>
|
|
@ -0,0 +1,53 @@
|
|||
<template>
|
||||
<DocSectionText v-bind="$attrs">
|
||||
<p>Checkboxes can be generated using a list of values.</p>
|
||||
</DocSectionText>
|
||||
<div class="card flex justify-center">
|
||||
<div class="flex flex-col gap-4">
|
||||
<div v-for="category of categories" :key="category.key" class="flex items-center gap-2">
|
||||
<Checkbox v-model="selectedCategories" :inputId="category.key" name="category" :value="category.name" />
|
||||
<label :for="category.key">{{ category.name }}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<DocSectionCode :code="code" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Checkbox from '@/plex/checkbox';
|
||||
import { ref } from 'vue';
|
||||
|
||||
const selectedCategories = ref(['Marketing']);
|
||||
const categories = ref([
|
||||
{ name: 'Accounting', key: 'A' },
|
||||
{ name: 'Marketing', key: 'M' },
|
||||
{ name: 'Production', key: 'P' },
|
||||
{ name: 'Research', key: 'R' }
|
||||
]);
|
||||
|
||||
const code = ref(`
|
||||
<template>
|
||||
<div class="card flex justify-center">
|
||||
<div class="flex flex-col gap-4">
|
||||
<div v-for="category of categories" :key="category.key" class="flex items-center gap-2">
|
||||
<Checkbox v-model="selectedCategories" :inputId="category.key" name="category" :value="category.name" />
|
||||
<label :for="category.key">{{ category.name }}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Checkbox from '@/plex/checkbox';
|
||||
import { ref } from 'vue';
|
||||
|
||||
const selectedCategories = ref(['Marketing']);
|
||||
const categories = ref([
|
||||
{ name: 'Accounting', key: 'A' },
|
||||
{ name: 'Marketing', key: 'M' },
|
||||
{ name: 'Production', key: 'P' },
|
||||
{ name: 'Research', key: 'R' }
|
||||
]);
|
||||
<\/script>
|
||||
`);
|
||||
</script>
|
|
@ -0,0 +1,31 @@
|
|||
<template>
|
||||
<DocSectionText v-bind="$attrs">
|
||||
<p>Specify the <i>variant</i> property as <i>filled</i> to display the component with a higher visual emphasis than the default <i>outlined</i> style.</p>
|
||||
</DocSectionText>
|
||||
<div class="card flex justify-center">
|
||||
<Checkbox v-model="checked" binary variant="filled" />
|
||||
</div>
|
||||
<DocSectionCode :code="code" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Checkbox from '@/plex/checkbox';
|
||||
import { ref } from 'vue';
|
||||
|
||||
const checked = ref(false);
|
||||
|
||||
const code = ref(`
|
||||
<template>
|
||||
<div class="card flex justify-center">
|
||||
<Checkbox v-model="checked" binary variant="filled" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Checkbox from '@/plex/checkbox';
|
||||
import { ref } from 'vue';
|
||||
|
||||
const checked = ref(false);
|
||||
<\/script>
|
||||
`);
|
||||
</script>
|
|
@ -0,0 +1,61 @@
|
|||
<template>
|
||||
<DocSectionText v-bind="$attrs">
|
||||
<p>Multiple checkboxes can be grouped together.</p>
|
||||
</DocSectionText>
|
||||
<div class="card flex flex-wrap justify-center gap-4">
|
||||
<div class="flex items-center gap-2">
|
||||
<Checkbox v-model="pizza" inputId="ingredient1" name="pizza" value="Cheese" />
|
||||
<label for="ingredient1"> Cheese </label>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<Checkbox v-model="pizza" inputId="ingredient2" name="pizza" value="Mushroom" />
|
||||
<label for="ingredient2"> Mushroom </label>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<Checkbox v-model="pizza" inputId="ingredient3" name="pizza" value="Pepper" />
|
||||
<label for="ingredient3"> Pepper </label>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<Checkbox v-model="pizza" inputId="ingredient4" name="pizza" value="Onion" />
|
||||
<label for="ingredient4"> Onion </label>
|
||||
</div>
|
||||
</div>
|
||||
<DocSectionCode :code="code" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Checkbox from '@/plex/checkbox';
|
||||
import { ref } from 'vue';
|
||||
|
||||
const pizza = ref(null);
|
||||
|
||||
const code = ref(`
|
||||
<template>
|
||||
<div class="card flex flex-wrap justify-center gap-4">
|
||||
<div class="flex items-center gap-2">
|
||||
<Checkbox v-model="pizza" inputId="ingredient1" name="pizza" value="Cheese" />
|
||||
<label for="ingredient1"> Cheese </label>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<Checkbox v-model="pizza" inputId="ingredient2" name="pizza" value="Mushroom" />
|
||||
<label for="ingredient2"> Mushroom </label>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<Checkbox v-model="pizza" inputId="ingredient3" name="pizza" value="Pepper" />
|
||||
<label for="ingredient3"> Pepper </label>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<Checkbox v-model="pizza" inputId="ingredient4" name="pizza" value="Onion" />
|
||||
<label for="ingredient4"> Onion </label>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Checkbox from '@/plex/checkbox';
|
||||
import { ref } from 'vue';
|
||||
|
||||
const pizza = ref(null);
|
||||
<\/script>
|
||||
`);
|
||||
</script>
|
|
@ -0,0 +1,16 @@
|
|||
<template>
|
||||
<DocSectionText v-bind="$attrs" />
|
||||
<DocSectionCode :code="code" lang="script" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
code: `
|
||||
import Checkbox from '@/plex/checkbox';
|
||||
`
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,31 @@
|
|||
<template>
|
||||
<DocSectionText v-bind="$attrs">
|
||||
<p>When <i>indeterminate</i> is present, the checkbox masks the actual value visually.</p>
|
||||
</DocSectionText>
|
||||
<div class="card flex justify-center">
|
||||
<Checkbox v-model="checked" indeterminate binary />
|
||||
</div>
|
||||
<DocSectionCode :code="code" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Checkbox from '@/plex/checkbox';
|
||||
import { ref } from 'vue';
|
||||
|
||||
const checked = ref(false);
|
||||
|
||||
const code = ref(`
|
||||
<template>
|
||||
<div class="card flex justify-center">
|
||||
<Checkbox v-model="checked" indeterminate binary />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Checkbox from '@/plex/checkbox';
|
||||
import { ref } from 'vue';
|
||||
|
||||
const checked = ref(false);
|
||||
<\/script>
|
||||
`);
|
||||
</script>
|
|
@ -0,0 +1,31 @@
|
|||
<template>
|
||||
<DocSectionText v-bind="$attrs">
|
||||
<p>Invalid state is displayed using the <i>invalid</i> prop to indicate a failed validation. You can use this style when integrating with form validation libraries.</p>
|
||||
</DocSectionText>
|
||||
<div class="card flex justify-center">
|
||||
<Checkbox v-model="checked" :invalid="!checked" binary />
|
||||
</div>
|
||||
<DocSectionCode :code="code" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Checkbox from '@/plex/checkbox';
|
||||
import { ref } from 'vue';
|
||||
|
||||
const checked = ref(false);
|
||||
|
||||
const code = ref(`
|
||||
<template>
|
||||
<div class="card flex justify-center">
|
||||
<Checkbox v-model="checked" :invalid="!checked" binary />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Checkbox from '@/plex/checkbox';
|
||||
import { ref } from 'vue';
|
||||
|
||||
const checked = ref(false);
|
||||
<\/script>
|
||||
`);
|
||||
</script>
|
|
@ -0,0 +1,53 @@
|
|||
<template>
|
||||
<DocSectionText v-bind="$attrs">
|
||||
<p>Checkbox provides <i>small</i> and <i>large</i> sizes as alternatives to the base.</p>
|
||||
</DocSectionText>
|
||||
<div class="card flex flex-wrap justify-center gap-4">
|
||||
<div class="flex items-center gap-2">
|
||||
<Checkbox v-model="size" inputId="size_small" name="size" value="Small" size="small" />
|
||||
<label for="size_small" class="text-sm">Small</label>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<Checkbox v-model="size" inputId="size_normal" name="size" value="Normal" />
|
||||
<label for="size_normal">Normal</label>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<Checkbox v-model="size" inputId="size_large" name="size" value="Large" size="large" />
|
||||
<label for="size_large" class="text-lg">Large</label>
|
||||
</div>
|
||||
</div>
|
||||
<DocSectionCode :code="code" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Checkbox from '@/plex/checkbox';
|
||||
import { ref } from 'vue';
|
||||
|
||||
const size = ref(null);
|
||||
|
||||
const code = ref(`
|
||||
<template>
|
||||
<div class="card flex flex-wrap justify-center gap-4">
|
||||
<div class="flex items-center gap-2">
|
||||
<Checkbox v-model="size" inputId="size_small" name="size" value="Small" size="small" />
|
||||
<label for="size_small" class="text-sm">Small</label>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<Checkbox v-model="size" inputId="size_normal" name="size" value="Normal" />
|
||||
<label for="size_normal">Normal</label>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<Checkbox v-model="size" inputId="size_large" name="size" value="Large" size="large" />
|
||||
<label for="size_large" class="text-lg">Large</label>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Checkbox from '@/plex/checkbox';
|
||||
import { ref } from 'vue';
|
||||
|
||||
const size = ref(null);
|
||||
<\/script>
|
||||
`);
|
||||
</script>
|
|
@ -0,0 +1,69 @@
|
|||
<template>
|
||||
<DocComponent title="Vue Checkbox Component" header="Checkbox" description="Checkbox is an extension to standard checkbox element with theming." :componentDocs="docs" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BasicDoc from '@/doc/checkbox/BasicDoc.vue';
|
||||
import DisabledDoc from '@/doc/checkbox/DisabledDoc.vue';
|
||||
import DynamicDoc from '@/doc/checkbox/DynamicDoc.vue';
|
||||
import FilledDoc from '@/doc/checkbox/FilledDoc.vue';
|
||||
import GroupDoc from '@/doc/checkbox/GroupDoc.vue';
|
||||
import ImportDoc from '@/doc/checkbox/ImportDoc.vue';
|
||||
import IndeterminateDoc from '@/doc/checkbox/IndeterminateDoc.vue';
|
||||
import InvalidDoc from '@/doc/checkbox/InvalidDoc.vue';
|
||||
import SizesDoc from '@/doc/checkbox/SizesDoc.vue';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
docs: [
|
||||
{
|
||||
id: 'import',
|
||||
label: 'Import',
|
||||
component: ImportDoc
|
||||
},
|
||||
{
|
||||
id: 'basic',
|
||||
label: 'Basic',
|
||||
component: BasicDoc
|
||||
},
|
||||
{
|
||||
id: 'group',
|
||||
label: 'Group',
|
||||
component: GroupDoc
|
||||
},
|
||||
{
|
||||
id: 'dynamic',
|
||||
label: 'Dynamic',
|
||||
component: DynamicDoc
|
||||
},
|
||||
{
|
||||
id: 'indeterminate',
|
||||
label: 'Indeterminate',
|
||||
component: IndeterminateDoc
|
||||
},
|
||||
{
|
||||
id: 'filled',
|
||||
label: 'Filled',
|
||||
component: FilledDoc
|
||||
},
|
||||
{
|
||||
id: 'sizes',
|
||||
label: 'Sizes',
|
||||
component: SizesDoc
|
||||
},
|
||||
{
|
||||
id: 'invalid',
|
||||
label: 'Invalid',
|
||||
component: InvalidDoc
|
||||
},
|
||||
{
|
||||
id: 'disabled',
|
||||
label: 'Disabled',
|
||||
component: DisabledDoc
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,33 @@
|
|||
<template>
|
||||
<Checkbox unstyled :pt="theme" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Checkbox from 'primevue/checkbox';
|
||||
import { ref } from 'vue';
|
||||
|
||||
const theme = ref({
|
||||
root: `relative inline-flex select-none w-5 h-5 align-bottom
|
||||
p-small:w-4 p-small:h-4
|
||||
p-large:w-6 p-large:h-6`,
|
||||
input: `peer cursor-pointer disabled:cursor-default appearance-none absolute start-0 top-0 w-full h-full m-0 p-0 opacity-0 z-10
|
||||
border border-transparent rounded-sm`,
|
||||
box: `flex justify-center items-center rounded-sm w-5 h-5
|
||||
border border-surface-300 dark:border-surface-700
|
||||
bg-surface-0 dark:bg-surface-950
|
||||
text-surface-700 dark:text-surface-0
|
||||
peer-enabled:peer-hover:border-surface-400 dark:peer-enabled:peer-hover:border-surface-600
|
||||
p-checked:border-primary p-checked:bg-primary p-checked:text-primary-contrast
|
||||
transition-colors duration-200
|
||||
p-invalid:border-red-400 dark:p-invalid:border-red-300
|
||||
peer-focus-visible:outline peer-focus-visible:outline-1 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-primary
|
||||
p-filled:bg-surface-50 dark:p-filled:bg-surface-800
|
||||
p-disabled:bg-surface-200 dark:p-disabled:bg-surface-400 p-disabled:border-surface-300 dark:p-disabled:border-surface-700 p-disabled:text-surface-700 dark:p-disabled:text-surface-400
|
||||
shadow-[0_1px_2px_0_rgba(18,18,23,0.05)]
|
||||
p-small:w-4 p-small:h-4
|
||||
p-large:w-6 p-large:h-6`,
|
||||
icon: `text-sm w-[0.875rem] h-[0.875rem] transition-none
|
||||
p-small:w-3 p-small:h-3
|
||||
p-large:w-4 p-large:h-4`
|
||||
});
|
||||
</script>
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div :class="cx('root')" v-bind="getPTOptions('root')" :data-p-checked="checked" :data-p-indeterminate="d_indeterminate || undefined" :data-p-disabled="disabled">
|
||||
<div :class="cx('root')" v-bind="getPTOptions('root')" :data-p-checked="checked" :data-p-indeterminate="d_indeterminate || undefined" :data-p-disabled="disabled" :data-p="dataP">
|
||||
<input
|
||||
:id="inputId"
|
||||
type="checkbox"
|
||||
|
@ -21,16 +21,17 @@
|
|||
@change="onChange"
|
||||
v-bind="getPTOptions('input')"
|
||||
/>
|
||||
<div :class="cx('box')" v-bind="getPTOptions('box')">
|
||||
<div :class="cx('box')" v-bind="getPTOptions('box')" :data-p="dataP">
|
||||
<slot name="icon" :checked="checked" :indeterminate="d_indeterminate" :class="cx('icon')">
|
||||
<CheckIcon v-if="checked" :class="cx('icon')" v-bind="getPTOptions('icon')" />
|
||||
<MinusIcon v-else-if="d_indeterminate" :class="cx('icon')" v-bind="getPTOptions('icon')" />
|
||||
<CheckIcon v-if="checked" :class="cx('icon')" v-bind="getPTOptions('icon')" :data-p="dataP" />
|
||||
<MinusIcon v-else-if="d_indeterminate" :class="cx('icon')" v-bind="getPTOptions('icon')" :data-p="dataP" />
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { cn } from '@primeuix/utils';
|
||||
import { contains, equals } from '@primeuix/utils/object';
|
||||
import CheckIcon from '@primevue/icons/check';
|
||||
import MinusIcon from '@primevue/icons/minus';
|
||||
|
@ -105,6 +106,15 @@ export default {
|
|||
const value = this.$pcCheckboxGroup ? this.$pcCheckboxGroup.d_value : this.d_value;
|
||||
|
||||
return this.d_indeterminate ? false : this.binary ? value === this.trueValue : contains(this.value, value);
|
||||
},
|
||||
dataP() {
|
||||
return cn({
|
||||
invalid: this.$invalid,
|
||||
checked: this.checked,
|
||||
disabled: this.disabled,
|
||||
filled: this.$variant === 'filled',
|
||||
[this.size]: this.size
|
||||
});
|
||||
}
|
||||
},
|
||||
components: {
|
||||
|
|
Loading…
Reference in New Issue