@quaffui/quaff 1.0.0-alpha2 → 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
@@ -0,0 +1,319 @@
1
+ <script lang="ts">
2
+ import { slide } from "svelte/transition";
3
+ import { goto } from "$app/navigation";
4
+ import { QBtn, QIcon, QItem, QItemSection } from "..";
5
+ import { isActivationKey, type QEvent } from "../../utils";
6
+ import type { QExpansionItemProps } from "./props";
7
+
8
+ // #region: --- Props
9
+ let {
10
+ value = $bindable(false),
11
+ label,
12
+ icon,
13
+ caption,
14
+ expandIcon = "keyboard_arrow_down",
15
+ expandedIcon,
16
+ defaultOpened = false,
17
+ dense = false,
18
+ duration = 300,
19
+ hideExpandIcon = false,
20
+ toggleAriaLabel = "Open details",
21
+ expandIconToggle = false,
22
+ to,
23
+ href,
24
+ name,
25
+ noRotateExpandIcon = false,
26
+ disabled = false,
27
+ noRipple = false,
28
+ summary,
29
+ children,
30
+ onExpandIconClick,
31
+ ...props
32
+ }: QExpansionItemProps = $props();
33
+ // #endregion: --- Props
34
+
35
+ // #region: --- Non-reactive variables
36
+ const id = $props.id();
37
+ const contentId = `q-expansion-item__content-${id}`;
38
+ const summaryId = `q-expansion-item__summary-${id}`;
39
+ const supportDetailsContent =
40
+ typeof CSS !== "undefined" &&
41
+ CSS.supports("selector(details::details-content)");
42
+ // #endregion: --- Non-reactive variables
43
+
44
+ // #region: --- Reactive variables
45
+ let detailsEl = $state<HTMLDetailsElement>();
46
+ // #endregion: --- Reactive variables
47
+
48
+ // #region: --- Derived values
49
+ const summaryAttributes = $derived(
50
+ !supportDetailsContent
51
+ ? {
52
+ id: summaryId,
53
+ "aria-expanded": value,
54
+ "aria-controls": contentId,
55
+ }
56
+ : {},
57
+ );
58
+
59
+ const contentAttributes = $derived(
60
+ !supportDetailsContent
61
+ ? {
62
+ id: contentId,
63
+ role: "region",
64
+ "aria-labelledby": summaryId,
65
+ }
66
+ : {},
67
+ );
68
+
69
+ const iconAttributes = $derived({
70
+ [expandIconToggle ? "icon" : "name"]:
71
+ expandedIcon && value ? expandedIcon : expandIcon,
72
+ flat: expandIconToggle || undefined,
73
+ "aria-label": toggleAriaLabel,
74
+ });
75
+ // #endregion: --- Derived values
76
+
77
+ // #region: --- Effects
78
+ $effect.pre(() => {
79
+ if (defaultOpened) {
80
+ show();
81
+ }
82
+ });
83
+
84
+ $effect(() => {
85
+ if (supportDetailsContent || !name || !value) {
86
+ return;
87
+ }
88
+
89
+ // If the browser does not support details content, we need to manually
90
+ // handle the group open state of the details elements
91
+ const parent = detailsEl?.parentElement;
92
+
93
+ if (!parent) {
94
+ return;
95
+ }
96
+
97
+ const group = parent.querySelectorAll("details[open]");
98
+ group.forEach((item) => {
99
+ if (item !== detailsEl) {
100
+ item.removeAttribute("open");
101
+ }
102
+ });
103
+ });
104
+ // #endregion: --- Effects
105
+
106
+ // #region: --- Methods
107
+ export function toggle() {
108
+ value = !value;
109
+ }
110
+
111
+ export function show() {
112
+ value = true;
113
+ }
114
+
115
+ export function hide() {
116
+ value = false;
117
+ }
118
+ // #endregion: --- Methods
119
+
120
+ // #region: --- Functions
121
+ function preventAndStop<T extends Event>(e: T) {
122
+ e.preventDefault();
123
+ e.stopPropagation();
124
+ }
125
+
126
+ function onclick(e: QEvent<MouseEvent, HTMLElement>) {
127
+ if (disabled) {
128
+ preventAndStop(e);
129
+ return;
130
+ }
131
+
132
+ props.onclick?.(e);
133
+ }
134
+
135
+ function onIconClick(e: QEvent<MouseEvent, HTMLElement>) {
136
+ if (disabled) {
137
+ preventAndStop(e);
138
+ return;
139
+ }
140
+
141
+ e.stopPropagation();
142
+ e.preventDefault();
143
+
144
+ toggle();
145
+ onExpandIconClick?.(e);
146
+ }
147
+
148
+ function onkeydown(e: KeyboardEvent) {
149
+ if (disabled) {
150
+ preventAndStop(e);
151
+ return;
152
+ }
153
+
154
+ if (e.key === "Escape") {
155
+ detailsEl?.blur();
156
+ return;
157
+ }
158
+
159
+ if (!isActivationKey(e)) {
160
+ return;
161
+ }
162
+
163
+ if (to || href) {
164
+ preventAndStop(e);
165
+ goto((to || href) as string);
166
+ return;
167
+ }
168
+
169
+ if (expandIconToggle) {
170
+ // If expandIconToggle is true, we don't want to toggle the expansion item
171
+ // as the icon should do it
172
+ return;
173
+ }
174
+
175
+ e.preventDefault();
176
+ toggle();
177
+ }
178
+
179
+ function onIconKeydown(e: KeyboardEvent) {
180
+ if (disabled) {
181
+ preventAndStop(e);
182
+ return;
183
+ }
184
+
185
+ if (e.key === "Escape") {
186
+ (e.target as HTMLElement)?.blur();
187
+ return;
188
+ }
189
+
190
+ if (!isActivationKey(e) || !expandIconToggle) {
191
+ return;
192
+ }
193
+
194
+ preventAndStop(e);
195
+
196
+ const clickEvent = new MouseEvent("click", {
197
+ relatedTarget: e.target as HTMLElement,
198
+ }) as QEvent<MouseEvent, HTMLElement>;
199
+ onIconClick(clickEvent);
200
+ }
201
+ // #endregion: --- Functions
202
+ </script>
203
+
204
+ {#snippet labelSnippet()}
205
+ {label}
206
+ {/snippet}
207
+
208
+ {#snippet captionSnippet()}
209
+ {caption}
210
+ {/snippet}
211
+
212
+ {#snippet content()}
213
+ {#if value}
214
+ <div
215
+ class="q-expansion-item__content"
216
+ {...contentAttributes}
217
+ transition:slide={{ duration }}
218
+ >
219
+ {@render children?.()}
220
+ </div>
221
+ {/if}
222
+ {/snippet}
223
+
224
+ <details
225
+ bind:this={detailsEl}
226
+ bind:open={value}
227
+ {...props}
228
+ {name}
229
+ aria-disabled={disabled || undefined}
230
+ class={["q-expansion-item", value && "q-expansion-item--expanded"]}
231
+ style:--duration="{duration}ms"
232
+ >
233
+ <summary
234
+ tabindex={-1}
235
+ {...summaryAttributes}
236
+ onmousedown={disabled ? preventAndStop : undefined}
237
+ >
238
+ {#if summary}
239
+ <QItem
240
+ {dense}
241
+ {to}
242
+ {href}
243
+ {disabled}
244
+ noRipple={expandIconToggle || noRipple}
245
+ clickable={!expandIconToggle}
246
+ {onclick}
247
+ {onkeydown}
248
+ >
249
+ {@render summary({ expanded: value, show, hide, toggle })}
250
+ </QItem>
251
+ {:else}
252
+ <QItem
253
+ {dense}
254
+ {to}
255
+ {href}
256
+ {disabled}
257
+ noRipple={expandIconToggle || noRipple}
258
+ clickable={!expandIconToggle}
259
+ {onclick}
260
+ {onkeydown}
261
+ >
262
+ {#if icon}
263
+ <QItemSection type="icon">
264
+ <QIcon name={icon} />
265
+ </QItemSection>
266
+ {/if}
267
+
268
+ {#if label || caption}
269
+ <QItemSection
270
+ headline={label ? labelSnippet : undefined}
271
+ line1={caption ? captionSnippet : undefined}
272
+ />
273
+ {/if}
274
+
275
+ {#if !hideExpandIcon}
276
+ <QItemSection type="trailingIcon">
277
+ {#if expandIconToggle}
278
+ <QBtn
279
+ class={[
280
+ "q-expansion-item__toggle-icon",
281
+ value &&
282
+ !expandedIcon &&
283
+ !noRotateExpandIcon &&
284
+ "q-expansion-item__toggle-icon--rotate",
285
+ ]}
286
+ {...iconAttributes}
287
+ {disabled}
288
+ color="on-surface"
289
+ tag="div"
290
+ tabindex={0}
291
+ onclick={onIconClick}
292
+ onkeydowncapture={onIconKeydown}
293
+ />
294
+ {:else}
295
+ <QIcon
296
+ class={[
297
+ "q-expansion-item__toggle-icon",
298
+ value &&
299
+ !expandedIcon &&
300
+ !noRotateExpandIcon &&
301
+ "q-expansion-item__toggle-icon--rotate",
302
+ ]}
303
+ {...iconAttributes}
304
+ />
305
+ {/if}
306
+ </QItemSection>
307
+ {/if}
308
+ </QItem>
309
+ {/if}
310
+ </summary>
311
+
312
+ {#if supportDetailsContent}
313
+ {@render content()}
314
+ {/if}
315
+ </details>
316
+
317
+ {#if !supportDetailsContent}
318
+ {@render content()}
319
+ {/if}
@@ -0,0 +1,8 @@
1
+ import type { QExpansionItemProps } from "./props";
2
+ declare const QExpansionItem: import("svelte").Component<QExpansionItemProps, {
3
+ toggle: () => void;
4
+ show: () => void;
5
+ hide: () => void;
6
+ }, "value">;
7
+ type QExpansionItem = ReturnType<typeof QExpansionItem>;
8
+ export default QExpansionItem;
@@ -0,0 +1,2 @@
1
+ import type { QComponentDocs } from "../../utils";
2
+ export declare const QExpansionItemDocs: QComponentDocs;
@@ -0,0 +1,17 @@
1
+ import { QExpansionItemDocsProps, QExpansionItemDocsSnippets } from "./docs.props";
2
+ export const QExpansionItemDocs = {
3
+ name: "QExpansionItem",
4
+ description: "The QExpansionItem component allows users to create expandable/collapsible sections within a list or a card.",
5
+ docs: {
6
+ props: QExpansionItemDocsProps,
7
+ snippets: QExpansionItemDocsSnippets,
8
+ methods: [],
9
+ events: [
10
+ {
11
+ name: "click",
12
+ type: "(e: MouseEvent) => void",
13
+ description: "Emitted when the user clicks on the expansion item.",
14
+ },
15
+ ],
16
+ },
17
+ };
@@ -0,0 +1,129 @@
1
+ import { MaterialSymbol } from "material-symbols";
2
+ import { Snippet } from "svelte";
3
+ import { HTMLDetailsAttributes, MouseEventHandler } from "svelte/elements";
4
+ export interface QExpansionItemProps extends HTMLDetailsAttributes {
5
+ /**
6
+ * The value of the expansion item, used to define the expansion state of the item.
7
+ */
8
+ value?: boolean;
9
+ /**
10
+ * The label of the expansion item, displayed in the header.
11
+ */
12
+ label?: string;
13
+ /**
14
+ * The icon to display in the header of the expansion item.
15
+ */
16
+ icon?: MaterialSymbol;
17
+ /**
18
+ * The caption, displayed below the label in the header.
19
+ */
20
+ caption?: string;
21
+ /**
22
+ * The icon to use as the toggle icon for the expansion item.
23
+ * If not provided, a chevron icon will be used.
24
+ *
25
+ * @default "chevron_down"
26
+ */
27
+ expandIcon?: MaterialSymbol;
28
+ /**
29
+ * The icon to use as the collapse icon for the expanded item.
30
+ * If not provided, the expandIcon will be rotated 180 degrees when the item is expanded.
31
+ */
32
+ expandedIcon?: MaterialSymbol;
33
+ /**
34
+ * Whether the expansion item is initially expanded.
35
+ *
36
+ * @default false
37
+ */
38
+ defaultOpened?: boolean;
39
+ /**
40
+ * Use the dense style for the expansion item, reducing its height.
41
+ *
42
+ * @default false
43
+ */
44
+ dense?: boolean;
45
+ /**
46
+ * Duration for the expansion animation in milliseconds.
47
+ *
48
+ * @default 300
49
+ */
50
+ duration?: number;
51
+ /**
52
+ * Whether to hide the expand icon.
53
+ *
54
+ * @default false
55
+ */
56
+ hideExpandIcon?: boolean;
57
+ /**
58
+ * Register the expansion item into a group, closing other items in the group when this one is opened.
59
+ * This is often called "accordion" behavior. This name is used to identify the group of items
60
+ * and should thus be unique.
61
+ */
62
+ name?: string;
63
+ /**
64
+ * The aria-label for the toggle button of the expansion item for accessibility.
65
+ *
66
+ * @default "Open details"
67
+ */
68
+ toggleAriaLabel?: string;
69
+ /**
70
+ * Makes the toggle icon the trigger for the expansion item instead of the whole header.
71
+ * This is useful when using the expansion item as link, so the icon allows to expand/collapse the item
72
+ * while the header changes the route.
73
+ *
74
+ * @default false
75
+ */
76
+ expandIconToggle?: boolean;
77
+ /**
78
+ * Make the expansion item navigational, allowing it to be used as a link.
79
+ * It can be used interchangeably with the `href` prop.
80
+ * If both `href` and `to` are provided, the `to` prop will take precedence.
81
+ */
82
+ to?: string;
83
+ /**
84
+ * The URL to navigate to when the expansion item is clicked.
85
+ * It can be used interchangeably with the `to` prop.
86
+ * If both `href` and `to` are provided, the `to` prop will take precedence.
87
+ */
88
+ href?: string;
89
+ /**
90
+ * Prevents the rotation of the expand icon when the item is expanded.
91
+ * This is useful when using a custom icon that does not need to be rotated.
92
+ *
93
+ * @default false
94
+ */
95
+ noRotateExpandIcon?: boolean;
96
+ /**
97
+ * Whether the expansion item is disabled.
98
+ *
99
+ * @default false
100
+ */
101
+ disabled?: boolean;
102
+ /**
103
+ * Disables the ripple effect on the expansion item.
104
+ * This is useful when the item is used as a link and you want to prevent the ripple effect.
105
+ *
106
+ * @default false
107
+ */
108
+ noRipple?: boolean;
109
+ /**
110
+ * The summary snippet, to override the default header.
111
+ * As the header uses QItem, you can easily use QItemSection components to customize the header layout.
112
+ */
113
+ summary?: Snippet<[
114
+ {
115
+ expanded: boolean;
116
+ show: () => void;
117
+ hide: () => void;
118
+ toggle: () => void;
119
+ }
120
+ ]>;
121
+ /**
122
+ * Event triggered when the expansion icon is clicked.
123
+ */
124
+ onExpandIconClick?: MouseEventHandler<HTMLElement>;
125
+ /**
126
+ * Event triggered when the expansion item is clicked.
127
+ */
128
+ onclick?: MouseEventHandler<HTMLElement>;
129
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -22,7 +22,7 @@
22
22
  background-color: var(--surface);
23
23
 
24
24
  &.q-footer--bordered {
25
- @include mixins.border(var(--outline), "top");
25
+ @include mixins.border($position: "top");
26
26
  }
27
27
 
28
28
  &.q-footer--collapsed {
@@ -1,14 +1,10 @@
1
1
  <script lang="ts">
2
- import { getContext, onMount, untrack } from "svelte";
3
- import { QScrollObserver } from "../..";
4
- import { QContext } from "../../classes/QContext.svelte";
5
- import { QLayoutCtxName } from "../../utils";
6
- import type { QLayoutProps } from "../layout/props";
7
- import type { AppbarContext } from "../layout/QLayout.svelte";
2
+ import { onMount } from "svelte";
3
+ import { useRevealScrollObserver } from "../../composables";
4
+ import { footerCtx } from "../layout/QLayout.svelte";
8
5
  import type { QFooterProps } from "./props";
9
6
 
10
- let footerEl = $state<HTMLElement>();
11
-
7
+ // #region: --- Props
12
8
  let {
13
9
  value = $bindable(true),
14
10
  bordered = false,
@@ -18,44 +14,51 @@
18
14
  children,
19
15
  ...props
20
16
  }: QFooterProps = $props();
17
+ // #endregion: --- Props
21
18
 
19
+ // #region: --- Non-reactive variables
22
20
  const uid = $props.id();
21
+ // #endregion: --- Non-reactive variables
22
+
23
+ // #region: --- Reactive variables
24
+ let footerEl = $state<HTMLElement>();
25
+ let contentScrollHeight = $state(0);
23
26
 
24
- const footerContext = QContext.get<AppbarContext>(QLayoutCtxName.footer);
25
- const layoutView = getContext<{ value: NonNullable<QLayoutProps["view"]> }>(
26
- QLayoutCtxName.view,
27
+ const footerContext = footerCtx.assertGet(
28
+ "QFooter should be used inside QLayout",
27
29
  );
30
+ // #endregion: --- Reactive variables
28
31
 
29
- if (!footerContext || !layoutView) {
30
- throw new Error("QFooter should be used inside QLayout");
31
- }
32
+ // #region: --- Derived values
33
+ const revealObserver = useRevealScrollObserver("footer", uid, () => reveal);
34
+ const revealScroll = $derived(revealObserver.scroll);
32
35
 
33
- const scroll = $derived(
34
- reveal
35
- ? new QScrollObserver(`.q-footer--${uid} ~ .q-layout__content`)
36
- : undefined,
36
+ const offset = $derived(
37
+ revealScroll ? revealScroll.position + height : undefined,
37
38
  );
38
- let contentScrollHeight = $state(0);
39
39
 
40
- const offset = $derived(scroll ? scroll.position + height : undefined);
41
- // Collapse the footer `${reavealOffset}px` above the bottom of layout content when scrolling up
40
+ // Collapse the footer `${revealOffset}px` above the bottom of layout content when scrolling up
42
41
  const collapsed = $derived(
43
42
  reveal &&
44
- scroll?.direction === "up" &&
43
+ revealScroll?.direction === "up" &&
45
44
  offset! + revealOffset < contentScrollHeight,
46
45
  );
47
46
 
48
- const leftOffset = () => layoutView.value.charAt(8) === "l";
49
- const rightOffset = () => layoutView.value.charAt(10) === "r";
47
+ const leftOffset = $derived(footerContext.view.charAt(8) === "l");
48
+ const rightOffset = $derived(footerContext.view.charAt(10) === "r");
49
+ // #endregion: --- Derived values
50
50
 
51
+ // #region: --- Effects
51
52
  $effect.pre(() => {
52
- untrack(() => footerContext).updateEntries({
53
+ footerCtx.updateEntries({
53
54
  height,
54
55
  collapsed,
55
56
  ready: true,
56
57
  });
57
58
  });
59
+ // #endregion: --- Effects
58
60
 
61
+ // #region: --- Lifecycle
59
62
  onMount(() => {
60
63
  // Calculating the layout content's height
61
64
  const content = document.querySelector(
@@ -73,13 +76,14 @@
73
76
  }, 100);
74
77
 
75
78
  return () => {
76
- footerContext.updateEntries({
79
+ footerCtx.updateEntries({
77
80
  height: 0,
78
81
  collapsed: false,
79
82
  ready: false,
80
83
  });
81
84
  };
82
85
  });
86
+ // #endregion: --- Lifecycle
83
87
  </script>
84
88
 
85
89
  {#if value}
@@ -92,8 +96,8 @@
92
96
  `q-footer--${uid}`,
93
97
  collapsed && "q-footer--collapsed",
94
98
  bordered && "q-footer--bordered",
95
- leftOffset() && "q-footer--offset-left",
96
- rightOffset() && "q-footer--offset-right",
99
+ leftOffset && "q-footer--offset-left",
100
+ rightOffset && "q-footer--offset-right",
97
101
  ]}
98
102
  style:--footer-height="{height}px"
99
103
  data-quaff
@@ -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 QFooterProps_ = typeof __propDef.props;
10
- export { QFooterProps_ as QFooterProps };
11
- export type QFooterEvents = typeof __propDef.events;
12
- export type QFooterSlots = typeof __propDef.slots;
13
- export default class QFooter extends SvelteComponentTyped<QFooterProps_, QFooterEvents, QFooterSlots> {
14
- }
1
+ import type { QFooterProps } from "./props";
2
+ declare const QFooter: import("svelte").Component<QFooterProps, {}, "value">;
3
+ type QFooter = ReturnType<typeof QFooter>;
4
+ export default QFooter;
@@ -30,7 +30,7 @@
30
30
  }
31
31
 
32
32
  &.q-header--bordered {
33
- @include mixins.border(var(--outline), "bottom");
33
+ @include mixins.border($position: "bottom");
34
34
  }
35
35
 
36
36
  &.q-header--dense {