Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Accordion, Checkbox, Radio, Toggle changes #27

Merged
merged 1 commit into from
Nov 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@
groupName?: string
optionValue: string
value: string
readonly?: boolean | undefined
}
const props = withDefaults(defineProps<IBuiRadioProps>(), {
disabled: false
Expand All @@ -31,6 +32,10 @@
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 @@
<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
Loading