Skip to content

Commit

Permalink
fix: Accordion, Checkbox, Radio, Toggle changes (#27)
Browse files Browse the repository at this point in the history
  • Loading branch information
victoriakaropva authored Nov 28, 2023
1 parent 4d60cbd commit 480c89b
Show file tree
Hide file tree
Showing 13 changed files with 185 additions and 93 deletions.
83 changes: 83 additions & 0 deletions src/components/BuiAccordion/BuiAccordion.story.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<script setup lang="ts">
import BuiAccordion from '@/components/BuiAccordion/BuiAccordion.vue'
import BuiButton from '@/components/BuiButton/BuiButton.vue'
import { ref } from 'vue'
const model = ref({ section1: true, section2: false } as Object)
const model2 = ref(false)
function collapseAll() {
const newModel = {}
Object.keys(model.value).forEach((key) => {
newModel[key] = false
})
model.value = newModel
}
</script>

<template>
<Story title="BuiAccordion" autoPropsDisabled :layout="{ type: 'grid', width: '50%' }">
<Variant title="Default without description">
<BuiAccordion title="My title">
<div class="text-sm p-4">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat.
</div>
</BuiAccordion>
</Variant>
<Variant title="Collapsed by default with description and custom icon">
<BuiAccordion title="My title" description="My description" v-model="model2">
<template #icon>
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
class="cursor-pointer"
>
<g class="opacity-[0.56] dark:opacity-[1]">
<rect width="16" height="16" rx="4" fill="transparent" />
<path
d="M12 10L8 6L4 10"
stroke="#7371F9"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</g>
</svg>
</template>
<div class="text-sm p-4">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat.
</div>
</BuiAccordion>
</Variant>
<Variant title="Several sections">
{{ model }}
<button @click="collapseAll" class="mb-4">Collapse all</button>
<BuiAccordion
title="Section #1"
tag="h3"
description="My description"
v-model="model['section1']"
class="mb-5"
>
<div class="text-sm p-4">Lorem ipsum dolor sit amet.</div>
</BuiAccordion>
<BuiAccordion
title="Section #2"
description="My description"
v-model="model['section2']"
tag="h3"
>
<div class="text-sm p-4">Ut enim ad minim veniam, quis nostrud exercitation.</div>
</BuiAccordion>
</Variant>
</Story>
</template>

<style scoped></style>
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
<script setup lang="ts">
import { ref } from 'vue'
import ArrowButton from '@/components/BuiCollapsableSection/svgComponents/ArrowButton.vue'
import { computed, ref } from 'vue'
import ArrowButton from '@/components/BuiAccordion/svgComponents/ArrowButton.vue'
const props = withDefaults(
defineProps<{
title: string
tag?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'
description?: string
isInitiallyOpen?: boolean
value?: boolean | undefined
}>(),
{ isInitiallyOpen: true }
{ value: undefined, tag: 'h2' }
)
const emit = defineEmits(['input'])
const hasModel = computed(() => props.value !== undefined)
const internalValue = ref(true)
const isUncollapsed = computed(() => (hasModel.value ? props.value : internalValue.value))
const isUncollapsed = ref(props.isInitiallyOpen)
function toggleCollapsingState() {
isUncollapsed.value = !isUncollapsed.value
if (hasModel.value) {
emit('input', !props.value)
} else {
internalValue.value = !internalValue.value
}
}
</script>

Expand All @@ -24,14 +33,18 @@ function toggleCollapsingState() {
class="w-full min-w-full flex px-2 py-4 rounded-tl dark:bg-white/[.04] bg-primary-800/[.04]"
>
<div class="py-1 px-2">
<ArrowButton :class="isUncollapsed ? '' : 'rotate-180'" />
<div v-if="$slots.icon" :class="isUncollapsed ? '' : 'rotate-180'">
<slot name="icon" />
</div>
<ArrowButton v-else :class="isUncollapsed ? '' : 'rotate-180'" />
</div>
<div class="flex flex-1 flex-col">
<div
<component
:is="props.tag"
class="text-base font-semibold leading-6 align-middle text-clay-500 dark:text-gray-100"
>
{{ title }}
</div>
</component>
<div class="text-xs font-normal leading-4 align-middle text-clay-500 dark:text-gray-100">
{{ description }}
</div>
Expand Down
18 changes: 13 additions & 5 deletions src/components/BuiCheckbox/BuiCheckbox.story.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,23 @@ const model2 = ref(false)
</BuiCheckbox>
</div>
</Variant>
<Variant title="Readonly">
<div class="p-2">
<BuiCheckbox :readonly="true" :value="true">
My Label
<template #description>My description</template>
</BuiCheckbox>
</div>
</Variant>
<Variant title="List">
<form ref="modelGeneral">
<div class="flex flex-col">
<BuiCheckbox groupName="options" option-name="option1" v-model="model"
>Option 1
<BuiCheckbox groupName="options" option-name="option1" v-model="model">
Option 1
</BuiCheckbox>
<BuiCheckbox groupName="options" option-name="option2" v-model="model2">
Option 2
</BuiCheckbox>
<BuiCheckbox groupName="options" option-name="option2" v-model="model2"
>Option 2</BuiCheckbox
>
</div>
</form>
</Variant>
Expand Down
41 changes: 28 additions & 13 deletions src/components/BuiCheckbox/BuiCheckbox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ interface IBuiRadioProps {
groupName?: string
optionName?: string
value: boolean
readonly?: boolean | undefined
}
const props = withDefaults(defineProps<IBuiRadioProps>(), {
disabled: false,
Expand All @@ -31,19 +32,29 @@ const id = nanoid(10)
const disabledAttrValue = computed(() => {
return Object.keys(props).includes('disabled') && props.disabled !== false ? true : undefined
})
const readonlyAttrValue = computed(() => {
return Object.keys(props).includes('readonly') && props.readonly !== false ? true : undefined
})
const idForLabel = readonlyAttrValue.value || disabledAttrValue.value ? undefined : id
const baseLabelClasses = 'font-semibold leading-6 text-sm hover:cursor-pointer'
const disabledLabelClasses = 'hover:!cursor-default text-gray-400'
const baseLabelClasses = 'font-semibold leading-6 text-sm'
const disabledLabelClasses = 'hover:cursor-not-allowed text-gray-400 cursor-not-allowed'
const baseDescriptionClasses = 'font-normal leading-4 text-xs '
const disabledDescriptionClasses = 'text-gray-400'
const baseDescriptionClasses = 'font-normal leading-4 text-xs'
const disabledDescriptionClasses = 'text-gray-400 cursor-not-allowed'
const finalClasses = computed(() => {
return {
labelClasses: twMerge(baseLabelClasses, !!disabledAttrValue.value && disabledLabelClasses),
labelClasses: twMerge(
baseLabelClasses,
!!disabledAttrValue.value && disabledLabelClasses,
!readonlyAttrValue.value && !disabledAttrValue.value && 'cursor-pointer'
),
descriptionClasses: twMerge(
baseDescriptionClasses,
!!disabledAttrValue.value && disabledDescriptionClasses
!!disabledAttrValue.value && disabledDescriptionClasses,
!readonlyAttrValue.value && !disabledAttrValue.value && 'cursor-pointer'
)
}
})
Expand All @@ -60,17 +71,21 @@ const finalClasses = computed(() => {
class="peer hidden"
:disabled="disabledAttrValue"
/>
<label :for="id" class="hidden peer-checked:!block">
<ActiveCheckboxIcon :disabled="disabledAttrValue" />
<label :for="idForLabel" class="hidden peer-checked:!block">
<ActiveCheckboxIcon :disabled="disabledAttrValue" :readonly="readonlyAttrValue" />
</label>
<label class="block peer-checked:!hidden" :for="id">
<InactiveCheckboxIcon :disabled="disabledAttrValue" />
<label class="block peer-checked:!hidden" :for="idForLabel">
<InactiveCheckboxIcon :disabled="disabledAttrValue" :readonly="readonlyAttrValue" />
</label>
</div>
<label class="flex-1 flex flex-col" :for="id">
<div v-if="$slots.default" :class="finalClasses.labelClasses"><slot></slot></div>
<label
class="flex-1 flex flex-col"
:for="idForLabel"
v-if="$slots.default || $slots.description"
>
<div v-if="$slots.default" :class="finalClasses.labelClasses"><slot /></div>
<div v-if="$slots.description" :class="finalClasses.descriptionClasses">
<slot name="description"></slot>
<slot name="description" />
</div>
</label>
</div>
Expand Down
14 changes: 10 additions & 4 deletions src/components/BuiCheckbox/svgComponents/ActiveCheckboxIcon.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,20 @@
</template>
<script setup lang="ts">
import { twMerge } from 'tailwind-merge'
const props = withDefaults(defineProps<{ disabled: boolean }>(), {
disabled: false
const props = withDefaults(defineProps<{ disabled: boolean; readonly: boolean }>(), {
disabled: false,
readonly: false
})
const svgClasses = twMerge('cursor-pointer', props.disabled && 'opacity-[0.32] cursor-default')
const svgClasses = twMerge(
'cursor-pointer',
props.disabled && 'opacity-[0.32] cursor-not-allowed',
props.readonly && 'cursor-default'
)
const rectClasses = twMerge(
'fill-primary-500 group-hover:fill-primary-550',
props.disabled && 'group-hover:fill-primary-500'
props.disabled && 'group-hover:fill-primary-500',
props.readonly && 'group-hover:fill-primary-500'
)
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,17 @@
<script setup lang="ts">
import { twMerge } from 'tailwind-merge'
const props = withDefaults(defineProps<{ disabled: boolean }>(), {
disabled: false
const props = withDefaults(defineProps<{ disabled: boolean; readonly: boolean }>(), {
disabled: false,
readonly: false
})
const rectClasses = twMerge(
'bui-checkbox',
'dark:stroke-primary-500 dark:fill-primary-500 dark:group-hover:fill-primary-500 dark:group-hover:[.bui-checkbox-hover]',
'dark:stroke-primary-500 dark:fill-primary-500 dark:group-hover:fill-primary-500',
'cursor-pointer stroke-gray-300 fill-white group-hover:fill-gray-150',
props.disabled &&
'disabled cursor-default dark:fill-white dark:stroke-white dark:group-hover:fill-white fill-slate-200 group-hover:fill-slate-200'
'disabled cursor-not-allowed dark:fill-white dark:stroke-white dark:group-hover:fill-white fill-slate-200 group-hover:fill-slate-200',
props.readonly && 'group-hover:fill-white dark:group-hover:fill-primary-500'
)
</script>

This file was deleted.

11 changes: 8 additions & 3 deletions src/components/BuiRadio/BuiRadio.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ interface IBuiRadioProps {
groupName?: string
optionValue: string
value: string
readonly?: boolean | undefined
}
const props = withDefaults(defineProps<IBuiRadioProps>(), {
disabled: false
Expand All @@ -31,6 +32,10 @@ const disabledAttrValue = computed(() => {
return Object.keys(props).includes('disabled') && props.disabled !== false ? true : undefined
})
const readonlyAttrValue = computed(() => {

Check failure on line 35 in src/components/BuiRadio/BuiRadio.vue

View workflow job for this annotation

GitHub Actions / build-pkg (18.x)

'readonlyAttrValue' is declared but its value is never read.
return Object.keys(props).includes('readonly') && props.readonly !== false ? true : undefined
})
const baseLabelClasses = 'font-semibold leading-6 text-sm hover:cursor-pointer'
const disabledLabelClasses = 'hover:!cursor-default text-gray-400'
Expand Down Expand Up @@ -66,10 +71,10 @@ const finalClasses = computed(() => {
<InactiveRadioIcon :disabled="disabledAttrValue" />
</label>
</div>
<label class="flex-1 flex flex-col" :for="id">
<div v-if="$slots.default" :class="finalClasses.labelClasses"><slot></slot></div>
<label class="flex-1 flex flex-col" :for="id" v-if="$slots.default || $slots.description">
<div v-if="$slots.default" :class="finalClasses.labelClasses"><slot /></div>
<div v-if="$slots.description" :class="finalClasses.descriptionClasses">
<slot name="description"></slot>
<slot name="description" />
</div>
</label>
</div>
Expand Down
8 changes: 5 additions & 3 deletions src/components/BuiRadio/svgComponents/ActiveRadioIcon.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
</template>
<script setup lang="ts">
import { twMerge } from 'tailwind-merge'
const props = withDefaults(defineProps<{ disabled: boolean }>(), {
disabled: false
const props = withDefaults(defineProps<{ disabled: boolean; readonly: boolean }>(), {
disabled: false,
readonly: false
})
const rectClasses = twMerge(
'cursor-pointer stroke-primary-500 group-hover:stroke-primary-550 fill-white group-hover:fill-slate-150',
props.disabled &&
'cursor-default group-hover:stroke-primary-500 group-hover:fill-transparent opacity-[0.32] fill-transparent'
'cursor-not-allowed group-hover:stroke-primary-500 group-hover:fill-transparent opacity-[0.32] fill-transparent',
props.readonly && 'cursor-default group-hover:stroke-primary-500 group-hover:fill-white'
)
</script>
Loading

0 comments on commit 480c89b

Please sign in to comment.