@bug-on/md3-react 3.0.2 → 3.0.3
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.
- package/.turbo/turbo-build.log +12 -11
- package/dist/index.css +107 -0
- package/dist/index.d.mts +1426 -1039
- package/dist/index.d.ts +1426 -1039
- package/dist/index.js +3830 -2820
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3818 -2822
- package/dist/index.mjs.map +1 -1
- package/package.json +11 -6
- package/scripts/copy-assets.js +113 -8
- package/src/index.ts +59 -19
- package/src/test/button.test.tsx +1 -1
- package/src/ui/app-bar/app-bar.tokens.ts +5 -24
- package/src/ui/badge.tsx +2 -1
- package/src/ui/buttons/button/button-tokens.ts +118 -0
- package/src/ui/{button.test.tsx → buttons/button/button.test.tsx} +0 -21
- package/src/ui/buttons/button/button.tsx +381 -0
- package/src/ui/buttons/button/index.ts +3 -0
- package/src/ui/buttons/button/types.ts +90 -0
- package/src/ui/buttons/button-group/button-group-defaults.ts +95 -0
- package/src/ui/buttons/button-group/button-group-tokens.ts +20 -0
- package/src/ui/{button-group.test.tsx → buttons/button-group/button-group.test.tsx} +9 -10
- package/src/ui/buttons/button-group/button-group.tsx +699 -0
- package/src/ui/buttons/button-group/index.ts +8 -0
- package/src/ui/buttons/button-group/types.ts +77 -0
- package/src/ui/{fab.tsx → buttons/fabs/fab/fab.tsx} +6 -6
- package/src/ui/buttons/fabs/fab/index.ts +1 -0
- package/src/ui/{fab-menu.tsx → buttons/fabs/fab-menu/fab-menu.tsx} +7 -4
- package/src/ui/buttons/fabs/fab-menu/index.ts +1 -0
- package/src/ui/buttons/fabs/index.ts +2 -0
- package/src/ui/{icon-button.tsx → buttons/icon-button/icon-button.tsx} +6 -6
- package/src/ui/buttons/icon-button/index.ts +1 -0
- package/src/ui/buttons/index.ts +4 -0
- package/src/ui/code-block.tsx +1 -1
- package/src/ui/dialog.tsx +4 -7
- package/src/ui/drawer.tsx +4 -7
- package/src/ui/menu/menu-animations.ts +14 -20
- package/src/ui/menu/menu-tokens.ts +7 -5
- package/src/ui/menu/menu.test.tsx +9 -4
- package/src/ui/navigation-bar.tsx +20 -4
- package/src/ui/navigation-rail.tsx +17 -7
- package/src/ui/search/search-view-fullscreen.tsx +1 -1
- package/src/ui/search/search.tokens.ts +9 -43
- package/src/ui/search/trailing-action.tsx +1 -1
- package/src/ui/shared/constants.ts +25 -27
- package/src/ui/shared/motion-tokens.ts +238 -0
- package/src/ui/snackbar/snackbar.tsx +4 -6
- package/src/ui/switch/switch.tsx +12 -18
- package/src/ui/text-field/text-field.tokens.ts +12 -12
- package/src/ui/text-field/text-field.tsx +31 -19
- package/src/ui/theme-provider/index.tsx +1 -5
- package/src/ui/toc.tsx +1 -1
- package/src/ui/toolbar/__snapshots__/bottom-docked-toolbar.test.tsx.snap +51 -0
- package/src/ui/toolbar/__snapshots__/floating-toolbar-with-fab.test.tsx.snap +113 -0
- package/src/ui/toolbar/__snapshots__/floating-toolbar.test.tsx.snap +169 -0
- package/src/ui/toolbar/bottom-docked-toolbar.test.tsx +114 -0
- package/src/ui/toolbar/docked-toolbar.tsx +186 -0
- package/src/ui/toolbar/floating-toolbar-with-fab.test.tsx +139 -0
- package/src/ui/toolbar/floating-toolbar-with-fab.tsx +199 -0
- package/src/ui/toolbar/floating-toolbar.test.tsx +230 -0
- package/src/ui/toolbar/floating-toolbar.tsx +344 -0
- package/src/ui/toolbar/index.ts +35 -0
- package/src/ui/toolbar/toolbar-colors.ts +37 -0
- package/src/ui/toolbar/toolbar-context.tsx +13 -0
- package/src/ui/toolbar/toolbar-divider.test.tsx +54 -0
- package/src/ui/toolbar/toolbar-divider.tsx +73 -0
- package/src/ui/toolbar/toolbar-icon-button.test.tsx +68 -0
- package/src/ui/toolbar/toolbar-icon-button.tsx +136 -0
- package/src/ui/toolbar/toolbar-scroll-behavior.ts +140 -0
- package/src/ui/toolbar/toolbar-tokens.ts +51 -0
- package/test-clip.html +31 -0
- package/test-shadow.html +5 -1
- package/test-width.html +34 -0
- package/src/ui/button-group.tsx +0 -350
- package/src/ui/button.tsx +0 -665
- package/test-render.tsx +0 -4
- /package/src/ui/{fab.test.tsx → buttons/fabs/fab/fab.test.tsx} +0 -0
- /package/src/ui/{fab-menu.test.tsx → buttons/fabs/fab-menu/fab-menu.test.tsx} +0 -0
- /package/src/ui/{icon-button.test.tsx → buttons/icon-button/icon-button.test.tsx} +0 -0
- /package/src/ui/{Text.tsx → text.tsx} +0 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file toolbar-icon-button.tsx
|
|
3
|
+
*
|
|
4
|
+
* A thin wrapper around the MD3 `IconButton` component, pre-configured
|
|
5
|
+
* for use inside Toolbar slots.
|
|
6
|
+
*
|
|
7
|
+
* Supports the three emphasis variants described in the MD3 Flexibility & slots
|
|
8
|
+
* spec, plus narrow/wide sizing for asymmetric visual hierarchy.
|
|
9
|
+
*
|
|
10
|
+
* @see https://m3.material.io/components/toolbars/guidelines (Anatomy → Flexibility & slots)
|
|
11
|
+
* @see https://m3.material.io/components/icon-buttons/overview
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import * as React from "react";
|
|
15
|
+
|
|
16
|
+
import { cn } from "../../lib/utils";
|
|
17
|
+
import { type BaseIconButtonProps, IconButton } from "../buttons/icon-button";
|
|
18
|
+
import { ToolbarIconButtonTokens } from "./toolbar-tokens";
|
|
19
|
+
|
|
20
|
+
export interface ToolbarIconButtonProps
|
|
21
|
+
extends Omit<BaseIconButtonProps, "colorStyle" | "size" | "shape"> {
|
|
22
|
+
/**
|
|
23
|
+
* Visual emphasis variant.
|
|
24
|
+
*
|
|
25
|
+
* ⚠️ Avoid emphasising more than one action at a time.
|
|
26
|
+
* @default "standard"
|
|
27
|
+
*/
|
|
28
|
+
emphasis?: ToolbarIconButtonVariant;
|
|
29
|
+
/**
|
|
30
|
+
* Button width sizing.
|
|
31
|
+
*
|
|
32
|
+
* Height is always `48px` to meet MD3 touch-target requirements.
|
|
33
|
+
* @default "default"
|
|
34
|
+
*/
|
|
35
|
+
toolbarSize?: ToolbarIconButtonSize;
|
|
36
|
+
/** Icon content — typically a single SVG icon component. */
|
|
37
|
+
children: React.ReactNode;
|
|
38
|
+
/**
|
|
39
|
+
* Accessible label — **REQUIRED** because icon buttons have no visible text.
|
|
40
|
+
*/
|
|
41
|
+
"aria-label": string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Width sizing for a toolbar icon button.
|
|
46
|
+
*
|
|
47
|
+
* MD3 guideline: *"Use wide and narrow icon buttons"* to create visual hierarchy.
|
|
48
|
+
* Touch-target height is always 48dp regardless of width.
|
|
49
|
+
*
|
|
50
|
+
* - `narrow` → 40px wide (secondary, de-emphasised)
|
|
51
|
+
* - `default` → 48px wide (standard square touch target)
|
|
52
|
+
* - `wide` → 64px wide (primary emphasis, draws eye)
|
|
53
|
+
*/
|
|
54
|
+
export type ToolbarIconButtonSize = "narrow" | "default" | "wide";
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Visual emphasis variant for a toolbar icon button.
|
|
58
|
+
*
|
|
59
|
+
* MD3 guideline: *"Use different icon button color styles, such as filled,
|
|
60
|
+
* tonal, and standard."*
|
|
61
|
+
*
|
|
62
|
+
* ⚠️ **Avoid emphasising more than one action at a time.**
|
|
63
|
+
* Use `"filled"` or `"tonal"` for the single highest-priority action and
|
|
64
|
+
* keep all other buttons as `"standard"`.
|
|
65
|
+
*/
|
|
66
|
+
export type ToolbarIconButtonVariant = "standard" | "tonal" | "filled";
|
|
67
|
+
|
|
68
|
+
const TOOLBAR_ICON_BUTTON_WIDTH: Record<ToolbarIconButtonSize, string> = {
|
|
69
|
+
narrow: `w-[${ToolbarIconButtonTokens.NarrowWidth}px]`,
|
|
70
|
+
default: `w-[${ToolbarIconButtonTokens.DefaultWidth}px]`,
|
|
71
|
+
wide: `w-[${ToolbarIconButtonTokens.WideWidth}px]`,
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const VARIANT_TO_COLOR_STYLE: Record<
|
|
75
|
+
ToolbarIconButtonVariant,
|
|
76
|
+
"standard" | "filled" | "tonal"
|
|
77
|
+
> = {
|
|
78
|
+
standard: "standard",
|
|
79
|
+
tonal: "tonal",
|
|
80
|
+
filled: "filled",
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* An MD3 icon button optimised for use inside Toolbar slots.
|
|
85
|
+
*
|
|
86
|
+
* Wraps the project's `IconButton` and adds:
|
|
87
|
+
* - Three emphasis styles (`standard`, `tonal`, `filled`) via `emphasis` prop.
|
|
88
|
+
* - Three width sizes (`narrow`, `default`, `wide`) for visual hierarchy.
|
|
89
|
+
* - Always `rounded-full` shape (required for floating toolbars per MD3 spec).
|
|
90
|
+
* - Always 48dp height to meet MD3 accessibility touch-target requirements.
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ```tsx
|
|
94
|
+
* // Standard (default) — use for most actions
|
|
95
|
+
* <ToolbarIconButton aria-label="Share">
|
|
96
|
+
* <ShareIcon />
|
|
97
|
+
* </ToolbarIconButton>
|
|
98
|
+
*
|
|
99
|
+
* // Filled + wide — use for the single highest-priority action
|
|
100
|
+
* <ToolbarIconButton emphasis="filled" toolbarSize="wide" aria-label="Add">
|
|
101
|
+
* <PlusIcon />
|
|
102
|
+
* </ToolbarIconButton>
|
|
103
|
+
* ```
|
|
104
|
+
*
|
|
105
|
+
* @see https://m3.material.io/components/toolbars/guidelines
|
|
106
|
+
*/
|
|
107
|
+
export const ToolbarIconButton = React.forwardRef<
|
|
108
|
+
HTMLButtonElement,
|
|
109
|
+
ToolbarIconButtonProps
|
|
110
|
+
>(
|
|
111
|
+
(
|
|
112
|
+
{ emphasis = "standard", toolbarSize = "default", className, ...props },
|
|
113
|
+
ref,
|
|
114
|
+
) => {
|
|
115
|
+
const widthClass = TOOLBAR_ICON_BUTTON_WIDTH[toolbarSize];
|
|
116
|
+
const colorStyle = VARIANT_TO_COLOR_STYLE[emphasis];
|
|
117
|
+
|
|
118
|
+
return (
|
|
119
|
+
<IconButton
|
|
120
|
+
ref={ref}
|
|
121
|
+
variant="default"
|
|
122
|
+
colorStyle={colorStyle}
|
|
123
|
+
size="md"
|
|
124
|
+
shape="round"
|
|
125
|
+
className={cn(
|
|
126
|
+
`h-[${ToolbarIconButtonTokens.Height}px]`,
|
|
127
|
+
widthClass,
|
|
128
|
+
className,
|
|
129
|
+
)}
|
|
130
|
+
{...props}
|
|
131
|
+
/>
|
|
132
|
+
);
|
|
133
|
+
},
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
ToolbarIconButton.displayName = "ToolbarIconButton";
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { useMotionValueEvent, useScroll } from "motion/react";
|
|
2
|
+
import { type RefObject, useEffect, useRef, useState } from "react";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Configuration options for the `useFloatingToolbarScrollBehavior` hook.
|
|
6
|
+
*/
|
|
7
|
+
export interface UseFloatingToolbarScrollBehaviorOptions {
|
|
8
|
+
/** Direction toolbar exits: 'top' | 'bottom' | 'start' | 'end'. Defaults to 'bottom'. */
|
|
9
|
+
exitDirection?: "top" | "bottom" | "start" | "end";
|
|
10
|
+
/** Scroll distance threshold to trigger collapse (in px). Defaults to 10. */
|
|
11
|
+
collapseThreshold?: number;
|
|
12
|
+
/** Scroll distance threshold to trigger expand (in px). Defaults to 10. */
|
|
13
|
+
expandThreshold?: number;
|
|
14
|
+
/** Optional ref to a scrollable container. If not provided, it listens to window scroll. */
|
|
15
|
+
scrollContainerRef?: RefObject<HTMLElement | null>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The resulting behavior object returned by `useFloatingToolbarScrollBehavior`.
|
|
20
|
+
*/
|
|
21
|
+
export interface FloatingToolbarScrollBehavior {
|
|
22
|
+
/** Current offset. 0 is fully visible, -1 is fully hidden. */
|
|
23
|
+
offset: number;
|
|
24
|
+
/** Whether the toolbar is currently expanded. */
|
|
25
|
+
isExpanded: boolean;
|
|
26
|
+
/** Optional scroll handler to bind to a React scrollable container (legacy fallback). */
|
|
27
|
+
onScroll?: (event: React.UIEvent<HTMLElement>) => void;
|
|
28
|
+
/** Manually update the expanded state of the toolbar. */
|
|
29
|
+
setExpanded: (expanded: boolean) => void;
|
|
30
|
+
/** The configured exit direction. */
|
|
31
|
+
exitDirection: "top" | "bottom" | "start" | "end";
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* A hook that provides scroll behavior for floating toolbars, allowing them to
|
|
36
|
+
* collapse (exit) when scrolling down and expand (enter) when scrolling up.
|
|
37
|
+
* Leverages Framer Motion's useScroll internally for optimized performance.
|
|
38
|
+
*
|
|
39
|
+
* @param options Configuration options for scroll behavior.
|
|
40
|
+
* @returns An object containing the current scroll state and handlers.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```tsx
|
|
44
|
+
* const scrollBehavior = useFloatingToolbarScrollBehavior({
|
|
45
|
+
* exitDirection: 'bottom',
|
|
46
|
+
* collapseThreshold: 20
|
|
47
|
+
* });
|
|
48
|
+
*
|
|
49
|
+
* <HorizontalFloatingToolbar scrollBehavior={scrollBehavior}>
|
|
50
|
+
* <IconButton icon="bold" />
|
|
51
|
+
* </HorizontalFloatingToolbar>
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
export function useFloatingToolbarScrollBehavior(
|
|
55
|
+
options: UseFloatingToolbarScrollBehaviorOptions = {},
|
|
56
|
+
): FloatingToolbarScrollBehavior {
|
|
57
|
+
const {
|
|
58
|
+
exitDirection = "bottom",
|
|
59
|
+
collapseThreshold = 10,
|
|
60
|
+
expandThreshold = 10,
|
|
61
|
+
scrollContainerRef,
|
|
62
|
+
} = options;
|
|
63
|
+
|
|
64
|
+
const [isExpanded, setIsExpanded] = useState(true);
|
|
65
|
+
const [offset, setOffset] = useState(0); // 0 to -1
|
|
66
|
+
|
|
67
|
+
const { scrollY } = useScroll({
|
|
68
|
+
container: scrollContainerRef,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
const lastScrollY = useRef(0);
|
|
72
|
+
const accumulatedScroll = useRef(0);
|
|
73
|
+
|
|
74
|
+
useMotionValueEvent(scrollY, "change", (currentScrollY) => {
|
|
75
|
+
const deltaY = currentScrollY - lastScrollY.current;
|
|
76
|
+
|
|
77
|
+
// Ignore bouncing (negative scroll or past max scroll on macOS)
|
|
78
|
+
if (currentScrollY < 0) return;
|
|
79
|
+
|
|
80
|
+
lastScrollY.current = currentScrollY;
|
|
81
|
+
|
|
82
|
+
// Only accumulate if we are scrolling in the same direction
|
|
83
|
+
if (Math.sign(deltaY) !== Math.sign(accumulatedScroll.current)) {
|
|
84
|
+
accumulatedScroll.current = deltaY;
|
|
85
|
+
} else {
|
|
86
|
+
accumulatedScroll.current += deltaY;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (deltaY > 0 && isExpanded) {
|
|
90
|
+
// Scrolling down -> collapse
|
|
91
|
+
if (accumulatedScroll.current > collapseThreshold) {
|
|
92
|
+
setIsExpanded(false);
|
|
93
|
+
setOffset(-1);
|
|
94
|
+
}
|
|
95
|
+
} else if (deltaY < 0 && !isExpanded) {
|
|
96
|
+
// Scrolling up -> expand
|
|
97
|
+
if (Math.abs(accumulatedScroll.current) > expandThreshold) {
|
|
98
|
+
setIsExpanded(true);
|
|
99
|
+
setOffset(0);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// Accessibility: Always force expanded if forced-colors mode or accessibility preferences
|
|
105
|
+
useEffect(() => {
|
|
106
|
+
if (typeof window !== "undefined") {
|
|
107
|
+
const matchMedia = window.matchMedia("(forced-colors: active)");
|
|
108
|
+
if (matchMedia.matches) {
|
|
109
|
+
setIsExpanded(true);
|
|
110
|
+
setOffset(0);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const listener = (e: MediaQueryListEvent) => {
|
|
114
|
+
if (e.matches) {
|
|
115
|
+
setIsExpanded(true);
|
|
116
|
+
setOffset(0);
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
matchMedia.addEventListener("change", listener);
|
|
121
|
+
return () => matchMedia.removeEventListener("change", listener);
|
|
122
|
+
}
|
|
123
|
+
}, []);
|
|
124
|
+
|
|
125
|
+
const setExpanded = (expanded: boolean) => {
|
|
126
|
+
setIsExpanded(expanded);
|
|
127
|
+
setOffset(expanded ? 0 : -1);
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
// Dummy onScroll for legacy compatibility if users still attach it
|
|
131
|
+
const onScroll = () => {};
|
|
132
|
+
|
|
133
|
+
return {
|
|
134
|
+
offset,
|
|
135
|
+
isExpanded,
|
|
136
|
+
onScroll,
|
|
137
|
+
setExpanded,
|
|
138
|
+
exitDirection,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Design tokens for the MD3 Expressive Toolbars components.
|
|
3
|
+
* Extracted from `FloatingToolbarTokens.kt` and `FabBaselineTokens.kt`.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export const FloatingToolbarTokens = {
|
|
7
|
+
ContainerBetweenSpace: 4,
|
|
8
|
+
ContainerExternalPadding: 16,
|
|
9
|
+
ContainerHeight: 64,
|
|
10
|
+
ContainerLeadingSpace: 8,
|
|
11
|
+
ContainerShape: "full",
|
|
12
|
+
ContainerTrailingSpace: 8,
|
|
13
|
+
VerticalContainerExternalPadding: 24,
|
|
14
|
+
} as const;
|
|
15
|
+
|
|
16
|
+
export const FabBaselineTokens = {
|
|
17
|
+
ContainerHeight: 56,
|
|
18
|
+
ContainerWidth: 56,
|
|
19
|
+
MediumContainerHeight: 80,
|
|
20
|
+
MediumContainerWidth: 80,
|
|
21
|
+
IconSize: 24,
|
|
22
|
+
MediumIconSize: 28,
|
|
23
|
+
} as const;
|
|
24
|
+
|
|
25
|
+
export const ToolbarToFabGap = 8;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Design tokens for the ToolbarDivider component.
|
|
29
|
+
* The divider is a decorative separator used to group toolbar actions.
|
|
30
|
+
*/
|
|
31
|
+
export const ToolbarDividerTokens = {
|
|
32
|
+
/** Divider line thickness in px */
|
|
33
|
+
Thickness: 1,
|
|
34
|
+
/** Divider size as a fraction of the toolbar container dimension */
|
|
35
|
+
HeightRatio: 0.5,
|
|
36
|
+
} as const;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Design tokens for the ToolbarIconButton component.
|
|
40
|
+
* Sizes follow MD3 Expressive touch-target minimums (48dp height always).
|
|
41
|
+
* - narrow: de-emphasised secondary actions
|
|
42
|
+
* - default: standard icon button
|
|
43
|
+
* - wide: primary action emphasis inside the toolbar
|
|
44
|
+
*/
|
|
45
|
+
export const ToolbarIconButtonTokens = {
|
|
46
|
+
NarrowWidth: 40,
|
|
47
|
+
DefaultWidth: 48,
|
|
48
|
+
WideWidth: 64,
|
|
49
|
+
/** Minimum touch-target height per MD3 accessibility guidelines */
|
|
50
|
+
Height: 48,
|
|
51
|
+
} as const;
|
package/test-clip.html
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<title>Test Clip - MD3 Expressive</title>
|
|
5
|
+
<meta name="description" content="Test file for clipping behavior in MD3 Expressive components.">
|
|
6
|
+
<meta property="og:title" content="Test Clip - MD3 Expressive">
|
|
7
|
+
<meta property="og:description" content="Test file for clipping behavior in MD3 Expressive components.">
|
|
8
|
+
<style>
|
|
9
|
+
.wrapper {
|
|
10
|
+
display: flex;
|
|
11
|
+
align-items: center;
|
|
12
|
+
overflow: hidden;
|
|
13
|
+
width: fit-content;
|
|
14
|
+
height: 64px;
|
|
15
|
+
background: rgba(255,0,0,0.2);
|
|
16
|
+
}
|
|
17
|
+
.inner {
|
|
18
|
+
width: 200px;
|
|
19
|
+
height: 64px;
|
|
20
|
+
border-radius: 32px;
|
|
21
|
+
background: blue;
|
|
22
|
+
box-shadow: 0 4px 6px rgba(0,0,0,0.5);
|
|
23
|
+
}
|
|
24
|
+
</style>
|
|
25
|
+
</head>
|
|
26
|
+
<body>
|
|
27
|
+
<div class="wrapper">
|
|
28
|
+
<div class="inner"></div>
|
|
29
|
+
</div>
|
|
30
|
+
</body>
|
|
31
|
+
</html>
|
package/test-shadow.html
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
|
-
<
|
|
4
|
+
<title>Test Shadow - MD3 Expressive</title>
|
|
5
|
+
<meta name="description" content="Test file for shadow behavior in MD3 Expressive components.">
|
|
6
|
+
<meta property="og:title" content="Test Shadow - MD3 Expressive">
|
|
7
|
+
<meta property="og:description" content="Test file for shadow behavior in MD3 Expressive components.">
|
|
8
|
+
<style>
|
|
5
9
|
.outer {
|
|
6
10
|
width: 200px;
|
|
7
11
|
display: flex;
|
package/test-width.html
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<title>Test Width - MD3 Expressive</title>
|
|
5
|
+
<meta name="description" content="Test file for width transitions in MD3 Expressive components.">
|
|
6
|
+
<meta property="og:title" content="Test Width - MD3 Expressive">
|
|
7
|
+
<meta property="og:description" content="Test file for width transitions in MD3 Expressive components.">
|
|
8
|
+
<style>
|
|
9
|
+
.wrapper {
|
|
10
|
+
box-sizing: border-box;
|
|
11
|
+
overflow: hidden;
|
|
12
|
+
padding: 20px;
|
|
13
|
+
margin: -20px;
|
|
14
|
+
width: 0px; /* Animate to 0 */
|
|
15
|
+
background: rgba(0,255,0,0.5);
|
|
16
|
+
border: 1px solid red;
|
|
17
|
+
}
|
|
18
|
+
.inner {
|
|
19
|
+
width: 100px;
|
|
20
|
+
height: 50px;
|
|
21
|
+
background: blue;
|
|
22
|
+
}
|
|
23
|
+
</style>
|
|
24
|
+
</head>
|
|
25
|
+
<body>
|
|
26
|
+
<div style="display: flex;">
|
|
27
|
+
<div style="width: 50px; height: 50px; background: yellow;"></div>
|
|
28
|
+
<div class="wrapper">
|
|
29
|
+
<div class="inner"></div>
|
|
30
|
+
</div>
|
|
31
|
+
<div style="width: 50px; height: 50px; background: yellow;"></div>
|
|
32
|
+
</div>
|
|
33
|
+
</body>
|
|
34
|
+
</html>
|