@flux-ui/application 3.0.0-next.61 → 3.0.0-next.64

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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@flux-ui/application",
3
3
  "description": "Contains components to create applications with Flux UI.",
4
- "version": "3.0.0-next.61",
4
+ "version": "3.0.0-next.64",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "funding": "https://github.com/sponsors/basmilius",
@@ -51,9 +51,9 @@
51
51
  "typings": "./dist/index.d.ts",
52
52
  "sideEffects": false,
53
53
  "dependencies": {
54
- "@flux-ui/components": "3.0.0-next.61",
55
- "@flux-ui/internals": "3.0.0-next.61",
56
- "@flux-ui/types": "3.0.0-next.61",
54
+ "@flux-ui/components": "3.0.0-next.64",
55
+ "@flux-ui/internals": "3.0.0-next.64",
56
+ "@flux-ui/types": "3.0.0-next.64",
57
57
  "clsx": "^2.1.1"
58
58
  },
59
59
  "peerDependencies": {
@@ -62,13 +62,13 @@
62
62
  "vue-router": "^5.0.6"
63
63
  },
64
64
  "devDependencies": {
65
- "@basmilius/vite-preset": "^3.24.0",
65
+ "@basmilius/vite-preset": "^3.25.0",
66
66
  "@types/node": "^25.6.0",
67
67
  "@vitejs/plugin-vue": "^6.0.6",
68
68
  "@vue/tsconfig": "^0.9.1",
69
69
  "sass-embedded": "^1.99.0",
70
70
  "typescript": "^6.0.3",
71
71
  "vite": "^8.0.10",
72
- "vue-tsc": "^3.2.7"
72
+ "vue-tsc": "^3.2.8"
73
73
  }
74
74
  }
@@ -19,8 +19,9 @@
19
19
  <script
20
20
  lang="ts"
21
21
  setup>
22
+ import { useBreakpoints } from '@flux-ui/components';
22
23
  import { useRemembered } from '@flux-ui/internals';
23
- import { computed, onUnmounted, provide, ref, shallowRef, toRef, type VNode, watch } from 'vue';
24
+ import { computed, onMounted, onUnmounted, provide, ref, shallowRef, toRef, type VNode, watch } from 'vue';
24
25
  import { type FluxApplicationContextInfo, FluxApplicationInjectionKey, type FluxApplicationLayout } from '../data';
25
26
  import { useNamedRoutes, useRoute } from '../routing';
26
27
  import $style from '~flux/application/css/component/Application.module.scss';
@@ -39,14 +40,44 @@
39
40
  side(): VNode[];
40
41
  }>();
41
42
 
42
- const route = useRoute();
43
- const matchedMenuRoutes = useNamedRoutes(toRef(() => contextMenuName));
43
+ let resizeTimer: ReturnType<typeof setTimeout> | undefined;
44
44
 
45
45
  const isMenuCollapsed = useRemembered('application-menu-collapsed', true);
46
+ const matchedMenuRoutes = useNamedRoutes(toRef(() => contextMenuName));
47
+ const route = useRoute();
48
+ const {lg, xl} = useBreakpoints();
49
+
50
+ const contextStack = shallowRef<FluxApplicationContextInfo[]>([]);
46
51
  const layout = ref<FluxApplicationLayout>('default');
52
+ const viewIndex = ref(0);
47
53
 
54
+ const activeContext = computed(() => contextStack.value.at(-1));
55
+ const contexts = computed(() => contextStack.value);
48
56
  const totalLevels = computed(() => 1 + matchedMenuRoutes.value.length);
49
- const viewIndex = ref(0);
57
+
58
+ onMounted(() => {
59
+ if (typeof window === 'undefined') {
60
+ return;
61
+ }
62
+
63
+ window.addEventListener('resize', onResize, {passive: true});
64
+ });
65
+
66
+ onUnmounted(() => {
67
+ if (typeof window !== 'undefined') {
68
+ window.removeEventListener('resize', onResize);
69
+ }
70
+
71
+ if (resizeTimer !== undefined) {
72
+ clearTimeout(resizeTimer);
73
+ resizeTimer = undefined;
74
+ }
75
+
76
+ if (typeof document !== 'undefined') {
77
+ delete document.documentElement.dataset.applicationMenuOpen;
78
+ delete document.documentElement.dataset.applicationResizing;
79
+ }
80
+ });
50
81
 
51
82
  function clampViewIndex(target: number): number {
52
83
  if (target < 0) {
@@ -79,9 +110,22 @@
79
110
  viewIndex.value = clampViewIndex(viewIndex.value + 1);
80
111
  }
81
112
 
82
- const contextStack = shallowRef<FluxApplicationContextInfo[]>([]);
83
- const contexts = computed(() => contextStack.value);
84
- const activeContext = computed(() => contextStack.value.at(-1));
113
+ function onResize(): void {
114
+ if (typeof document === 'undefined') {
115
+ return;
116
+ }
117
+
118
+ document.documentElement.dataset.applicationResizing = '';
119
+
120
+ if (resizeTimer !== undefined) {
121
+ clearTimeout(resizeTimer);
122
+ }
123
+
124
+ resizeTimer = setTimeout(() => {
125
+ delete document.documentElement.dataset.applicationResizing;
126
+ resizeTimer = undefined;
127
+ }, 150);
128
+ }
85
129
 
86
130
  function pushContext(info: FluxApplicationContextInfo): void {
87
131
  contextStack.value = [...contextStack.value, info];
@@ -91,25 +135,12 @@
91
135
  contextStack.value = contextStack.value.filter(entry => entry.id !== id);
92
136
  }
93
137
 
94
- provide(FluxApplicationInjectionKey, {
95
- activeContext,
96
- contexts,
97
- isMenuCollapsed,
98
- layout,
99
- showDesktopMenuToggle: toRef(() => showDesktopMenuToggle),
100
- totalLevels,
101
- viewIndex,
102
- goToChild,
103
- goToCurrent,
104
- goToLevel,
105
- goToMain,
106
- goToParent,
107
- pushContext,
108
- removeContext
109
- });
110
-
111
138
  watch(() => route.fullPath, () => {
112
139
  viewIndex.value = totalLevels.value - 1;
140
+
141
+ if (!lg.value && !xl.value) {
142
+ isMenuCollapsed.value = true;
143
+ }
113
144
  });
114
145
 
115
146
  watch(totalLevels, (next) => {
@@ -135,9 +166,20 @@
135
166
  }
136
167
  }, {immediate: true});
137
168
 
138
- onUnmounted(() => {
139
- if (typeof document !== 'undefined') {
140
- delete document.documentElement.dataset.applicationMenuOpen;
141
- }
169
+ provide(FluxApplicationInjectionKey, {
170
+ activeContext,
171
+ contexts,
172
+ isMenuCollapsed,
173
+ layout,
174
+ showDesktopMenuToggle: toRef(() => showDesktopMenuToggle),
175
+ totalLevels,
176
+ viewIndex,
177
+ goToChild,
178
+ goToCurrent,
179
+ goToLevel,
180
+ goToMain,
181
+ goToParent,
182
+ pushContext,
183
+ removeContext
142
184
  });
143
185
  </script>
@@ -10,11 +10,6 @@
10
10
  --application-top-height: 66px;
11
11
  }
12
12
 
13
- [dark] {
14
- --application-menu-surface: color-mix(in srgb, var(--gray-25), black 25%);
15
- --application-menu-surface-stroke: var(--gray-100);
16
- }
17
-
18
13
  .application {
19
14
  position: relative;
20
15
  display: flex;
@@ -47,7 +42,7 @@
47
42
  height: 100dvh;
48
43
  padding: 0;
49
44
  border: 0;
50
- background: rgb(from var(--gray-200) r g b / .5);
45
+ background: var(--overlay);
51
46
  backdrop-filter: blur(3px) saturate(180%);
52
47
  transition: var(--application-duration) var(--swift-out);
53
48
  transition-property: background, backdrop-filter, opacity;
@@ -86,3 +81,8 @@
86
81
  overscroll-behavior: contain;
87
82
  }
88
83
  }
84
+
85
+ html[data-application-resizing] .application,
86
+ html[data-application-resizing] .applicationMenuBackdrop {
87
+ transition: none;
88
+ }
@@ -90,41 +90,6 @@
90
90
  overflow-y: auto;
91
91
  }
92
92
 
93
- .applicationMenuPageIndicator {
94
- display: flex;
95
- flex-flow: row nowrap;
96
- gap: 6px;
97
- justify-content: center;
98
- align-items: center;
99
- padding: 9px 12px;
100
- background: var(--application-menu-surface);
101
- z-index: 1;
102
- }
103
-
104
- .applicationMenuPageIndicatorDot {
105
- height: 6px;
106
- width: 6px;
107
- padding: 0;
108
- cursor: pointer;
109
- background: transparent;
110
- border: 1.5px solid var(--application-menu-surface-stroke);
111
- border-radius: 50%;
112
- transition: 200ms var(--swift-out);
113
- transition-property: background, border-color, transform;
114
-
115
- @include mixin.hover {
116
- border-color: var(--foreground-secondary);
117
- transform: scale(1.2);
118
- }
119
-
120
- @include mixin.focus-ring;
121
- }
122
-
123
- .applicationMenuPageIndicatorDotActive {
124
- background: var(--foreground-prominent);
125
- border-color: var(--foreground-prominent);
126
- }
127
-
128
93
  .applicationMenuPanelEnterActive,
129
94
  .applicationMenuPanelEnterFrom,
130
95
  .applicationMenuPanelLeaveActive,
@@ -404,3 +369,16 @@
404
369
  translate: -100% 0;
405
370
  }
406
371
  }
372
+
373
+ html[data-application-resizing] {
374
+ .applicationMenu,
375
+ .applicationMenuFooter,
376
+ .applicationMenuFooter::before,
377
+ .applicationMenuHeader,
378
+ .applicationMenuTrack,
379
+ .applicationMenu :local(.menuItemLabel),
380
+ .applicationMenuContextPillContent :global(strong),
381
+ .applicationMenuContextPillContent :global(span) {
382
+ transition: none;
383
+ }
384
+ }