@quaffui/quaff 1.0.0-beta1 → 1.0.0-beta12

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 (216) hide show
  1. package/README.md +2 -0
  2. package/dist/classes/QScrollObserver.svelte.d.ts +4 -4
  3. package/dist/classes/QScrollObserver.svelte.js +26 -13
  4. package/dist/components/avatar/QAvatar.svelte +4 -0
  5. package/dist/components/avatar/QAvatar.svelte.d.ts +4 -14
  6. package/dist/components/breadcrumbs/QBreadcrumbs.scss +9 -5
  7. package/dist/components/breadcrumbs/QBreadcrumbs.svelte +46 -16
  8. package/dist/components/breadcrumbs/QBreadcrumbs.svelte.d.ts +24 -12
  9. package/dist/components/breadcrumbs/QBreadcrumbsEl.scss +22 -3
  10. package/dist/components/breadcrumbs/QBreadcrumbsEl.svelte +50 -38
  11. package/dist/components/breadcrumbs/QBreadcrumbsEl.svelte.d.ts +4 -14
  12. package/dist/components/breadcrumbs/props.d.ts +4 -4
  13. package/dist/components/button/QBtn.scss +3 -1
  14. package/dist/components/button/QBtn.svelte +38 -22
  15. package/dist/components/button/QBtn.svelte.d.ts +4 -14
  16. package/dist/components/button/props.d.ts +9 -2
  17. package/dist/components/card/QCard.svelte +9 -5
  18. package/dist/components/card/QCard.svelte.d.ts +4 -14
  19. package/dist/components/card/QCardActions.svelte +4 -0
  20. package/dist/components/card/QCardActions.svelte.d.ts +4 -14
  21. package/dist/components/card/QCardSection.svelte +2 -0
  22. package/dist/components/card/QCardSection.svelte.d.ts +4 -14
  23. package/dist/components/checkbox/QCheckbox.svelte +6 -4
  24. package/dist/components/checkbox/QCheckbox.svelte.d.ts +4 -14
  25. package/dist/components/checkbox/props.d.ts +1 -1
  26. package/dist/components/chip/QChip.scss +3 -1
  27. package/dist/components/chip/QChip.svelte +24 -14
  28. package/dist/components/chip/QChip.svelte.d.ts +4 -14
  29. package/dist/components/codeBlock/QCodeBlock.svelte +8 -0
  30. package/dist/components/codeBlock/QCodeBlock.svelte.d.ts +4 -14
  31. package/dist/components/dialog/QDialog.scss +17 -0
  32. package/dist/components/dialog/QDialog.svelte +34 -9
  33. package/dist/components/dialog/QDialog.svelte.d.ts +8 -21
  34. package/dist/components/drawer/QDrawer.scss +2 -2
  35. package/dist/components/drawer/QDrawer.svelte +124 -69
  36. package/dist/components/drawer/QDrawer.svelte.d.ts +8 -21
  37. package/dist/components/drawer/props.d.ts +3 -3
  38. package/dist/components/expansion-item/QExpansionItem.scss +59 -0
  39. package/dist/components/expansion-item/QExpansionItem.svelte +319 -0
  40. package/dist/components/expansion-item/QExpansionItem.svelte.d.ts +8 -0
  41. package/dist/components/expansion-item/docs.d.ts +2 -0
  42. package/dist/components/expansion-item/docs.js +17 -0
  43. package/dist/components/expansion-item/props.d.ts +129 -0
  44. package/dist/components/expansion-item/props.js +1 -0
  45. package/dist/components/footer/QFooter.scss +1 -1
  46. package/dist/components/footer/QFooter.svelte +32 -28
  47. package/dist/components/footer/QFooter.svelte.d.ts +4 -14
  48. package/dist/components/header/QHeader.scss +1 -1
  49. package/dist/components/header/QHeader.svelte +41 -33
  50. package/dist/components/header/QHeader.svelte.d.ts +4 -14
  51. package/dist/components/icon/QIcon.svelte +6 -4
  52. package/dist/components/icon/QIcon.svelte.d.ts +4 -14
  53. package/dist/components/index.d.ts +3 -1
  54. package/dist/components/index.js +3 -1
  55. package/dist/components/input/QInput.svelte +139 -17
  56. package/dist/components/input/QInput.svelte.d.ts +4 -14
  57. package/dist/components/input/docs.js +2 -2
  58. package/dist/components/input/mask.d.ts +10 -0
  59. package/dist/components/input/mask.js +204 -0
  60. package/dist/components/input/props.d.ts +37 -4
  61. package/dist/components/layout/QLayout.svelte +248 -93
  62. package/dist/components/layout/QLayout.svelte.d.ts +67 -15
  63. package/dist/components/layout/props.d.ts +1 -1
  64. package/dist/components/list/QItem.scss +7 -4
  65. package/dist/components/list/QItem.svelte +44 -24
  66. package/dist/components/list/QItem.svelte.d.ts +17 -13
  67. package/dist/components/list/QItemSection.scss +24 -3
  68. package/dist/components/list/QItemSection.svelte +19 -21
  69. package/dist/components/list/QItemSection.svelte.d.ts +4 -14
  70. package/dist/components/list/QList.scss +17 -4
  71. package/dist/components/list/QList.svelte +30 -8
  72. package/dist/components/list/QList.svelte.d.ts +17 -13
  73. package/dist/components/list/props.d.ts +3 -3
  74. package/dist/components/menu/QMenu.scss +37 -0
  75. package/dist/components/menu/QMenu.svelte +314 -0
  76. package/dist/components/menu/QMenu.svelte.d.ts +8 -0
  77. package/dist/components/menu/docs.d.ts +2 -0
  78. package/dist/components/menu/docs.js +27 -0
  79. package/dist/components/menu/props.d.ts +48 -0
  80. package/dist/components/menu/props.js +1 -0
  81. package/dist/components/progress/QCircularProgress.svelte +17 -14
  82. package/dist/components/progress/QCircularProgress.svelte.d.ts +4 -14
  83. package/dist/components/progress/QLinearProgress.svelte +15 -15
  84. package/dist/components/progress/QLinearProgress.svelte.d.ts +4 -14
  85. package/dist/components/radio/QRadio.svelte +6 -4
  86. package/dist/components/radio/QRadio.svelte.d.ts +4 -14
  87. package/dist/components/radio/props.d.ts +1 -1
  88. package/dist/components/railbar/QRailbar.scss +1 -1
  89. package/dist/components/railbar/QRailbar.svelte +36 -35
  90. package/dist/components/railbar/QRailbar.svelte.d.ts +4 -14
  91. package/dist/components/select/QSelect.svelte +316 -102
  92. package/dist/components/select/QSelect.svelte.d.ts +4 -14
  93. package/dist/components/select/filter.d.ts +13 -0
  94. package/dist/components/select/filter.js +73 -0
  95. package/dist/components/select/index.scss +28 -27
  96. package/dist/components/select/option.d.ts +9 -0
  97. package/dist/components/select/option.js +59 -0
  98. package/dist/components/select/props.d.ts +40 -7
  99. package/dist/components/separator/QSeparator.scss +2 -0
  100. package/dist/components/separator/QSeparator.svelte +9 -8
  101. package/dist/components/separator/QSeparator.svelte.d.ts +4 -14
  102. package/dist/components/switch/QSwitch.scss +12 -6
  103. package/dist/components/switch/QSwitch.svelte +7 -1
  104. package/dist/components/switch/QSwitch.svelte.d.ts +4 -14
  105. package/dist/components/table/QTable.svelte +31 -19
  106. package/dist/components/table/QTable.svelte.d.ts +4 -14
  107. package/dist/components/table/index.scss +1 -1
  108. package/dist/components/tabs/QTab.scss +2 -0
  109. package/dist/components/tabs/QTab.svelte +19 -22
  110. package/dist/components/tabs/QTab.svelte.d.ts +4 -14
  111. package/dist/components/tabs/QTabs.svelte +59 -32
  112. package/dist/components/tabs/QTabs.svelte.d.ts +18 -18
  113. package/dist/components/toolbar/QToolbar.svelte +2 -0
  114. package/dist/components/toolbar/QToolbar.svelte.d.ts +4 -14
  115. package/dist/components/toolbar/QToolbarTitle.svelte +2 -0
  116. package/dist/components/toolbar/QToolbarTitle.svelte.d.ts +4 -14
  117. package/dist/components/tooltip/QTooltip.svelte +48 -38
  118. package/dist/components/tooltip/QTooltip.svelte.d.ts +29 -17
  119. package/dist/components/tooltip/QTooltipBase.svelte +18 -8
  120. package/dist/components/tooltip/QTooltipBase.svelte.d.ts +4 -14
  121. package/dist/composables/index.d.ts +2 -0
  122. package/dist/composables/index.js +2 -0
  123. package/dist/composables/useColor.d.ts +1 -0
  124. package/dist/composables/useColor.js +19 -0
  125. package/dist/composables/useRevealScrollObserver.svelte.d.ts +9 -0
  126. package/dist/composables/useRevealScrollObserver.svelte.js +25 -0
  127. package/dist/composables/useRouterLink.d.ts +3 -2
  128. package/dist/composables/useRouterLink.js +2 -2
  129. package/dist/css/_components.scss +2 -0
  130. package/dist/css/classes/_grid.scss +12 -1
  131. package/dist/css/index.css +1 -1
  132. package/dist/css/mixins/_design.scss +1 -1
  133. package/dist/css/mixins/_field.scss +3 -2
  134. package/dist/css/mixins/_table.scss +1 -1
  135. package/dist/css/mixins/_toolbar.scss +1 -1
  136. package/dist/css/shared/q-field.scss +7 -6
  137. package/dist/css/theme/_page.scss +8 -6
  138. package/dist/css/theme/_reset.scss +2 -1
  139. package/dist/helpers/clickOutside.js +5 -4
  140. package/dist/helpers/ripple.js +5 -6
  141. package/dist/helpers/version.d.ts +1 -1
  142. package/dist/helpers/version.js +1 -1
  143. package/dist/{components/private/ContextReseter.svelte → internal/ContextResetter.svelte} +2 -3
  144. package/dist/internal/ContextResetter.svelte.d.ts +8 -0
  145. package/dist/{components/private → internal}/QIconSnippet.svelte +2 -2
  146. package/dist/internal/QIconSnippet.svelte.d.ts +10 -0
  147. package/dist/utils/context.d.ts +49 -32
  148. package/dist/utils/context.js +82 -33
  149. package/dist/utils/dom.d.ts +6 -0
  150. package/dist/utils/dom.js +33 -0
  151. package/dist/utils/events.d.ts +0 -24
  152. package/dist/utils/events.js +0 -24
  153. package/package.json +44 -38
  154. package/dist/classes/QContext.svelte.d.ts +0 -42
  155. package/dist/classes/QContext.svelte.js +0 -63
  156. package/dist/components/avatar/docs.props.d.ts +0 -3
  157. package/dist/components/avatar/docs.props.js +0 -87
  158. package/dist/components/breadcrumbs/docs.props.d.ts +0 -5
  159. package/dist/components/breadcrumbs/docs.props.js +0 -144
  160. package/dist/components/button/docs.props.d.ts +0 -3
  161. package/dist/components/button/docs.props.js +0 -227
  162. package/dist/components/card/docs.props.d.ts +0 -7
  163. package/dist/components/card/docs.props.js +0 -89
  164. package/dist/components/checkbox/docs.props.d.ts +0 -3
  165. package/dist/components/checkbox/docs.props.js +0 -41
  166. package/dist/components/chip/docs.props.d.ts +0 -3
  167. package/dist/components/chip/docs.props.js +0 -137
  168. package/dist/components/codeBlock/docs.props.d.ts +0 -3
  169. package/dist/components/codeBlock/docs.props.js +0 -83
  170. package/dist/components/dialog/docs.props.d.ts +0 -3
  171. package/dist/components/dialog/docs.props.js +0 -65
  172. package/dist/components/drawer/docs.props.d.ts +0 -3
  173. package/dist/components/drawer/docs.props.js +0 -149
  174. package/dist/components/footer/docs.props.d.ts +0 -3
  175. package/dist/components/footer/docs.props.js +0 -65
  176. package/dist/components/header/docs.props.d.ts +0 -7
  177. package/dist/components/header/docs.props.js +0 -131
  178. package/dist/components/icon/docs.props.d.ts +0 -3
  179. package/dist/components/icon/docs.props.js +0 -107
  180. package/dist/components/input/docs.props.d.ts +0 -3
  181. package/dist/components/input/docs.props.js +0 -162
  182. package/dist/components/layout/docs.props.d.ts +0 -3
  183. package/dist/components/layout/docs.props.js +0 -81
  184. package/dist/components/list/docs.props.d.ts +0 -11
  185. package/dist/components/list/docs.props.js +0 -434
  186. package/dist/components/private/ContextReseter.svelte.d.ts +0 -14
  187. package/dist/components/private/QApi.svelte +0 -296
  188. package/dist/components/private/QApi.svelte.d.ts +0 -14
  189. package/dist/components/private/QDocs.svelte +0 -155
  190. package/dist/components/private/QDocs.svelte.d.ts +0 -14
  191. package/dist/components/private/QDocsSection.svelte +0 -62
  192. package/dist/components/private/QDocsSection.svelte.d.ts +0 -14
  193. package/dist/components/private/QIconSnippet.svelte.d.ts +0 -14
  194. package/dist/components/private/index.d.ts +0 -6
  195. package/dist/components/private/index.js +0 -6
  196. package/dist/components/progress/docs.props.d.ts +0 -5
  197. package/dist/components/progress/docs.props.js +0 -314
  198. package/dist/components/radio/docs.props.d.ts +0 -3
  199. package/dist/components/radio/docs.props.js +0 -53
  200. package/dist/components/railbar/docs.props.d.ts +0 -3
  201. package/dist/components/railbar/docs.props.js +0 -47
  202. package/dist/components/select/docs.props.d.ts +0 -3
  203. package/dist/components/select/docs.props.js +0 -198
  204. package/dist/components/separator/docs.props.d.ts +0 -5
  205. package/dist/components/separator/docs.props.js +0 -196
  206. package/dist/components/switch/docs.props.d.ts +0 -3
  207. package/dist/components/switch/docs.props.js +0 -119
  208. package/dist/components/table/docs.props.d.ts +0 -3
  209. package/dist/components/table/docs.props.js +0 -94
  210. package/dist/components/tabs/docs.props.d.ts +0 -5
  211. package/dist/components/tabs/docs.props.js +0 -86
  212. package/dist/components/toolbar/docs.props.d.ts +0 -5
  213. package/dist/components/toolbar/docs.props.js +0 -68
  214. package/dist/components/tooltip/docs.props.d.ts +0 -3
  215. package/dist/components/tooltip/docs.props.js +0 -77
  216. package/dist/utils/types.json +0 -31
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 (compiled by the relevant package scripts)
65
67
 
66
68
  ## Acknowledgements
67
69
 
@@ -1,8 +1,6 @@
1
1
  type Direction = "up" | "right" | "down" | "left";
2
- type WindowScrollType = "scrollX" | "scrollY";
3
2
  type DocumentScrollType = "scrollLeft" | "scrollTop";
4
3
  type ScrollType = {
5
- window: WindowScrollType;
6
4
  document: DocumentScrollType;
7
5
  };
8
6
  type Target = HTMLElement | typeof window | Document | string;
@@ -30,6 +28,7 @@ export default class QScrollObserver {
30
28
  protected lastScroll: number;
31
29
  protected horizontal: boolean;
32
30
  protected clearTimer: (() => void) | null;
31
+ protected removeScrollListener: (() => void) | null;
33
32
  protected target: Exclude<Target, string> | null;
34
33
  protected debounce: number;
35
34
  protected handler: (e: Event) => void;
@@ -40,9 +39,10 @@ export default class QScrollObserver {
40
39
  position: number;
41
40
  constructor(target?: Target | null, { horizontal, debounce }?: ScrollObserverOptions);
42
41
  protected getScrollPosition(target?: HTMLElement | typeof window | undefined): number;
42
+ protected isScrollEventForTarget(eventTarget: EventTarget | null): boolean;
43
43
  protected baseHandler(e: Event): void;
44
- protected updateDirection(target: HTMLElement): void;
45
- protected handleDebounce(target: HTMLElement, debounce: number): void;
44
+ protected updateDirection(target: HTMLElement | typeof window): void;
45
+ protected handleDebounce(target: HTMLElement | typeof window, debounce: number): void;
46
46
  destroy(): void;
47
47
  }
48
48
  export {};
@@ -1,5 +1,8 @@
1
1
  import { onMount } from "svelte";
2
+ import { on } from "svelte/events";
3
+ import { scrollX, scrollY } from "svelte/reactivity/window";
2
4
  import { elFromSelector } from "../utils";
5
+ const SCROLL_LISTENER_OPTIONS = { capture: true };
3
6
  /**
4
7
  * A scroll observer utility.
5
8
  * @example
@@ -17,12 +20,12 @@ import { elFromSelector } from "../utils";
17
20
  */
18
21
  export default class QScrollObserver {
19
22
  scrollType = {
20
- window: "scrollY",
21
23
  document: "scrollTop",
22
24
  };
23
25
  lastScroll;
24
26
  horizontal = false;
25
27
  clearTimer = null;
28
+ removeScrollListener = null;
26
29
  target = null;
27
30
  debounce = 0;
28
31
  handler;
@@ -34,10 +37,8 @@ export default class QScrollObserver {
34
37
  constructor(target, { horizontal, debounce } = { horizontal: false, debounce: 0 }) {
35
38
  this.horizontal = horizontal ?? false;
36
39
  this.debounce = debounce ?? 0;
37
- this.handler = this.baseHandler.bind(this);
38
- this.scrollType = horizontal
39
- ? { window: "scrollX", document: "scrollLeft" }
40
- : { window: "scrollY", document: "scrollTop" };
40
+ this.handler = (e) => this.baseHandler(e);
41
+ this.scrollType = horizontal ? { document: "scrollLeft" } : { document: "scrollTop" };
41
42
  this.lastScroll = 0;
42
43
  this.position = 0;
43
44
  this.inflectionPoint = 0;
@@ -49,25 +50,36 @@ export default class QScrollObserver {
49
50
  parsedTarget = window;
50
51
  }
51
52
  this.target = parsedTarget;
52
- parsedTarget.addEventListener("scroll", this.handler, { capture: true });
53
+ this.removeScrollListener = on(parsedTarget, "scroll", this.handler, SCROLL_LISTENER_OPTIONS);
53
54
  return this.destroy.bind(this);
54
55
  });
55
56
  }
56
57
  getScrollPosition(target = window) {
57
58
  return Math.max(0, target === window
58
- ? target[this.scrollType.window]
59
+ ? ((this.horizontal ? scrollX.current : scrollY.current) ?? 0)
59
60
  : target[this.scrollType.document]);
60
61
  }
62
+ isScrollEventForTarget(eventTarget) {
63
+ if (!this.target || !eventTarget) {
64
+ return false;
65
+ }
66
+ if (this.target === window) {
67
+ return (eventTarget === document ||
68
+ eventTarget === document.documentElement ||
69
+ eventTarget === window);
70
+ }
71
+ return eventTarget === this.target;
72
+ }
61
73
  baseHandler(e) {
62
- const eventTarget = e.target;
63
- if (!eventTarget || !this.target || eventTarget !== this.target) {
74
+ if (!this.isScrollEventForTarget(e.target)) {
64
75
  return;
65
76
  }
77
+ const target = this.target;
66
78
  if (this.debounce) {
67
- this.handleDebounce(this.target, this.debounce);
79
+ this.handleDebounce(target, this.debounce);
68
80
  }
69
81
  else {
70
- this.updateDirection(this.target);
82
+ this.updateDirection(target);
71
83
  }
72
84
  }
73
85
  updateDirection(target) {
@@ -87,7 +99,7 @@ export default class QScrollObserver {
87
99
  if (this.clearTimer) {
88
100
  return;
89
101
  }
90
- const timer = setTimeout(this.updateDirection.bind(this, target), debounce);
102
+ const timer = setTimeout(() => this.updateDirection(target), debounce);
91
103
  this.clearTimer = () => {
92
104
  clearTimeout(timer);
93
105
  this.clearTimer = null;
@@ -96,7 +108,8 @@ export default class QScrollObserver {
96
108
  destroy() {
97
109
  this.clearTimer?.();
98
110
  this.clearTimer = null;
99
- this.target?.removeEventListener("scroll", this.handler);
111
+ this.removeScrollListener?.();
112
+ this.removeScrollListener = null;
100
113
  this.target = null;
101
114
  this.direction = "down";
102
115
  this.changedDirection = false;
@@ -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,14 +1,4 @@
1
- import { SvelteComponentTyped } from "svelte";
2
- declare const __propDef: {
3
- props: Record<string, never>;
4
- events: {
5
- [evt: string]: CustomEvent<any>;
6
- };
7
- slots: {};
8
- };
9
- type QAvatarProps_ = typeof __propDef.props;
10
- export { QAvatarProps_ as QAvatarProps };
11
- export type QAvatarEvents = typeof __propDef.events;
12
- export type QAvatarSlots = typeof __propDef.slots;
13
- export default class QAvatar extends SvelteComponentTyped<QAvatarProps_, QAvatarEvents, QAvatarSlots> {
14
- }
1
+ import type { QAvatarProps } from "./props";
2
+ declare const QAvatar: import("svelte").Component<QAvatarProps, {}, "">;
3
+ type QAvatar = ReturnType<typeof QAvatar>;
4
+ export default QAvatar;
@@ -1,10 +1,14 @@
1
1
  .q-breadcrumbs {
2
- display: flex;
3
- align-items: center;
4
- justify-content: center;
5
2
  width: fit-content;
6
3
 
7
- & > .q-breadcrumbs__separator:first-child {
8
- display: none;
4
+ &__list {
5
+ display: flex;
6
+ align-items: center;
7
+ justify-content: center;
8
+
9
+ margin: 0;
10
+ padding: 0;
11
+
12
+ list-style: none;
9
13
  }
10
14
  }
@@ -1,36 +1,66 @@
1
- <script lang="ts">
2
- import { setContext, untrack } 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
+ import { useColor } from "../../composables";
14
+
15
+ // #region: --- Props
6
16
  let {
7
17
  activeColor = "primary",
8
18
  gutter = "sm",
9
19
  separator = "/",
10
- separatorColor = "outline",
20
+ separatorColor = "outline-variant",
11
21
  children,
12
22
  ...props
13
23
  }: QBreadcrumbsProps = $props();
24
+ // #endregion: --- Props
25
+
26
+ // #region: --- Derived values
27
+ const parsedActiveColor = $derived(useColor(activeColor));
28
+ const parsedSeparatorColor = $derived(useColor(separatorColor));
29
+ // #endregion: --- Derived values
14
30
 
15
- let breadrumbElement: HTMLDivElement;
31
+ // #region: --- Non-reactive variables
32
+ let breadcrumbList: HTMLOListElement;
33
+ // #endregion: --- Non-reactive variables
16
34
 
17
- $effect(() => {
18
- untrack(() => breadrumbElement.firstChild?.remove());
35
+ // #region: --- Context
36
+ breadcrumbsCtx.set({
37
+ get separator() {
38
+ return separator;
39
+ },
40
+ get gutter() {
41
+ return gutter;
42
+ },
19
43
  });
44
+ // #endregion: --- Context
20
45
 
21
- setContext(QBreadcrumbsCtxName.activeColor, activeColor);
22
- setContext(QBreadcrumbsCtxName.separator, {
23
- type: separator,
24
- color: separatorColor,
25
- gutter,
46
+ // #region: --- Lifecycle
47
+ onMount(() => {
48
+ breadcrumbList
49
+ .querySelector(".q-breadcrumbs__separator:first-child")
50
+ ?.remove();
26
51
  });
52
+ // #endregion: --- Lifecycle
27
53
  </script>
28
54
 
29
- <div
30
- bind:this={breadrumbElement}
55
+ <nav
31
56
  {...props}
32
57
  class={["q-breadcrumbs", props.class]}
58
+ aria-label="Breadcrumbs"
33
59
  data-quaff
60
+ style:--q-separator-color={parsedSeparatorColor}
61
+ style:--q-active-color={parsedActiveColor}
34
62
  >
35
- {@render children?.()}
36
- </div>
63
+ <ol bind:this={breadcrumbList} class="q-breadcrumbs__list">
64
+ {@render children?.()}
65
+ </ol>
66
+ </nav>
@@ -1,14 +1,26 @@
1
- import { SvelteComponentTyped } from "svelte";
2
- declare const __propDef: {
3
- props: Record<string, never>;
4
- events: {
5
- [evt: string]: CustomEvent<any>;
1
+ import type { QBreadcrumbsProps } from "./props";
2
+ export declare const breadcrumbsCtx: {
3
+ readonly symbol: symbol;
4
+ get(): {
5
+ readonly separator: QBreadcrumbsProps["separator"];
6
+ readonly gutter: QBreadcrumbsProps["gutter"];
7
+ } | undefined;
8
+ assertGet(errorMsg?: string): {
9
+ readonly separator: QBreadcrumbsProps["separator"];
10
+ readonly gutter: QBreadcrumbsProps["gutter"];
6
11
  };
7
- slots: {};
12
+ set(context: {
13
+ readonly separator: QBreadcrumbsProps["separator"];
14
+ readonly gutter: QBreadcrumbsProps["gutter"];
15
+ }): void;
16
+ reset(): void;
17
+ exists(): boolean;
18
+ updateEntry(key: "separator" | "gutter", value: any): void;
19
+ updateEntries(updates: Partial<{
20
+ readonly separator: QBreadcrumbsProps["separator"];
21
+ readonly gutter: QBreadcrumbsProps["gutter"];
22
+ }>): void;
8
23
  };
9
- type QBreadcrumbsProps_ = typeof __propDef.props;
10
- export { QBreadcrumbsProps_ as QBreadcrumbsProps };
11
- export type QBreadcrumbsEvents = typeof __propDef.events;
12
- export type QBreadcrumbsSlots = typeof __propDef.slots;
13
- export default class QBreadcrumbs extends SvelteComponentTyped<QBreadcrumbsProps_, QBreadcrumbsEvents, QBreadcrumbsSlots> {
14
- }
24
+ declare const QBreadcrumbs: import("svelte").Component<QBreadcrumbsProps, {}, "">;
25
+ type QBreadcrumbs = ReturnType<typeof QBreadcrumbs>;
26
+ export default QBreadcrumbs;
@@ -1,10 +1,29 @@
1
1
  @use "$css/mixins";
2
2
 
3
- .q-breadcrumbs__el {
3
+ .q-breadcrumbs__item {
4
4
  display: flex;
5
5
  align-items: center;
6
6
 
7
- & > .q-icon {
8
- @include mixins.margin("r-sm");
7
+ color: var(--q-breadcrumbs-color, currentColor);
8
+
9
+ &:has(> a):hover .q-breadcrumbs__label {
10
+ text-decoration: underline;
11
+ text-decoration-color: currentColor;
12
+
13
+ &__item:first-child > .q-breadcrumbs__separator {
14
+ display: none;
15
+ }
16
+ }
17
+
18
+ .q-breadcrumbs__separator {
19
+ color: var(--q-separator-color, currentColor);
20
+ }
21
+
22
+ .q-breadcrumbs__el {
23
+ display: flex;
24
+ align-items: center;
25
+ gap: 0.5rem;
26
+ text-decoration: none;
27
+ color: inherit;
9
28
  }
10
29
  }
@@ -1,33 +1,30 @@
1
1
  <script lang="ts">
2
- import { getContext, type Snippet } 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
6
  import type { QBreadcrumbsElProps } from "./props";
7
7
 
8
+ // #region: --- Props
8
9
  let {
9
10
  activeClass = "active",
10
11
  href,
11
12
  label = "",
12
13
  icon,
13
- tag = "div",
14
+ tag = "span",
14
15
  to,
15
16
  children = fallback,
16
17
  ...props
17
18
  }: QBreadcrumbsElProps = $props();
19
+ // #endregion: --- Props
18
20
 
19
- const activeColor = getContext<string>(QBreadcrumbsCtxName.activeColor);
20
- const separator = getContext<{
21
- type: `icon:${MaterialSymbol}` | Snippet;
22
- color: string;
23
- gutter: string;
24
- }>(QBreadcrumbsCtxName.separator);
21
+ // #region: --- Derived values
22
+ const isActive = $derived(isRouteActive(href || to));
23
+ // #endregion: --- Derived values
25
24
 
26
- const classesIfActive = $derived(
27
- isRouteActive(href || to)
28
- ? `${activeClass} text-${activeColor}`
29
- : undefined,
30
- );
25
+ // #region: --- Context
26
+ const ctx = breadcrumbsCtx.assertGet();
27
+ // #endregion: --- Context
31
28
  </script>
32
29
 
33
30
  {#snippet fallback()}
@@ -39,38 +36,53 @@
39
36
  {#if typeof icon === "string"}
40
37
  <QIcon name={icon} size="1rem" />
41
38
  {:else}
42
- {@render icon()}
39
+ <span class="q-icon">
40
+ {@render icon()}
41
+ </span>
43
42
  {/if}
44
43
  {/if}
45
44
 
46
- {@render children()}
45
+ <span class="q-breadcrumbs__label">
46
+ {@render children()}
47
+ </span>
47
48
  {/snippet}
48
49
 
49
- <div
50
+ <li
50
51
  {...props}
51
- class={["q-breadcrumbs__separator", `q-px-${separator.gutter}`, props.class]}
52
- data-quaff
52
+ class={["q-breadcrumbs__item", props.class]}
53
+ style:--q-breadcrumbs-color={isActive ? "var(--q-active-color)" : undefined}
53
54
  >
54
- {#if typeof separator.type === "string"}
55
- {#if separator.type.startsWith("icon:")}
56
- <QIcon
57
- name={separator.type.replace("icon:", "") as MaterialSymbol}
58
- size="1rem"
59
- />
55
+ <span
56
+ class={["q-breadcrumbs__separator", `q-px-${ctx?.gutter}`]}
57
+ aria-hidden="true"
58
+ >
59
+ {#if typeof ctx.separator === "string"}
60
+ {#if ctx.separator.startsWith("icon:")}
61
+ <QIcon name={ctx.separator.slice(5) as MaterialSymbol} size="1rem" />
62
+ {:else}
63
+ {ctx.separator}
64
+ {/if}
60
65
  {:else}
61
- {separator.type}
66
+ {@render ctx.separator?.()}
62
67
  {/if}
68
+ </span>
69
+
70
+ {#if href || to}
71
+ <a
72
+ href={href || to}
73
+ class={["q-breadcrumbs__el", isActive && activeClass]}
74
+ aria-current={isActive ? "page" : undefined}
75
+ data-quaff
76
+ >
77
+ {@render breadcrumbEl()}
78
+ </a>
63
79
  {:else}
64
- {@render separator.type()}
80
+ <svelte:element
81
+ this={tag}
82
+ class={["q-breadcrumbs__el", isActive && activeClass]}
83
+ data-quaff
84
+ >
85
+ {@render breadcrumbEl()}
86
+ </svelte:element>
65
87
  {/if}
66
- </div>
67
-
68
- {#if href !== undefined || to !== undefined}
69
- <a href={href || to} class={["q-breadcrumbs__el", classesIfActive]}>
70
- {@render breadcrumbEl()}
71
- </a>
72
- {:else}
73
- <svelte:element this={tag} class={["q-breadcrumbs__el", classesIfActive]}>
74
- {@render breadcrumbEl()}
75
- </svelte:element>
76
- {/if}
88
+ </li>
@@ -1,14 +1,4 @@
1
- import { SvelteComponentTyped } from "svelte";
2
- declare const __propDef: {
3
- props: Record<string, never>;
4
- events: {
5
- [evt: string]: CustomEvent<any>;
6
- };
7
- slots: {};
8
- };
9
- type QBreadcrumbsElProps_ = typeof __propDef.props;
10
- export { QBreadcrumbsElProps_ as QBreadcrumbsElProps };
11
- export type QBreadcrumbsElEvents = typeof __propDef.events;
12
- export type QBreadcrumbsElSlots = typeof __propDef.slots;
13
- export default class QBreadcrumbsEl extends SvelteComponentTyped<QBreadcrumbsElProps_, QBreadcrumbsElEvents, QBreadcrumbsElSlots> {
14
- }
1
+ import type { QBreadcrumbsElProps } from "./props";
2
+ declare const QBreadcrumbsEl: import("svelte").Component<QBreadcrumbsElProps, {}, "">;
3
+ type QBreadcrumbsEl = ReturnType<typeof QBreadcrumbsEl>;
4
+ export default QBreadcrumbsEl;
@@ -2,7 +2,7 @@ import type { MaterialSymbol } from "material-symbols";
2
2
  import type { Snippet } from "svelte";
3
3
  import type { HTMLAttributes } from "svelte/elements";
4
4
  export type QBreadcrumbsGutterOptions = Exclude<Q.Size, "xs" | "xl">;
5
- export interface QBreadcrumbsProps extends HTMLAttributes<HTMLDivElement> {
5
+ export interface QBreadcrumbsProps extends HTMLAttributes<HTMLElement> {
6
6
  /**
7
7
  * Color to use for the active breadcrumb element. See <link to colors docs> to see what colors can be used.
8
8
  * @default "primary"
@@ -17,14 +17,14 @@ export interface QBreadcrumbsProps extends HTMLAttributes<HTMLDivElement> {
17
17
  * Separator to use between the breadcrumb elements. To use an icon, prefix with "icon:" followed by the name of the icon.
18
18
  * @default "/"
19
19
  */
20
- separator?: string | `icon:${MaterialSymbol}` | Snippet;
20
+ separator?: Q.StringWithSuggestions<`icon:${MaterialSymbol}`> | Snippet;
21
21
  /**
22
22
  * Color to use for the separators. See <link to colors docs> to see what colors can be used.
23
23
  * @default "outline"
24
24
  */
25
25
  separatorColor?: string;
26
26
  }
27
- export interface QBreadcrumbsElProps extends HTMLAttributes<HTMLElement> {
27
+ export interface QBreadcrumbsElProps extends HTMLAttributes<HTMLLIElement> {
28
28
  /**
29
29
  * Class to apply to the breadcrumb element when the route is active.
30
30
  * @default "active"
@@ -47,7 +47,7 @@ export interface QBreadcrumbsElProps extends HTMLAttributes<HTMLElement> {
47
47
  href?: string;
48
48
  /**
49
49
  * Tag to use for the breadcrumb element.
50
- * @default "div"
50
+ * @default "span"
51
51
  */
52
52
  tag?: string;
53
53
  /**
@@ -34,6 +34,8 @@
34
34
  variables.$speed3 border-radius,
35
35
  variables.$speed3 padding;
36
36
 
37
+ isolation: isolate;
38
+
37
39
  @include mixins.btn-image;
38
40
 
39
41
  $sizeMap: (
@@ -96,7 +98,7 @@
96
98
  }
97
99
 
98
100
  &--outlined {
99
- outline: solid 0.0625rem var(--outline);
101
+ outline: solid 0.0625rem var(--outline-variant);
100
102
 
101
103
  &:not([aria-disabled]):focus {
102
104
  outline-color: var(--primary);