@flux-ui/components 3.0.0-next.61 → 3.0.0-next.63

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.
Files changed (123) hide show
  1. package/dist/component/FluxActionStack.vue.d.ts +25 -19
  2. package/dist/component/FluxAspectRatio.vue.d.ts +4 -3
  3. package/dist/component/FluxBorderShine.vue.d.ts +1 -1
  4. package/dist/component/FluxCalendar.vue.d.ts +2 -6
  5. package/dist/component/FluxContainer.vue.d.ts +3 -2
  6. package/dist/component/FluxFilter.vue.d.ts +6 -7
  7. package/dist/component/FluxFilterBar.vue.d.ts +5 -4
  8. package/dist/component/FluxFilterBase.vue.d.ts +14 -11
  9. package/dist/component/FluxFilterDate.vue.d.ts +3 -6
  10. package/dist/component/FluxFilterDateRange.vue.d.ts +3 -6
  11. package/dist/component/FluxFilterOption.vue.d.ts +3 -6
  12. package/dist/component/FluxFilterOptionAsync.vue.d.ts +3 -6
  13. package/dist/component/FluxFilterOptions.vue.d.ts +3 -6
  14. package/dist/component/FluxFilterOptionsAsync.vue.d.ts +3 -6
  15. package/dist/component/FluxFilterRange.vue.d.ts +3 -7
  16. package/dist/component/FluxFilterWindow.vue.d.ts +3 -8
  17. package/dist/component/FluxFlex.vue.d.ts +30 -0
  18. package/dist/component/{FluxRow.vue.d.ts → FluxFlexItem.vue.d.ts} +5 -3
  19. package/dist/component/FluxGrid.vue.d.ts +3 -2
  20. package/dist/component/FluxGridColumn.vue.d.ts +3 -2
  21. package/dist/component/FluxKanbanColumn.vue.d.ts +3 -0
  22. package/dist/component/FluxScroller.vue.d.ts +32 -0
  23. package/dist/component/{FluxStack.vue.d.ts → FluxSplitView.vue.d.ts} +7 -6
  24. package/dist/component/{FluxColumn.vue.d.ts → FluxSplitViewPane.vue.d.ts} +4 -1
  25. package/dist/component/FluxSticky.vue.d.ts +34 -0
  26. package/dist/component/index.d.ts +6 -3
  27. package/dist/component/primitive/FilterBadge.vue.d.ts +2 -2
  28. package/dist/component/primitive/FilterItem.vue.d.ts +3 -2
  29. package/dist/component/primitive/SelectBase.vue.d.ts +4 -4
  30. package/dist/composable/private/index.d.ts +1 -0
  31. package/dist/composable/private/useSplitView.d.ts +23 -0
  32. package/dist/data/di.d.ts +19 -2
  33. package/dist/data/index.d.ts +0 -1
  34. package/dist/index.css +583 -331
  35. package/dist/index.d.ts +2 -0
  36. package/dist/index.js +8755 -8109
  37. package/dist/index.js.map +1 -1
  38. package/dist/util/defineFilter.d.ts +3 -0
  39. package/dist/util/filter.d.ts +7 -0
  40. package/dist/util/index.d.ts +2 -0
  41. package/dist/vite/defineFilterMacro.d.ts +3 -0
  42. package/dist/vite/index.d.ts +1 -0
  43. package/dist/vite.js +217 -0
  44. package/dist/vite.js.map +1 -0
  45. package/package.json +11 -7
  46. package/src/component/FluxActionBar.vue +3 -4
  47. package/src/component/FluxActionStack.vue +3 -3
  48. package/src/component/FluxAspectRatio.vue +5 -3
  49. package/src/component/FluxBadgeStack.vue +4 -4
  50. package/src/component/FluxButtonStack.vue +6 -4
  51. package/src/component/FluxCalendar.vue +160 -157
  52. package/src/component/FluxContainer.vue +4 -2
  53. package/src/component/FluxFilter.vue +10 -11
  54. package/src/component/FluxFilterBar.vue +71 -15
  55. package/src/component/FluxFilterBase.vue +65 -51
  56. package/src/component/FluxFilterDate.vue +24 -8
  57. package/src/component/FluxFilterDateRange.vue +27 -9
  58. package/src/component/FluxFilterOption.vue +20 -10
  59. package/src/component/FluxFilterOptionAsync.vue +19 -11
  60. package/src/component/FluxFilterOptions.vue +26 -11
  61. package/src/component/FluxFilterOptionsAsync.vue +28 -12
  62. package/src/component/FluxFilterRange.vue +25 -11
  63. package/src/component/FluxFilterWindow.vue +25 -11
  64. package/src/component/FluxFlex.vue +53 -0
  65. package/src/component/FluxFlexItem.vue +40 -0
  66. package/src/component/FluxFormDateTimeInput.vue +3 -4
  67. package/src/component/FluxGrid.vue +4 -2
  68. package/src/component/FluxGridColumn.vue +4 -2
  69. package/src/component/FluxInfoStack.vue +3 -3
  70. package/src/component/FluxItemStack.vue +4 -4
  71. package/src/component/FluxKanbanColumn.vue +16 -3
  72. package/src/component/FluxNoticeStack.vue +3 -3
  73. package/src/component/FluxProgressBar.vue +4 -3
  74. package/src/component/FluxScroller.vue +63 -0
  75. package/src/component/FluxSplitView.vue +101 -0
  76. package/src/component/FluxSplitViewPane.vue +23 -0
  77. package/src/component/FluxSticky.vue +67 -0
  78. package/src/component/FluxTagStack.vue +4 -4
  79. package/src/component/FluxToolbar.vue +3 -4
  80. package/src/component/FluxToolbarGroup.vue +3 -4
  81. package/src/component/FluxTooltipProvider.vue +56 -25
  82. package/src/component/index.ts +6 -3
  83. package/src/component/primitive/FilterBadge.vue +2 -2
  84. package/src/component/primitive/FilterItem.vue +4 -2
  85. package/src/component/primitive/FilterMenuRenderer.ts +10 -5
  86. package/src/component/primitive/FilterOptionBase.vue +1 -1
  87. package/src/composable/private/index.ts +1 -0
  88. package/src/composable/private/useAsyncFilterOptions.ts +1 -1
  89. package/src/composable/private/useFilterOption.ts +1 -1
  90. package/src/composable/private/useSplitView.ts +249 -0
  91. package/src/composable/useFilterInjection.ts +3 -1
  92. package/src/css/component/Calendar.module.scss +11 -17
  93. package/src/css/component/Comment.module.scss +3 -11
  94. package/src/css/component/Filter.module.scss +6 -2
  95. package/src/css/component/Flex.module.scss +84 -0
  96. package/src/css/component/Flyout.module.scss +1 -0
  97. package/src/css/component/Kanban.module.scss +31 -28
  98. package/src/css/component/LayerPane.module.scss +5 -0
  99. package/src/css/component/Layout.module.scss +0 -41
  100. package/src/css/component/Legend.module.scss +3 -4
  101. package/src/css/component/Menu.module.scss +1 -0
  102. package/src/css/component/Pagination.module.scss +1 -1
  103. package/src/css/component/Pane.module.scss +1 -1
  104. package/src/css/component/Progress.module.scss +2 -2
  105. package/src/css/component/Scroller.module.scss +109 -0
  106. package/src/css/component/SplitView.module.scss +78 -0
  107. package/src/css/component/Sticky.module.scss +35 -0
  108. package/src/css/component/Tab.module.scss +1 -0
  109. package/src/css/component/Table.module.scss +1 -0
  110. package/src/css/component/Tooltip.module.scss +14 -0
  111. package/src/data/di.ts +22 -2
  112. package/src/data/index.ts +0 -1
  113. package/src/index.ts +11 -0
  114. package/src/util/defineFilter.ts +10 -0
  115. package/src/util/filter.ts +63 -0
  116. package/src/util/index.ts +2 -0
  117. package/src/vite/defineFilterMacro.ts +335 -0
  118. package/src/vite/index.ts +1 -0
  119. package/dist/data/filter.d.ts +0 -7
  120. package/src/component/FluxColumn.vue +0 -24
  121. package/src/component/FluxRow.vue +0 -24
  122. package/src/component/FluxStack.vue +0 -41
  123. package/src/data/filter.ts +0 -165
@@ -1,163 +1,165 @@
1
1
  <template>
2
- <div
3
- ref="root"
4
- :class="$style.calendar">
5
- <div
6
- :class="$style.calendarItemRegistry"
7
- aria-hidden="true">
8
- <slot/>
9
- </div>
10
-
11
- <FluxActionBar :class="$style.calendarActions">
12
- <template #primary>
13
- <div
14
- :class="$style.calendarCurrent"
15
- role="presentation">
16
- <template v-if="resolvedView === 'month'">
17
- <FluxFlyout :width="300">
18
- <template #opener="{open}">
19
- <button
20
- :class="$style.calendarCurrentMonth"
21
- :aria-label="translate('flux.selectMonth')"
22
- type="button"
23
- @click="open">
24
- {{ monthViewMonth }}
25
- </button>
26
- </template>
27
-
28
- <template #default="{close}">
29
- <div :class="$styleDatePicker.datePickerMonths">
30
- <template
31
- v-for="month of months"
32
- :key="month.label">
2
+ <FluxLayerPane :class="$style.calendar">
3
+ <FluxPaneBody>
4
+ <FluxActionBar :class="$style.calendarActions">
5
+ <template #primary>
6
+ <div
7
+ :class="$style.calendarCurrent"
8
+ role="presentation">
9
+ <template v-if="resolvedView === 'month'">
10
+ <FluxFlyout :width="300">
11
+ <template #opener="{open}">
12
+ <button
13
+ :class="$style.calendarCurrentMonth"
14
+ :aria-label="translate('flux.selectMonth')"
15
+ type="button"
16
+ @click="open">
17
+ {{ monthViewMonth }}
18
+ </button>
19
+ </template>
20
+
21
+ <template #default="{close}">
22
+ <div :class="$styleDatePicker.datePickerMonths">
23
+ <template
24
+ v-for="month of months"
25
+ :key="month.label">
26
+ <FluxSecondaryButton
27
+ :label="month.label"
28
+ tabindex="-1"
29
+ @click="setMonthViewMonth(month.date, close)"/>
30
+ </template>
31
+ </div>
32
+ </template>
33
+ </FluxFlyout>
34
+
35
+ <FluxFlyout :width="300">
36
+ <template #opener="{open}">
37
+ <button
38
+ :class="$style.calendarCurrentYear"
39
+ :aria-label="translate('flux.selectYear')"
40
+ type="button"
41
+ @click="open">
42
+ {{ monthViewYear }}
43
+ </button>
44
+ </template>
45
+
46
+ <template #default="{close}">
47
+ <div :class="$styleDatePicker.datePickerYears">
33
48
  <FluxSecondaryButton
34
- :label="month.label"
49
+ :aria-label="translate('flux.previousYears')"
50
+ icon-leading="angle-left"
35
51
  tabindex="-1"
36
- @click="setMonthViewMonth(month.date, close)"/>
37
- </template>
38
- </div>
39
- </template>
40
- </FluxFlyout>
41
-
42
- <FluxFlyout :width="300">
43
- <template #opener="{open}">
44
- <button
45
- :class="$style.calendarCurrentYear"
46
- :aria-label="translate('flux.selectYear')"
47
- type="button"
48
- @click="open">
49
- {{ monthViewYear }}
50
- </button>
51
- </template>
52
-
53
- <template #default="{close}">
54
- <div :class="$styleDatePicker.datePickerYears">
55
- <FluxSecondaryButton
56
- :aria-label="translate('flux.previousYears')"
57
- icon-leading="angle-left"
58
- tabindex="-1"
59
- @click="previousYears"/>
60
-
61
- <template
62
- v-for="year of years"
63
- :key="year">
52
+ @click="previousYears"/>
53
+
54
+ <template
55
+ v-for="year of years"
56
+ :key="year">
57
+ <FluxSecondaryButton
58
+ :label="year.toString()"
59
+ tabindex="-1"
60
+ @click="setMonthViewYear(year, close)"/>
61
+ </template>
62
+
64
63
  <FluxSecondaryButton
65
- :label="year.toString()"
64
+ :aria-label="translate('flux.nextYears')"
65
+ icon-leading="angle-right"
66
66
  tabindex="-1"
67
- @click="setMonthViewYear(year, close)"/>
68
- </template>
69
-
70
- <FluxSecondaryButton
71
- :aria-label="translate('flux.nextYears')"
72
- icon-leading="angle-right"
73
- tabindex="-1"
74
- @click="nextYears"/>
75
- </div>
76
- </template>
77
- </FluxFlyout>
78
- </template>
79
-
80
- <template v-else>
81
- <FluxFlyout :width="320">
82
- <template #opener="{open}">
83
- <button
84
- :class="$style.calendarRangeLabel"
85
- :aria-label="translate('flux.selectDate')"
86
- type="button"
87
- @click="open">
88
- {{ rangeLabel }}
89
- </button>
90
- </template>
91
-
92
- <template #default="{close}">
93
- <FluxDatePicker
94
- :model-value="datePickerValue"
95
- @update:model-value="(value) => onDatePicked(value, close)"/>
96
- </template>
97
- </FluxFlyout>
98
- </template>
99
- </div>
100
- </template>
101
-
102
- <template #actionsEnd>
103
- <FluxSecondaryButton
104
- :aria-label="translate('flux.today')"
105
- :label="translate('flux.today')"
106
- @click="setToday"/>
107
-
108
- <FluxButtonGroup>
109
- <FluxSecondaryButton
110
- :aria-label="translate('flux.previous')"
111
- icon-leading="angle-left"
112
- @click="navigatePrevious"
113
- @dragenter="onNavDragEnter('previous')"
114
- @dragover="onNavDragOver"
115
- @dragleave="onNavDragLeave"/>
116
-
67
+ @click="nextYears"/>
68
+ </div>
69
+ </template>
70
+ </FluxFlyout>
71
+ </template>
72
+
73
+ <template v-else>
74
+ <FluxFlyout :width="320">
75
+ <template #opener="{open}">
76
+ <button
77
+ :class="$style.calendarRangeLabel"
78
+ :aria-label="translate('flux.selectDate')"
79
+ type="button"
80
+ @click="open">
81
+ {{ rangeLabel }}
82
+ </button>
83
+ </template>
84
+
85
+ <template #default="{close}">
86
+ <FluxDatePicker
87
+ :model-value="datePickerValue"
88
+ @update:model-value="onDatePicked($event); close();"/>
89
+ </template>
90
+ </FluxFlyout>
91
+ </template>
92
+ </div>
93
+ </template>
94
+
95
+ <template #actionsEnd>
117
96
  <FluxSecondaryButton
118
- :aria-label="translate('flux.next')"
119
- icon-leading="angle-right"
120
- @click="navigateNext"
121
- @dragenter="onNavDragEnter('next')"
122
- @dragover="onNavDragOver"
123
- @dragleave="onNavDragLeave"/>
124
- </FluxButtonGroup>
125
- </template>
126
- </FluxActionBar>
127
-
128
- <FluxCalendarMonthView
129
- v-if="resolvedView === 'month'"
130
- :dates="monthDates"
131
- :days="monthDays"
132
- :view-date="monthViewDate"
133
- :is-transitioning-to-past="monthIsTransitioningToPast"
134
- :draggable="draggable"
135
- :items="items"
136
- :has-active-drag="dragState !== null"
137
- :focused-date="monthFocusedDate"
138
- @cell-drop="onMonthCellDrop"/>
139
-
140
- <FluxCalendarTimeGridView
141
- v-else
142
- :view-dates="timeGridViewDates"
143
- :is-transitioning-to-past="timeGridIsTransitioningToPast"
144
- :draggable="draggable"
145
- :items="items"
146
- :has-active-drag="dragState !== null"
147
- :hour-range="effectiveHourRange"
148
- :pixels-per-minute="pixelsPerMinute"
149
- :snap-minutes="SNAP_MINUTES"
150
- :day-count="timeGridDayCount"
151
- @time-grid-drop="onTimeGridDrop"
152
- @all-day-drop="onAllDayDrop"
153
- @resize="onResize"/>
154
-
155
- <div
156
- v-if="isLoading"
157
- :class="$style.calendarLoader">
158
- <FluxSpinner/>
159
- </div>
160
- </div>
97
+ :aria-label="translate('flux.today')"
98
+ :label="translate('flux.today')"
99
+ @click="setToday"/>
100
+
101
+ <FluxButtonGroup>
102
+ <FluxSecondaryButton
103
+ :aria-label="translate('flux.previous')"
104
+ icon-leading="angle-left"
105
+ @click="navigatePrevious"
106
+ @dragenter="onNavDragEnter('previous')"
107
+ @dragover="onNavDragOver"
108
+ @dragleave="onNavDragLeave"/>
109
+
110
+ <FluxSecondaryButton
111
+ :aria-label="translate('flux.next')"
112
+ icon-leading="angle-right"
113
+ @click="navigateNext"
114
+ @dragenter="onNavDragEnter('next')"
115
+ @dragover="onNavDragOver"
116
+ @dragleave="onNavDragLeave"/>
117
+ </FluxButtonGroup>
118
+ </template>
119
+ </FluxActionBar>
120
+ </FluxPaneBody>
121
+
122
+ <FluxPane :class="$style.calendarView">
123
+ <FluxCalendarMonthView
124
+ v-if="resolvedView === 'month'"
125
+ :dates="monthDates"
126
+ :days="monthDays"
127
+ :view-date="monthViewDate"
128
+ :is-transitioning-to-past="monthIsTransitioningToPast"
129
+ :draggable="draggable"
130
+ :items="items"
131
+ :has-active-drag="dragState !== null"
132
+ :focused-date="monthFocusedDate"
133
+ @cell-drop="onMonthCellDrop"/>
134
+
135
+ <FluxCalendarTimeGridView
136
+ v-else
137
+ :view-dates="timeGridViewDates"
138
+ :is-transitioning-to-past="timeGridIsTransitioningToPast"
139
+ :draggable="draggable"
140
+ :items="items"
141
+ :has-active-drag="dragState !== null"
142
+ :hour-range="effectiveHourRange"
143
+ :pixels-per-minute="pixelsPerMinute"
144
+ :snap-minutes="SNAP_MINUTES"
145
+ :day-count="timeGridDayCount"
146
+ @time-grid-drop="onTimeGridDrop"
147
+ @all-day-drop="onAllDayDrop"
148
+ @resize="onResize"/>
149
+
150
+ <div
151
+ v-if="isLoading"
152
+ :class="$style.calendarLoader">
153
+ <FluxSpinner/>
154
+ </div>
155
+
156
+ <div
157
+ :class="$style.calendarItemRegistry"
158
+ aria-hidden="true">
159
+ <slot/>
160
+ </div>
161
+ </FluxPane>
162
+ </FluxLayerPane>
161
163
  </template>
162
164
 
163
165
  <script
@@ -174,6 +176,9 @@
174
176
  import FluxButtonGroup from './FluxButtonGroup.vue';
175
177
  import FluxDatePicker from './FluxDatePicker.vue';
176
178
  import FluxFlyout from './FluxFlyout.vue';
179
+ import FluxLayerPane from './FluxLayerPane.vue';
180
+ import FluxPane from './FluxPane.vue';
181
+ import FluxPaneBody from './FluxPaneBody.vue';
177
182
  import FluxSecondaryButton from './FluxSecondaryButton.vue';
178
183
  import FluxSpinner from './FluxSpinner.vue';
179
184
  import $style from '~flux/components/css/component/Calendar.module.scss';
@@ -409,7 +414,7 @@
409
414
  }
410
415
  });
411
416
 
412
- function onDatePicked(value: DateTime | DateTime[] | null, close: () => void): void {
417
+ function onDatePicked(value: DateTime | DateTime[] | null): void {
413
418
  if (!value || Array.isArray(value)) {
414
419
  return;
415
420
  }
@@ -419,8 +424,6 @@
419
424
  } else {
420
425
  setTimeGridViewDate(value);
421
426
  }
422
-
423
- close();
424
427
  }
425
428
 
426
429
  function setMonthViewMonth(month: DateTime, close: () => void): void {
@@ -1,9 +1,10 @@
1
1
  <template>
2
- <div
2
+ <Component
3
+ :is="tag ?? 'div'"
3
4
  :class="$style.container"
4
5
  :style="{'--gutter': `${gutter}px`}">
5
6
  <slot/>
6
- </div>
7
+ </Component>
7
8
  </template>
8
9
 
9
10
  <script
@@ -16,6 +17,7 @@
16
17
  gutter = 18
17
18
  } = defineProps<{
18
19
  readonly gutter?: number;
20
+ readonly tag?: keyof HTMLElementTagNameMap;
19
21
  }>();
20
22
 
21
23
  defineSlots<{
@@ -1,8 +1,8 @@
1
1
  <template>
2
2
  <FluxFilterBase
3
3
  v-model="modelValue"
4
- :resettable="resettable"
5
- @reset="reset">
4
+ @clear="onClear"
5
+ @reset="onReset">
6
6
  <template #filters>
7
7
  <slot/>
8
8
  </template>
@@ -10,9 +10,7 @@
10
10
  <template #default="{ filters, menuItems }">
11
11
  <FluxFilterWindow
12
12
  :filters="filters"
13
- :menu-items="menuItems"
14
- :resettable="resettable"
15
- @reset="reset"/>
13
+ :menu-items="menuItems"/>
16
14
  </template>
17
15
  </FluxFilterBase>
18
16
  </template>
@@ -26,22 +24,23 @@
26
24
  import FluxFilterWindow from './FluxFilterWindow.vue';
27
25
 
28
26
  const emit = defineEmits<{
29
- reset: [string]
27
+ clear: [string];
28
+ reset: [string];
30
29
  }>();
31
30
 
32
31
  const modelValue = defineModel<FluxFilterState>({
33
32
  required: true
34
33
  });
35
34
 
36
- defineProps<{
37
- readonly resettable?: string[];
38
- }>();
39
-
40
35
  defineSlots<{
41
36
  default(): VNode[];
42
37
  }>();
43
38
 
44
- function reset(name: string): void {
39
+ function onClear(name: string): void {
40
+ emit('clear', name);
41
+ }
42
+
43
+ function onReset(name: string): void {
45
44
  emit('reset', name);
46
45
  }
47
46
  </script>
@@ -1,13 +1,13 @@
1
1
  <template>
2
2
  <FluxFilterBase
3
3
  v-model="modelValue"
4
- :resettable="resettable"
5
- @reset="reset">
4
+ @clear="onClear"
5
+ @reset="onReset">
6
6
  <template #filters>
7
7
  <slot/>
8
8
  </template>
9
9
 
10
- <template #default="{ buttons, filters, menuItems }">
10
+ <template #default="{ buttons, filters, menuItems, clear, reset }">
11
11
  <div :class="$style.filterBar">
12
12
  <FluxFormInput
13
13
  v-if="isSearchable"
@@ -26,6 +26,7 @@
26
26
  <FluxSecondaryButton
27
27
  v-if="modelValue[button.name]"
28
28
  :class="$style.filterButton"
29
+ :disabled="button.disabled"
29
30
  :icon-leading="button.icon"
30
31
  :label="button.label"
31
32
  @click="open()">
@@ -37,11 +38,31 @@
37
38
  </FluxSecondaryButton>
38
39
  </template>
39
40
 
40
- <div :class="$style.filter">
41
- <FluxMenu>
42
- <VNodeRenderer :vnode="filters[button.name]"/>
43
- </FluxMenu>
44
- </div>
41
+ <template #default="{close}">
42
+ <div :class="$style.filter">
43
+ <FluxMenu>
44
+ <FluxMenuGroup
45
+ :class="[$style.filterHeader, $style.filterHeaderActions]"
46
+ is-horizontal>
47
+ <FluxMenuItem
48
+ v-if="isResettable(button, modelValue[button.name])"
49
+ :class="$style.filterAction"
50
+ icon-leading="rotate-left"
51
+ @click="onResetClick(close, reset, button.name)"
52
+ style="flex-grow: 0"/>
53
+
54
+ <FluxMenuItem
55
+ :class="$style.filterAction"
56
+ icon-leading="trash"
57
+ is-destructive
58
+ @click="onClearClick(close, clear, button.name)"
59
+ style="flex-grow: 0"/>
60
+ </FluxMenuGroup>
61
+
62
+ <VNodeRenderer :vnode="filters[button.name]"/>
63
+ </FluxMenu>
64
+ </div>
65
+ </template>
45
66
  </FluxFlyout>
46
67
  </template>
47
68
 
@@ -56,14 +77,18 @@
56
77
  <FluxSecondaryButton
57
78
  icon-leading="sliders-simple"
58
79
  label="Filter"
59
- @click="open()"/>
80
+ @click="open()">
81
+ <template
82
+ v-if="filterCount > 0"
83
+ #after>
84
+ <FluxBadge :label="String(filterCount)"/>
85
+ </template>
86
+ </FluxSecondaryButton>
60
87
  </template>
61
88
 
62
89
  <FluxFilterWindow
63
90
  :filters="filters"
64
- :menu-items="menuItems"
65
- :resettable="resettable"
66
- @reset="reset"/>
91
+ :menu-items="menuItems"/>
67
92
  </FluxFlyout>
68
93
  </template>
69
94
  </FluxOverflowBar>
@@ -78,17 +103,22 @@
78
103
  import type { FluxFilterState } from '@flux-ui/types';
79
104
  import { computed, unref, type VNode } from 'vue';
80
105
  import { FilterBadge, VNodeRenderer } from '~flux/components/component/primitive';
106
+ import { isResettable } from '~flux/components/util';
107
+ import FluxBadge from './FluxBadge.vue';
81
108
  import FluxFilterBase from './FluxFilterBase.vue';
82
109
  import FluxFilterWindow from './FluxFilterWindow.vue';
83
110
  import FluxFlyout from './FluxFlyout.vue';
84
111
  import FluxFormInput from './FluxFormInput.vue';
85
112
  import FluxMenu from './FluxMenu.vue';
113
+ import FluxMenuGroup from './FluxMenuGroup.vue';
114
+ import FluxMenuItem from './FluxMenuItem.vue';
86
115
  import FluxOverflowBar from './FluxOverflowBar.vue';
87
116
  import FluxSecondaryButton from './FluxSecondaryButton.vue';
88
117
  import FluxSeparator from './FluxSeparator.vue';
89
118
  import $style from '~flux/components/css/component/Filter.module.scss';
90
119
 
91
120
  const emit = defineEmits<{
121
+ clear: [string];
92
122
  reset: [string];
93
123
  }>();
94
124
 
@@ -102,7 +132,6 @@
102
132
 
103
133
  defineProps<{
104
134
  readonly isSearchable?: boolean;
105
- readonly resettable?: string[];
106
135
  readonly searchPlaceholder?: string;
107
136
  }>();
108
137
 
@@ -110,9 +139,36 @@
110
139
  default?(): VNode[];
111
140
  }>();
112
141
 
113
- const isFiltered = computed(() => Object.entries(unref(modelValue)).filter(([, val]) => Boolean(val)).length > 0);
142
+ const filterCount = computed(() => Object.entries(unref(modelValue))
143
+ .filter(([, val]) => {
144
+ if (val === null || val === undefined) {
145
+ return false;
146
+ }
147
+
148
+ if (Array.isArray(val)) {
149
+ return val.length > 0;
150
+ }
151
+
152
+ return true;
153
+ }).length);
114
154
 
115
- function reset(name: string): void {
155
+ const isFiltered = computed(() => unref(filterCount) > 0);
156
+
157
+ function onClear(name: string): void {
158
+ emit('clear', name);
159
+ }
160
+
161
+ function onReset(name: string): void {
116
162
  emit('reset', name);
117
163
  }
164
+
165
+ function onClearClick(close: () => void, clear: (name: string) => void, name: string): void {
166
+ close();
167
+ clear(name);
168
+ }
169
+
170
+ function onResetClick(close: () => void, reset: (name: string) => void, name: string): void {
171
+ close();
172
+ reset(name);
173
+ }
118
174
  </script>