@noxlovette/material 0.7.0 → 0.8.0

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 (33) hide show
  1. package/claude-skill/material-design/references/motion-guide.md +9 -9
  2. package/dist/animation/containerTransform.d.ts +0 -27
  3. package/dist/animation/containerTransform.js +40 -9
  4. package/dist/components/buttons/ButtonIcon.svelte +6 -2
  5. package/dist/components/buttons/ButtonIcon.svelte.d.ts +1 -1
  6. package/dist/components/buttons/context.d.ts +10 -0
  7. package/dist/components/buttons/context.js +9 -0
  8. package/dist/components/containers/popover/theme.d.ts +3 -3
  9. package/dist/components/forms/checkbox/Checkbox.svelte +1 -1
  10. package/dist/components/forms/checkbox/theme.d.ts +0 -12
  11. package/dist/components/forms/checkbox/theme.js +2 -7
  12. package/dist/components/forms/search/Search.mdx +76 -8
  13. package/dist/components/forms/search/Search.stories.svelte +107 -0
  14. package/dist/components/forms/search/Search.stories.svelte.d.ts +2 -17
  15. package/dist/components/forms/search/Search.svelte +55 -2
  16. package/dist/components/forms/search/Search.svelte.d.ts +4 -1
  17. package/dist/components/forms/search/SearchView.svelte +269 -0
  18. package/dist/components/forms/search/SearchView.svelte.d.ts +21 -0
  19. package/dist/components/forms/search/index.d.ts +1 -0
  20. package/dist/components/forms/search/index.js +1 -0
  21. package/dist/components/forms/search/theme.d.ts +68 -1
  22. package/dist/components/forms/search/theme.js +91 -2
  23. package/dist/components/forms/search/types.d.ts +75 -2
  24. package/dist/components/nav/appbar/AppBar.mdx +5 -1
  25. package/dist/components/nav/appbar/AppBar.stories.svelte +38 -0
  26. package/dist/components/nav/appbar/AppBar.svelte +55 -2
  27. package/dist/components/nav/appbar/AppBar.svelte.d.ts +6 -2
  28. package/dist/components/nav/appbar/theme.js +13 -2
  29. package/dist/components/nav/appbar/types.d.ts +18 -1
  30. package/dist/components/table/theme.js +3 -1
  31. package/dist/styles/components.css +6 -0
  32. package/dist/styles/motion.css +35 -0
  33. package/package.json +1 -1
@@ -1,10 +1,78 @@
1
1
  import type { IconProps } from '../../../utils/index.js';
2
2
  import type { Snippet } from 'svelte';
3
3
  import type { HTMLInputAttributes } from 'svelte/elements';
4
+ import type { Responsive } from '../../containers/pane/theme.js';
5
+ /**
6
+ * Where the search view puts its suggestions and results
7
+ * (https://m3.material.io/components/search/guidelines).
8
+ * - `fullScreen`: the view covers the window; for compact windows.
9
+ * - `docked`: the bar widens in place and results open in a container below it.
10
+ */
11
+ export type SearchLayout = 'fullScreen' | 'docked';
12
+ /**
13
+ * Handed to the `results` snippet. Spread it onto the `List` that holds the suggestions, and give
14
+ * each item `role="option"`, so the field can drive it as a combobox.
15
+ *
16
+ * ```svelte
17
+ * {#snippet results(listbox)}
18
+ * <List {...listbox}>
19
+ * <ListItem role="option" asChild headline="Material" onclick={pick} />
20
+ * </List>
21
+ * {/snippet}
22
+ * ```
23
+ */
24
+ export interface SearchResultsProps {
25
+ id: string;
26
+ role: 'listbox';
27
+ 'aria-label': string;
28
+ }
29
+ /** Props shared by the search view and the components that open it. */
30
+ export interface SearchViewOptions {
31
+ /**
32
+ * Suggestions and results, shown in the search view. Setting it gives the bar a search view,
33
+ * opened by clicking or typing in the bar.
34
+ */
35
+ results?: Snippet<[SearchResultsProps]>;
36
+ /**
37
+ * The search view's layout, one value or one per window tier.
38
+ * @default { small: 'fullScreen', medium: 'docked' }
39
+ */
40
+ layout?: Responsive<SearchLayout>;
41
+ /** Accessible label for the back button that closes the search view. */
42
+ backLabel?: string;
43
+ /** Accessible name of the search view and its suggestion list. Defaults to the placeholder. */
44
+ resultsLabel?: string;
45
+ }
46
+ /**
47
+ * Props for the SearchView component.
48
+ */
49
+ export interface SearchViewProps extends Omit<SearchViewOptions, 'results'> {
50
+ /** Whether the view is open. Opening and closing morph between `anchor` and the view. */
51
+ open?: boolean;
52
+ /** The search query, shared with the bar that opened the view. */
53
+ value?: string | null;
54
+ /**
55
+ * The search bar the view opens from: the container transform starts there, the docked layout
56
+ * is placed over it, and focus returns to its input on close.
57
+ */
58
+ anchor: HTMLElement | undefined;
59
+ /** Suggestions and results. */
60
+ results: Snippet<[SearchResultsProps]>;
61
+ /** Hint text in the view's field. */
62
+ placeholder?: string;
63
+ /** Actions after the clear button in the view's bar, e.g. a mic icon button. */
64
+ trailing?: Snippet;
65
+ /** Accessible label for the clear button. */
66
+ clearLabel?: string;
67
+ /** Extra props for the view's `<input>`. */
68
+ inputProps?: HTMLInputAttributes;
69
+ /** Reference to the view's `<input>` while it is open. */
70
+ inputRef?: HTMLInputElement;
71
+ }
4
72
  /**
5
73
  * Props for the Search component.
6
74
  */
7
- export interface SearchProps extends Omit<HTMLInputAttributes, 'size'> {
75
+ export interface SearchProps extends Omit<HTMLInputAttributes, 'size' | 'results'>, SearchViewOptions {
8
76
  /**
9
77
  * The current value of the search input.
10
78
  */
@@ -13,12 +81,17 @@ export interface SearchProps extends Omit<HTMLInputAttributes, 'size'> {
13
81
  * Reference to the HTML input element.
14
82
  */
15
83
  elementRef?: HTMLInputElement;
84
+ /**
85
+ * Whether the search view is open. Only has an effect with `results`.
86
+ */
87
+ open?: boolean;
16
88
  /**
17
89
  * A leading action, e.g. a menu or back icon button. Replaces the leading icon.
18
90
  */
19
91
  leading?: Snippet;
20
92
  /**
21
- * Trailing actions and/or an avatar, e.g. a mic icon button. Rendered after the clear button.
93
+ * Trailing actions and/or an avatar, e.g. a mic icon button. Rendered after the clear button,
94
+ * in the bar and in the search view.
22
95
  */
23
96
  trailing?: Snippet;
24
97
  /**
@@ -24,12 +24,16 @@ The props form a union, so the bar is one of two kinds:
24
24
  `{ small: 'small', large: 'large' }` to grow the bar on wider windows. The switch happens in CSS,
25
25
  so server rendering needs no JS.
26
26
  - **Search bar.** Pass `search` (the hint text) instead. The bar is always 64dp. `title` then
27
- becomes a screen-reader-only heading.
27
+ becomes a screen-reader-only heading. Per M3, selecting the field should open the search view:
28
+ pass `searchResults` (and optionally `bind:searchOpen`, `searchLayout`) and it opens the same
29
+ view as `Search`, with a container transform from the field. See Forms/Search for the view.
28
30
 
29
31
  <Canvas of={AppBarStories.MediumFlexible} />
30
32
 
31
33
  <Canvas of={AppBarStories.Search} />
32
34
 
35
+ <Canvas of={AppBarStories.SearchView} />
36
+
33
37
  ## Placement
34
38
 
35
39
  The bar is fixed at the top at every window size. Pass `ghost` to render a same-height spacer
@@ -2,6 +2,8 @@
2
2
  import { defineMeta } from '@storybook/addon-svelte-csf';
3
3
  import AppBar from './AppBar.svelte';
4
4
  import ButtonIcon from '../../buttons/ButtonIcon.svelte';
5
+ import List from '../../containers/list/List.svelte';
6
+ import ListItem from '../../containers/list/ListItem.svelte';
5
7
 
6
8
  const { Story } = defineMeta({
7
9
  title: 'Navigation/App Bar',
@@ -30,6 +32,11 @@
30
32
 
31
33
  <script lang="ts">
32
34
  let scroller = $state<HTMLElement | null>(null);
35
+
36
+ const products = ['Headphones', 'Keyboard', 'Laptop stand', 'Monitor', 'Mouse', 'Webcam'];
37
+ let query = $state('');
38
+ let searchOpen = $state(false);
39
+ const found = $derived(products.filter((p) => p.toLowerCase().includes(query.toLowerCase())));
33
40
  </script>
34
41
 
35
42
  <Story name="Playground">
@@ -125,6 +132,37 @@
125
132
  </AppBar>
126
133
  </Story>
127
134
 
135
+ <!-- Selecting the search field opens the search view: full-screen here, docked from medium up. -->
136
+ <Story
137
+ name="Search view"
138
+ asChild
139
+ parameters={{ docs: { story: { inline: false, height: '560px' } } }}
140
+ >
141
+ <AppBar search="Search products" title="Products" bind:query bind:searchOpen ghost>
142
+ {#snippet leading()}
143
+ <ButtonIcon variant="standard" iconProps={{ name: 'menu' }} aria-label="Menu" />
144
+ {/snippet}
145
+ {#snippet searchTrailing()}
146
+ <ButtonIcon variant="standard" iconProps={{ name: 'mic' }} aria-label="Voice search" />
147
+ {/snippet}
148
+ {#snippet searchResults(listbox)}
149
+ <List {...listbox}>
150
+ {#each found as product (product)}
151
+ <ListItem
152
+ role="option"
153
+ asChild
154
+ headline={product}
155
+ onclick={() => {
156
+ query = product;
157
+ searchOpen = false;
158
+ }}
159
+ />
160
+ {/each}
161
+ </List>
162
+ {/snippet}
163
+ </AppBar>
164
+ </Story>
165
+
128
166
  <Story name="Scroll container" asChild>
129
167
  <div bind:this={scroller} class="h-[480px] overflow-y-auto">
130
168
  <AppBar title="Scroll this box" scrollContainer={scroller} ghost />
@@ -8,7 +8,8 @@ They’re used for branding, screen titles, navigation, and actions.
8
8
  Sizes: `small` (64dp, one line) and the Expressive `medium`/`large` flexible bars, whose
9
9
  headline block wraps and grows. `size` also takes one value per breakpoint
10
10
  (`{ small: 'small', large: 'large' }`), switched in CSS so server rendering needs no JS.
11
- `align="center"` centres the title. Setting `search` makes it a search app bar.
11
+ `align="center"` centres the title. Setting `search` makes it a search app bar; add
12
+ `searchResults` and selecting the field opens the search view, as with `Search`.
12
13
 
13
14
  The bar takes its on-scroll color once `scrollContainer` (default: the page) scrolls.
14
15
 
@@ -17,6 +18,9 @@ Publishes its measured height as `--appbar-height` on the document root, so any
17
18
  that amount with no props or wiring on either side — see Pane.svelte's doc
18
19
  comment.
19
20
 
21
+ A `ButtonIcon` anywhere inside it defaults to `variant="standard"`, per M3; pass
22
+ `variant` to override.
23
+
20
24
  @see https://m3.material.io/components/app-bars/specs
21
25
  -->
22
26
  <script lang="ts">
@@ -24,6 +28,8 @@ comment.
24
28
  import type { AppBarProps } from './types.js';
25
29
  import clsx from 'clsx';
26
30
  import ButtonIcon from '../../buttons/ButtonIcon.svelte';
31
+ import { setButtonIconVariant } from '../../buttons/context.js';
32
+ import SearchView from '../../forms/search/SearchView.svelte';
27
33
 
28
34
  let {
29
35
  children,
@@ -43,11 +49,18 @@ comment.
43
49
  query = $bindable(''),
44
50
  searchProps,
45
51
  searchTrailing,
52
+ searchResults,
53
+ searchOpen = $bindable(false),
54
+ searchLayout,
46
55
  scrollContainer,
47
56
  ghost = false,
48
57
  ...rest
49
58
  }: AppBarProps = $props();
50
59
 
60
+ // M3 app bar icon buttons are standard (no container); a filled one over-emphasizes a back or
61
+ // action button. Applies to buttons passed in `leading`/`trailing`/`children` too.
62
+ setButtonIconVariant('standard');
63
+
51
64
  let scrolled = $state(false);
52
65
  let barHeight = $state(64);
53
66
 
@@ -61,6 +74,33 @@ comment.
61
74
  });
62
75
 
63
76
  const isSearch = $derived(search !== undefined);
77
+
78
+ let searchBar = $state<HTMLElement>();
79
+
80
+ // Same as Search: click, typing or ↓ opens the view; focus alone doesn't.
81
+ const opener = $derived(
82
+ searchResults
83
+ ? {
84
+ 'aria-haspopup': 'dialog' as const,
85
+ 'aria-expanded': searchOpen,
86
+ onclick: (e: MouseEvent & { currentTarget: HTMLInputElement }) => {
87
+ searchProps?.onclick?.(e);
88
+ if (!e.defaultPrevented) searchOpen = true;
89
+ },
90
+ oninput: (e: Event & { currentTarget: HTMLInputElement }) => {
91
+ searchProps?.oninput?.(e);
92
+ if (!e.defaultPrevented) searchOpen = true;
93
+ },
94
+ onkeydown: (e: KeyboardEvent & { currentTarget: HTMLInputElement }) => {
95
+ searchProps?.onkeydown?.(e);
96
+ if (!e.defaultPrevented && e.key === 'ArrowDown') {
97
+ e.preventDefault();
98
+ searchOpen = true;
99
+ }
100
+ }
101
+ }
102
+ : {}
103
+ );
64
104
  const noLeading = $derived(!leading && !showBack);
65
105
 
66
106
  const s = $derived(
@@ -110,10 +150,11 @@ comment.
110
150
  {#if title}
111
151
  <h1 {...titleProps} class={clsx('sr-only', titleProps?.class)}>{title}</h1>
112
152
  {/if}
113
- <label class={s.search()}>
153
+ <label class={s.search()} bind:this={searchBar}>
114
154
  <input
115
155
  type="search"
116
156
  {...searchProps}
157
+ {...opener}
117
158
  placeholder={search}
118
159
  aria-label={searchProps?.['aria-label'] ?? search}
119
160
  bind:value={query}
@@ -148,6 +189,18 @@ comment.
148
189
  {/if}
149
190
  </nav>
150
191
 
192
+ {#if isSearch && searchResults}
193
+ <SearchView
194
+ bind:open={searchOpen}
195
+ bind:value={query}
196
+ anchor={searchBar}
197
+ results={searchResults}
198
+ layout={searchLayout}
199
+ placeholder={search}
200
+ trailing={searchTrailing}
201
+ />
202
+ {/if}
203
+
151
204
  {#if ghost}
152
205
  <div class={s.ghost()} style="height: {barHeight}px" aria-hidden="true"></div>
153
206
  {/if}
@@ -8,7 +8,8 @@ import type { AppBarProps } from './types.js';
8
8
  * Sizes: `small` (64dp, one line) and the Expressive `medium`/`large` flexible bars, whose
9
9
  * headline block wraps and grows. `size` also takes one value per breakpoint
10
10
  * (`{ small: 'small', large: 'large' }`), switched in CSS so server rendering needs no JS.
11
- * `align="center"` centres the title. Setting `search` makes it a search app bar.
11
+ * `align="center"` centres the title. Setting `search` makes it a search app bar; add
12
+ * `searchResults` and selecting the field opens the search view, as with `Search`.
12
13
  *
13
14
  * The bar takes its on-scroll color once `scrollContainer` (default: the page) scrolls.
14
15
  *
@@ -17,8 +18,11 @@ import type { AppBarProps } from './types.js';
17
18
  * that amount with no props or wiring on either side — see Pane.svelte's doc
18
19
  * comment.
19
20
  *
21
+ * A `ButtonIcon` anywhere inside it defaults to `variant="standard"`, per M3; pass
22
+ * `variant` to override.
23
+ *
20
24
  * @see https://m3.material.io/components/app-bars/specs
21
25
  */
22
- declare const AppBar: import("svelte").Component<AppBarProps, {}, "query">;
26
+ declare const AppBar: import("svelte").Component<AppBarProps, {}, "query" | "searchOpen">;
23
27
  type AppBar = ReturnType<typeof AppBar>;
24
28
  export default AppBar;
@@ -131,7 +131,7 @@ export const appbar = tv({
131
131
  subtitle: 'text-md-sys-color-on-surface-variant',
132
132
  leading: 'text-md-sys-color-on-surface col-start-1 row-start-1 flex shrink-0 items-center justify-self-start',
133
133
  trailing: 'text-md-sys-color-on-surface-variant col-start-3 row-start-1 flex shrink-0 items-center justify-self-end',
134
- search: 'state-layer relative flex h-spacing-700 w-full min-w-spacing-0 cursor-text items-center rounded-full ps-spacing-200 pe-spacing-200 transition-colors md-sys-motion-effects before:rounded-full hover:before:bg-md-sys-color-on-surface/8 focus-within:outline-3 focus-within:outline-offset-2 focus-within:outline-md-sys-color-secondary',
134
+ search: 'state-layer relative flex h-spacing-700 w-full min-w-spacing-0 cursor-text items-center rounded-xl ps-spacing-200 pe-spacing-200 transition-colors md-sys-motion-effects before:rounded-xl hover:before:bg-md-sys-color-on-surface/8 focus-within:outline-3 focus-within:outline-offset-2 focus-within:outline-md-sys-color-secondary [:root:active-view-transition_&]:outline-0',
135
135
  searchInput: 'md-sys-typescale-body-large text-md-sys-color-on-surface placeholder:text-md-sys-color-on-surface-variant w-full min-w-spacing-0 bg-transparent text-start outline-none placeholder-shown:text-center [&::-webkit-search-cancel-button]:hidden',
136
136
  searchTrailing: 'text-md-sys-color-on-surface-variant flex shrink-0 items-center'
137
137
  },
@@ -141,12 +141,23 @@ export const appbar = tv({
141
141
  // 1fr side columns centre a small bar's title on the bar, not between uneven button groups.
142
142
  center: { row: 'grid-cols-[1fr_auto_1fr]', textContainer: 'items-center text-center' }
143
143
  },
144
+ /*
145
+ From medium up, a Pane rounds its top corners (md:rounded-t-*) and sits as a surface card
146
+ on the App's surface-container, beside a surface-container Rail. The bar is part of that
147
+ chrome there, so it stays surface-container whether scrolled or not: a surface bar
148
+ would read as a strip glued over the card, with the App's colour showing through the
149
+ pane's corners beneath it. Below medium the pane is flat and full-bleed, so the bar keeps
150
+ M3's surface → surface-container on-scroll change.
151
+ */
144
152
  scrolled: {
145
153
  true: {
146
154
  base: 'bg-md-sys-color-surface-container',
147
155
  search: 'bg-md-sys-color-surface-container-highest'
148
156
  },
149
- false: { base: 'bg-md-sys-color-surface', search: 'bg-md-sys-color-surface-container' }
157
+ false: {
158
+ base: 'bg-md-sys-color-surface md:bg-md-sys-color-surface-container',
159
+ search: 'bg-md-sys-color-surface-container md:bg-md-sys-color-surface-container-highest'
160
+ }
150
161
  },
151
162
  // Search app bar: the search container fills the text column, 8dp from the buttons.
152
163
  searchContainer: {
@@ -1,6 +1,7 @@
1
1
  import type { Snippet } from 'svelte';
2
2
  import type { HTMLAttributes, HTMLInputAttributes } from 'svelte/elements';
3
3
  import type { Responsive } from '../../containers/pane/theme.js';
4
+ import type { SearchLayout, SearchResultsProps } from '../../forms/search/types.js';
4
5
  import type { AppBarSize, AppbarVariants } from './theme.js';
5
6
  type AppBarBaseProps = Pick<AppbarVariants, 'align'> & HTMLAttributes<HTMLElementTagNameMap['nav']> & {
6
7
  /** Extra content rendered in a full-width row below the title, e.g. a Breadcrumb trail. */
@@ -43,6 +44,9 @@ export type TitleAppBarProps = AppBarBaseProps & {
43
44
  query?: never;
44
45
  searchProps?: never;
45
46
  searchTrailing?: never;
47
+ searchResults?: never;
48
+ searchOpen?: never;
49
+ searchLayout?: never;
46
50
  };
47
51
  /** A search app bar: a search field in place of the title, always 64dp. */
48
52
  export type SearchAppBarProps = AppBarBaseProps & {
@@ -54,8 +58,21 @@ export type SearchAppBarProps = AppBarBaseProps & {
54
58
  title?: string;
55
59
  /** Props for the search `<input>`, e.g. `onfocus` to open a search view. */
56
60
  searchProps?: HTMLInputAttributes;
57
- /** An action inside the search field, e.g. a mic icon button. */
61
+ /** An action inside the search field, e.g. a mic icon button. Also shown in the search view. */
58
62
  searchTrailing?: Snippet;
63
+ /**
64
+ * Suggestions and results. Setting it gives the bar a search view (`SearchView`), opened by
65
+ * clicking or typing in the field. Spread the snippet's argument onto a `List` of
66
+ * `role="option"` items.
67
+ */
68
+ searchResults?: Snippet<[SearchResultsProps]>;
69
+ /** Whether the search view is open. Only has an effect with `searchResults`. */
70
+ searchOpen?: boolean;
71
+ /**
72
+ * The search view's layout, one value or one per window tier.
73
+ * @default { small: 'fullScreen', medium: 'docked' }
74
+ */
75
+ searchLayout?: Responsive<SearchLayout>;
59
76
  size?: never;
60
77
  };
61
78
  /**
@@ -1,7 +1,9 @@
1
1
  import { tv } from '../../utils/tv.js';
2
2
  export const table = tv({
3
3
  slots: {
4
- root: 'w-full border-collapse text-left md-sys-typescale-body-medium text-md-sys-color-on-surface',
4
+ // `isolate` scopes the sticky head's z-10 to the table, so it only covers the rows
5
+ // scrolling beneath it and never app bars, menus or sheets outside the table.
6
+ root: 'isolate w-full border-collapse text-left md-sys-typescale-body-medium text-md-sys-color-on-surface',
5
7
  head: '',
6
8
  body: '[&_tr:last-child]:border-b-0',
7
9
  foot: 'border-t border-md-sys-color-outline-variant',
@@ -11,6 +11,12 @@
11
11
  --md-comp-nav-rail-expanded-top-space: 2.75rem; /* 44dp */
12
12
  --md-comp-nav-rail-expanded-container-width-minimum: 13.75rem; /* 220dp */
13
13
  --md-comp-nav-rail-expanded-container-width-maximum: 22.5rem; /* 360dp */
14
+
15
+ /* Search view, contained style, docked layout: https://m3.material.io/components/search/specs */
16
+ --md-comp-search-view-contained-docked-container-width-minimum: 22.5rem; /* 360dp */
17
+ --md-comp-search-view-contained-docked-container-width-maximum: 45rem; /* 720dp */
18
+ --md-comp-search-view-contained-docked-container-height-minimum: 15rem; /* 240dp */
19
+ --md-comp-search-view-contained-docked-container-height-maximum: calc(100dvh * 2 / 3);
14
20
  }
15
21
 
16
22
  /*
@@ -331,3 +331,38 @@
331
331
  transition-duration: var(--md-sys-motion-duration-slow-effects-spring);
332
332
  transition-timing-function: var(--md-sys-motion-timing-function-slow-effects-spring);
333
333
  }
334
+
335
+ /*
336
+ Container transform (animation/containerTransform.ts): both snapshots keep their own width and
337
+ sit at the container's top, clipped by it as it grows or shrinks. Motion's crop would otherwise
338
+ `object-fit: cover` them, which blows a short bar's snapshot up to the height of a full view.
339
+ Motion injects its per-name rule at runtime, after this sheet and at the same specificity, so
340
+ these need `!important` to win.
341
+ */
342
+ ::view-transition-old(.md-container-transform),
343
+ ::view-transition-new(.md-container-transform) {
344
+ top: 0 !important;
345
+ width: 100% !important;
346
+ height: auto !important;
347
+ object-fit: fill !important;
348
+ }
349
+
350
+ /*
351
+ Outgoing on top, fading off the incoming snapshot underneath, which stays opaque. Normal
352
+ blending: the browser runs `plus-lighter` on the pair as an animation, which only
353
+ `!important` outranks, and adding the outgoing bar onto the opaque view flashed it white.
354
+ The incoming snapshot also drops the browser's default fade-in.
355
+ */
356
+ ::view-transition-old(.md-container-transform) {
357
+ z-index: 1;
358
+ mix-blend-mode: normal !important;
359
+ }
360
+ ::view-transition-new(.md-container-transform) {
361
+ mix-blend-mode: normal !important;
362
+ animation-name: none !important;
363
+ }
364
+
365
+ /* Filled with the destination's own background while it morphs (set by containerTransform). */
366
+ ::view-transition-group(.md-container-transform) {
367
+ background-color: var(--md-container-transform-color, transparent);
368
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noxlovette/material",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "type": "module",
5
5
  "description": "A Material Design 3 component library for Svelte, built on Bits UI.",
6
6
  "keywords": [