From 39eb3012a619ae2c45df22e0b326b97a4d7b8d68 Mon Sep 17 00:00:00 2001 From: Andrea Leardini Date: Thu, 8 Aug 2024 11:44:08 +0200 Subject: [PATCH 1/6] feat: add NeDropdownFilter component --- src/components/NeDropdownFilter.vue | 253 ++++++++++++++++++++++++++++ src/main.ts | 2 + stories/NeDropdownFilter.stories.ts | 175 +++++++++++++++++++ 3 files changed, 430 insertions(+) create mode 100644 src/components/NeDropdownFilter.vue create mode 100644 stories/NeDropdownFilter.stories.ts diff --git a/src/components/NeDropdownFilter.vue b/src/components/NeDropdownFilter.vue new file mode 100644 index 0000000..bba6ad8 --- /dev/null +++ b/src/components/NeDropdownFilter.vue @@ -0,0 +1,253 @@ + + + + + diff --git a/src/main.ts b/src/main.ts index c7f7a62..08d7213 100644 --- a/src/main.ts +++ b/src/main.ts @@ -36,6 +36,7 @@ export { default as NeToastNotification } from '@/components/NeToastNotification export { default as NeModal } from '@/components/NeModal.vue' export { default as NeHeading } from '@/components/NeHeading.vue' export { default as NeListbox } from '@/components/NeListbox.vue' +export { default as NeDropdownFilter } from '@/components/NeDropdownFilter.vue' // types export export type { NeComboboxOption } from '@/components/NeCombobox.vue' @@ -43,6 +44,7 @@ export type { Tab } from '@/components/NeTabs.vue' export type { NeNotification } from '@/components/NeToastNotification.vue' export type { NeListboxOption } from '@/components/NeListbox.vue' export type { NeDropdownItem } from '@/components/NeDropdown.vue' +export type { FilterOption, FilterKind } from '@/components/NeDropdownFilter.vue' // library functions export export { diff --git a/stories/NeDropdownFilter.stories.ts b/stories/NeDropdownFilter.stories.ts new file mode 100644 index 0000000..a63054d --- /dev/null +++ b/stories/NeDropdownFilter.stories.ts @@ -0,0 +1,175 @@ +// Copyright (C) 2024 Nethesis S.r.l. +// SPDX-License-Identifier: GPL-3.0-or-later + +import type { Meta, StoryObj } from '@storybook/vue3' +import { NeDropdownFilter, NeButton } from '../src/main' +import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome' + +const meta = { + title: 'NeDropdownFilter', + component: NeDropdownFilter, + tags: ['autodocs'], + argTypes: { + kind: { control: 'inline-radio', options: ['radio', 'checkbox'] }, + size: { control: 'inline-radio', options: ['xs', 'sm', 'md', 'lg', 'xl'] } + }, + args: { + label: 'Filter label', + options: [ + { + id: 'option1', + label: 'Option 1' + }, + { + id: 'option2', + label: 'Option 2' + }, + { + id: 'option3', + label: 'Option 3', + disabled: true + }, + { + id: 'option4', + label: 'Option 4' + } + ], + kind: 'checkbox', + clearFilterLabel: 'Clear filter', + openMenuAriaLabel: 'Open filter', + showClearFilter: true, + showSelectionCount: true, + alignToRight: false, + size: 'md', + disabled: false, + id: '' + } +} satisfies Meta + +export default meta +type Story = StoryObj + +const template = '' + +export const CheckboxOptions: Story = { + render: (args) => ({ + components: { NeDropdownFilter }, + setup() { + return { args } + }, + template: template + }), + args: {} +} + +export const RadioOptions: Story = { + render: (args) => ({ + components: { NeDropdownFilter }, + setup() { + return { args } + }, + template: template + }), + args: { + kind: 'radio' + } +} + +export const OptionsWithDescription: Story = { + render: (args) => ({ + components: { NeDropdownFilter }, + setup() { + return { args } + }, + template: template + }), + args: { + options: [ + { + id: 'option1', + label: 'Option 1', + description: 'Description for option 1', + disabled: false + }, + { + id: 'option2', + label: 'Option 2', + description: 'Description for option 2', + disabled: false + }, + { + id: 'option3', + label: 'Option 3', + description: 'Description for option 3', + disabled: true + }, + { + id: 'option4', + label: 'Option 4', + description: 'Description for option 4', + disabled: false + } + ] + } +} + +export const NoClearFilter: Story = { + render: (args) => ({ + components: { NeDropdownFilter }, + setup() { + return { args } + }, + template: template + }), + args: { + kind: 'checkbox', + showClearFilter: false + } +} + +const alignToRightTemplate = `
+ +
` + +export const AlignToRight: Story = { + render: (args) => ({ + components: { NeDropdownFilter }, + setup() { + return { args } + }, + template: alignToRightTemplate + }), + args: { alignToRight: true } +} + +export const Disabled: Story = { + render: (args) => ({ + components: { NeDropdownFilter }, + setup() { + return { args } + }, + template: template + }), + args: { + disabled: true + } +} + +const withSlotTemplate = ` + +` + +export const ButtonSlot: Story = { + render: (args) => ({ + components: { NeDropdownFilter, NeButton, FontAwesomeIcon }, + setup() { + return { args } + }, + template: withSlotTemplate + }), + args: {} +} From c63d81436354880e11c9242b49bed2af3e8fccf5 Mon Sep 17 00:00:00 2001 From: Andrea Leardini Date: Fri, 9 Aug 2024 15:45:35 +0200 Subject: [PATCH 2/6] fix: do not use div inside label elements --- src/components/NeDropdownFilter.vue | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/components/NeDropdownFilter.vue b/src/components/NeDropdownFilter.vue index bba6ad8..377b135 100644 --- a/src/components/NeDropdownFilter.vue +++ b/src/components/NeDropdownFilter.vue @@ -148,7 +148,7 @@ function calculatePosition() { size="xs" class="ml-2" /> -