@quaffui/quaff 1.0.0-beta7 → 1.0.0-beta9

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 (55) hide show
  1. package/README.md +2 -0
  2. package/dist/classes/Quaff.svelte.d.ts +1 -1
  3. package/dist/components/avatar/QAvatar.svelte +4 -0
  4. package/dist/components/breadcrumbs/QBreadcrumbs.svelte +28 -5
  5. package/dist/components/breadcrumbs/QBreadcrumbs.svelte.d.ts +23 -0
  6. package/dist/components/breadcrumbs/QBreadcrumbsEl.svelte +17 -14
  7. package/dist/components/button/QBtn.svelte +21 -11
  8. package/dist/components/card/QCard.svelte +9 -5
  9. package/dist/components/card/QCardActions.svelte +4 -0
  10. package/dist/components/card/QCardSection.svelte +2 -0
  11. package/dist/components/checkbox/QCheckbox.svelte +2 -0
  12. package/dist/components/chip/QChip.svelte +24 -14
  13. package/dist/components/codeBlock/QCodeBlock.svelte +8 -0
  14. package/dist/components/dialog/QDialog.svelte +12 -0
  15. package/dist/components/drawer/QDrawer.svelte +50 -39
  16. package/dist/components/expansion-item/QExpansionItem.svelte +16 -2
  17. package/dist/components/footer/QFooter.svelte +27 -22
  18. package/dist/components/header/QHeader.svelte +37 -28
  19. package/dist/components/icon/QIcon.svelte +4 -0
  20. package/dist/components/input/QInput.svelte +9 -2
  21. package/dist/components/layout/QLayout.svelte +243 -90
  22. package/dist/components/layout/QLayout.svelte.d.ts +64 -2
  23. package/dist/components/list/QItem.svelte +43 -24
  24. package/dist/components/list/QItem.svelte.d.ts +14 -0
  25. package/dist/components/list/QItemSection.svelte +16 -12
  26. package/dist/components/list/QList.svelte +28 -6
  27. package/dist/components/list/QList.svelte.d.ts +15 -0
  28. package/dist/components/private/ContextReseter.svelte +2 -3
  29. package/dist/components/private/QApi.svelte +15 -7
  30. package/dist/components/private/QDocs.svelte +40 -20
  31. package/dist/components/private/QDocs.svelte.d.ts +30 -0
  32. package/dist/components/private/QDocsSection.svelte +11 -7
  33. package/dist/components/progress/QCircularProgress.svelte +14 -5
  34. package/dist/components/progress/QLinearProgress.svelte +12 -6
  35. package/dist/components/radio/QRadio.svelte +2 -0
  36. package/dist/components/railbar/QRailbar.svelte +36 -35
  37. package/dist/components/select/QSelect.svelte +32 -23
  38. package/dist/components/separator/QSeparator.svelte +4 -0
  39. package/dist/components/switch/QSwitch.svelte +6 -0
  40. package/dist/components/table/QTable.svelte +23 -13
  41. package/dist/components/tabs/QTab.svelte +19 -22
  42. package/dist/components/tabs/QTabs.svelte +59 -32
  43. package/dist/components/tabs/QTabs.svelte.d.ts +15 -4
  44. package/dist/components/toolbar/QToolbar.svelte +2 -0
  45. package/dist/components/toolbar/QToolbarTitle.svelte +2 -0
  46. package/dist/components/tooltip/QTooltip.svelte +22 -8
  47. package/dist/components/tooltip/QTooltipBase.svelte +18 -8
  48. package/dist/css/index.css +1 -1
  49. package/dist/helpers/version.d.ts +1 -1
  50. package/dist/helpers/version.js +1 -1
  51. package/dist/utils/context.d.ts +49 -32
  52. package/dist/utils/context.js +82 -33
  53. package/package.json +24 -23
  54. package/dist/classes/QContext.svelte.d.ts +0 -42
  55. package/dist/classes/QContext.svelte.js +0 -63
package/README.md CHANGED
@@ -11,6 +11,7 @@ This is an independent project and is not endorsed by or affiliated with Materia
11
11
 
12
12
  Key features:
13
13
 
14
+ - Beautiful [documentation](https://quaff.dev/)
14
15
  - Built for [Svelte 5](https://svelte.dev/) and [SvelteKit](https://kit.svelte.dev/) with full runes support
15
16
  - Follows Material Design 3 guidelines
16
17
  - Type-safe components with TypeScript
@@ -62,6 +63,7 @@ You can preview the production build with `bun run preview`.
62
63
  - `/src/lib/css` - Styling and theming utilities
63
64
  - `/src/routes` - Documentation and examples
64
65
  - `/docgen` - Documentation generation tools
66
+ - `/plugins` - Preprocessors used by Quaff (in development, don't forget to run `bun gen:plugins` before `bun dev`)
65
67
 
66
68
  ## Acknowledgements
67
69
 
@@ -12,7 +12,7 @@ declare class Quaff {
12
12
  lg: number;
13
13
  xl: number;
14
14
  };
15
- router: import("@sveltejs/kit").Page<import("../../..").LayoutParams<"/">, import("../../..").RouteId | null>;
15
+ router: import("@sveltejs/kit").Page<Record<string, string>, string | null>;
16
16
  protected dark: boolean;
17
17
  init(): void;
18
18
  protected toggleDarkMode(): void;
@@ -2,6 +2,7 @@
2
2
  import { useSize } from "../../composables";
3
3
  import type { QAvatarProps } from "./props";
4
4
 
5
+ // #region: --- Props
5
6
  let {
6
7
  alt,
7
8
  shape = "circle",
@@ -13,9 +14,12 @@
13
14
  videoAccessibility,
14
15
  ...props
15
16
  }: QAvatarProps = $props();
17
+ // #endregion: --- Props
16
18
 
19
+ // #region: --- Derived values
17
20
  const qSize = $derived(useSize(size, "q-avatar"));
18
21
  const qShape = $derived(`q-avatar--${shape}`);
22
+ // #endregion: --- Derived values
19
23
  </script>
20
24
 
21
25
  <div
@@ -1,8 +1,17 @@
1
- <script lang="ts">
2
- import { onMount, setContext } from "svelte";
3
- import { QBreadcrumbsCtxName } from "../../utils";
1
+ <script lang="ts" module>
4
2
  import type { QBreadcrumbsProps } from "./props";
5
3
 
4
+ export const breadcrumbsCtx = QContext<{
5
+ readonly separator: QBreadcrumbsProps["separator"];
6
+ readonly gutter: QBreadcrumbsProps["gutter"];
7
+ }>("QBreadcrumbs");
8
+ </script>
9
+
10
+ <script lang="ts">
11
+ import { onMount } from "svelte";
12
+ import { QContext } from "../../utils";
13
+
14
+ // #region: --- Props
6
15
  let {
7
16
  activeColor = "primary",
8
17
  gutter = "sm",
@@ -11,16 +20,30 @@
11
20
  children,
12
21
  ...props
13
22
  }: QBreadcrumbsProps = $props();
23
+ // #endregion: --- Props
14
24
 
25
+ // #region: --- Non-reactive variables
15
26
  let breadcrumbList: HTMLOListElement;
27
+ // #endregion: --- Non-reactive variables
28
+
29
+ // #region: --- Context
30
+ breadcrumbsCtx.set({
31
+ get separator() {
32
+ return separator;
33
+ },
34
+ get gutter() {
35
+ return gutter;
36
+ },
37
+ });
38
+ // #endregion: --- Context
16
39
 
40
+ // #region: --- Lifecycle
17
41
  onMount(() => {
18
42
  breadcrumbList
19
43
  .querySelector(".q-breadcrumbs__separator:first-child")
20
44
  ?.remove();
21
45
  });
22
-
23
- setContext(QBreadcrumbsCtxName.separator, { type: separator, gutter });
46
+ // #endregion: --- Lifecycle
24
47
  </script>
25
48
 
26
49
  <nav
@@ -1,4 +1,27 @@
1
1
  import { SvelteComponentTyped } from "svelte";
2
+ import type { QBreadcrumbsProps } from "./props";
3
+ export declare const breadcrumbsCtx: {
4
+ readonly symbol: symbol;
5
+ get(): {
6
+ readonly separator: QBreadcrumbsProps["separator"];
7
+ readonly gutter: QBreadcrumbsProps["gutter"];
8
+ } | undefined;
9
+ assertGet(errorMsg?: string): {
10
+ readonly separator: QBreadcrumbsProps["separator"];
11
+ readonly gutter: QBreadcrumbsProps["gutter"];
12
+ };
13
+ set(context: {
14
+ readonly separator: QBreadcrumbsProps["separator"];
15
+ readonly gutter: QBreadcrumbsProps["gutter"];
16
+ }): void;
17
+ reset(): void;
18
+ exists(): boolean;
19
+ updateEntry(key: "separator" | "gutter", value: any): void;
20
+ updateEntries(updates: Partial<{
21
+ readonly separator: QBreadcrumbsProps["separator"];
22
+ readonly gutter: QBreadcrumbsProps["gutter"];
23
+ }>): void;
24
+ };
2
25
  declare const __propDef: {
3
26
  props: Record<string, never>;
4
27
  events: {
@@ -1,10 +1,11 @@
1
1
  <script lang="ts">
2
- import { getContext } from "svelte";
3
2
  import { QIcon } from "../..";
4
- import { isRouteActive, QBreadcrumbsCtxName } from "../../utils";
3
+ import { isRouteActive } from "../../utils";
4
+ import { breadcrumbsCtx } from "./QBreadcrumbs.svelte";
5
5
  import type { MaterialSymbol } from "material-symbols";
6
- import type { QBreadcrumbsElProps, QBreadcrumbsProps } from "./props";
6
+ import type { QBreadcrumbsElProps } from "./props";
7
7
 
8
+ // #region: --- Props
8
9
  let {
9
10
  activeClass = "active",
10
11
  href,
@@ -15,13 +16,15 @@
15
16
  children = fallback,
16
17
  ...props
17
18
  }: QBreadcrumbsElProps = $props();
19
+ // #endregion: --- Props
18
20
 
19
- const separator = getContext<{
20
- type: QBreadcrumbsProps["separator"];
21
- gutter: QBreadcrumbsProps["gutter"];
22
- }>(QBreadcrumbsCtxName.separator);
23
-
21
+ // #region: --- Derived values
24
22
  const isActive = $derived(isRouteActive(href || to));
23
+ // #endregion: --- Derived values
24
+
25
+ // #region: --- Context
26
+ const ctx = breadcrumbsCtx.assertGet();
27
+ // #endregion: --- Context
25
28
  </script>
26
29
 
27
30
  {#snippet fallback()}
@@ -50,17 +53,17 @@
50
53
  style:--q-breadcrumbs-color={isActive ? "var(--q-active-color)" : undefined}
51
54
  >
52
55
  <span
53
- class={["q-breadcrumbs__separator", `q-px-${separator.gutter}`]}
56
+ class={["q-breadcrumbs__separator", `q-px-${ctx?.gutter}`]}
54
57
  aria-hidden="true"
55
58
  >
56
- {#if typeof separator.type === "string"}
57
- {#if separator.type.startsWith("icon:")}
58
- <QIcon name={separator.type.slice(5) as MaterialSymbol} size="1rem" />
59
+ {#if typeof ctx.separator === "string"}
60
+ {#if ctx.separator.startsWith("icon:")}
61
+ <QIcon name={ctx.separator.slice(5) as MaterialSymbol} size="1rem" />
59
62
  {:else}
60
- {separator.type}
63
+ {ctx.separator}
61
64
  {/if}
62
65
  {:else}
63
- {@render separator.type?.()}
66
+ {@render ctx.separator?.()}
64
67
  {/if}
65
68
  </span>
66
69
 
@@ -7,6 +7,9 @@
7
7
  import type { MaterialSymbol } from "material-symbols";
8
8
  import type { QBtnProps, QBtnVariantOptions } from "./props";
9
9
 
10
+ type QBtnMouseEvent = QEvent<MouseEvent, typeof qBtn>;
11
+
12
+ // #region: --- Props
10
13
  let {
11
14
  disabled = false,
12
15
  variant,
@@ -31,12 +34,14 @@
31
34
  children,
32
35
  ...props
33
36
  }: QBtnProps = $props();
37
+ // #endregion: --- Props
34
38
 
39
+ // #region: --- Non-reactive variables
35
40
  let qBtn: HTMLElement;
36
41
  let qBtnLabel: HTMLSpanElement;
42
+ // #endregion: --- Non-reactive variables
37
43
 
38
- type QBtnMouseEvent = QEvent<MouseEvent, typeof qBtn>;
39
-
44
+ // #region: --- Derived values
40
45
  const computedTag = $derived(to ? "a" : tag || "button");
41
46
  const qSize = $derived(useSize(size, "q-btn"));
42
47
 
@@ -84,7 +89,20 @@
84
89
  const rippleColorVar = $derived(
85
90
  rippleColor ? `var(--${rippleColor}, ${rippleColor})` : colorVar,
86
91
  );
92
+ // #endregion: --- Derived values
93
+
94
+ // #region: --- Lifecycle
95
+ onMount(() => {
96
+ const { width, height } = qBtnLabel.getBoundingClientRect();
97
+
98
+ // This is required for buttons with no label and with a tooltip to be round
99
+ if (width === 0 && height === 0) {
100
+ qBtn.classList.add("q-btn--round");
101
+ }
102
+ });
103
+ // #endregion: --- Lifecycle
87
104
 
105
+ // #region: --- Functions
88
106
  function stopIfDisabled(e: QBtnMouseEvent) {
89
107
  if (disabled) {
90
108
  e.preventDefault();
@@ -112,15 +130,7 @@
112
130
  }) as QBtnMouseEvent;
113
131
  stopIfDisabled(click);
114
132
  }
115
-
116
- onMount(() => {
117
- const { width, height } = qBtnLabel.getBoundingClientRect();
118
-
119
- // This is required for buttons with no label and with a tooltip to be round
120
- if (width === 0 && height === 0) {
121
- qBtn.classList.add("q-btn--round");
122
- }
123
- });
133
+ // #endregion: --- Functions
124
134
  </script>
125
135
 
126
136
  <svelte:element
@@ -1,6 +1,7 @@
1
1
  <script lang="ts">
2
- import type { QCardProps } from "./props";
2
+ import type { QCardProps, QCardFillColors } from "./props";
3
3
 
4
+ // #region: --- Props
4
5
  let {
5
6
  fill = false,
6
7
  flat = false,
@@ -9,24 +10,27 @@
9
10
  children,
10
11
  ...props
11
12
  }: QCardProps = $props();
13
+ // #endregion: --- Props
12
14
 
13
- type ColorOptions = "primary" | "secondary" | "tertiary";
14
-
15
- const colorOptions: ColorOptions[] = [
15
+ // #region: --- Non-reactive variables
16
+ const colorOptions: QCardFillColors[] = [
16
17
  "primary",
17
18
  "secondary",
18
19
  "tertiary",
19
20
  ] as const;
21
+ // #endregion: --- Non-reactive variables
20
22
 
23
+ // #region: --- Derived values
21
24
  const color = $derived.by(() => {
22
25
  if (fill) {
23
- return fill === true || !colorOptions.includes(fill as ColorOptions)
26
+ return fill === true || !colorOptions.includes(fill as QCardFillColors)
24
27
  ? "surface-variant"
25
28
  : fill;
26
29
  }
27
30
 
28
31
  return "surface";
29
32
  });
33
+ // #endregion: --- Derived values
30
34
  </script>
31
35
 
32
36
  <article
@@ -2,14 +2,18 @@
2
2
  import { useAlign } from "../../composables";
3
3
  import type { QCardActionsProps } from "./props";
4
4
 
5
+ // #region: --- Props
5
6
  let {
6
7
  align,
7
8
  vertical = false,
8
9
  children,
9
10
  ...props
10
11
  }: QCardActionsProps = $props();
12
+ // #endregion: --- Props
11
13
 
14
+ // #region: --- Derived values
12
15
  const alignClass = $derived(useAlign(align));
16
+ // #endregion: --- Derived values
13
17
  </script>
14
18
 
15
19
  <nav
@@ -1,7 +1,9 @@
1
1
  <script lang="ts">
2
2
  import type { QCardSectionProps } from "./props";
3
3
 
4
+ // #region: --- Props
4
5
  let { horizontal = false, children, ...props }: QCardSectionProps = $props();
6
+ // #endregion: --- Props
5
7
  </script>
6
8
 
7
9
  <div
@@ -1,12 +1,14 @@
1
1
  <script lang="ts">
2
2
  import type { QCheckboxProps } from "./props";
3
3
 
4
+ // #region: --- Props
4
5
  let {
5
6
  value = $bindable(),
6
7
  label = "",
7
8
  disable = false,
8
9
  ...props
9
10
  }: QCheckboxProps = $props();
11
+ // #endregion: --- Props
10
12
  </script>
11
13
 
12
14
  <label
@@ -7,23 +7,43 @@
7
7
 
8
8
  type QChipMouseEvent = QEvent<MouseEvent, HTMLElement>;
9
9
 
10
+ // #region: --- Props
10
11
  let {
11
12
  kind = "assist",
13
+ selected = $bindable(kind === "filter" ? false : undefined),
12
14
  label,
13
15
  icon,
14
16
  trailingIcon,
15
17
  disabled = false,
16
18
  elevated,
17
19
  noRipple = false,
18
- selected = $bindable(kind === "filter" ? false : undefined),
19
20
  size = "sm",
20
21
  onTrailingIconClick,
21
22
  children,
22
23
  ...props
23
24
  }: QChipProps = $props();
25
+ // #endregion: --- Props
24
26
 
27
+ // #region: --- Non-reactive variables
25
28
  let qChip: HTMLDivElement;
29
+ // #endregion: --- Non-reactive variables
30
+
31
+ // #region: --- Derived values
32
+ const trailing = $derived(
33
+ (kind === "assist" || kind === "suggestion") && trailingIcon
34
+ ? undefined
35
+ : trailingIcon,
36
+ );
37
+
38
+ const tabindex = disabled ? -1 : props.tabindex || 0;
39
+ const role = $derived(
40
+ ["assist", "filter"].includes(kind) ? "button" : undefined,
41
+ );
42
+
43
+ const avatar = $derived(extractImgSrc(icon));
44
+ // #endregion: --- Derived values
26
45
 
46
+ // #region: --- Effects
27
47
  $effect.pre(() => {
28
48
  if (selected !== undefined && kind !== "filter") {
29
49
  throw new Error(
@@ -37,20 +57,9 @@
37
57
  );
38
58
  }
39
59
  });
60
+ // #endregion: --- Effects
40
61
 
41
- const trailing = $derived(
42
- (kind === "assist" || kind === "suggestion") && trailingIcon
43
- ? undefined
44
- : trailingIcon,
45
- );
46
-
47
- const tabindex = disabled ? -1 : props.tabindex || 0;
48
- const role = $derived(
49
- ["assist", "filter"].includes(kind) ? "button" : undefined,
50
- );
51
-
52
- const avatar = $derived(extractImgSrc(icon));
53
-
62
+ // #region: --- Functions
54
63
  function stopIfDisabled(e: QChipMouseEvent, iconClick = false) {
55
64
  if (disabled) {
56
65
  e.preventDefault();
@@ -87,6 +96,7 @@
87
96
  }) as QChipMouseEvent;
88
97
  stopIfDisabled(click);
89
98
  }
99
+ // #endregion: --- Functions
90
100
  </script>
91
101
 
92
102
  <div
@@ -3,6 +3,7 @@
3
3
  import { copy } from "../../utils";
4
4
  import type { QCodeBlockProps } from "./props";
5
5
 
6
+ // #region: --- Props
6
7
  let {
7
8
  language,
8
9
  lightTheme = "github-light-default",
@@ -12,12 +13,16 @@
12
13
  copiable,
13
14
  ...props
14
15
  }: QCodeBlockProps = $props();
16
+ // #endregion: --- Props
15
17
 
18
+ // #region: --- Reactive variables
16
19
  let btnContent = $state("Copy");
17
20
  let btnColor = $state("primary");
18
21
 
19
22
  let html = $state("");
23
+ // #endregion: --- Reactive variables
20
24
 
25
+ // #region: --- Effects
21
26
  $effect(() => {
22
27
  // eslint-disable-next-line @typescript-eslint/no-unused-expressions
23
28
  Quaff.darkMode.isActive;
@@ -25,7 +30,9 @@
25
30
  // This is required to have the html updated when the code changes
26
31
  getHtml(code);
27
32
  });
33
+ // #endregion: --- Effects
28
34
 
35
+ // #region: --- Functions
29
36
  function setBtn(type: "base" | "error" | "success") {
30
37
  switch (type) {
31
38
  case "error":
@@ -68,6 +75,7 @@
68
75
  html = `<pre>${code}</pre>`;
69
76
  }
70
77
  }
78
+ // #endregion: --- Functions
71
79
  </script>
72
80
 
73
81
  <div {...props} class="q-code-block" data-quaff>
@@ -1,6 +1,7 @@
1
1
  <script lang="ts">
2
2
  import type { QDialogProps } from "./props";
3
3
 
4
+ // #region: --- Props
4
5
  let {
5
6
  value = $bindable(false),
6
7
  position = "default",
@@ -10,11 +11,17 @@
10
11
  children,
11
12
  ...props
12
13
  }: QDialogProps = $props();
14
+ // #endregion: --- Props
13
15
 
16
+ // #region: --- Reactive variables
14
17
  let dialogEl = $state<HTMLDialogElement>();
18
+ // #endregion: --- Reactive variables
15
19
 
20
+ // #region: --- Derived values
16
21
  const canHide = $derived(value && !persistent);
22
+ // #endregion: --- Derived values
17
23
 
24
+ // #region: --- Effects
18
25
  $effect(() => {
19
26
  if (value) {
20
27
  dialogEl?.[modal ? "showModal" : "show"]();
@@ -28,7 +35,9 @@
28
35
  window.removeEventListener("click", tryCancel);
29
36
  }
30
37
  });
38
+ // #endregion: --- Effects
31
39
 
40
+ // #region: --- Methods
32
41
  export function hide() {
33
42
  if (dialogEl?.open) {
34
43
  value = false;
@@ -48,7 +57,9 @@
48
57
  show();
49
58
  }
50
59
  }
60
+ // #endregion: --- Methods
51
61
 
62
+ // #region: --- Functions
52
63
  function addAnimation() {
53
64
  if (persistent && value) {
54
65
  dialogEl?.classList.add("q-dialog--animating");
@@ -77,6 +88,7 @@
77
88
  e.preventDefault();
78
89
  }
79
90
  }
91
+ // #endregion: --- Functions
80
92
  </script>
81
93
 
82
94
  <dialog
@@ -1,14 +1,11 @@
1
1
  <script lang="ts">
2
- import { getContext, onMount, untrack } from "svelte";
2
+ import { onMount, untrack } from "svelte";
3
3
  import { on } from "svelte/events";
4
4
  import { navigating } from "$app/state";
5
5
  import { useSize } from "../../composables";
6
- import { QContext } from "../../classes/QContext.svelte";
7
- import { QLayoutCtxName } from "../../utils";
8
- import type { QLayoutProps } from "../layout/props";
9
- import type { DrawerContext } from "../layout/QLayout.svelte";
10
- import type { QDrawerProps } from "./props";
6
+ import { leftDrawerCtx, rightDrawerCtx } from "../layout/QLayout.svelte";
11
7
 
8
+ // #region: --- Props
12
9
  let {
13
10
  value = $bindable(false),
14
11
  side = "left",
@@ -21,7 +18,10 @@
21
18
  children,
22
19
  ...props
23
20
  }: QDrawerProps = $props();
21
+ // #endregion: --- Props
22
+ import type { QDrawerProps } from "./props";
24
23
 
24
+ // #region: --- Non-reactive variables
25
25
  const PEEK_THRESHOLD = 30; // How far the drawer peeks out when cursor is near the edge
26
26
  const TRANSITION = "top 0.3s, bottom 0.3s, transform 0.3s";
27
27
 
@@ -30,20 +30,22 @@
30
30
  let unlistenPointermove: () => void;
31
31
  let unlistenPointerup: () => void;
32
32
  let unlistenPointercancel: () => void;
33
+ // #endregion: --- Non-reactive variables
33
34
 
35
+ // #region: --- Reactive variables
34
36
  let drawerEl = $state<HTMLDivElement>();
35
37
  let swipeAreaEl = $state<HTMLDivElement>();
36
38
 
37
39
  let isSwiping = $state(false);
38
40
  let startX = $state(0);
39
41
  let dragOffset = $state(0);
42
+ // #endregion: --- Reactive variables
40
43
 
41
- const drawerContext = QContext.get<DrawerContext>(
42
- QLayoutCtxName.drawer[side],
43
- );
44
- const layoutView = getContext<{ value: NonNullable<QLayoutProps["view"]> }>(
45
- QLayoutCtxName.view,
44
+ // #region: --- Derived values
45
+ const drawerCtxToUse = $derived(
46
+ side === "left" ? leftDrawerCtx : rightDrawerCtx,
46
47
  );
48
+ const drawerContext = $derived(drawerCtxToUse.get());
47
49
 
48
50
  const canHideOnClickOutside = $derived((value && !persistent) || overlay);
49
51
 
@@ -51,31 +53,23 @@
51
53
 
52
54
  const offsetTop = $derived.by(() => {
53
55
  const charPos = side === "left" ? 0 : 2;
54
- return layoutView?.value.charAt(charPos) === "h";
56
+ return drawerContext?.view.charAt(charPos) === "h";
55
57
  });
56
58
  const offsetBottom = $derived.by(() => {
57
59
  const charPos = side === "left" ? 8 : 10;
58
- return layoutView?.value.charAt(charPos) === "f";
60
+ return drawerContext?.view.charAt(charPos) === "f";
59
61
  });
60
62
 
61
- export const show = (e?: MouseEvent) => {
62
- if (!value) {
63
- value = true;
64
- e?.stopPropagation();
65
- }
66
- };
63
+ const widthStyle = $derived(!drawerContext ? useSize(width).style : null);
67
64
 
68
- export const hide = () => {
69
- if (value) {
70
- value = false;
71
- }
72
- };
65
+ const drawerWidthStyle = $derived(
66
+ widthStyle === null ? "" : `--${side}-drawer-width: ${widthStyle};`,
67
+ );
73
68
 
74
- export const toggle = (e?: MouseEvent) => {
75
- value = !value;
76
- e?.stopPropagation();
77
- };
69
+ const style = $derived(`${drawerWidthStyle}${props.style ?? ""}`);
70
+ // #endregion: --- Derived values
78
71
 
72
+ // #region: --- Lifecycle
79
73
  onMount(() => {
80
74
  setTimeout(() => {
81
75
  drawerEl?.style.setProperty("transition", TRANSITION);
@@ -93,14 +87,16 @@
93
87
  resetBodyStyles();
94
88
  }
95
89
 
96
- drawerContext?.updateEntries({
97
- width: 0,
90
+ drawerCtxToUse.updateEntries({
98
91
  takesSpace: false,
92
+ width: 0,
99
93
  ready: false,
100
94
  });
101
95
  };
102
96
  });
97
+ // #endregion: --- Lifecycle
103
98
 
99
+ // #region: --- Effects
104
100
  $effect(() => {
105
101
  if (navigating.type && hideOnRouteChange) {
106
102
  hide();
@@ -137,23 +133,37 @@
137
133
  // eslint-disable-next-line @typescript-eslint/no-unused-expressions
138
134
  [value, overlay, width];
139
135
 
140
- untrack(() =>
141
- drawerContext?.updateEntries({
136
+ untrack(() => {
137
+ drawerCtxToUse.updateEntries({
142
138
  takesSpace: !!value && !overlay,
143
139
  width,
144
140
  ready: true,
145
- }),
146
- );
141
+ });
142
+ });
147
143
  });
144
+ // #endregion: --- Effects
148
145
 
149
- const widthStyle = $derived(!drawerContext ? useSize(width).style : null);
146
+ // #region: --- Methods
147
+ export const show = (e?: MouseEvent) => {
148
+ if (!value) {
149
+ value = true;
150
+ e?.stopPropagation();
151
+ }
152
+ };
150
153
 
151
- const drawerWidthStyle = $derived(
152
- widthStyle === null ? "" : `--${side}-drawer-width: ${widthStyle};`,
153
- );
154
+ export const hide = () => {
155
+ if (value) {
156
+ value = false;
157
+ }
158
+ };
154
159
 
155
- const style = $derived(`${drawerWidthStyle}${props.style ?? ""}`);
160
+ export const toggle = (e?: MouseEvent) => {
161
+ value = !value;
162
+ e?.stopPropagation();
163
+ };
164
+ // #endregion: --- Methods
156
165
 
166
+ // #region: --- Functions
157
167
  function tryClose(e: MouseEvent) {
158
168
  const isTargetDrawer = e.target === drawerEl;
159
169
  const isTargetInsideDrawer = drawerEl?.contains(e.target as Node);
@@ -315,6 +325,7 @@
315
325
  document.body.style.removeProperty("cursor");
316
326
  document.body.style.removeProperty("user-select");
317
327
  }
328
+ // #endregion: --- Functions
318
329
  </script>
319
330
 
320
331
  <div