@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
@@ -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,5 +1,5 @@
1
1
  <script lang="ts">
2
- import { setContext, untrack } from "svelte";
2
+ import { onMount, setContext } from "svelte";
3
3
  import { QBreadcrumbsCtxName } from "../../utils";
4
4
  import type { QBreadcrumbsProps } from "./props";
5
5
 
@@ -12,25 +12,26 @@
12
12
  ...props
13
13
  }: QBreadcrumbsProps = $props();
14
14
 
15
- let breadrumbElement: HTMLDivElement;
15
+ let breadcrumbList: HTMLOListElement;
16
16
 
17
- $effect(() => {
18
- untrack(() => breadrumbElement.firstChild?.remove());
17
+ onMount(() => {
18
+ breadcrumbList
19
+ .querySelector(".q-breadcrumbs__separator:first-child")
20
+ ?.remove();
19
21
  });
20
22
 
21
- setContext(QBreadcrumbsCtxName.activeColor, activeColor);
22
- setContext(QBreadcrumbsCtxName.separator, {
23
- type: separator,
24
- color: separatorColor,
25
- gutter,
26
- });
23
+ setContext(QBreadcrumbsCtxName.separator, { type: separator, gutter });
27
24
  </script>
28
25
 
29
- <div
30
- bind:this={breadrumbElement}
26
+ <nav
31
27
  {...props}
32
28
  class={["q-breadcrumbs", props.class]}
29
+ aria-label="Breadcrumbs"
33
30
  data-quaff
31
+ style:--q-separator-color="var(--{separatorColor}, {separatorColor})"
32
+ style:--q-active-color="var(--{activeColor}, {activeColor})"
34
33
  >
35
- {@render children?.()}
36
- </div>
34
+ <ol bind:this={breadcrumbList} class="q-breadcrumbs__list">
35
+ {@render children?.()}
36
+ </ol>
37
+ </nav>
@@ -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,27 @@
1
1
  <script lang="ts">
2
- import { getContext, type Snippet } from "svelte";
2
+ import { getContext } from "svelte";
3
3
  import { QIcon } from "../..";
4
4
  import { isRouteActive, QBreadcrumbsCtxName } from "../../utils";
5
5
  import type { MaterialSymbol } from "material-symbols";
6
- import type { QBreadcrumbsElProps } from "./props";
6
+ import type { QBreadcrumbsElProps, QBreadcrumbsProps } from "./props";
7
7
 
8
8
  let {
9
9
  activeClass = "active",
10
10
  href,
11
11
  label = "",
12
12
  icon,
13
- tag = "div",
13
+ tag = "span",
14
14
  to,
15
15
  children = fallback,
16
16
  ...props
17
17
  }: QBreadcrumbsElProps = $props();
18
18
 
19
- const activeColor = getContext<string>(QBreadcrumbsCtxName.activeColor);
20
19
  const separator = getContext<{
21
- type: `icon:${MaterialSymbol}` | Snippet;
22
- color: string;
23
- gutter: string;
20
+ type: QBreadcrumbsProps["separator"];
21
+ gutter: QBreadcrumbsProps["gutter"];
24
22
  }>(QBreadcrumbsCtxName.separator);
25
23
 
26
- const classesIfActive = $derived(
27
- isRouteActive(href || to)
28
- ? `${activeClass} text-${activeColor}`
29
- : undefined,
30
- );
24
+ const isActive = $derived(isRouteActive(href || to));
31
25
  </script>
32
26
 
33
27
  {#snippet fallback()}
@@ -39,38 +33,53 @@
39
33
  {#if typeof icon === "string"}
40
34
  <QIcon name={icon} size="1rem" />
41
35
  {:else}
42
- {@render icon()}
36
+ <span class="q-icon">
37
+ {@render icon()}
38
+ </span>
43
39
  {/if}
44
40
  {/if}
45
41
 
46
- {@render children()}
42
+ <span class="q-breadcrumbs__label">
43
+ {@render children()}
44
+ </span>
47
45
  {/snippet}
48
46
 
49
- <div
47
+ <li
50
48
  {...props}
51
- class={["q-breadcrumbs__separator", `q-px-${separator.gutter}`, props.class]}
52
- data-quaff
49
+ class={["q-breadcrumbs__item", props.class]}
50
+ style:--q-breadcrumbs-color={isActive ? "var(--q-active-color)" : undefined}
53
51
  >
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
- />
52
+ <span
53
+ class={["q-breadcrumbs__separator", `q-px-${separator.gutter}`]}
54
+ aria-hidden="true"
55
+ >
56
+ {#if typeof separator.type === "string"}
57
+ {#if separator.type.startsWith("icon:")}
58
+ <QIcon name={separator.type.slice(5) as MaterialSymbol} size="1rem" />
59
+ {:else}
60
+ {separator.type}
61
+ {/if}
60
62
  {:else}
61
- {separator.type}
63
+ {@render separator.type?.()}
62
64
  {/if}
65
+ </span>
66
+
67
+ {#if href || to}
68
+ <a
69
+ href={href || to}
70
+ class={["q-breadcrumbs__el", isActive && activeClass]}
71
+ aria-current={isActive ? "page" : undefined}
72
+ data-quaff
73
+ >
74
+ {@render breadcrumbEl()}
75
+ </a>
63
76
  {:else}
64
- {@render separator.type()}
77
+ <svelte:element
78
+ this={tag}
79
+ class={["q-breadcrumbs__el", isActive && activeClass]}
80
+ data-quaff
81
+ >
82
+ {@render breadcrumbEl()}
83
+ </svelte:element>
65
84
  {/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}
85
+ </li>
@@ -1,5 +1,5 @@
1
1
  // AUTO GENERATED FILE - DO NOT MODIFY OR DELETE
2
- // @quaffHash 66c85971b241303d63478c8c8bca6aa0
2
+ // @quaffHash ba78678fbdfaa1cac758b50914ab69b7
3
3
  export const QBreadcrumbsDocsProps = [
4
4
  {
5
5
  isArray: false,
@@ -32,11 +32,7 @@ export const QBreadcrumbsDocsProps = [
32
32
  name: "separator",
33
33
  type: [
34
34
  {
35
- name: "string",
36
- isClickable: false,
37
- },
38
- {
39
- name: "`icon:${MaterialSymbol}`",
35
+ name: "Q.StringWithSuggestions<`icon:${MaterialSymbol}`>",
40
36
  isClickable: false,
41
37
  },
42
38
  {
@@ -126,7 +122,7 @@ export const QBreadcrumbsElDocsProps = [
126
122
  isClickable: false,
127
123
  },
128
124
  description: "Tag to use for the breadcrumb element.",
129
- default: '"div"',
125
+ default: '"span"',
130
126
  },
131
127
  {
132
128
  isArray: false,
@@ -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
  /**
@@ -10,6 +10,7 @@
10
10
  let {
11
11
  disabled = false,
12
12
  variant,
13
+ color,
13
14
  filled = false,
14
15
  tonal = false,
15
16
  outlined = false,
@@ -25,17 +26,18 @@
25
26
  unelevated = false,
26
27
  size = "md",
27
28
  target,
29
+ tag,
28
30
  onclick,
29
31
  children,
30
32
  ...props
31
33
  }: QBtnProps = $props();
32
34
 
33
- let qBtn: HTMLButtonElement | HTMLAnchorElement;
35
+ let qBtn: HTMLElement;
34
36
  let qBtnLabel: HTMLSpanElement;
35
37
 
36
38
  type QBtnMouseEvent = QEvent<MouseEvent, typeof qBtn>;
37
39
 
38
- const tag = $derived(to ? "a" : "button");
40
+ const computedTag = $derived(to ? "a" : tag || "button");
39
41
  const qSize = $derived(useSize(size, "q-btn"));
40
42
 
41
43
  const src = $derived(extractImgSrc(icon));
@@ -57,11 +59,15 @@
57
59
  variant || boolVariant || "elevated",
58
60
  );
59
61
 
60
- const color = $derived.by(() => {
62
+ const computedColor = $derived.by(() => {
61
63
  if (disabled) {
62
64
  return undefined;
63
65
  }
64
66
 
67
+ if (color) {
68
+ return color;
69
+ }
70
+
65
71
  if (finalVariant === "filled") {
66
72
  return "on-primary";
67
73
  }
@@ -73,7 +79,7 @@
73
79
  return "primary";
74
80
  });
75
81
 
76
- const colorVar = $derived(color && `var(--${color})`);
82
+ const colorVar = $derived(computedColor && `var(--${computedColor})`);
77
83
 
78
84
  const rippleColorVar = $derived(
79
85
  rippleColor ? `var(--${rippleColor}, ${rippleColor})` : colorVar,
@@ -118,7 +124,7 @@
118
124
  </script>
119
125
 
120
126
  <svelte:element
121
- this={tag}
127
+ this={computedTag}
122
128
  bind:this={qBtn}
123
129
  use:ripple={{
124
130
  disabled: noRipple || disabled,
@@ -138,9 +144,9 @@
138
144
  style:--ripple-color={colorVar}
139
145
  {target}
140
146
  href={to}
141
- role={tag === "a" ? "button" : undefined}
147
+ role={computedTag === "a" ? "button" : undefined}
142
148
  aria-disabled={disabled || undefined}
143
- tabindex={disabled ? -1 : 0}
149
+ tabindex={disabled ? -1 : props.tabindex || 0}
144
150
  {onkeydown}
145
151
  onclick={stopIfDisabled}
146
152
  data-quaff
@@ -1,5 +1,5 @@
1
1
  // AUTO GENERATED FILE - DO NOT MODIFY OR DELETE
2
- // @quaffHash 0be24e79cccd1bb68f94fa2bcb3fd8ff
2
+ // @quaffHash 7a471ce6ecf43b530f7b11bbb7dcabc9
3
3
  export const QBtnDocsProps = [
4
4
  {
5
5
  isArray: false,
@@ -13,6 +13,18 @@ export const QBtnDocsProps = [
13
13
  description: "Puts the button in a disabled state, making it unclickable.",
14
14
  default: "false",
15
15
  },
16
+ {
17
+ isArray: false,
18
+ optional: true,
19
+ isSnippet: false,
20
+ name: "color",
21
+ type: {
22
+ name: "string",
23
+ isClickable: false,
24
+ },
25
+ description: "Sets the color of the button. If a color is specified, it overwrites all other color variants defined with boolean attributes.",
26
+ default: "",
27
+ },
16
28
  {
17
29
  isArray: false,
18
30
  optional: true,
@@ -23,7 +35,7 @@ export const QBtnDocsProps = [
23
35
  isClickable: true,
24
36
  },
25
37
  description: "Choose the variant for the button. If a variant is specified, it overwrites all other variants defined with boolean attributes. If no variant is specified using this prop or boolean props, the `elevated` variant will be used.",
26
- default: "undefined",
38
+ default: "",
27
39
  },
28
40
  {
29
41
  isArray: false,
@@ -211,13 +223,25 @@ export const QBtnDocsProps = [
211
223
  description: 'For "a" (anchor) tag only, apply the target attribute.',
212
224
  default: "undefined",
213
225
  },
226
+ {
227
+ isArray: false,
228
+ optional: true,
229
+ isSnippet: false,
230
+ name: "tag",
231
+ type: {
232
+ name: "keyof HTMLElementTagNameMap",
233
+ isClickable: false,
234
+ },
235
+ description: "The tag to use for the button. If not specified, a button element will be used or, if `to` is specified, an anchor tag will be used.",
236
+ default: "",
237
+ },
214
238
  {
215
239
  isArray: false,
216
240
  optional: true,
217
241
  isSnippet: false,
218
242
  name: "onclick",
219
243
  type: {
220
- name: "MouseEventHandler<HTMLButtonElement | HTMLAnchorElement>",
244
+ name: "MouseEventHandler<HTMLElement>",
221
245
  isClickable: false,
222
246
  },
223
247
  description: "This event is emitted when the button is clicked.",
@@ -8,9 +8,12 @@ export interface QBtnProps extends HTMLAttributes<HTMLButtonElement> {
8
8
  * @default false
9
9
  */
10
10
  disabled?: boolean;
11
+ /**
12
+ * Sets the color of the button. If a color is specified, it overwrites all other color variants defined with boolean attributes.
13
+ */
14
+ color?: string;
11
15
  /**
12
16
  * Choose the variant for the button. If a variant is specified, it overwrites all other variants defined with boolean attributes. If no variant is specified using this prop or boolean props, the `elevated` variant will be used.
13
- * @default undefined
14
17
  */
15
18
  variant?: QBtnVariantOptions;
16
19
  /**
@@ -88,9 +91,13 @@ export interface QBtnProps extends HTMLAttributes<HTMLButtonElement> {
88
91
  * @default undefined
89
92
  */
90
93
  target?: HTMLAnchorAttributes["target"];
94
+ /**
95
+ * The tag to use for the button. If not specified, a button element will be used or, if `to` is specified, an anchor tag will be used.
96
+ */
97
+ tag?: keyof HTMLElementTagNameMap;
91
98
  /**
92
99
  * This event is emitted when the button is clicked.
93
100
  * @default undefined
94
101
  */
95
- onclick?: MouseEventHandler<HTMLButtonElement | HTMLAnchorElement>;
102
+ onclick?: MouseEventHandler<HTMLElement>;
96
103
  }
@@ -0,0 +1,46 @@
1
+ @use "$css/mixins";
2
+ @use "$css/variables";
3
+
4
+ .q-expansion-item {
5
+ width: 100%;
6
+ padding: 0;
7
+
8
+ &[aria-disabled] :is(.q-item__section, .q-item__section *) {
9
+ color: unset;
10
+ }
11
+
12
+ & summary::marker,
13
+ & summary::-webkit-details-marker {
14
+ display: none;
15
+ content: "";
16
+ }
17
+
18
+ &::details-content {
19
+ transition: content-visibility var(--duration) allow-discrete;
20
+ }
21
+
22
+ &__toggle-icon {
23
+ margin: 0;
24
+ z-index: 1;
25
+
26
+ &:is(.q-btn) {
27
+ margin-right: -0.5rem;
28
+ }
29
+
30
+ &:not(.q-btn),
31
+ &.q-btn .q-icon {
32
+ transition: rotate var(--duration);
33
+ }
34
+
35
+ &--rotate:not(.q-btn),
36
+ &--rotate.q-btn .q-icon {
37
+ rotate: 180deg;
38
+ }
39
+ }
40
+
41
+ &__content {
42
+ @include mixins.padding("x-md", "y-sm");
43
+ width: 100%;
44
+ overflow: hidden;
45
+ }
46
+ }