@flux-ui/components 3.0.0-next.19 → 3.0.0-next.20

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 (36) hide show
  1. package/dist/component/FluxActions.vue.d.ts.map +1 -1
  2. package/dist/component/FluxDataTable.vue.d.ts +23 -11
  3. package/dist/component/FluxDataTable.vue.d.ts.map +1 -1
  4. package/dist/component/FluxFilter.vue.d.ts.map +1 -1
  5. package/dist/component/FluxFlyout.vue.d.ts.map +1 -1
  6. package/dist/component/FluxFormDateInput.vue.d.ts.map +1 -1
  7. package/dist/component/FluxFormDateRangeInput.vue.d.ts.map +1 -1
  8. package/dist/component/FluxFormDateTimeInput.vue.d.ts.map +1 -1
  9. package/dist/component/FluxFormInput.vue.d.ts +1 -0
  10. package/dist/component/FluxFormInput.vue.d.ts.map +1 -1
  11. package/dist/component/FluxFormInputGroup.vue.d.ts +1 -0
  12. package/dist/component/FluxFormInputGroup.vue.d.ts.map +1 -1
  13. package/dist/component/FluxFormTimeZonePicker.vue.d.ts.map +1 -1
  14. package/dist/component/FluxPrompt.vue.d.ts +2 -0
  15. package/dist/component/FluxPrompt.vue.d.ts.map +1 -1
  16. package/dist/component/FluxTabBarItem.vue.d.ts.map +1 -1
  17. package/dist/component/FluxTooltip.vue.d.ts.map +1 -1
  18. package/dist/component/primitive/AnchorPopup.vue.d.ts.map +1 -1
  19. package/dist/component/primitive/SelectBase.vue.d.ts +2 -0
  20. package/dist/component/primitive/SelectBase.vue.d.ts.map +1 -1
  21. package/dist/index.css +5808 -1
  22. package/dist/index.js +11209 -7932
  23. package/dist/index.js.map +1 -1
  24. package/package.json +14 -14
  25. package/src/component/FluxDataTable.vue +24 -15
  26. package/src/component/FluxFlyout.vue +2 -1
  27. package/src/component/FluxFormInput.vue +2 -0
  28. package/src/component/FluxFormInputGroup.vue +2 -0
  29. package/src/component/FluxFormTimeZonePicker.vue +5 -0
  30. package/src/component/FluxProgressBar.vue +1 -1
  31. package/src/component/FluxTooltip.vue +2 -0
  32. package/src/component/primitive/AnchorPopup.vue +5 -3
  33. package/src/css/component/Form.module.scss +9 -4
  34. package/src/css/component/Progress.module.scss +12 -1
  35. package/src/css/component/Table.module.scss +34 -1
  36. package/src/data/iconRegistry.ts +1 -1
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@flux-ui/components",
3
3
  "description": "A set of opiniated UI components.",
4
- "version": "3.0.0-next.19",
4
+ "version": "3.0.0-next.20",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "funding": "https://github.com/sponsors/basmilius",
@@ -51,26 +51,26 @@
51
51
  "typings": "./dist/index.d.ts",
52
52
  "sideEffects": false,
53
53
  "dependencies": {
54
- "@basmilius/utils": "^2.9.0",
55
- "@flux-ui/internals": "3.0.0-next.19",
56
- "@flux-ui/types": "3.0.0-next.19",
57
- "@fortawesome/fontawesome-common-types": "^7.0.0",
54
+ "@basmilius/utils": "^2.13.0",
55
+ "@flux-ui/internals": "3.0.0-next.20",
56
+ "@flux-ui/types": "3.0.0-next.20",
57
+ "@fortawesome/fontawesome-common-types": "^7.1.0",
58
58
  "clsx": "^2.1.1",
59
59
  "imask": "^7.6.1",
60
60
  "lodash-es": "^4.17.21",
61
- "luxon": "^3.7.1",
62
- "vue": "^3.5.18"
61
+ "luxon": "^3.7.2",
62
+ "vue": "^3.5.23"
63
63
  },
64
64
  "devDependencies": {
65
- "@basmilius/vite-preset": "^2.9.0",
65
+ "@basmilius/vite-preset": "^2.13.0",
66
66
  "@types/lodash-es": "^4.17.12",
67
67
  "@types/luxon": "^3.7.1",
68
- "@types/node": "^24.2.1",
68
+ "@types/node": "^24.10.0",
69
69
  "@vitejs/plugin-vue": "^6.0.1",
70
- "pinia": "^3.0.3",
71
- "sass-embedded": "^1.90.0",
72
- "typescript": "^5.9.2",
73
- "vite": "^7.1.1",
74
- "vue-tsc": "^3.0.5"
70
+ "pinia": "^3.0.4",
71
+ "sass-embedded": "^1.93.3",
72
+ "typescript": "^5.9.3",
73
+ "vite": "^7.2.1",
74
+ "vue-tsc": "^3.1.3"
75
75
  }
76
76
  }
@@ -15,10 +15,12 @@
15
15
  <template
16
16
  v-if="'header' in slots"
17
17
  #header>
18
+ <slot name="filter" v-bind="{page, perPage, items: limitedItems, total}"/>
19
+
18
20
  <FluxTableRow>
19
21
  <slot
20
22
  name="header"
21
- v-bind="{page, perPage, rows, total}"/>
23
+ v-bind="{page, perPage, items: limitedItems, total}"/>
22
24
  </FluxTableRow>
23
25
  </template>
24
26
 
@@ -28,7 +30,7 @@
28
30
  <FluxTableRow>
29
31
  <slot
30
32
  name="footer"
31
- v-bind="{page, perPage, rows, total}"/>
33
+ v-bind="{page, perPage, items: limitedItems, total}"/>
32
34
  </FluxTableRow>
33
35
  </template>
34
36
 
@@ -37,7 +39,7 @@
37
39
  #pagination>
38
40
  <slot
39
41
  name="pagination"
40
- v-bind="{page, perPage, rows, total}">
42
+ v-bind="{page, perPage, items: limitedItems, total}">
41
43
  <FluxPaginationBar
42
44
  :limits="limits"
43
45
  :page="page"
@@ -49,12 +51,12 @@
49
51
  </template>
50
52
 
51
53
  <FluxTableRow
52
- v-for="(row, index) of rows"
53
- :key="uniqueKey ? row[uniqueKey] : index">
54
+ v-for="(item, index) of limitedItems"
55
+ :key="uniqueKey ? item[uniqueKey] : index">
54
56
  <template v-for="(_, name) of slots">
55
57
  <slot
56
58
  v-if="!IGNORED_SLOTS.includes(name as string)"
57
- v-bind="{index, page, perPage, row, rows, total}"
59
+ v-bind="{index, item, items: limitedItems, page, perPage, total}"
58
60
  :name="name"/>
59
61
  </template>
60
62
  </FluxTableRow>
@@ -71,7 +73,7 @@
71
73
  import FluxTable from './FluxTable.vue';
72
74
  import FluxTableRow from './FluxTableRow.vue';
73
75
 
74
- const IGNORED_SLOTS: string[] = ['header', 'footer', 'colgroups', 'pagination'];
76
+ const IGNORED_SLOTS: string[] = ['filter', 'header', 'footer', 'colgroups', 'pagination'];
75
77
 
76
78
  const emit = defineEmits<{
77
79
  limit: [number];
@@ -84,16 +86,16 @@
84
86
  isLoading = false,
85
87
  isSeparated = true,
86
88
  isStriped = false,
87
- dataSet,
89
+ items,
88
90
  perPage
89
91
  } = defineProps<{
90
- readonly dataSet: T[];
91
92
  readonly fillColumns?: number;
92
93
  readonly isBordered?: boolean;
93
94
  readonly isHoverable?: boolean;
94
95
  readonly isLoading?: boolean;
95
96
  readonly isSeparated?: boolean;
96
97
  readonly isStriped?: boolean;
98
+ readonly items: T[];
97
99
  readonly limits: number[];
98
100
  readonly page: number;
99
101
  readonly perPage: number;
@@ -106,34 +108,41 @@
106
108
  readonly index: number;
107
109
  readonly page: number;
108
110
  readonly perPage: number;
109
- readonly row: T;
110
- readonly rows: T[];
111
+ readonly item: T;
112
+ readonly items: T[];
111
113
  readonly total: number;
112
114
  }) => VNode;
113
115
 
116
+ filter(props: {
117
+ readonly page: number;
118
+ readonly perPage: number;
119
+ readonly items: T[];
120
+ readonly total: number;
121
+ }): VNode;
122
+
114
123
  footer(props: {
115
124
  readonly page: number;
116
125
  readonly perPage: number;
117
- readonly rows: T[];
126
+ readonly items: T[];
118
127
  readonly total: number;
119
128
  }): VNode;
120
129
 
121
130
  header(props: {
122
131
  readonly page: number;
123
132
  readonly perPage: number;
124
- readonly rows: T[];
133
+ readonly items: T[];
125
134
  readonly total: number;
126
135
  }): VNode;
127
136
 
128
137
  pagination(props: {
129
138
  readonly page: number;
130
139
  readonly perPage: number;
131
- readonly rows: T[];
140
+ readonly items: T[];
132
141
  readonly total: number;
133
142
  }): VNode;
134
143
 
135
144
  colgroups(): VNode;
136
145
  }>();
137
146
 
138
- const rows = computed(() => dataSet.slice(0, perPage));
147
+ const limitedItems = computed(() => items.slice(0, perPage));
139
148
  </script>
@@ -39,7 +39,7 @@
39
39
  <script
40
40
  lang="ts"
41
41
  setup>
42
- import { unrefTemplateElement, useFocusTrap } from '@flux-ui/internals';
42
+ import { isSSR, unrefTemplateElement, useEventListener, useFocusTrap } from '@flux-ui/internals';
43
43
  import type { FluxDirection } from '@flux-ui/types';
44
44
  import { clsx } from 'clsx';
45
45
  import { provide, ref, unref, useTemplateRef, watch } from 'vue';
@@ -88,6 +88,7 @@
88
88
  const paneMarginX = ref(0);
89
89
  const paneMarginY = ref(0);
90
90
 
91
+ !isSSR && useEventListener(ref(window), 'resize', () => unref(isOpen) && reposition());
91
92
  useFocusTrap(paneRef);
92
93
 
93
94
  function close(): void {
@@ -2,6 +2,7 @@
2
2
  <div
3
3
  :class="clsx(
4
4
  disabled ? $style.formInputDisabled : $style.formInputEnabled,
5
+ isCondensed && $style.isCondensed,
5
6
  isSecondary && $style.isSecondary
6
7
  )"
7
8
  :aria-disabled="disabled ? true : undefined">
@@ -85,6 +86,7 @@
85
86
  readonly iconLeading?: FluxIconName;
86
87
  readonly iconTrailing?: FluxIconName;
87
88
  readonly disabled?: boolean;
89
+ readonly isCondensed?: boolean;
88
90
  readonly isReadonly?: boolean;
89
91
  readonly isSecondary?: boolean;
90
92
  readonly max?: string | number;
@@ -2,6 +2,7 @@
2
2
  <div
3
3
  :class="clsx(
4
4
  $style.formInputGroup,
5
+ isCondensed && $style.isCondensed,
5
6
  isSecondary && $style.isSecondary
6
7
  )"
7
8
  role="textbox">
@@ -17,6 +18,7 @@
17
18
 
18
19
  defineProps<{
19
20
  readonly isSecondary?: boolean;
21
+ readonly isCondensed?: boolean;
20
22
  }>();
21
23
 
22
24
  defineSlots<{
@@ -10,6 +10,7 @@
10
10
  <script
11
11
  lang="ts"
12
12
  setup>
13
+ import { isSSR } from '@flux-ui/internals';
13
14
  import type { FluxFormSelectEntry } from '@flux-ui/types';
14
15
  import { upperFirst } from 'lodash-es';
15
16
  import { computed, toRef } from 'vue';
@@ -651,6 +652,10 @@
651
652
  const translate = useTranslate();
652
653
 
653
654
  const options = computed<FluxFormSelectEntry[]>(() => {
655
+ if (isSSR) {
656
+ return [];
657
+ }
658
+
654
659
  const groups: Record<string, FluxFormSelectEntry[]> = {};
655
660
  const options: FluxFormSelectEntry[] = [];
656
661
 
@@ -8,7 +8,7 @@
8
8
  :aria-valuemin="min">
9
9
  <div :class="isIndeterminate ? $style.progressBarTrackIndeterminate : $style.progressBarTrack">
10
10
  <div
11
- :class="$style.progressBarValue"
11
+ :class="position >= 1 ? $style.progressBarValueComplete : $style.progressBarValueIncomplete"
12
12
  :style="{
13
13
  width: `${isIndeterminate ? 100 : position * 100}%`
14
14
  }"/>
@@ -20,12 +20,14 @@
20
20
  const elm = instance.proxy!.$el;
21
21
  elm.addEventListener('mouseenter', onHover, {passive: true});
22
22
  elm.addEventListener('mouseleave', onLeave, {passive: true});
23
+ window.addEventListener('scroll', onLeave, {capture: true});
23
24
  });
24
25
 
25
26
  onUnmounted(() => {
26
27
  const elm = instance.proxy!.$el;
27
28
  elm.removeEventListener('mouseenter', onHover);
28
29
  elm.removeEventListener('mouseleave', onLeave);
30
+ window.removeEventListener('scroll', onLeave);
29
31
  onLeave();
30
32
  });
31
33
 
@@ -150,7 +150,7 @@
150
150
  px = x + width / 2 - popupWidth / 2;
151
151
  py = y + height + margin;
152
152
 
153
- if (py + popupHeight > innerHeight) {
153
+ if (py + popupHeight + margin > innerHeight) {
154
154
  py = y - popupHeight - margin;
155
155
  }
156
156
  }
@@ -188,7 +188,9 @@
188
188
 
189
189
  anchorRef.value = isHtmlElement(anchor) ? anchor : anchor.$el;
190
190
 
191
- requestAnimationFrame(resize);
192
- requestAnimationFrame(reposition);
191
+ requestAnimationFrame(() => {
192
+ requestAnimationFrame(resize);
193
+ requestAnimationFrame(reposition);
194
+ });
193
195
  });
194
196
  </script>
@@ -319,6 +319,15 @@
319
319
  border-bottom-left-radius: 0;
320
320
  }
321
321
 
322
+ &.isCondensed,
323
+ &.isSecondary {
324
+ .formInputAddition:not(:last-child) {
325
+ padding-right: 0;
326
+ background: unset;
327
+ border-color: transparent;
328
+ }
329
+ }
330
+
322
331
  &.isSecondary {
323
332
  .formInput {
324
333
  background: transparent;
@@ -326,10 +335,6 @@
326
335
  box-shadow: none;
327
336
  }
328
337
 
329
- .formInputAddition:not(:last-child) {
330
- padding-right: 0;
331
- }
332
-
333
338
  .secondaryButton {
334
339
  background: transparent;
335
340
  border-color: var(--gray-2);
@@ -16,9 +16,20 @@
16
16
  top: 0;
17
17
  left: 0;
18
18
  height: inherit;
19
+ border-radius: inherit;
20
+ }
21
+
22
+ .progressBarValueComplete {
23
+ composes: progressBarValue;
24
+
25
+ background: var(--primary-7);
26
+ }
27
+
28
+ .progressBarValueIncomplete {
29
+ composes: progressBarValue;
30
+
19
31
  background: linear-gradient(to right, var(--primary-7) 20%, var(--primary-6), var(--primary-7) 80%);
20
32
  background-size: 150px 100%;
21
- border-radius: inherit;
22
33
  animation: progressBarValue 1s linear infinite;
23
34
  }
24
35
 
@@ -3,6 +3,7 @@
3
3
 
4
4
  position: relative;
5
5
  display: flex;
6
+ container: table / inline-size;
6
7
  flex-flow: column;
7
8
  overflow: auto;
8
9
 
@@ -14,7 +15,7 @@
14
15
  }
15
16
 
16
17
  .tableBase {
17
- min-width: 100%;
18
+ min-width: 100cqw;
18
19
  bottom: 0;
19
20
  border-spacing: 0;
20
21
  text-align: left;
@@ -70,6 +71,7 @@
70
71
  position: sticky;
71
72
  top: 0;
72
73
  background: var(--gray-1);
74
+ z-index: 1;
73
75
  }
74
76
  }
75
77
 
@@ -119,12 +121,43 @@ tfoot .tableCell {
119
121
  }
120
122
  }
121
123
 
124
+ .tableBar {
125
+ composes: tableCell;
126
+
127
+ position: relative;
128
+ background: var(--gray-1);
129
+ box-shadow: 0 0 24px var(--gray-1),
130
+ 0 0 18px var(--gray-1),
131
+ 0 0 12px var(--gray-1),
132
+ 0 0 9px var(--gray-1),
133
+ 0 0 6px var(--gray-1),
134
+ 0 0 3px var(--gray-1);
135
+ z-index: 2;
136
+ }
137
+
138
+ .tableBarContent {
139
+ composes: tableCellContent;
140
+
141
+ position: sticky;
142
+ left: 0;
143
+ max-width: 100cqw;
144
+ flex-flow: row nowrap;
145
+ gap: 15px;
146
+
147
+ > :local(.formInput) {
148
+ max-width: 300px;
149
+ min-width: 210px;
150
+ }
151
+ }
152
+
122
153
  .tablePagination {
123
154
  position: sticky;
124
155
  bottom: 0;
125
156
  margin-top: auto;
157
+ margin-bottom: -1px;
126
158
  background: var(--gray-0);
127
159
  border-top: 1px solid var(--gray-2);
160
+ translate: 0 -1px;
128
161
  z-index: 100;
129
162
  }
130
163
 
@@ -10,7 +10,7 @@ export let iconRegistry: IconRegistry = {};
10
10
  export function fluxRegisterIcons(icons: Icons): void {
11
11
  iconRegistry = Object.keys(icons).reduce((acc: IconRegistry, key: string) => {
12
12
  const {icon, iconName} = icons[key];
13
- acc[iconName] = icon;
13
+ acc[iconName as FluxIconName] = icon;
14
14
 
15
15
  if (Array.isArray(icon[2])) {
16
16
  icon[2].forEach((iconName: string) => acc[iconName as FluxIconName] = icon);