@fiscozen/dropdown 0.1.27 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ export * from './src/index'
@@ -0,0 +1,104 @@
1
+ import { FzActionProps } from '@fiscozen/action';
2
+ import { FzDropdownSlots } from './types';
3
+
4
+ /**
5
+ * @deprecated Use the isOpen model instead
6
+ */
7
+ declare function open(): void;
8
+ /**
9
+ * @deprecated Use the isOpen model instead
10
+ */
11
+ declare function close(): void;
12
+ declare const _default: __VLS_WithTemplateSlots<import('vue').DefineComponent<import('vue').ExtractPropTypes<{
13
+ isOpen: import('vue').PropType<boolean>;
14
+ size: {
15
+ type: import('vue').PropType<import('@fiscozen/button').ButtonSize>;
16
+ };
17
+ disabled: {
18
+ type: import('vue').PropType<boolean>;
19
+ };
20
+ environment: {
21
+ type: import('vue').PropType<"backoffice" | "frontoffice">;
22
+ default: string;
23
+ };
24
+ listClass: {
25
+ type: import('vue').PropType<string>;
26
+ };
27
+ teleport: {
28
+ type: import('vue').PropType<boolean>;
29
+ default: boolean;
30
+ };
31
+ buttonVariant: {
32
+ type: import('vue').PropType<import('@fiscozen/button').ButtonVariant>;
33
+ };
34
+ actions: {
35
+ type: import('vue').PropType<(FzActionProps | (import('@fiscozen/action').FzActionSectionProps & {
36
+ type: "section";
37
+ }))[]>;
38
+ required: true;
39
+ default: () => never[];
40
+ };
41
+ align: {
42
+ type: import('vue').PropType<"right" | "left" | "center">;
43
+ };
44
+ closeOnActionClick: {
45
+ type: import('vue').PropType<boolean>;
46
+ default: boolean;
47
+ };
48
+ }>, {
49
+ open: typeof open;
50
+ close: typeof close;
51
+ }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
52
+ "fzaction:click": (actionIndex: number, action: FzActionProps) => void;
53
+ }, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
54
+ isOpen: import('vue').PropType<boolean>;
55
+ size: {
56
+ type: import('vue').PropType<import('@fiscozen/button').ButtonSize>;
57
+ };
58
+ disabled: {
59
+ type: import('vue').PropType<boolean>;
60
+ };
61
+ environment: {
62
+ type: import('vue').PropType<"backoffice" | "frontoffice">;
63
+ default: string;
64
+ };
65
+ listClass: {
66
+ type: import('vue').PropType<string>;
67
+ };
68
+ teleport: {
69
+ type: import('vue').PropType<boolean>;
70
+ default: boolean;
71
+ };
72
+ buttonVariant: {
73
+ type: import('vue').PropType<import('@fiscozen/button').ButtonVariant>;
74
+ };
75
+ actions: {
76
+ type: import('vue').PropType<(FzActionProps | (import('@fiscozen/action').FzActionSectionProps & {
77
+ type: "section";
78
+ }))[]>;
79
+ required: true;
80
+ default: () => never[];
81
+ };
82
+ align: {
83
+ type: import('vue').PropType<"right" | "left" | "center">;
84
+ };
85
+ closeOnActionClick: {
86
+ type: import('vue').PropType<boolean>;
87
+ default: boolean;
88
+ };
89
+ }>> & Readonly<{
90
+ "onFzaction:click"?: ((actionIndex: number, action: FzActionProps) => any) | undefined;
91
+ }>, {
92
+ environment: "backoffice" | "frontoffice";
93
+ teleport: boolean;
94
+ actions: (FzActionProps | (import('@fiscozen/action').FzActionSectionProps & {
95
+ type: "section";
96
+ }))[];
97
+ closeOnActionClick: boolean;
98
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>, Readonly<FzDropdownSlots> & FzDropdownSlots>;
99
+ export default _default;
100
+ type __VLS_WithTemplateSlots<T, S> = T & {
101
+ new (): {
102
+ $slots: S;
103
+ };
104
+ };
@@ -0,0 +1,55 @@
1
+ import { FzIconDropdownProps, FzIconDropdownSlots } from './types';
2
+ import { FzActionProps } from '@fiscozen/action';
3
+
4
+ declare const _default: __VLS_WithTemplateSlots<import('vue').DefineComponent<import('vue').ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<FzIconDropdownProps>, {
5
+ iconName: string;
6
+ closeOnActionClick: boolean;
7
+ align: string;
8
+ teleport: boolean;
9
+ environment: string;
10
+ buttonVariant: string;
11
+ label: string;
12
+ }>>, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
13
+ "fzaction:click": (index: number, action: FzActionProps) => void;
14
+ }, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<FzIconDropdownProps>, {
15
+ iconName: string;
16
+ closeOnActionClick: boolean;
17
+ align: string;
18
+ teleport: boolean;
19
+ environment: string;
20
+ buttonVariant: string;
21
+ label: string;
22
+ }>>> & Readonly<{
23
+ "onFzaction:click"?: ((index: number, action: FzActionProps) => any) | undefined;
24
+ }>, {
25
+ label: string;
26
+ environment: "backoffice" | "frontoffice";
27
+ iconName: string;
28
+ teleport: boolean;
29
+ buttonVariant: import('@fiscozen/button').CommonButtonVariant;
30
+ align: "right" | "left" | "center";
31
+ closeOnActionClick: boolean;
32
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>, Readonly<FzIconDropdownSlots> & FzIconDropdownSlots>;
33
+ export default _default;
34
+ type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
35
+ type __VLS_TypePropsToRuntimeProps<T> = {
36
+ [K in keyof T]-?: {} extends Pick<T, K> ? {
37
+ type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
38
+ } : {
39
+ type: import('vue').PropType<T[K]>;
40
+ required: true;
41
+ };
42
+ };
43
+ type __VLS_WithDefaults<P, D> = {
44
+ [K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_Prettify<P[K] & {
45
+ default: D[K];
46
+ }> : P[K];
47
+ };
48
+ type __VLS_Prettify<T> = {
49
+ [K in keyof T]: T[K];
50
+ } & {};
51
+ type __VLS_WithTemplateSlots<T, S> = T & {
52
+ new (): {
53
+ $slots: S;
54
+ };
55
+ };
@@ -0,0 +1,3 @@
1
+ export { default as FzDropdown } from './FzDropdown.vue';
2
+ export { default as FzIconDropdown } from './FzIconDropdown.vue';
3
+ export type * from './types';
@@ -0,0 +1,96 @@
1
+ import { ButtonSize, IconButtonVariant, ButtonVariant } from '@fiscozen/button';
2
+ import { FzActionProps, FzActionSectionProps } from '@fiscozen/action';
3
+ import { VNode } from 'vue';
4
+
5
+ type FzDropdownProps = {
6
+ /**
7
+ * @deprecated Use the environment prop instead
8
+ * Size of the dropdown trigger
9
+ */
10
+ size?: ButtonSize;
11
+ /**
12
+ * Environment of the dropdown trigger
13
+ * @default 'frontoffice'
14
+ */
15
+ environment?: 'frontoffice' | 'backoffice';
16
+ /**
17
+ * @deprecated Declare your actions list inside the actionsList slot instead
18
+ * List of actions
19
+ */
20
+ actions: (FzActionProps | (FzActionSectionProps & {
21
+ type: 'section';
22
+ }))[];
23
+ /**
24
+ * Whether to align to the left or right
25
+ * @default 'center'
26
+ */
27
+ align?: 'left' | 'right' | 'center';
28
+ /**
29
+ * Whether to close the action list when an action is clicked
30
+ */
31
+ closeOnActionClick?: boolean;
32
+ /**
33
+ * Class to apply to the actions list
34
+ */
35
+ listClass?: string;
36
+ /**
37
+ * Whether opener is disabled
38
+ */
39
+ disabled?: boolean;
40
+ /**
41
+ * Button variant
42
+ * @default 'primary'
43
+ */
44
+ buttonVariant?: ButtonVariant;
45
+ /**
46
+ * Teleport floating to body
47
+ * @default true
48
+ */
49
+ teleport?: boolean;
50
+ };
51
+ type FzDropdownSlots = {
52
+ /**
53
+ *
54
+ * Label of the standard button opener
55
+ */
56
+ default(props: {
57
+ isOpen: boolean;
58
+ }): VNode | VNode[];
59
+ /**
60
+ * Actions list slot
61
+ */
62
+ actionList(): VNode | VNode[];
63
+ /**
64
+ *
65
+ * Use this to replace the button opener entirely
66
+ */
67
+ opener(props: {
68
+ isOpen: boolean;
69
+ open: () => void;
70
+ close: () => void;
71
+ }): VNode | VNode[];
72
+ };
73
+ export type FzIconDropdownProps = Omit<FzDropdownProps, 'buttonVariant'> & {
74
+ /**
75
+ * icon name
76
+ */
77
+ iconName: string;
78
+ hasNotification?: boolean;
79
+ /**
80
+ * A11y label for the button opener
81
+ * @default 'Open dropdown'
82
+ */
83
+ label?: string;
84
+ /**
85
+ * Button variant (limited to IconButton variants)
86
+ * @default 'secondary'
87
+ */
88
+ buttonVariant?: IconButtonVariant;
89
+ };
90
+ export type FzIconDropdownSlots = {
91
+ /**
92
+ * Actions list slot
93
+ */
94
+ actionList(): VNode | VNode[];
95
+ };
96
+ export type { FzDropdownProps, FzDropdownSlots };
package/dist/style.css ADDED
@@ -0,0 +1 @@
1
+ .fz-icon-button-wrapper[data-v-b4be112d]>button{gap:0!important;min-width:0!important}.fz-icon-button-wrapper--backoffice[data-v-b4be112d]>button{padding-left:5px;padding-right:5px}.fz-icon-button-wrapper--frontoffice[data-v-b4be112d]>button{padding-left:11px;padding-right:11px}.fz-container[data-v-8c40daeb]{display:flex}.fz-container--vertical[data-v-8c40daeb]{flex-direction:column}.fz-container--horizontal[data-v-8c40daeb]{flex-direction:row;flex-wrap:nowrap}.fz-container.align-items-start[data-v-8c40daeb]{align-items:flex-start}.fz-container.align-items-center[data-v-8c40daeb]{align-items:center}.fz-container.align-items-end[data-v-8c40daeb]{align-items:flex-end}.fz-container.align-items-stretch[data-v-8c40daeb]{align-items:stretch}.fz-container.align-items-baseline[data-v-8c40daeb]{align-items:baseline}.fz-container--horizontal.layout-expand-first[data-v-8c40daeb]>*:first-child{flex-grow:1}.fz-container--horizontal.layout-expand-all[data-v-8c40daeb]>*{flex-grow:1}.fz-container--horizontal.layout-space-between[data-v-8c40daeb]{justify-content:space-between}.fz-container--horizontal.layout-expand-last[data-v-8c40daeb]>*:last-child{flex-grow:1}.fz-container--vertical.gap-main-content-sm[data-v-8c40daeb]>p+p{margin-top:calc((0px - var(--main-content-sm, 32px)) + var(--paragraph-gap, 8px))}.fz-container--vertical.gap-main-content-base[data-v-8c40daeb]>p+p{margin-top:calc((0px - var(--main-content-base, 48px)) + var(--paragraph-gap, 8px))}.fz-container--vertical.gap-main-content-lg[data-v-8c40daeb]>p+p{margin-top:calc((0px - var(--main-content-lg, 64px)) + var(--paragraph-gap, 8px))}.fz-container--vertical.gap-section-content-none[data-v-8c40daeb]>p+p{margin-top:calc((0px - var(--section-content-none, 0px)) + var(--paragraph-gap, 8px))}.fz-container--vertical.gap-section-content-xs[data-v-8c40daeb]>p+p{margin-top:calc((0px - var(--section-content-xs, 8px)) + var(--paragraph-gap, 8px))}.fz-container--vertical.gap-section-content-sm[data-v-8c40daeb]>p+p{margin-top:calc((0px - var(--section-content-sm, 16px)) + var(--paragraph-gap, 8px))}.fz-container--vertical.gap-section-content-base[data-v-8c40daeb]>p+p{margin-top:calc((0px - var(--section-content-base, 24px)) + var(--paragraph-gap, 8px))}.fz-container--vertical.gap-section-content-lg[data-v-8c40daeb]>p+p{margin-top:calc((0px - var(--section-content-lg, 32px)) + var(--paragraph-gap, 8px))}.fz-container--horizontal[data-v-8c40daeb]>p+p{margin-top:0}.fz-button-group[data-v-79dd8b6f]>*:nth-child(1):nth-last-child(2),.fz-button-group[data-v-79dd8b6f]>*:nth-child(1):nth-last-child(2)~*{flex-basis:50%;flex-grow:0;flex-shrink:1}.fz-button-group[data-v-79dd8b6f]>*:nth-child(1):nth-last-child(3),.fz-button-group[data-v-79dd8b6f]>*:nth-child(1):nth-last-child(3)~*{flex-basis:33.333%;flex-grow:0;flex-shrink:1}.fz-button-group[data-v-79dd8b6f]>.fz-icon-button-wrapper{flex-basis:initial!important;flex-grow:0!important;flex-shrink:0!important}a[data-v-9fa082d4]{text-decoration:none!important}.fz__actionlist[data-v-ae0f16c9]{box-shadow:0 1px 2px #0000000f,0 1px 3px #0000001a}
package/package.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@fiscozen/dropdown",
3
- "version": "0.1.27",
3
+ "version": "1.0.1",
4
4
  "description": "Design System Dropdown component",
5
5
  "main": "src/index.ts",
6
6
  "type": "module",
7
7
  "keywords": [],
8
8
  "author": "Alen Ajam",
9
9
  "dependencies": {
10
- "@fiscozen/button": "^0.1.13",
11
- "@fiscozen/actionlist": "^0.1.9",
12
- "@fiscozen/composables": "^0.1.36"
10
+ "@fiscozen/action": "^1.1.0-next.1",
11
+ "@fiscozen/button": "^1.0.1-next.1",
12
+ "@fiscozen/composables": "^1.0.0"
13
13
  },
14
14
  "peerDependencies": {
15
15
  "tailwindcss": "^3.4.1",
@@ -31,9 +31,9 @@
31
31
  "vite": "^5.0.10",
32
32
  "vitest": "^1.2.0",
33
33
  "vue-tsc": "^1.8.25",
34
- "@fiscozen/eslint-config": "^0.1.0",
35
34
  "@fiscozen/prettier-config": "^0.1.0",
36
- "@fiscozen/tsconfig": "^0.1.0"
35
+ "@fiscozen/tsconfig": "^0.1.0",
36
+ "@fiscozen/eslint-config": "^0.1.0"
37
37
  },
38
38
  "license": "MIT",
39
39
  "scripts": {
@@ -4,8 +4,8 @@
4
4
  :position="floatingPosition"
5
5
  ref="container"
6
6
  overrideContentClass
7
+ contentClass="mt-4 z-70"
7
8
  :teleport="teleport"
8
- :contentClass="['fixed pt-4 z-70', props.floatingClass || '']"
9
9
  >
10
10
  <template #opener>
11
11
  <slot name="opener" :isOpen="isOpen" :open :close>
@@ -13,43 +13,60 @@
13
13
  icon-position="after"
14
14
  :icon-name="buttonIconName"
15
15
  @click="isOpen = !isOpen"
16
- :size
17
- :variant
18
- :disabled="openerDisabled"
19
- :class="openerClass"
16
+ :environment="mappedSizeToEnvironment"
17
+ :variant="buttonVariant"
18
+ :disabled="disabled"
20
19
  >
21
20
  <slot :isOpen="isOpen"></slot>
22
21
  </FzButton>
23
22
  </slot>
24
23
  </template>
25
- <FzActionlist :items="actions" :label="actionsLabel" :listClass="props.listClass" @fzaction:click="handleActionClick">
26
- <template v-for="(action, index) in actions" :key="index" #[`fzaction-item-${index}`]>
27
- <slot :name="`fzaction-item-${index}`" :item="action" :open :close></slot>
28
- </template>
29
- </FzActionlist>
24
+ <slot name="actionList">
25
+ <FzActionList :listClass="props.listClass">
26
+ <FzActionSection
27
+ v-for="(section, index) in groupedActions"
28
+ :key="index"
29
+ :label="index !== '__default__' ? index : undefined"
30
+ :environment="environment"
31
+ >
32
+ <FzAction
33
+ v-for="(action, actionIndex) in section"
34
+ :key="actionIndex"
35
+ v-bind="action"
36
+ @click="handleActionClick(action)"
37
+ :environment="environment"
38
+ />
39
+ </FzActionSection>
40
+ </FzActionList>
41
+ </slot>
30
42
  </FzFloating>
31
43
  </template>
32
44
 
33
45
  <script setup lang="ts">
34
46
  import { ComponentPublicInstance, computed, ref } from 'vue'
35
47
  import { FzButton } from '@fiscozen/button'
36
- import { FzActionlist, ActionlistItem } from '@fiscozen/actionlist'
48
+ import { FzAction, FzActionList, FzActionProps, FzActionSection } from '@fiscozen/action'
37
49
  import { FzFloating, useClickOutside, useKeyDown } from '@fiscozen/composables'
38
50
  import { FzDropdownProps, FzDropdownSlots } from './types'
51
+ import { sizeToEnvironmentMapping } from '@fiscozen/button/src/utils'
39
52
 
40
53
  const props = withDefaults(defineProps<FzDropdownProps>(), {
41
- size: 'md',
54
+ environment: 'frontoffice',
42
55
  actions: () => [],
43
- closeOnActionClick: true
56
+ closeOnActionClick: true,
57
+ teleport: true
44
58
  })
45
59
 
60
+ const mappedSizeToEnvironment = computed<'backoffice' | 'frontoffice'>(() => {
61
+ return props.size ? sizeToEnvironmentMapping[props.size] : props.environment
62
+ })
46
63
  const emit = defineEmits<{
47
- 'fzaction:click': [index: number, action: ActionlistItem]
64
+ 'fzaction:click': [actionIndex: number, action: FzActionProps]
48
65
  }>()
49
66
 
50
67
  defineSlots<FzDropdownSlots>()
51
68
 
52
- const isOpen = ref(false)
69
+ const isOpen = defineModel<boolean>('isOpen', { default: false })
53
70
  const container = ref<ComponentPublicInstance>()
54
71
  const containerDom = computed(() => container.value?.$el)
55
72
  const buttonIconName = computed(() => (isOpen.value ? 'angle-up' : 'angle-down'))
@@ -64,6 +81,24 @@ const floatingPosition = computed(() => {
64
81
  }
65
82
  })
66
83
 
84
+ const groupedActions = computed(() => {
85
+ const sections: Record<string, FzActionProps[]> = {}
86
+
87
+ let section = '__default__'
88
+ props.actions.forEach((action) => {
89
+ if (action.type === 'section') {
90
+ section = action.label || '__default__'
91
+ return
92
+ }
93
+
94
+ if (!sections[section]) {
95
+ sections[section] = []
96
+ }
97
+ sections[section].push(action)
98
+ })
99
+ return sections
100
+ })
101
+
67
102
  useClickOutside(containerDom, () => {
68
103
  isOpen.value = false
69
104
  })
@@ -73,16 +108,25 @@ useKeyDown(containerDom, (event) => {
73
108
  isOpen.value = false
74
109
  })
75
110
 
76
- function handleActionClick(index: number, action: ActionlistItem) {
111
+ function handleActionClick(action: FzActionProps) {
112
+ const stringifiedAction = JSON.stringify(action)
113
+ const index = props.actions.findIndex((compareAction) => JSON.stringify(compareAction) == stringifiedAction)
77
114
  emit('fzaction:click', index, action)
78
115
  if (props.closeOnActionClick) {
79
116
  isOpen.value = false
80
117
  }
81
118
  }
82
119
 
120
+ /**
121
+ * @deprecated Use the isOpen model instead
122
+ */
83
123
  function open() {
84
124
  isOpen.value = true
85
125
  }
126
+
127
+ /**
128
+ * @deprecated Use the isOpen model instead
129
+ */
86
130
  function close() {
87
131
  isOpen.value = false
88
132
  }
@@ -1,26 +1,52 @@
1
1
  <template>
2
- <FzDropdown v-bind="props" ref="dropdown" @fzaction:click="(...args) => emit('fzaction:click', ...args)">
2
+ <FzDropdown
3
+ v-bind="props"
4
+ ref="dropdown"
5
+ @fzaction:click="(...args) => emit('fzaction:click', ...args)"
6
+ :environment="mappedSizeToEnvironment"
7
+ >
3
8
  <template #opener="{ open }">
4
- <FzIconButton :iconName="iconName" @click.stop="open()" :variant="buttonVariant" :disabled="openerDisabled" :size />
9
+ <FzIconButton
10
+ :iconName="iconName"
11
+ @click.stop="open()"
12
+ :variant="buttonVariant"
13
+ :disabled="disabled"
14
+ :environment="mappedSizeToEnvironment"
15
+ :aria-label="label"
16
+ :hasNotification="hasNotification"
17
+ />
18
+ </template>
19
+ <template #actionList>
20
+ <slot name="actionList"></slot>
5
21
  </template>
6
22
  </FzDropdown>
7
23
  </template>
8
24
 
9
25
  <script setup lang="ts">
26
+ import { computed } from 'vue'
10
27
  import FzDropdown from './FzDropdown.vue'
11
- import { type FzIconDropdownProps } from './types'
28
+ import { type FzIconDropdownProps, type FzIconDropdownSlots } from './types'
12
29
  import { FzIconButton } from '@fiscozen/button'
13
- import { ActionlistItem } from '@fiscozen/actionlist'
30
+ import { FzActionProps } from '@fiscozen/action'
31
+ import { sizeToEnvironmentMapping } from '@fiscozen/button/src/utils'
14
32
 
15
33
  const props = withDefaults(defineProps<FzIconDropdownProps>(), {
16
34
  iconName: 'bars',
17
35
  closeOnActionClick: true,
18
36
  align: 'center',
19
37
  teleport: true,
20
- buttonVariant: 'secondary'
38
+ environment: 'frontoffice',
39
+ buttonVariant: 'secondary',
40
+ label: 'Open dropdown'
41
+ })
42
+
43
+ const mappedSizeToEnvironment = computed<'backoffice' | 'frontoffice'>(() => {
44
+ return props.size ? sizeToEnvironmentMapping[props.size] : props.environment
21
45
  })
22
46
 
47
+ defineSlots<FzIconDropdownSlots>()
48
+
23
49
  const emit = defineEmits<{
24
- 'fzaction:click': [index: number, action: ActionlistItem]
50
+ 'fzaction:click': [index: number, action: FzActionProps]
25
51
  }>()
26
52
  </script>