@quaffui/quaff 1.0.0-beta3 → 1.0.0-beta5

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 (31) hide show
  1. package/dist/components/breadcrumbs/QBreadcrumbs.scss +9 -5
  2. package/dist/components/breadcrumbs/QBreadcrumbs.svelte +15 -14
  3. package/dist/components/breadcrumbs/QBreadcrumbsEl.scss +22 -3
  4. package/dist/components/breadcrumbs/QBreadcrumbsEl.svelte +45 -36
  5. package/dist/components/breadcrumbs/docs.props.js +3 -7
  6. package/dist/components/breadcrumbs/props.d.ts +4 -4
  7. package/dist/components/button/QBtn.svelte +13 -7
  8. package/dist/components/button/docs.props.js +27 -3
  9. package/dist/components/button/props.d.ts +9 -2
  10. package/dist/components/expansion-item/QExpansionItem.scss +46 -0
  11. package/dist/components/expansion-item/QExpansionItem.svelte +300 -0
  12. package/dist/components/expansion-item/QExpansionItem.svelte.d.ts +21 -0
  13. package/dist/components/expansion-item/docs.d.ts +2 -0
  14. package/dist/components/expansion-item/docs.js +17 -0
  15. package/dist/components/expansion-item/docs.props.d.ts +3 -0
  16. package/dist/components/expansion-item/docs.props.js +280 -0
  17. package/dist/components/expansion-item/props.d.ts +129 -0
  18. package/dist/components/expansion-item/props.js +1 -0
  19. package/dist/components/index.d.ts +2 -1
  20. package/dist/components/index.js +2 -1
  21. package/dist/components/list/QItem.svelte +1 -0
  22. package/dist/components/select/QSelect.svelte +38 -24
  23. package/dist/components/select/docs.props.js +13 -1
  24. package/dist/components/select/props.d.ts +10 -6
  25. package/dist/components/table/QTable.svelte +8 -6
  26. package/dist/css/_components.scss +1 -0
  27. package/dist/css/index.css +1 -1
  28. package/dist/helpers/version.d.ts +1 -1
  29. package/dist/helpers/version.js +1 -1
  30. package/dist/utils/types.json +2 -4
  31. package/package.json +1 -1
@@ -0,0 +1,300 @@
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
+ let {
9
+ value = $bindable(false),
10
+ label,
11
+ icon,
12
+ caption,
13
+ expandIcon = "keyboard_arrow_down",
14
+ expandedIcon,
15
+ defaultOpened = false,
16
+ dense = false,
17
+ duration = 300,
18
+ hideExpandIcon = false,
19
+ toggleAriaLabel = "Open details",
20
+ expandIconToggle = false,
21
+ to,
22
+ href,
23
+ name,
24
+ noRotateExpandIcon = false,
25
+ disabled = false,
26
+ noRipple = false,
27
+ summary,
28
+ children,
29
+ onExpandIconClick,
30
+ ...props
31
+ }: QExpansionItemProps = $props();
32
+
33
+ const id = $props.id();
34
+ const contentId = `q-expansion-item__content-${id}`;
35
+ const summaryId = `q-expansion-item__summary-${id}`;
36
+
37
+ const supportDetailsContent = CSS.supports(
38
+ "selector(details::details-content)",
39
+ );
40
+
41
+ const summaryAttributes = $derived(
42
+ !supportDetailsContent
43
+ ? {
44
+ id: summaryId,
45
+ "aria-expanded": value,
46
+ "aria-controls": contentId,
47
+ }
48
+ : {},
49
+ );
50
+
51
+ const contentAttributes = $derived(
52
+ !supportDetailsContent
53
+ ? {
54
+ id: contentId,
55
+ role: "region",
56
+ "aria-labelledby": summaryId,
57
+ }
58
+ : {},
59
+ );
60
+
61
+ let detailsEl = $state<HTMLDetailsElement>();
62
+
63
+ const iconAttributes = $derived({
64
+ [expandIconToggle ? "icon" : "name"]:
65
+ expandedIcon && value ? expandedIcon : expandIcon,
66
+ flat: expandIconToggle || undefined,
67
+ "aria-label": toggleAriaLabel,
68
+ });
69
+
70
+ $effect.pre(() => {
71
+ if (defaultOpened) {
72
+ show();
73
+ }
74
+ });
75
+
76
+ $effect(() => {
77
+ if (supportDetailsContent || !name || !value) {
78
+ return;
79
+ }
80
+
81
+ // If the browser does not support details content, we need to manually
82
+ // handle the group open state of the details elements
83
+ const parent = detailsEl?.parentElement;
84
+
85
+ if (!parent) {
86
+ return;
87
+ }
88
+
89
+ const group = parent.querySelectorAll("details[open]");
90
+ group.forEach((item) => {
91
+ if (item !== detailsEl) {
92
+ item.removeAttribute("open");
93
+ }
94
+ });
95
+ });
96
+
97
+ export function toggle() {
98
+ value = !value;
99
+ }
100
+
101
+ export function show() {
102
+ value = true;
103
+ }
104
+
105
+ export function hide() {
106
+ value = false;
107
+ }
108
+
109
+ function onclick(e: QEvent<MouseEvent, HTMLElement>) {
110
+ console.log("QExpansionItem: onclick", e);
111
+ if (disabled) {
112
+ e.preventDefault();
113
+ e.stopPropagation();
114
+ return;
115
+ }
116
+
117
+ props.onclick?.(e);
118
+ }
119
+
120
+ function onIconClick(e: QEvent<MouseEvent, HTMLElement>) {
121
+ if (disabled) {
122
+ e.preventDefault();
123
+ return;
124
+ }
125
+
126
+ e.stopPropagation();
127
+ e.preventDefault();
128
+
129
+ toggle();
130
+ onExpandIconClick?.(e);
131
+ }
132
+
133
+ function onkeydown(e: KeyboardEvent) {
134
+ if (disabled) {
135
+ e.preventDefault();
136
+ return;
137
+ }
138
+
139
+ if (e.key === "Escape") {
140
+ detailsEl?.blur();
141
+ return;
142
+ }
143
+
144
+ if (!isActivationKey(e)) {
145
+ return;
146
+ }
147
+
148
+ if (to || href) {
149
+ e.preventDefault();
150
+ goto((to || href) as string);
151
+ return;
152
+ }
153
+
154
+ if (expandIconToggle) {
155
+ // If expandIconToggle is true, we don't want to toggle the expansion item
156
+ // as the icon should do it
157
+ return;
158
+ }
159
+
160
+ e.preventDefault();
161
+ toggle();
162
+ }
163
+
164
+ function onIconKeydown(e: KeyboardEvent) {
165
+ if (disabled) {
166
+ e.preventDefault();
167
+ return;
168
+ }
169
+
170
+ if (e.key === "Escape") {
171
+ (e.target as HTMLElement)?.blur();
172
+ return;
173
+ }
174
+
175
+ if (!isActivationKey(e) || !expandIconToggle) {
176
+ return;
177
+ }
178
+
179
+ e.preventDefault();
180
+ e.stopPropagation();
181
+
182
+ const clickEvent = new MouseEvent("click", {
183
+ relatedTarget: e.target as HTMLElement,
184
+ }) as QEvent<MouseEvent, HTMLElement>;
185
+ onIconClick(clickEvent);
186
+ }
187
+ </script>
188
+
189
+ {#snippet labelSnippet()}
190
+ {label}
191
+ {/snippet}
192
+
193
+ {#snippet captionSnippet()}
194
+ {caption}
195
+ {/snippet}
196
+
197
+ {#snippet content()}
198
+ {#if value}
199
+ <div
200
+ class="q-expansion-item__content"
201
+ {...contentAttributes}
202
+ transition:slide={{ duration }}
203
+ >
204
+ {@render children?.()}
205
+ </div>
206
+ {/if}
207
+ {/snippet}
208
+
209
+ <details
210
+ bind:this={detailsEl}
211
+ bind:open={value}
212
+ {...props}
213
+ {name}
214
+ aria-disabled={disabled}
215
+ class={["q-expansion-item", value && "q-expansion-item--expanded"]}
216
+ style:--duration="{duration}ms"
217
+ >
218
+ <summary tabindex="-1" {...summaryAttributes}>
219
+ {#if summary}
220
+ <QItem
221
+ {dense}
222
+ {to}
223
+ {href}
224
+ {disabled}
225
+ noRipple={expandIconToggle || noRipple}
226
+ clickable={!expandIconToggle}
227
+ {onclick}
228
+ {onkeydown}
229
+ >
230
+ {@render summary({ expanded: value, show, hide, toggle })}
231
+ </QItem>
232
+ {:else}
233
+ <QItem
234
+ {dense}
235
+ {to}
236
+ {href}
237
+ {disabled}
238
+ noRipple={expandIconToggle || noRipple}
239
+ clickable={!expandIconToggle}
240
+ {onclick}
241
+ {onkeydown}
242
+ >
243
+ {#if icon}
244
+ <QItemSection type="icon">
245
+ <QIcon name={icon} />
246
+ </QItemSection>
247
+ {/if}
248
+
249
+ {#if label || caption}
250
+ <QItemSection
251
+ headline={label ? labelSnippet : undefined}
252
+ line1={caption ? captionSnippet : undefined}
253
+ />
254
+ {/if}
255
+
256
+ {#if !hideExpandIcon}
257
+ <QItemSection type="trailingIcon">
258
+ {#if expandIconToggle}
259
+ <QBtn
260
+ class={[
261
+ "q-expansion-item__toggle-icon",
262
+ value &&
263
+ !expandedIcon &&
264
+ !noRotateExpandIcon &&
265
+ "q-expansion-item__toggle-icon--rotate",
266
+ ]}
267
+ {...iconAttributes}
268
+ {disabled}
269
+ color="on-surface"
270
+ tag="div"
271
+ tabindex={0}
272
+ onclick={onIconClick}
273
+ onkeydowncapture={onIconKeydown}
274
+ />
275
+ {:else}
276
+ <QIcon
277
+ class={[
278
+ "q-expansion-item__toggle-icon",
279
+ value &&
280
+ !expandedIcon &&
281
+ !noRotateExpandIcon &&
282
+ "q-expansion-item__toggle-icon--rotate",
283
+ ]}
284
+ {...iconAttributes}
285
+ />
286
+ {/if}
287
+ </QItemSection>
288
+ {/if}
289
+ </QItem>
290
+ {/if}
291
+ </summary>
292
+
293
+ {#if supportDetailsContent}
294
+ {@render content()}
295
+ {/if}
296
+ </details>
297
+
298
+ {#if !supportDetailsContent}
299
+ {@render content()}
300
+ {/if}
@@ -0,0 +1,21 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ toggle?: () => void;
5
+ show?: () => void;
6
+ hide?: () => void;
7
+ };
8
+ events: {
9
+ [evt: string]: CustomEvent<any>;
10
+ };
11
+ slots: {};
12
+ };
13
+ type QExpansionItemProps_ = typeof __propDef.props;
14
+ export { QExpansionItemProps_ as QExpansionItemProps };
15
+ export type QExpansionItemEvents = typeof __propDef.events;
16
+ export type QExpansionItemSlots = typeof __propDef.slots;
17
+ export default class QExpansionItem extends SvelteComponentTyped<QExpansionItemProps_, QExpansionItemEvents, QExpansionItemSlots> {
18
+ get toggle(): () => void;
19
+ get show(): () => void;
20
+ get hide(): () => void;
21
+ }
@@ -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,3 @@
1
+ import { ParsedProp, ParsedSnippet } from "../../../../docgen/props/parseInterface";
2
+ export declare const QExpansionItemDocsProps: ParsedProp[];
3
+ export declare const QExpansionItemDocsSnippets: ParsedSnippet[];
@@ -0,0 +1,280 @@
1
+ // AUTO GENERATED FILE - DO NOT MODIFY OR DELETE
2
+ // @quaffHash ccfbfbd518f70dccf3dc979f494134eb
3
+ export const QExpansionItemDocsProps = [
4
+ {
5
+ isArray: false,
6
+ optional: true,
7
+ isSnippet: false,
8
+ name: "value",
9
+ type: {
10
+ name: "boolean",
11
+ isClickable: false,
12
+ },
13
+ description: "The value of the expansion item, used to define the expansion state of the item.",
14
+ default: "",
15
+ },
16
+ {
17
+ isArray: false,
18
+ optional: true,
19
+ isSnippet: false,
20
+ name: "label",
21
+ type: {
22
+ name: "string",
23
+ isClickable: false,
24
+ },
25
+ description: "The label of the expansion item, displayed in the header.",
26
+ default: "",
27
+ },
28
+ {
29
+ isArray: false,
30
+ optional: true,
31
+ isSnippet: false,
32
+ name: "icon",
33
+ type: {
34
+ name: "MaterialSymbol",
35
+ isClickable: false,
36
+ },
37
+ description: "The icon to display in the header of the expansion item.",
38
+ default: "",
39
+ },
40
+ {
41
+ isArray: false,
42
+ optional: true,
43
+ isSnippet: false,
44
+ name: "caption",
45
+ type: {
46
+ name: "string",
47
+ isClickable: false,
48
+ },
49
+ description: "The caption, displayed below the label in the header.",
50
+ default: "",
51
+ },
52
+ {
53
+ isArray: false,
54
+ optional: true,
55
+ isSnippet: false,
56
+ name: "expandIcon",
57
+ type: {
58
+ name: "MaterialSymbol",
59
+ isClickable: false,
60
+ },
61
+ description: "The icon to use as the toggle icon for the expansion item.\nIf not provided, a chevron icon will be used.",
62
+ default: '"chevron_down"',
63
+ },
64
+ {
65
+ isArray: false,
66
+ optional: true,
67
+ isSnippet: false,
68
+ name: "expandedIcon",
69
+ type: {
70
+ name: "MaterialSymbol",
71
+ isClickable: false,
72
+ },
73
+ description: "The icon to use as the collapse icon for the expanded item.\nIf not provided, the expandIcon will be rotated 180 degrees when the item is expanded.",
74
+ default: "",
75
+ },
76
+ {
77
+ isArray: false,
78
+ optional: true,
79
+ isSnippet: false,
80
+ name: "defaultOpened",
81
+ type: {
82
+ name: "boolean",
83
+ isClickable: false,
84
+ },
85
+ description: "Whether the expansion item is initially expanded.",
86
+ default: "false",
87
+ },
88
+ {
89
+ isArray: false,
90
+ optional: true,
91
+ isSnippet: false,
92
+ name: "dense",
93
+ type: {
94
+ name: "boolean",
95
+ isClickable: false,
96
+ },
97
+ description: "Use the dense style for the expansion item, reducing its height.",
98
+ default: "false",
99
+ },
100
+ {
101
+ isArray: false,
102
+ optional: true,
103
+ isSnippet: false,
104
+ name: "duration",
105
+ type: {
106
+ name: "number",
107
+ isClickable: false,
108
+ },
109
+ description: "Duration for the expansion animation in milliseconds.",
110
+ default: "300",
111
+ },
112
+ {
113
+ isArray: false,
114
+ optional: true,
115
+ isSnippet: false,
116
+ name: "hideExpandIcon",
117
+ type: {
118
+ name: "boolean",
119
+ isClickable: false,
120
+ },
121
+ description: "Whether to hide the expand icon.",
122
+ default: "false",
123
+ },
124
+ {
125
+ isArray: false,
126
+ optional: true,
127
+ isSnippet: false,
128
+ name: "name",
129
+ type: {
130
+ name: "string",
131
+ isClickable: false,
132
+ },
133
+ description: 'Register the expansion item into a group, closing other items in the group when this one is opened.\nThis is often called "accordion" behavior. This name is used to identify the group of items\nand should thus be unique.',
134
+ default: "",
135
+ },
136
+ {
137
+ isArray: false,
138
+ optional: true,
139
+ isSnippet: false,
140
+ name: "toggleAriaLabel",
141
+ type: {
142
+ name: "string",
143
+ isClickable: false,
144
+ },
145
+ description: "The aria-label for the toggle button of the expansion item for accessibility.",
146
+ default: '"Open details"',
147
+ },
148
+ {
149
+ isArray: false,
150
+ optional: true,
151
+ isSnippet: false,
152
+ name: "expandIconToggle",
153
+ type: {
154
+ name: "boolean",
155
+ isClickable: false,
156
+ },
157
+ description: "Makes the toggle icon the trigger for the expansion item instead of the whole header.\nThis is useful when using the expansion item as link, so the icon allows to expand/collapse the item\nwhile the header changes the route.",
158
+ default: "false",
159
+ },
160
+ {
161
+ isArray: false,
162
+ optional: true,
163
+ isSnippet: false,
164
+ name: "to",
165
+ type: {
166
+ name: "string",
167
+ isClickable: false,
168
+ },
169
+ description: "Make the expansion item navigational, allowing it to be used as a link.\nIt can be used interchangeably with the `href` prop.\nIf both `href` and `to` are provided, the `to` prop will take precedence.",
170
+ default: "",
171
+ },
172
+ {
173
+ isArray: false,
174
+ optional: true,
175
+ isSnippet: false,
176
+ name: "href",
177
+ type: {
178
+ name: "string",
179
+ isClickable: false,
180
+ },
181
+ description: "The URL to navigate to when the expansion item is clicked.\nIt can be used interchangeably with the `to` prop.\nIf both `href` and `to` are provided, the `to` prop will take precedence.",
182
+ default: "",
183
+ },
184
+ {
185
+ isArray: false,
186
+ optional: true,
187
+ isSnippet: false,
188
+ name: "noRotateExpandIcon",
189
+ type: {
190
+ name: "boolean",
191
+ isClickable: false,
192
+ },
193
+ description: "Prevents the rotation of the expand icon when the item is expanded.\nThis is useful when using a custom icon that does not need to be rotated.",
194
+ default: "false",
195
+ },
196
+ {
197
+ isArray: false,
198
+ optional: true,
199
+ isSnippet: false,
200
+ name: "disabled",
201
+ type: {
202
+ name: "boolean",
203
+ isClickable: false,
204
+ },
205
+ description: "Whether the expansion item is disabled.",
206
+ default: "false",
207
+ },
208
+ {
209
+ isArray: false,
210
+ optional: true,
211
+ isSnippet: false,
212
+ name: "noRipple",
213
+ type: {
214
+ name: "boolean",
215
+ isClickable: false,
216
+ },
217
+ description: "Disables the ripple effect on the expansion item.\nThis is useful when the item is used as a link and you want to prevent the ripple effect.",
218
+ default: "false",
219
+ },
220
+ {
221
+ isArray: false,
222
+ optional: true,
223
+ isSnippet: false,
224
+ name: "onExpandIconClick",
225
+ type: {
226
+ name: "MouseEventHandler<HTMLElement>",
227
+ isClickable: false,
228
+ },
229
+ description: "Event triggered when the expansion icon is clicked.",
230
+ default: "",
231
+ },
232
+ {
233
+ isArray: false,
234
+ optional: true,
235
+ isSnippet: false,
236
+ name: "onclick",
237
+ type: {
238
+ name: "MouseEventHandler<HTMLElement>",
239
+ isClickable: false,
240
+ },
241
+ description: "Event triggered when the expansion item is clicked.",
242
+ default: "",
243
+ },
244
+ ];
245
+ export const QExpansionItemDocsSnippets = [
246
+ {
247
+ isArray: false,
248
+ optional: true,
249
+ isSnippet: true,
250
+ name: "summary",
251
+ type: [
252
+ {
253
+ propName: "expanded",
254
+ isClickable: false,
255
+ optional: false,
256
+ name: "boolean",
257
+ },
258
+ {
259
+ propName: "show",
260
+ isClickable: false,
261
+ optional: false,
262
+ name: "() => void",
263
+ },
264
+ {
265
+ propName: "hide",
266
+ isClickable: false,
267
+ optional: false,
268
+ name: "() => void",
269
+ },
270
+ {
271
+ propName: "toggle",
272
+ isClickable: false,
273
+ optional: false,
274
+ name: "() => void",
275
+ },
276
+ ],
277
+ description: "The summary snippet, to override the default header.\nAs the header uses QItem, you can easily use QItemSection components to customize the header layout.",
278
+ default: "",
279
+ },
280
+ ];