Skip to content

Commit

Permalink
feat: added NeCheckbox
Browse files Browse the repository at this point in the history
  • Loading branch information
Tbaile committed Dec 18, 2023
1 parent cc89686 commit c1d7672
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 4 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"@fortawesome/free-solid-svg-icons": "^6.5.1",
"@fortawesome/vue-fontawesome": "^3.0.5",
"@headlessui/vue": "^1.7.16",
"uuid": "^9.0.1",
"vue": "^3.3.4",
"vue-tippy": "^6.3.1"
},
Expand Down
67 changes: 67 additions & 0 deletions src/components/NeCheckbox.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<!--
Copyright (C) 2023 Nethesis S.r.l.
SPDX-License-Identifier: GPL-3.0-or-later
-->

<script lang="ts" setup>
import { computed } from 'vue'
import { v4 as uuidv4 } from 'uuid'

const props = defineProps({
modelValue: Boolean,
id: String,
label: String,
disableSelectOnLabel: Boolean,
disabled: Boolean
})

const emit = defineEmits(['update:modelValue'])

const componentId = computed(() => (props.id ? props.id : uuidv4()))

const model = computed({
get() {
return props.modelValue
},
set(val) {
emit('update:modelValue', val)
}
})
</script>
<template>
<div class="relative flex items-start">
<div class="flex h-6 items-center">
<input
:id="componentId"
v-model="model"
:aria-describedby="componentId + '-description'"
:disabled="disabled"
class="h-5 w-5 rounded border-gray-300 text-primary-700 focus:ring-2 focus:ring-primary-500 focus:ring-offset-2 focus:ring-offset-white disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-500 dark:text-primary-500 dark:focus:ring-primary-300 dark:focus:ring-offset-primary-950 sm:h-4 sm:w-4"
type="checkbox"
v-bind="$attrs"
/>
</div>
<div class="ml-3 text-sm leading-6">
<!-- show label prop or default slot -->
<label
:class="[
'font-medium text-gray-700 dark:text-gray-50',
{ 'cursor-not-allowed opacity-50': disabled }
]"
:for="disableSelectOnLabel ? '' : componentId"
>
<slot>{{ label }}</slot>
</label>
<span v-if="$slots.tooltip" class="ml-2">
<slot name="tooltip"></slot>
</span>
<div
v-if="$slots.description"
:id="componentId + '-description'"
class="text-gray-500 dark:text-gray-400"
>
<slot name="description" />
</div>
</div>
</div>
</template>
4 changes: 3 additions & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import NeTitle from '@/components/NeTitle.vue'
import NeTooltip from '@/components/NeTooltip.vue'
import NeBadge from '@/components/NeBadge.vue'
import NeButton from '@/components/NeButton.vue'
import NeCheckbox from '@/components/NeCheckbox.vue'
// style import
import '@/main.css'

Expand All @@ -26,5 +27,6 @@ export {
NeTitle,
NeTooltip,
NeBadge,
NeButton
NeButton,
NeCheckbox
}
106 changes: 106 additions & 0 deletions stories/NeCheckbox.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// Copyright (C) 2023 Nethesis S.r.l.
// SPDX-License-Identifier: GPL-3.0-or-later

import type { Meta, StoryObj } from '@storybook/vue3'
import { NeCheckbox, NeTooltip } from '../src/main'

const meta = {
title: 'Control/NeCheckbox',
component: NeCheckbox,
tags: ['autodocs'],
args: {
label: 'Label',
modelValue: true,
disabled: false,
disableSelectOnLabel: false,
id: ''
}
} satisfies Meta<typeof NeCheckbox>

export default meta
type Story = StoryObj<typeof meta>

const template = '<NeCheckbox v-bind="args" />'

export const Default: Story = {
render: (args) => ({
components: { NeCheckbox },
setup() {
return { args }
},
template: template
}),
args: {}
}

const templateWithSlot = '<NeCheckbox v-bind="args">Label using slot instead of prop</NeCheckbox>'

export const WithLabelSlot: Story = {
render: (args) => ({
components: { NeCheckbox },
setup() {
return { args }
},
template: templateWithSlot
}),
args: { label: '' }
}

export const Disabled: Story = {
render: (args) => ({
components: { NeCheckbox },
setup() {
return { args }
},
template: template
}),
args: { disabled: true }
}

const templateWithDescription =
'<NeCheckbox v-bind="args"><span>Label</span><template #description>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua</template></NeCheckbox>'

export const WithDescription: Story = {
render: (args) => ({
components: { NeCheckbox },
setup() {
return { args }
},
template: templateWithDescription
}),
args: {}
}

const templateDisableSelectOnLabel =
'<NeCheckbox v-bind="args">I agree to the <a class="underline cursor-pointer text-primary-700 dark:text-primary-500">Terms and conditions</a></NeCheckbox>'

export const DisableSelectOnLabel: Story = {
render: (args) => ({
components: { NeCheckbox },
setup() {
return { args }
},
template: templateDisableSelectOnLabel
}),
args: { label: '', disableSelectOnLabel: true }
}

const templateWithTooltip =
'<NeCheckbox v-bind="args">\
<template #tooltip>\
<NeTooltip>\
<template #content>Tooltip</template>\
</NeTooltip>\
</template>\
</NeCheckbox>'

export const WithTooltip: Story = {
render: (args) => ({
components: { NeCheckbox, NeTooltip },
setup() {
return { args }
},
template: templateWithTooltip
}),
args: {}
}
6 changes: 4 additions & 2 deletions vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,17 @@ export default defineConfig({
'vue-tippy',
'@fortawesome/vue-fontawesome',
'@fortawesome/free-solid-svg-icons',
'@headlessui/vue'
'@headlessui/vue',
'uuid'
],
output: {
globals: {
vue: 'Vue',
'vue-tippy': 'Tippy',
'@fortawesome/vue-fontawesome': 'FontAwesomeIcon',
'@fortawesome/free-solid-svg-icons': 'fa',
'@headlessui/vue': 'HeadlessUI'
'@headlessui/vue': 'HeadlessUI',
uuid: 'v'
}
}
}
Expand Down

0 comments on commit c1d7672

Please sign in to comment.