@flux-ui/components 3.0.0-next.13 → 3.0.0-next.14

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.
@@ -1,4 +1,4 @@
1
- import { Component, RenderFunction, Slots, SetupContext } from 'vue';
1
+ import { Component, RenderFunction, SetupContext, Slots } from 'vue';
2
2
  type Emit = SetupContext<['close']>['emit'];
3
3
  type Props = {
4
4
  readonly isCloseable?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"createDialogRenderer.d.ts","sourceRoot":"","sources":["../../src/util/createDialogRenderer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAsB,cAAc,EAAE,KAAK,EAAE,MAAM,KAAK,CAAC;AAC3E,OAAO,EAAsC,YAAY,EAAmB,MAAM,KAAK,CAAC;AAGxF,KAAK,IAAI,GAAG,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;AAC5C,KAAK,KAAK,GAAG;IACT,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC7B,CAAC;AAEF,MAAM,CAAC,OAAO,WAAW,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,GAAG,cAAc,CAqDxI"}
1
+ {"version":3,"file":"createDialogRenderer.d.ts","sourceRoot":"","sources":["../../src/util/createDialogRenderer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,YAAY,EAAE,KAAK,EAAS,MAAM,KAAK,CAAC;AAIjF,KAAK,IAAI,GAAG,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;AAC5C,KAAK,KAAK,GAAG;IACT,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC7B,CAAC;AAEF,MAAM,CAAC,OAAO,WAAW,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,GAAG,cAAc,CAiExI"}
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.13",
4
+ "version": "3.0.0-next.14",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "funding": "https://github.com/sponsors/basmilius",
@@ -52,8 +52,8 @@
52
52
  "sideEffects": false,
53
53
  "dependencies": {
54
54
  "@basmilius/utils": "^2.5.2",
55
- "@flux-ui/internals": "3.0.0-next.13",
56
- "@flux-ui/types": "3.0.0-next.13",
55
+ "@flux-ui/internals": "3.0.0-next.14",
56
+ "@flux-ui/types": "3.0.0-next.14",
57
57
  "@fortawesome/fontawesome-common-types": "^7.0.0",
58
58
  "clsx": "^2.1.1",
59
59
  "imask": "^7.6.1",
package/src/css/base.scss CHANGED
@@ -12,6 +12,7 @@
12
12
  }
13
13
 
14
14
  [dark] {
15
+ @include variables.defaults-dark;
15
16
  @include variables.color-dark;
16
17
  @include variables.shadow-dark;
17
18
  }
@@ -4,8 +4,9 @@
4
4
  inset: 0;
5
5
  height: 100dvh;
6
6
  width: 100dvw;
7
- background: oklch(from var(--gray-11) l c h / .6);
7
+ background: var(--overlay);
8
8
  backdrop-filter: blur(3px) saturate(180%);
9
+ outline: 0;
9
10
  z-index: 10000;
10
11
 
11
12
  > .basePaneStructure {
@@ -25,10 +26,6 @@
25
26
  }
26
27
  }
27
28
 
28
- [dark] .overlay {
29
- background: rgb(0 0 0 / .6);
30
- }
31
-
32
29
  .overlaySmall {
33
30
  composes: overlay;
34
31
 
@@ -151,3 +148,34 @@
151
148
  transform: translate3d(100%, 0, 0);
152
149
  }
153
150
  }
151
+
152
+ .overlay + .overlay {
153
+ background: transparent;
154
+ backdrop-filter: none;
155
+ }
156
+
157
+ .overlay > .basePaneStructure::after {
158
+ position: absolute;
159
+ display: block;
160
+ inset: 0;
161
+ content: '';
162
+ background: var(--overlay-secondary);
163
+ opacity: 0;
164
+ pointer-events: none;
165
+ transition: opacity 420ms var(--swift-out);
166
+ z-index: 1;
167
+ }
168
+
169
+ .overlay:has(+ .overlay) > .basePaneStructure {
170
+ transition: 420ms var(--swift-out);
171
+ transition-property: filter, scale;
172
+ }
173
+
174
+ .overlay:has(+ .overlay:not(.overlayTransitionLeaveActive)) > .pane {
175
+ filter: blur(3px);
176
+ scale: .95;
177
+
178
+ &::after {
179
+ opacity: 1;
180
+ }
181
+ }
@@ -178,6 +178,14 @@
178
178
  --foreground: var(--gray-8);
179
179
  --foreground-prominent: var(--gray-10);
180
180
  --foreground-secondary: var(--gray-5);
181
+
182
+ --overlay: oklch(from var(--gray-11) l c h / .6);
183
+ --overlay-secondary: oklch(from var(--gray-11) l c h / .4);
184
+ }
185
+
186
+ @mixin defaults-dark {
187
+ --overlay: rgb(0 0 0 / .6);
188
+ --overlay-secondary: rgb(0 0 0 / .4);
181
189
  }
182
190
 
183
191
  @mixin shadow-light {
@@ -1,6 +1,6 @@
1
- import { flattenVNodeTree } from '@flux-ui/internals';
2
- import { Component, getCurrentInstance, RenderFunction, Slots } from 'vue';
3
- import { Comment, h, onMounted, onUnmounted, SetupContext, Teleport, VNode } from 'vue';
1
+ import { flattenVNodeTree, useFocusTrap } from '@flux-ui/internals';
2
+ import type { Component, RenderFunction, SetupContext, Slots, VNode } from 'vue';
3
+ import { Comment, getCurrentInstance, h, onUnmounted, ref, Teleport, watch } from 'vue';
4
4
  import { registerDialog, useFluxStore } from '$flux/data';
5
5
 
6
6
  type Emit = SetupContext<['close']>['emit'];
@@ -14,22 +14,32 @@ export default function (attrs: object, props: Props, emit: Emit, slots: Slots,
14
14
  let unregister: Function | null = null;
15
15
  let zIndex = 0;
16
16
 
17
- onMounted(() => {
18
- window.addEventListener('keydown', onKeyDown);
19
- });
17
+ const dialogRef = ref<HTMLElement>();
18
+
19
+ useFocusTrap(dialogRef);
20
20
 
21
21
  onUnmounted(() => {
22
- window.removeEventListener('keydown', onKeyDown);
23
22
  unregister?.();
24
23
  });
25
24
 
25
+ watch(dialogRef, (dialog, _, onCleanup) => {
26
+ if (!dialog) {
27
+ return;
28
+ }
29
+
30
+ dialog.addEventListener('keydown', onKeyDown, {passive: true});
31
+ dialog.focus();
32
+
33
+ onCleanup(() => {
34
+ dialog.removeEventListener('keydown', onKeyDown);
35
+ });
36
+ });
37
+
26
38
  function onKeyDown(evt: KeyboardEvent): void {
27
39
  if (evt.key !== 'Escape' || !unregister || !props.isCloseable) {
28
40
  return;
29
41
  }
30
42
 
31
- evt.preventDefault();
32
- evt.stopPropagation();
33
43
  emit('close');
34
44
  }
35
45
 
@@ -38,7 +48,7 @@ export default function (attrs: object, props: Props, emit: Emit, slots: Slots,
38
48
 
39
49
  const children = flattenVNodeTree(slots.default?.() ?? []);
40
50
  const isVisible = children.length > 0 && children.some(child => child.type !== Comment);
41
- const content: VNode[] = [];
51
+ let content: VNode | undefined;
42
52
 
43
53
  if (isVisible) {
44
54
  if (!unregister) {
@@ -46,17 +56,19 @@ export default function (attrs: object, props: Props, emit: Emit, slots: Slots,
46
56
  zIndex = dialogCount + 1000;
47
57
  }
48
58
 
49
- content.push(h('div', {
59
+ content = h('div', {
50
60
  key: props.viewKey,
61
+ ref: dialogRef,
51
62
  class: className,
52
- style: {zIndex}
53
- }, children));
63
+ style: {zIndex},
64
+ tabindex: 0
65
+ }, children);
54
66
  } else {
55
67
  unregister?.();
56
68
  unregister = null;
57
69
  }
58
70
 
59
- return h(Teleport, {disabled: content.length === 0, to: instance?.appContext.app._container}, [
71
+ return h(Teleport, {defer: true, disabled: !content, to: instance?.appContext.app._container}, [
60
72
  h(transition, attrs, {
61
73
  default: () => content
62
74
  })