feat: Added prop 'openFirstItem' to accordion component

This commit is contained in:
Ilya Artamonov
2023-08-25 18:42:34 +03:00
parent 3fe681d106
commit 477eb11156
10 changed files with 657 additions and 506 deletions

View File

@@ -11,23 +11,17 @@ function buildSidebar() {
{ {
text: 'Components', text: 'Components',
collapsible: true, collapsible: true,
items: [ items: [...getComponents()],
...getComponents(),
],
}, },
{ {
text: 'Form', text: 'Form',
collapsible: true, collapsible: true,
items: [ items: [...getFormComponents()],
...getFormComponents(),
],
}, },
{ {
text: 'Utils', text: 'Utils',
collapsible: true, collapsible: true,
items: [ items: [...getUtils()],
...getUtils(),
],
}, },
] ]
} }
@@ -78,7 +72,7 @@ function getFormComponents() {
function getUtils() { function getUtils() {
return [ return [
{ text: 'Flowbite Themable', link: '/components/flowbiteThemable/flowbiteThemable.md' }, { text: 'Flowbite Themable', link: '/components/flowbiteThemable/flowbiteThemable.md' },
{ text: 'Toast Provider', link: '/components/toastProvider/toastProvider.md' } { text: 'Toast Provider', link: '/components/toastProvider/toastProvider.md' },
] ]
} }
@@ -90,9 +84,9 @@ export default defineConfig({
title: 'Flowbite Vue 3', title: 'Flowbite Vue 3',
cleanUrls: 'without-subfolders', cleanUrls: 'without-subfolders',
head: [ head: [
['link', { rel: "icon", type: "image/svg", href: "/assets/logo.svg"}], ['link', { rel: 'icon', type: 'image/svg', href: '/assets/logo.svg' }],
[ [
"script", 'script',
{}, {},
` `
// Fathom - beautiful, simple website analytics // Fathom - beautiful, simple website analytics
@@ -112,21 +106,20 @@ export default defineConfig({
fathom("set", "siteId", "MPNTKCVJ"); fathom("set", "siteId", "MPNTKCVJ");
fathom("trackPageview"); fathom("trackPageview");
// / Fathom // / Fathom
` `,
] ],
], ],
themeConfig: { themeConfig: {
sidebar: buildSidebar(), sidebar: buildSidebar(),
logo: '/assets/logo.svg', logo: '/assets/logo.svg',
socialLinks: [ socialLinks: [
{ icon: 'github', link: 'https://github.com/themesberg/flowbite-vue' }, { icon: 'github', link: 'https://github.com/themesberg/flowbite-vue' },
{ icon: 'discord', link: 'https://discord.gg/4eeurUVvTy' } { icon: 'discord', link: 'https://discord.gg/4eeurUVvTy' },
], ],
footer: { footer: {
message: 'Released under the MIT License.', message: 'Released under the MIT License.',
copyright: 'Copyright © 2023 Flowbite™' copyright: 'Copyright © 2023 Flowbite™',
}, },
}, },
}) })

View File

@@ -3,6 +3,7 @@ import AccordionExample from './accordion/examples/AccordionExample.vue';
import AccordionAlwaysOpenExample from './accordion/examples/AccordionAlwaysOpenExample.vue'; import AccordionAlwaysOpenExample from './accordion/examples/AccordionAlwaysOpenExample.vue';
import AccordionFlushExample from './accordion/examples/AccordionFlushExample.vue'; import AccordionFlushExample from './accordion/examples/AccordionFlushExample.vue';
import AccordionStyledHeadersExample from './accordion/examples/AccordionStyledHeadersExample.vue'; import AccordionStyledHeadersExample from './accordion/examples/AccordionStyledHeadersExample.vue';
import AccordionOpenFirstItemExample from './accordion/examples/AccordionOpenFirstItemExample.vue';
</script> </script>
# Vue Accordion - Flowbite # Vue Accordion - Flowbite
@@ -184,3 +185,47 @@ import { Accordion, AccordionPanel, AccordionHeader, AccordionContent } from 'fl
``` ```
<AccordionStyledHeadersExample /> <AccordionStyledHeadersExample />
## Closed first item
```vue
<script setup>
import { Accordion, AccordionPanel, AccordionHeader, AccordionContent } from 'flowbite-vue'
</script>
<template>
<Accordion :open-first-item="false">
<accordion-panel>
<accordion-header>header</accordion-header>
<accordion-content>
<div>
<p class="mb-2 text-gray-500 dark:text-gray-400">Flowbite is an open-source library of interactive components built on top of Tailwind CSS including buttons, dropdowns, modals, navbars, and more.</p>
<p class="text-gray-500 dark:text-gray-400">Check out this guide to learn how to <a href="/docs/getting-started/introduction/" class="text-blue-600 dark:text-blue-500 hover:underline">get started</a> and start developing websites even faster with components on top of Tailwind CSS.</p>
</div>
</accordion-content>
</accordion-panel>
<accordion-panel>
<accordion-header class="bg-pink-200 dark:bg-pink-900 dark:text-gray-50">another header</accordion-header>
<accordion-content>
<div>
<p class="mb-2 text-gray-500 dark:text-gray-400">Flowbite is first conceptualized and designed using the Figma software so everything you see in the library has a design equivalent in our Figma file.</p>
<p class="text-gray-500 dark:text-gray-400">Check out the <a href="https://flowbite.com/figma/" class="text-blue-600 dark:text-blue-500 hover:underline">Figma design system</a> based on the utility classes from Tailwind CSS and components from Flowbite.</p>
</div>
</accordion-content>
</accordion-panel>
<accordion-panel>
<accordion-header>and one more header</accordion-header>
<accordion-content>
<div>
<p class="mb-2 text-gray-500 dark:text-gray-400">Flowbite is first conceptualized and designed using the Figma software so everything you see in the library has a design equivalent in our Figma file.</p>
<p class="text-gray-500 dark:text-gray-400">Check out the <a href="https://flowbite.com/figma/" class="text-blue-600 dark:text-blue-500 hover:underline">Figma design system</a> based on the utility classes from Tailwind CSS and components from Flowbite.</p>
</div>
</accordion-content>
</accordion-panel>
</Accordion>
</template>
```
<AccordionOpenFirstItemExample />

View File

@@ -3,33 +3,50 @@ import { Accordion, AccordionPanel, AccordionHeader, AccordionContent } from '..
</script> </script>
<template> <template>
<div class="vp-raw">
<Accordion> <Accordion>
<accordion-panel> <AccordionPanel>
<accordion-header>header</accordion-header> <AccordionHeader>header</AccordionHeader>
<accordion-content> <AccordionContent>
<div> <div>
<p class="mb-2 text-gray-500 dark:text-gray-400">Flowbite is an open-source library of interactive components built on top of Tailwind CSS including buttons, dropdowns, modals, navbars, and more.</p> <p class="mb-2 text-gray-500 dark:text-gray-400">
<p class="text-gray-500 dark:text-gray-400">Check out this guide to learn how to <a href="/docs/getting-started/introduction/" class="text-blue-600 dark:text-blue-500 hover:underline">get started</a> and start developing websites even faster with components on top of Tailwind CSS.</p> Flowbite is an open-source library of interactive components built on top of Tailwind CSS including buttons, dropdowns, modals, navbars, and more.
</p>
<p class="text-gray-500 dark:text-gray-400">
Check out this guide to learn how to <a href="/docs/getting-started/introduction/" class="text-blue-600 dark:text-blue-500 hover:underline">get started</a> and start developing websites
even faster with components on top of Tailwind CSS.
</p>
</div> </div>
</accordion-content> </AccordionContent>
</accordion-panel> </AccordionPanel>
<accordion-panel> <AccordionPanel>
<accordion-header>another header</accordion-header> <AccordionHeader>another header</AccordionHeader>
<accordion-content> <AccordionContent>
<div> <div>
<p class="mb-2 text-gray-500 dark:text-gray-400">Flowbite is first conceptualized and designed using the Figma software so everything you see in the library has a design equivalent in our Figma file.</p> <p class="mb-2 text-gray-500 dark:text-gray-400">
<p class="text-gray-500 dark:text-gray-400">Check out the <a href="https://flowbite.com/figma/" class="text-blue-600 dark:text-blue-500 hover:underline">Figma design system</a> based on the utility classes from Tailwind CSS and components from Flowbite.</p> Flowbite is first conceptualized and designed using the Figma software so everything you see in the library has a design equivalent in our Figma file.
</p>
<p class="text-gray-500 dark:text-gray-400">
Check out the <a href="https://flowbite.com/figma/" class="text-blue-600 dark:text-blue-500 hover:underline">Figma design system</a> based on the utility classes from Tailwind CSS and
components from Flowbite.
</p>
</div> </div>
</accordion-content> </AccordionContent>
</accordion-panel> </AccordionPanel>
<accordion-panel> <AccordionPanel>
<accordion-header>and one more header</accordion-header> <AccordionHeader>and one more header</AccordionHeader>
<accordion-content> <AccordionContent>
<div> <div>
<p class="mb-2 text-gray-500 dark:text-gray-400">Flowbite is first conceptualized and designed using the Figma software so everything you see in the library has a design equivalent in our Figma file.</p> <p class="mb-2 text-gray-500 dark:text-gray-400">
<p class="text-gray-500 dark:text-gray-400">Check out the <a href="https://flowbite.com/figma/" class="text-blue-600 dark:text-blue-500 hover:underline">Figma design system</a> based on the utility classes from Tailwind CSS and components from Flowbite.</p> Flowbite is first conceptualized and designed using the Figma software so everything you see in the library has a design equivalent in our Figma file.
</p>
<p class="text-gray-500 dark:text-gray-400">
Check out the <a href="https://flowbite.com/figma/" class="text-blue-600 dark:text-blue-500 hover:underline">Figma design system</a> based on the utility classes from Tailwind CSS and
components from Flowbite.
</p>
</div> </div>
</accordion-content> </AccordionContent>
</accordion-panel> </AccordionPanel>
</Accordion> </Accordion>
</div>
</template> </template>

View File

@@ -0,0 +1,52 @@
<script setup>
import { Accordion, AccordionPanel, AccordionHeader, AccordionContent } from '../../../../src/index'
</script>
<template>
<div class="vp-raw">
<Accordion :open-first-item="false">
<AccordionPanel>
<AccordionHeader>header</AccordionHeader>
<AccordionContent>
<div>
<p class="mb-2 text-gray-500 dark:text-gray-400">
Flowbite is an open-source library of interactive components built on top of Tailwind CSS including buttons, dropdowns, modals, navbars, and more.
</p>
<p class="text-gray-500 dark:text-gray-400">
Check out this guide to learn how to <a href="/docs/getting-started/introduction/" class="text-blue-600 dark:text-blue-500 hover:underline">get started</a> and start developing websites
even faster with components on top of Tailwind CSS.
</p>
</div>
</AccordionContent>
</AccordionPanel>
<AccordionPanel>
<AccordionHeader>another header</AccordionHeader>
<AccordionContent>
<div>
<p class="mb-2 text-gray-500 dark:text-gray-400">
Flowbite is first conceptualized and designed using the Figma software so everything you see in the library has a design equivalent in our Figma file.
</p>
<p class="text-gray-500 dark:text-gray-400">
Check out the <a href="https://flowbite.com/figma/" class="text-blue-600 dark:text-blue-500 hover:underline">Figma design system</a> based on the utility classes from Tailwind CSS and
components from Flowbite.
</p>
</div>
</AccordionContent>
</AccordionPanel>
<AccordionPanel>
<AccordionHeader>and one more header</AccordionHeader>
<AccordionContent>
<div>
<p class="mb-2 text-gray-500 dark:text-gray-400">
Flowbite is first conceptualized and designed using the Figma software so everything you see in the library has a design equivalent in our Figma file.
</p>
<p class="text-gray-500 dark:text-gray-400">
Check out the <a href="https://flowbite.com/figma/" class="text-blue-600 dark:text-blue-500 hover:underline">Figma design system</a> based on the utility classes from Tailwind CSS and
components from Flowbite.
</p>
</div>
</AccordionContent>
</AccordionPanel>
</Accordion>
</div>
</template>

899
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,21 +1,21 @@
<template> <template>
<div class="vp-raw" :data-accordion-id="accordionId"> <div :data-accordion-id="accordionId">
<slot /> <slot />
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { nanoid } from 'nanoid' import { nanoid } from 'nanoid'
import { useAccordionState } from '@/components/Accordion/composables/useAccordionState' import { useAccordionState } from '@/components/Accordion/composables/useAccordionState'
interface AccordionProps {
alwaysOpen?: boolean
openFirstItem?: boolean
flush?: boolean
}
const props = defineProps({ const props = withDefaults(defineProps<AccordionProps>(), {
alwaysOpen: { alwaysOpen: false,
type: Boolean, openFirstItem: true,
default: false, flush: false,
},
flush: {
type: Boolean,
default: false,
},
}) })
const accordionId = nanoid() const accordionId = nanoid()

View File

@@ -1,19 +1,8 @@
<template> <template>
<div ref="header"> <div ref="header">
<button <button v-if="isLoaded" type="button" @click="toggleItem" :class="headerClasses">
v-if="isLoaded"
type="button"
@click="toggleItem"
:class="headerClasses"
>
<span class="w-full"><slot /></span> <span class="w-full"><slot /></span>
<svg <svg data-accordion-icon :class="arrowClasses" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
data-accordion-icon
:class="arrowClasses"
fill="currentColor"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
>
<path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"></path> <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"></path>
</svg> </svg>
</button> </button>
@@ -22,8 +11,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { useAccordionState } from '@/components/Accordion/composables/useAccordionState' import { useAccordionState } from '@/components/Accordion/composables/useAccordionState'
import { computed, onMounted, ref } from 'vue' import { computed, onMounted, ref, type ComputedRef } from 'vue'
import type { ComputedRef } from 'vue'
import { useAccordionHeaderClasses } from '@/components/Accordion/composables/useAccordionHeaderClasses' import { useAccordionHeaderClasses } from '@/components/Accordion/composables/useAccordionHeaderClasses'
const isLoaded = ref(false) const isLoaded = ref(false)
@@ -48,7 +36,7 @@ function alwaysOpenToggleItem() {
panelState.value.isVisible = !panelState.value.isVisible panelState.value.isVisible = !panelState.value.isVisible
} }
function toggleItem() { function toggleItem() {
if (accordionState.value.alwaysOpen ) return alwaysOpenToggleItem() if (accordionState.value.alwaysOpen) return alwaysOpenToggleItem()
commonToggleItem() commonToggleItem()
} }

View File

@@ -11,7 +11,6 @@ import { nanoid } from 'nanoid'
const { accordionsStates } = useAccordionState() const { accordionsStates } = useAccordionState()
const panelId = nanoid() const panelId = nanoid()
const panel = ref() const panel = ref()
const accordionId = computed(() => { const accordionId = computed(() => {
@@ -28,7 +27,7 @@ onMounted(() => {
accordionState.value.panels[panelId] = { accordionState.value.panels[panelId] = {
id: panelId, id: panelId,
order: panelsCount, order: panelsCount,
isVisible: !panelsCount, isVisible: (accordionState.value.openFirstItem && panelsCount === 0) ?? false,
} }
}) })
</script> </script>

View File

@@ -1,17 +1,24 @@
import { onBeforeMount, onBeforeUnmount, reactive } from 'vue' import { onBeforeMount, onBeforeUnmount, reactive } from 'vue'
import type { tState } from '@/components/Accordion/types' import type { tState } from '@/components/Accordion/types'
interface AccordionProps {
alwaysOpen?: boolean
openFirstItem?: boolean
flush?: boolean
}
const accordionsStates = reactive<tState>({}) const accordionsStates = reactive<tState>({})
export function useAccordionState(id?: string, options?: {flush: boolean, alwaysOpen: boolean}): { export function useAccordionState(
id?: string,
options?: AccordionProps
): {
accordionsStates: tState accordionsStates: tState
} { } {
onBeforeMount(() => { onBeforeMount(() => {
if (!id) return if (!id) return
accordionsStates[id] = { accordionsStates[id] = {
id: id, id: id,
flush: options?.flush ?? false, flush: options?.flush ?? false,
alwaysOpen: options?.alwaysOpen ?? false, alwaysOpen: options?.alwaysOpen ?? false,
openFirstItem: options?.openFirstItem ?? true,
panels: {}, panels: {},
} }
}) })
@@ -24,5 +31,3 @@ export function useAccordionState(id?: string, options?: {flush: boolean, always
accordionsStates, accordionsStates,
} }
} }

View File

@@ -8,9 +8,10 @@ type tAccordionPanels = {
[key: string]: tAccordionPanel [key: string]: tAccordionPanel
} }
type tStateElement = { type tStateElement = {
id: string, id: string
flush: boolean, flush: boolean
alwaysOpen: boolean, alwaysOpen: boolean
openFirstItem: boolean
panels: tAccordionPanels panels: tAccordionPanels
} }
export type tState = { export type tState = {