@quaffui/quaff 1.0.0-beta6 → 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/components/avatar/QAvatar.svelte +4 -0
  3. package/dist/components/breadcrumbs/QBreadcrumbs.svelte +28 -5
  4. package/dist/components/breadcrumbs/QBreadcrumbs.svelte.d.ts +23 -0
  5. package/dist/components/breadcrumbs/QBreadcrumbsEl.svelte +17 -14
  6. package/dist/components/button/QBtn.svelte +21 -11
  7. package/dist/components/card/QCard.svelte +9 -5
  8. package/dist/components/card/QCardActions.svelte +4 -0
  9. package/dist/components/card/QCardSection.svelte +2 -0
  10. package/dist/components/checkbox/QCheckbox.svelte +2 -0
  11. package/dist/components/chip/QChip.svelte +24 -14
  12. package/dist/components/codeBlock/QCodeBlock.svelte +8 -0
  13. package/dist/components/dialog/QDialog.svelte +12 -0
  14. package/dist/components/drawer/QDrawer.svelte +50 -39
  15. package/dist/components/expansion-item/QExpansionItem.svelte +16 -2
  16. package/dist/components/footer/QFooter.svelte +27 -22
  17. package/dist/components/header/QHeader.svelte +37 -28
  18. package/dist/components/icon/QIcon.svelte +4 -0
  19. package/dist/components/input/QInput.svelte +9 -2
  20. package/dist/components/layout/QLayout.svelte +243 -90
  21. package/dist/components/layout/QLayout.svelte.d.ts +64 -2
  22. package/dist/components/list/QItem.svelte +43 -24
  23. package/dist/components/list/QItem.svelte.d.ts +14 -0
  24. package/dist/components/list/QItemSection.svelte +16 -12
  25. package/dist/components/list/QList.svelte +28 -6
  26. package/dist/components/list/QList.svelte.d.ts +15 -0
  27. package/dist/components/private/ContextReseter.svelte +2 -3
  28. package/dist/components/private/QApi.svelte +15 -7
  29. package/dist/components/private/QDocs.svelte +40 -20
  30. package/dist/components/private/QDocs.svelte.d.ts +30 -0
  31. package/dist/components/private/QDocsSection.svelte +11 -7
  32. package/dist/components/progress/QCircularProgress.svelte +14 -5
  33. package/dist/components/progress/QLinearProgress.svelte +12 -6
  34. package/dist/components/radio/QRadio.svelte +2 -0
  35. package/dist/components/railbar/QRailbar.svelte +36 -35
  36. package/dist/components/select/QSelect.svelte +32 -23
  37. package/dist/components/separator/QSeparator.svelte +4 -0
  38. package/dist/components/switch/QSwitch.svelte +6 -0
  39. package/dist/components/table/QTable.svelte +23 -13
  40. package/dist/components/tabs/QTab.svelte +19 -22
  41. package/dist/components/tabs/QTabs.svelte +59 -32
  42. package/dist/components/tabs/QTabs.svelte.d.ts +15 -4
  43. package/dist/components/toolbar/QToolbar.svelte +2 -0
  44. package/dist/components/toolbar/QToolbarTitle.svelte +2 -0
  45. package/dist/components/tooltip/QTooltip.svelte +22 -8
  46. package/dist/components/tooltip/QTooltipBase.svelte +18 -8
  47. package/dist/composables/useRouterLink.d.ts +2 -1
  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 +28 -27
  54. package/dist/classes/QContext.svelte.d.ts +0 -42
  55. package/dist/classes/QContext.svelte.js +0 -63
@@ -7,6 +7,7 @@
7
7
  QTableSort,
8
8
  } from "./props";
9
9
 
10
+ // #region: --- Props
10
11
  let {
11
12
  columns = [],
12
13
  rows = [],
@@ -16,19 +17,16 @@
16
17
  bodyCell,
17
18
  ...props
18
19
  }: QTableProps = $props();
20
+ // #endregion: --- Props
19
21
 
20
- function getField(
21
- fieldRaw: QTableColumn["field"],
22
- row: QTableRow,
23
- ): string | number {
24
- return typeof fieldRaw === "function" ? fieldRaw(row) : row[fieldRaw];
25
- }
26
-
22
+ // #region: --- Reactive variables
27
23
  let page = $state(1);
28
24
  let rowsPerPage = $state(5);
29
25
 
30
26
  let sort: QTableSort = $state(null);
27
+ // #endregion: --- Reactive variables
31
28
 
29
+ // #region: --- Derived values
32
30
  const rowsPerPageOptions = $derived(
33
31
  [5, 10, 25, 50].filter((option) => {
34
32
  return rows.length >= option || option === 5;
@@ -41,12 +39,6 @@
41
39
  );
42
40
  const numberOf: number = $derived(rows.length);
43
41
 
44
- $effect(() => {
45
- if (rowsPerPage * (page - 1) >= rows.length) {
46
- page = 1;
47
- }
48
- });
49
-
50
42
  const rowsSorted: QTableRow[] = $derived.by(() => {
51
43
  if (sort) {
52
44
  return structuredClone(rows).sort((a: QTableRow, b: QTableRow) => {
@@ -75,6 +67,23 @@
75
67
  const rowsPaginated: QTableRow[] = $derived(
76
68
  rowsSorted.slice(numberFrom - 1, numberTo),
77
69
  );
70
+ // #endregion: --- Derived values
71
+
72
+ // #region: --- Effects
73
+ $effect(() => {
74
+ if (rowsPerPage * (page - 1) >= rows.length) {
75
+ page = 1;
76
+ }
77
+ });
78
+ // #endregion: --- Effects
79
+
80
+ // #region: --- Functions
81
+ function getField(
82
+ fieldRaw: QTableColumn["field"],
83
+ row: QTableRow,
84
+ ): string | number {
85
+ return typeof fieldRaw === "function" ? fieldRaw(row) : row[fieldRaw];
86
+ }
78
87
 
79
88
  function getThStyle(column: QTableColumn) {
80
89
  let style = allowsSort(column) ? "cursor: pointer; " : "";
@@ -111,6 +120,7 @@
111
120
  type: !sort?.type || sort?.type === "desc" ? "asc" : "desc",
112
121
  };
113
122
  }
123
+ // #endregion: --- Functions
114
124
  </script>
115
125
 
116
126
  <div {...props} class="q-table" data-quaff>
@@ -1,7 +1,5 @@
1
1
  <script lang="ts">
2
- import { getContext, hasContext } from "svelte";
3
2
  import { QIcon } from "../..";
4
- import { QContext } from "../../classes/QContext.svelte";
5
3
  import { ripple } from "../../helpers";
6
4
  import {
7
5
  getClosestFocusableBlock,
@@ -11,36 +9,34 @@
11
9
  isArrowKey,
12
10
  isRouteActive,
13
11
  isTabKey,
14
- QTabsCtxName,
15
12
  type Direction,
16
13
  type QEvent,
17
14
  } from "../../utils";
15
+ import { tabsCtx } from "./QTabs.svelte";
16
+ import type { QTabProps } from "./props";
18
17
 
19
- import type { QTabEl } from "./QTabs.svelte";
20
- import type { QTabProps, QTabsVariants } from "./props";
21
-
18
+ type QTabEl = HTMLAnchorElement | HTMLButtonElement;
22
19
  type QTabEvent<T> = QEvent<T, QTabEl>;
23
20
 
21
+ // #region: --- Props
24
22
  let { name, to, icon, children, ...props }: QTabProps = $props();
23
+ // #endregion: --- Props
25
24
 
25
+ // #region: --- Non-reactive variables
26
26
  let qTab: QTabEl;
27
+ // #endregion: --- Non-reactive variables
27
28
 
28
- const tag = $derived(to ? "a" : "button");
29
+ // #region: --- Reactive variables
30
+ const ctx = tabsCtx.assertGet("QTab should be use inside QTabs.");
31
+ // #endregion: --- Reactive variables
29
32
 
30
- if (!hasContext(QTabsCtxName.value)) {
31
- console.warn("QTab should be use inside QTabs.");
32
- }
33
-
34
- const qTabsRequestCtx = QContext.get<string | null>(QTabsCtxName.request)!;
33
+ // #region: --- Derived values
34
+ const tag = $derived(to ? "a" : "button");
35
35
 
36
- const qTabsValueCtx = QContext.get<string | undefined | null>(
37
- QTabsCtxName.value,
38
- )!;
39
- const variant = getContext<QTabsVariants>(QTabsCtxName.variant);
40
- const isActive = $derived(
41
- to ? isRouteActive(to) : name === qTabsValueCtx.value,
42
- );
36
+ const isActive = $derived(to ? isRouteActive(to) : name === ctx.value);
37
+ // #endregion: --- Derived values
43
38
 
39
+ // #region: --- Functions
44
40
  function onclick(e: QTabEvent<MouseEvent>) {
45
41
  props.onclick?.(e);
46
42
 
@@ -48,7 +44,7 @@
48
44
  return;
49
45
  }
50
46
 
51
- qTabsRequestCtx.update(name);
47
+ ctx.request = name;
52
48
  }
53
49
 
54
50
  function onkeydown(e: QTabEvent<KeyboardEvent>) {
@@ -81,6 +77,7 @@
81
77
  targetBlock?.focus();
82
78
  }
83
79
  }
80
+ // #endregion: --- Functions
84
81
  </script>
85
82
 
86
83
  <svelte:element
@@ -108,12 +105,12 @@
108
105
  <span>{@render children?.()}</span>
109
106
  {/if}
110
107
 
111
- {#if variant === "primary"}
108
+ {#if ctx.variant === "primary"}
112
109
  <div class="q-tab__indicator"></div>
113
110
  {/if}
114
111
  </div>
115
112
 
116
- {#if variant !== "primary"}
113
+ {#if ctx.variant !== "primary"}
117
114
  <div class="q-tab__indicator"></div>
118
115
  {/if}
119
116
  </svelte:element>
@@ -1,17 +1,21 @@
1
1
  <script module lang="ts">
2
- export type QTabEl = HTMLAnchorElement | HTMLButtonElement;
3
- export type QTabsElementsContext = {
4
- previous: QTabEl | null;
5
- active: QTabEl | null;
6
- };
2
+ import { QContext } from "../../utils";
3
+ import type { QTabsProps } from "./props";
4
+
5
+ interface QTabsContext {
6
+ readonly variant: QTabsProps["variant"];
7
+ value: QTabsProps["value"];
8
+ request: string | null;
9
+ }
10
+
11
+ export const tabsCtx = QContext<QTabsContext>("QTabs");
7
12
  </script>
8
13
 
9
14
  <script lang="ts">
10
- import { setContext, untrack } from "svelte";
11
- import { QContext } from "../../classes/QContext.svelte";
12
- import { QTabsCtxName, shouldReduceMotion } from "../../utils";
13
- import type { QTabsProps } from "./props";
15
+ import { tick, untrack } from "svelte";
16
+ import { shouldReduceMotion } from "../../utils";
14
17
 
18
+ // #region: --- Props
15
19
  let {
16
20
  value = $bindable(),
17
21
  variant = "primary",
@@ -19,28 +23,43 @@
19
23
  children,
20
24
  ...props
21
25
  }: QTabsProps = $props();
26
+ // #endregion: --- Props
22
27
 
28
+ // #region: --- Non-reactive variables
23
29
  let qTabs: HTMLElement;
24
30
  let tabList: HTMLElement[];
31
+ // #endregion: --- Non-reactive variables
32
+
33
+ // #region: --- Reactive variables
34
+ let request = $state<string | null>(null);
35
+ // #endregion: --- Reactive variables
36
+
37
+ // #region: --- Context
38
+ tabsCtx.set({
39
+ get value() {
40
+ return value;
41
+ },
42
+ set value(newValue) {
43
+ value = newValue;
44
+ },
45
+ get variant() {
46
+ return variant;
47
+ },
48
+ get request() {
49
+ return request;
50
+ },
51
+ set request(newValue) {
52
+ request = newValue;
53
+ },
54
+ });
55
+ // #endregion: --- Context
25
56
 
26
- const valueContext = new QContext<string | undefined | null>(
27
- QTabsCtxName.value,
28
- value,
29
- );
30
- const requestContext = new QContext<string | null>(
31
- QTabsCtxName.request,
32
- null,
33
- );
34
-
35
- // Set the variant context
36
- setContext(QTabsCtxName.variant, variant);
37
-
57
+ // #region: --- Effects
38
58
  $effect(() => {
39
59
  tabList = Array.from(qTabs.querySelectorAll(".q-tab"));
40
60
  });
41
61
 
42
- // Update the context when "value" changes
43
- $effect(() => {
62
+ $effect.pre(() => {
44
63
  if (!value) {
45
64
  return;
46
65
  }
@@ -48,35 +67,40 @@
48
67
  untrack(() => {
49
68
  const newTab = getResquetingTab(value!);
50
69
  animateIndicator(newTab);
51
-
52
- valueContext.update(value);
53
70
  });
54
71
  });
55
72
 
56
73
  // Try to update "value" when context changes from a QTab
57
74
  $effect(() => {
58
- const request = requestContext.value;
59
-
60
75
  if (!request) {
61
76
  return;
62
77
  }
63
78
 
79
+ updateValue(request);
80
+ });
81
+ // #endregion: --- Effects
82
+
83
+ // #region: --- Functions
84
+ async function updateValue(req: string) {
85
+ await tick();
86
+
64
87
  const defaultPrevented = !dispatchEvent(
65
88
  new Event("change", { bubbles: true, cancelable: true }),
66
89
  );
67
- const requester = getResquetingTab(request);
90
+ const requester = getResquetingTab(req);
91
+
68
92
  if (defaultPrevented || !requester) {
69
93
  return;
70
94
  }
71
95
 
72
96
  untrack(() => {
73
- value = request;
97
+ value = req;
74
98
  });
75
- });
99
+ }
76
100
 
77
101
  function getResquetingTab(requestingTabName: string) {
78
102
  return (
79
- tabList.find(
103
+ tabList?.find(
80
104
  (tab) => tab.getAttribute("aria-label") === requestingTabName,
81
105
  ) ?? null
82
106
  );
@@ -84,7 +108,8 @@
84
108
 
85
109
  function getActiveTab() {
86
110
  return (
87
- tabList.find((tab) => tab.getAttribute("aria-current") === "true") ?? null
111
+ tabList?.find((tab) => tab.getAttribute("aria-current") === "true") ??
112
+ null
88
113
  );
89
114
  }
90
115
 
@@ -141,6 +166,7 @@
141
166
  !isNaN(scale)
142
167
  ) {
143
168
  const translateAnimation = (fromPos - toPos).toFixed(4);
169
+
144
170
  const scaleAnimation = scale.toFixed(4);
145
171
  keyframe.transform = `translate${axis}(${translateAnimation}px) scale${axis}(${scaleAnimation})`;
146
172
  } else {
@@ -151,6 +177,7 @@
151
177
  // that can hide the animation.
152
178
  return [keyframe, { transform: "none" }];
153
179
  }
180
+ // #endregion: --- Functions
154
181
  </script>
155
182
 
156
183
  <nav
@@ -1,8 +1,19 @@
1
1
  import { SvelteComponentTyped } from "svelte";
2
- export type QTabEl = HTMLAnchorElement | HTMLButtonElement;
3
- export type QTabsElementsContext = {
4
- previous: QTabEl | null;
5
- active: QTabEl | null;
2
+ import type { QTabsProps } from "./props";
3
+ interface QTabsContext {
4
+ readonly variant: QTabsProps["variant"];
5
+ value: QTabsProps["value"];
6
+ request: string | null;
7
+ }
8
+ export declare const tabsCtx: {
9
+ readonly symbol: symbol;
10
+ get(): QTabsContext | undefined;
11
+ assertGet(errorMsg?: string): QTabsContext;
12
+ set(context: QTabsContext): void;
13
+ reset(): void;
14
+ exists(): boolean;
15
+ updateEntry(key: keyof QTabsContext, value: string | null | undefined): void;
16
+ updateEntries(updates: Partial<QTabsContext>): void;
6
17
  };
7
18
  declare const __propDef: {
8
19
  props: Record<string, never>;
@@ -1,6 +1,7 @@
1
1
  <script lang="ts">
2
2
  import type { QToolbarProps } from "./props";
3
3
 
4
+ // #region: --- Props
4
5
  let {
5
6
  inset = false,
6
7
  border = false,
@@ -9,6 +10,7 @@
9
10
  children,
10
11
  ...props
11
12
  }: QToolbarProps = $props();
13
+ // #endregion: --- Props
12
14
  </script>
13
15
 
14
16
  <nav
@@ -1,7 +1,9 @@
1
1
  <script lang="ts">
2
2
  import type { QToolbarTitleProps } from "./props";
3
3
 
4
+ // #region: --- Props
4
5
  let { shrink = false, children, ...props }: QToolbarTitleProps = $props();
6
+ // #endregion: --- Props
5
7
  </script>
6
8
 
7
9
  <div
@@ -4,6 +4,7 @@
4
4
  import QTooltipBase from "./QTooltipBase.svelte";
5
5
  import type { QTooltipProps } from "./props";
6
6
 
7
+ // #region: --- Props
7
8
  let {
8
9
  target,
9
10
  value = $bindable(false),
@@ -14,15 +15,9 @@
14
15
  children,
15
16
  ...props
16
17
  }: QTooltipProps<T> = $props();
18
+ // #endregion: --- Props
17
19
 
18
- let tooltipHelperEl = $state<HTMLDivElement>();
19
- let tooltipEl = $state<HTMLDivElement>();
20
-
21
- let realTarget = $state<HTMLElement>();
22
-
23
- let timerShow = $state<ReturnType<typeof setTimeout> | null>(null);
24
- let timerHide = $state<ReturnType<typeof setTimeout> | null>(null);
25
-
20
+ // #region: --- Non-reactive variables
26
21
  let mountedTooltip: ReturnType<typeof mountTooltip> | null = null;
27
22
 
28
23
  let targetMouseEnterListener: ReturnType<typeof addEventListener> | null =
@@ -36,11 +31,25 @@
36
31
  let windowWheelListener: ReturnType<typeof addEventListener> | null = null;
37
32
 
38
33
  const id = $props.id();
34
+ // #endregion: --- Non-reactive variables
35
+
36
+ // #region: --- Reactive variables
37
+ let tooltipHelperEl = $state<HTMLDivElement>();
38
+ let tooltipEl = $state<HTMLDivElement>();
39
+
40
+ let realTarget = $state<HTMLElement>();
41
+
42
+ let timerShow = $state<ReturnType<typeof setTimeout> | null>(null);
43
+ let timerHide = $state<ReturnType<typeof setTimeout> | null>(null);
44
+ // #endregion: --- Reactive variables
39
45
 
46
+ // #region: --- Effects
40
47
  $effect(() => {
41
48
  value ? untrack(show) : untrack(hide);
42
49
  });
50
+ // #endregion: --- Effects
43
51
 
52
+ // #region: --- Lifecycle
44
53
  onMount(() => {
45
54
  if (target) {
46
55
  realTarget =
@@ -85,7 +94,9 @@
85
94
  }
86
95
  };
87
96
  });
97
+ // #endregion: --- Lifecycle
88
98
 
99
+ // #region: --- Methods
89
100
  export function show() {
90
101
  if (timerHide) {
91
102
  clearTimeout(timerHide);
@@ -170,7 +181,9 @@
170
181
  export function toggle() {
171
182
  value = !value;
172
183
  }
184
+ // #endregion: --- Methods
173
185
 
186
+ // #region: --- Functions
174
187
  function abortHide() {
175
188
  if (timerHide) {
176
189
  clearTimeout(timerHide);
@@ -196,6 +209,7 @@
196
209
  },
197
210
  });
198
211
  }
212
+ // #endregion: --- Functions
199
213
  </script>
200
214
 
201
215
  {#if !target}
@@ -3,6 +3,7 @@
3
3
  import { scale } from "svelte/transition";
4
4
  import type { QTooltipProps } from "./props";
5
5
 
6
+ // #region: --- Props
6
7
  let {
7
8
  // At this point, target should be guaranteed to be a DOM element
8
9
  target,
@@ -11,17 +12,13 @@
11
12
  children,
12
13
  ...props
13
14
  }: QTooltipProps<HTMLElement> = $props();
15
+ // #endregion: --- Props
14
16
 
17
+ // #region: --- Reactive variables
15
18
  let tooltipEl = $state<HTMLDivElement>();
19
+ // #endregion: --- Reactive variables
16
20
 
17
- onMount(() => {
18
- setTimeout(() => {
19
- if (tooltipEl) {
20
- tooltipEl.style.opacity = "1";
21
- }
22
- }, 50);
23
- });
24
-
21
+ // #region: --- Derived values
25
22
  const tooltipPosition: Record<"top" | "left", number> | undefined =
26
23
  $derived.by(() => {
27
24
  if (!target || !tooltipEl) {
@@ -40,7 +37,19 @@
40
37
  left: `${tooltipPosition.left}px`,
41
38
  },
42
39
  );
40
+ // #endregion: --- Derived values
41
+
42
+ // #region: --- Lifecycle
43
+ onMount(() => {
44
+ setTimeout(() => {
45
+ if (tooltipEl) {
46
+ tooltipEl.style.opacity = "1";
47
+ }
48
+ }, 50);
49
+ });
50
+ // #endregion: --- Lifecycle
43
51
 
52
+ // #region: --- Functions
44
53
  function calculatePosition(
45
54
  anchor: HTMLElement,
46
55
  tooltip: HTMLElement,
@@ -71,6 +80,7 @@
71
80
  tooltip[tooltipDimension] / 2 +
72
81
  (offsetToUse || 0);
73
82
  }
83
+ // #endregion: --- Functions
74
84
  </script>
75
85
 
76
86
  <div
@@ -1,3 +1,4 @@
1
+ import { LayoutParams, RouteId } from "$app/types";
1
2
  import type { Page } from "@sveltejs/kit";
2
3
  export interface UseRouterLinkProps {
3
4
  href?: string;
@@ -7,7 +8,7 @@ export interface UseRouterLinkProps {
7
8
  replace?: boolean;
8
9
  }
9
10
  export declare const UseRouterLinkPropsDefaults: UseRouterLinkProps;
10
- export declare function isRouteActive(router: Page<Record<string, string>, string | null>, to: string | undefined): boolean;
11
+ export declare function isRouteActive(router: Page<LayoutParams<"/">, RouteId | null>, to: string | undefined): boolean;
11
12
  export declare function useRouterLink<T extends UseRouterLinkProps>(props: T): {
12
13
  hasLink: boolean;
13
14
  linkAttributes: {