mac-human-design 0.1.5 → 0.1.6
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/README.md +9 -7
- package/changelog.md +22 -0
- package/docs/macos-base-ui-coverage.md +7 -2
- package/package.json +3 -1
- package/scripts/verify-base-ui-coverage.mjs +6 -2
- package/scripts/verify-macos-design.mjs +42 -0
- package/src/components/MacBaseUI.tsx +209 -2
- package/src/components/MacBaseUIGallery.tsx +5 -2
package/README.md
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
A reusable shared library for Tauri macOS apps. It includes:
|
|
4
4
|
|
|
5
5
|
- macOS-styled wrappers for every public `@base-ui/react` component family.
|
|
6
|
+
- Default-on Motion-powered animations that respect reduced-motion settings.
|
|
6
7
|
- `MacSegmentedControl` and macOS design tokens/classes.
|
|
7
8
|
- A reusable SF Symbols fetch layer with React hooks/components.
|
|
8
9
|
- A Rust/Tauri plugin crate that exposes a native command:
|
|
@@ -19,11 +20,12 @@ A reusable shared library for Tauri macOS apps. It includes:
|
|
|
19
20
|
From the consumer app:
|
|
20
21
|
|
|
21
22
|
```bash
|
|
22
|
-
npm i mac-human-design @base-ui/react react react-dom
|
|
23
|
+
npm i mac-human-design @base-ui/react motion react react-dom
|
|
23
24
|
```
|
|
24
25
|
|
|
25
|
-
`@base-ui/react`, `react`, and `react-dom` are peer dependencies.
|
|
26
|
-
`@tauri-apps/api` too when using the SF Symbols helpers or Tauri
|
|
26
|
+
`@base-ui/react`, `motion`, `react`, and `react-dom` are peer dependencies.
|
|
27
|
+
Install `@tauri-apps/api` too when using the SF Symbols helpers or Tauri
|
|
28
|
+
integration.
|
|
27
29
|
|
|
28
30
|
Consumer apps should also include the macOS Base UI stylesheet once near their
|
|
29
31
|
app root:
|
|
@@ -54,7 +56,7 @@ fn main() {
|
|
|
54
56
|
|
|
55
57
|
```ts
|
|
56
58
|
import { useState } from "react";
|
|
57
|
-
import { MacButton, MacSegmentedControl, MacSelect } from "mac-human-design";
|
|
59
|
+
import { MacButton, MacMotionProvider, MacSegmentedControl, MacSelect } from "mac-human-design";
|
|
58
60
|
import { SystemSymbolImage } from "mac-human-design/symbols";
|
|
59
61
|
import "mac-human-design/styles/macos-base-ui.css";
|
|
60
62
|
|
|
@@ -62,7 +64,7 @@ export function Demo() {
|
|
|
62
64
|
const [tab, setTab] = useState<"files" | "settings">("files");
|
|
63
65
|
|
|
64
66
|
return (
|
|
65
|
-
<
|
|
67
|
+
<MacMotionProvider>
|
|
66
68
|
<SystemSymbolImage symbolName="folder" sizePx={18} fallback="▢" />
|
|
67
69
|
<MacSegmentedControl
|
|
68
70
|
options={[
|
|
@@ -78,7 +80,7 @@ export function Demo() {
|
|
|
78
80
|
<MacSelect.Value placeholder="Choose" />
|
|
79
81
|
</MacSelect.Trigger>
|
|
80
82
|
</MacSelect.Root>
|
|
81
|
-
</
|
|
83
|
+
</MacMotionProvider>
|
|
82
84
|
);
|
|
83
85
|
}
|
|
84
86
|
```
|
|
@@ -109,7 +111,7 @@ The following components are now in the shared library and can be imported by an
|
|
|
109
111
|
`MacHelpButton`, `MacCheckbox`, `MacCheckboxGroup`, `MacCollapsible`,
|
|
110
112
|
`MacCombobox`, `MacContextMenu`, `MacDialog`, `MacDrawer`, `MacField`,
|
|
111
113
|
`MacFieldset`, `MacForm`, `MacInput`, `MacTextField`, `MacSearchField`,
|
|
112
|
-
`MacMenu`, `MacMenubar`, `MacMeter`, `MacNavigationMenu`,
|
|
114
|
+
`MacMenu`, `MacMenubar`, `MacMeter`, `MacMotionProvider`, `MacNavigationMenu`,
|
|
113
115
|
`MacNumberField`, `MacOTPField`, `MacPopover`,
|
|
114
116
|
`MacPreviewCard`, `MacProgress`, `MacRadio`, `MacRadioGroup`,
|
|
115
117
|
`MacScrollArea`, `MacSelect`, `MacSeparator`, `MacSlider`, `MacSwitch`,
|
package/changelog.md
CHANGED
|
@@ -2,6 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
This file tracks changes between published npm versions of `mac-human-design`.
|
|
4
4
|
|
|
5
|
+
## 0.1.6
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added Motion for React as the default animation layer for the macOS Base UI
|
|
10
|
+
wrappers.
|
|
11
|
+
- Added `MacMotionProvider`, which applies the shared Motion transition config
|
|
12
|
+
and respects the user's reduced-motion preference by default.
|
|
13
|
+
- Added default macOS motion presets for controls, fields, selection controls,
|
|
14
|
+
panels, popups, dialogs, drawers, indicators, feedback meters, and utility
|
|
15
|
+
surfaces.
|
|
16
|
+
- Added verifier coverage for Motion peer/dev dependencies, provider export,
|
|
17
|
+
reduced-motion config, default transitions, and safe module-scope
|
|
18
|
+
`motion.create()` usage.
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- Bumped the package to `0.1.6`.
|
|
23
|
+
- Added `motion` as a required peer dependency and development dependency.
|
|
24
|
+
- Updated the gallery to render inside `MacMotionProvider` so animation defaults
|
|
25
|
+
are exercised by the shipped example app.
|
|
26
|
+
|
|
5
27
|
## 0.1.5
|
|
6
28
|
|
|
7
29
|
### Changed
|
|
@@ -7,8 +7,10 @@
|
|
|
7
7
|
import "mac-human-design/styles/macos-base-ui.css";
|
|
8
8
|
```
|
|
9
9
|
|
|
10
|
-
Consumer apps install `@base-ui/react`, `react`, and `react-dom` as
|
|
11
|
-
dependencies alongside this package.
|
|
10
|
+
Consumer apps install `@base-ui/react`, `motion`, `react`, and `react-dom` as
|
|
11
|
+
peer dependencies alongside this package. Motion animations are enabled by
|
|
12
|
+
default through the macOS wrappers and respect the user's reduced-motion
|
|
13
|
+
preference through `MacMotionProvider`.
|
|
12
14
|
|
|
13
15
|
## Component Families
|
|
14
16
|
|
|
@@ -70,6 +72,7 @@ render UI.
|
|
|
70
72
|
| Borderless button | `MacPlainButton` |
|
|
71
73
|
| Icon button | `MacIconButton` |
|
|
72
74
|
| Help button | `MacHelpButton` |
|
|
75
|
+
| Motion defaults provider | `MacMotionProvider` |
|
|
73
76
|
| Text field | `MacTextField` / `MacInput` |
|
|
74
77
|
| Search field | `MacSearchField` |
|
|
75
78
|
| Pop-up button | `MacSelect.PopUpButtonTrigger` |
|
|
@@ -104,6 +107,8 @@ The gate typechecks the library and verifies:
|
|
|
104
107
|
- macOS design features are present: system font stack, dark mode, reduced motion,
|
|
105
108
|
keyboard focus rings, accent tokens, styled `hd-mac` classes, and typography
|
|
106
109
|
constraints,
|
|
110
|
+
- Motion integration is present: dependency declarations, `MacMotionProvider`,
|
|
111
|
+
reduced-motion config, default transitions, and module-scope `motion.create()`,
|
|
107
112
|
- the visual gallery can be bundled for production from the shipped source,
|
|
108
113
|
- old UI-foundation references have not returned.
|
|
109
114
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mac-human-design",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "Reusable macOS-oriented UI primitives and SF Symbols bridge for Tauri apps.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -49,6 +49,7 @@
|
|
|
49
49
|
"peerDependencies": {
|
|
50
50
|
"@base-ui/react": "^1.5.0",
|
|
51
51
|
"@tauri-apps/api": "^2",
|
|
52
|
+
"motion": "^12.40.0",
|
|
52
53
|
"react": ">=18",
|
|
53
54
|
"react-dom": ">=18"
|
|
54
55
|
},
|
|
@@ -63,6 +64,7 @@
|
|
|
63
64
|
"@types/react": "^19.2.17",
|
|
64
65
|
"@types/react-dom": "^19.2.3",
|
|
65
66
|
"@vitejs/plugin-react": "^6.0.2",
|
|
67
|
+
"motion": "^12.40.0",
|
|
66
68
|
"react": "^19.2.7",
|
|
67
69
|
"react-dom": "^19.2.7",
|
|
68
70
|
"typescript": "^6.0.3",
|
|
@@ -47,7 +47,10 @@ function getBaseUiFamilies() {
|
|
|
47
47
|
|
|
48
48
|
function getMacExports(source) {
|
|
49
49
|
return new Set(
|
|
50
|
-
Array.from(
|
|
50
|
+
Array.from(
|
|
51
|
+
source.matchAll(/^export (?:const|function) (Mac[A-Za-z0-9]+)\b/gm),
|
|
52
|
+
(match) => match[1],
|
|
53
|
+
),
|
|
51
54
|
);
|
|
52
55
|
}
|
|
53
56
|
|
|
@@ -157,6 +160,7 @@ if (missingDocsRows.length > 0) {
|
|
|
157
160
|
}
|
|
158
161
|
|
|
159
162
|
const requiredVariants = [
|
|
163
|
+
"MacMotionProvider",
|
|
160
164
|
"MacPrimaryButton",
|
|
161
165
|
"MacSecondaryButton",
|
|
162
166
|
"MacDestructiveButton",
|
|
@@ -269,5 +273,5 @@ if (process.exitCode) {
|
|
|
269
273
|
}
|
|
270
274
|
|
|
271
275
|
console.log(
|
|
272
|
-
`Verified ${families.length} @base-ui/react component families, namespace parts, ${requiredVariants.length}
|
|
276
|
+
`Verified ${families.length} @base-ui/react component families, namespace parts, ${requiredVariants.length} provider/variant exports, ${requiredNestedVariants.length} nested variants, ${wrapperClasses.size} wrapper classes, gallery coverage, and no Base Web references.`,
|
|
273
277
|
);
|
|
@@ -4,6 +4,8 @@ import { fileURLToPath } from "node:url";
|
|
|
4
4
|
|
|
5
5
|
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
6
6
|
const stylesPath = path.join(repoRoot, "src", "styles", "macosBaseUi.css");
|
|
7
|
+
const packageJsonPath = path.join(repoRoot, "package.json");
|
|
8
|
+
const wrapperPath = path.join(repoRoot, "src", "components", "MacBaseUI.tsx");
|
|
7
9
|
|
|
8
10
|
function readText(filePath) {
|
|
9
11
|
return fs.readFileSync(filePath, "utf8");
|
|
@@ -39,6 +41,8 @@ const sources = new Map(
|
|
|
39
41
|
sourceFiles.map((relativeFile) => [relativeFile, readText(path.join(repoRoot, relativeFile))]),
|
|
40
42
|
);
|
|
41
43
|
const stylesSource = readText(stylesPath);
|
|
44
|
+
const packageJson = JSON.parse(readText(packageJsonPath));
|
|
45
|
+
const wrapperSource = readText(wrapperPath);
|
|
42
46
|
|
|
43
47
|
const requiredStyleFeatures = [
|
|
44
48
|
["system font stack", /-apple-system,\s*BlinkMacSystemFont/],
|
|
@@ -56,6 +60,44 @@ if (missingFeatures.length > 0) {
|
|
|
56
60
|
fail("Missing required macOS styling features.", missingFeatures);
|
|
57
61
|
}
|
|
58
62
|
|
|
63
|
+
const missingMotionDependencies = [];
|
|
64
|
+
if (!packageJson.peerDependencies?.motion) {
|
|
65
|
+
missingMotionDependencies.push("peerDependencies.motion");
|
|
66
|
+
}
|
|
67
|
+
if (!packageJson.devDependencies?.motion) {
|
|
68
|
+
missingMotionDependencies.push("devDependencies.motion");
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (missingMotionDependencies.length > 0) {
|
|
72
|
+
fail("Missing required Motion dependency declarations.", missingMotionDependencies);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const requiredMotionFeatures = [
|
|
76
|
+
["MotionConfig import", /import\s+\{[\s\S]*MotionConfig[\s\S]*\}\s+from\s+["']motion\/react["']/],
|
|
77
|
+
["motion import", /import\s+\{[\s\S]*\bmotion\b[\s\S]*\}\s+from\s+["']motion\/react["']/],
|
|
78
|
+
["MacMotionProvider export", /export function MacMotionProvider\b/],
|
|
79
|
+
["MotionProps wrapper typing", /React\.ComponentPropsWithoutRef<C> & MotionProps/],
|
|
80
|
+
["reduced motion user config", /reducedMotion\s*=\s*["']user["']/],
|
|
81
|
+
["motion.create wrapper", /motion\.create\(BaseWrapped as AnyComponent\)/],
|
|
82
|
+
["default Motion transition", /const macDefaultTransition:\s*Transition/],
|
|
83
|
+
];
|
|
84
|
+
|
|
85
|
+
const missingMotionFeatures = requiredMotionFeatures
|
|
86
|
+
.filter(([, pattern]) => !pattern.test(wrapperSource))
|
|
87
|
+
.map(([label]) => label);
|
|
88
|
+
|
|
89
|
+
if (missingMotionFeatures.length > 0) {
|
|
90
|
+
fail("Missing required Motion integration features.", missingMotionFeatures);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const motionCreateMatches = Array.from(wrapperSource.matchAll(/motion\.create\(/g));
|
|
94
|
+
const allowedMotionCreatePattern = /^\s*const MotionPart = motion\.create\(BaseWrapped as AnyComponent\);$/m;
|
|
95
|
+
if (motionCreateMatches.length !== 1 || !allowedMotionCreatePattern.test(wrapperSource)) {
|
|
96
|
+
fail("motion.create() must be called exactly once in the module-level macPart wrapper setup.", [
|
|
97
|
+
"src/components/MacBaseUI.tsx",
|
|
98
|
+
]);
|
|
99
|
+
}
|
|
100
|
+
|
|
59
101
|
const negativeLetterSpacing = [];
|
|
60
102
|
const viewportScaledFonts = [];
|
|
61
103
|
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
+
import {
|
|
3
|
+
MotionConfig,
|
|
4
|
+
motion,
|
|
5
|
+
type MotionConfigProps,
|
|
6
|
+
type MotionProps,
|
|
7
|
+
type TargetAndTransition,
|
|
8
|
+
type Transition,
|
|
9
|
+
} from "motion/react";
|
|
2
10
|
import { Accordion as BaseAccordion } from "@base-ui/react/accordion";
|
|
3
11
|
import { AlertDialog as BaseAlertDialog } from "@base-ui/react/alert-dialog";
|
|
4
12
|
import { Autocomplete as BaseAutocomplete } from "@base-ui/react/autocomplete";
|
|
@@ -42,6 +50,47 @@ import { Tooltip as BaseTooltip } from "@base-ui/react/tooltip";
|
|
|
42
50
|
|
|
43
51
|
type AnyComponent = React.ComponentType<any>;
|
|
44
52
|
type ClassNameProp = string | ((state: any) => string | undefined) | undefined;
|
|
53
|
+
type MacAnimatedComponent<C extends AnyComponent> = React.ForwardRefExoticComponent<
|
|
54
|
+
React.PropsWithoutRef<React.ComponentPropsWithoutRef<C> & MotionProps> & React.RefAttributes<unknown>
|
|
55
|
+
>;
|
|
56
|
+
type MotionDefaults = Pick<
|
|
57
|
+
MotionProps,
|
|
58
|
+
"initial" | "animate" | "exit" | "layout" | "whileFocus" | "whileHover" | "whileTap"
|
|
59
|
+
> & {
|
|
60
|
+
transition?: Transition;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const macDefaultTransition: Transition = {
|
|
64
|
+
default: { type: "spring", stiffness: 520, damping: 38, mass: 0.8 },
|
|
65
|
+
opacity: { duration: 0.12, ease: "easeOut" },
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const macFastTransition: Transition = {
|
|
69
|
+
default: { type: "spring", stiffness: 680, damping: 44, mass: 0.7 },
|
|
70
|
+
opacity: { duration: 0.09, ease: "easeOut" },
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const macSoftTransition: Transition = {
|
|
74
|
+
default: { type: "spring", stiffness: 420, damping: 34, mass: 0.9 },
|
|
75
|
+
opacity: { duration: 0.14, ease: "easeOut" },
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export type MacMotionProviderProps = React.PropsWithChildren<{
|
|
79
|
+
reducedMotion?: MotionConfigProps["reducedMotion"];
|
|
80
|
+
transition?: MotionConfigProps["transition"];
|
|
81
|
+
}>;
|
|
82
|
+
|
|
83
|
+
export function MacMotionProvider({
|
|
84
|
+
children,
|
|
85
|
+
reducedMotion = "user",
|
|
86
|
+
transition = macDefaultTransition,
|
|
87
|
+
}: MacMotionProviderProps) {
|
|
88
|
+
return (
|
|
89
|
+
<MotionConfig reducedMotion={reducedMotion} transition={transition}>
|
|
90
|
+
{children}
|
|
91
|
+
</MotionConfig>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
45
94
|
|
|
46
95
|
function joinClasses(...classes: Array<string | undefined | false>) {
|
|
47
96
|
return classes.filter(Boolean).join(" ");
|
|
@@ -54,8 +103,153 @@ function mergeClassName(macClassName: string, className: ClassNameProp): ClassNa
|
|
|
54
103
|
return joinClasses(macClassName, className);
|
|
55
104
|
}
|
|
56
105
|
|
|
106
|
+
function includesAny(value: string, tokens: string[]) {
|
|
107
|
+
return tokens.some((token) => value.includes(token));
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function isDisabled(props: Record<string, unknown>) {
|
|
111
|
+
return Boolean(props.disabled || props["data-disabled"] || props["aria-disabled"]);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function interactiveControlDefaults(macClassName: string, props: Record<string, unknown>): MotionDefaults {
|
|
115
|
+
if (isDisabled(props)) {
|
|
116
|
+
return {};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return {
|
|
120
|
+
whileHover: { y: -0.5, scale: 1.012 },
|
|
121
|
+
whileTap: { y: 1, scale: 0.985 },
|
|
122
|
+
transition: macFastTransition,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function fadeScaleDefaults(
|
|
127
|
+
initial: TargetAndTransition,
|
|
128
|
+
animate: TargetAndTransition = { opacity: 1, scale: 1, y: 0, x: 0 },
|
|
129
|
+
transition: Transition = macSoftTransition,
|
|
130
|
+
): MotionDefaults {
|
|
131
|
+
return {
|
|
132
|
+
initial,
|
|
133
|
+
animate,
|
|
134
|
+
exit: initial,
|
|
135
|
+
transition,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function getMotionDefaults(macClassName: string, props: Record<string, unknown>): MotionDefaults {
|
|
140
|
+
if (
|
|
141
|
+
includesAny(macClassName, [
|
|
142
|
+
"hd-mac-button",
|
|
143
|
+
"hd-mac-select-trigger",
|
|
144
|
+
"hd-mac-toggle",
|
|
145
|
+
"hd-mac-toolbar-button",
|
|
146
|
+
"hd-mac-stepper-button",
|
|
147
|
+
"hd-mac-disclosure-trigger",
|
|
148
|
+
])
|
|
149
|
+
) {
|
|
150
|
+
return interactiveControlDefaults(macClassName, props);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (macClassName.includes("hd-mac-input")) {
|
|
154
|
+
return {
|
|
155
|
+
whileFocus: { scale: 1.004 },
|
|
156
|
+
transition: macFastTransition,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (includesAny(macClassName, ["hd-mac-checkbox-indicator", "hd-mac-radio-indicator"])) {
|
|
161
|
+
return fadeScaleDefaults({ opacity: 0, scale: 0.72 }, { opacity: 1, scale: 1 });
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (macClassName.includes("hd-mac-switch-thumb") || macClassName.includes("hd-mac-slider-thumb")) {
|
|
165
|
+
return {
|
|
166
|
+
layout: true,
|
|
167
|
+
whileTap: { scale: 0.92 },
|
|
168
|
+
transition: macDefaultTransition,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (includesAny(macClassName, ["hd-mac-progress-indicator", "hd-mac-meter-indicator", "hd-mac-slider-indicator"])) {
|
|
173
|
+
return {
|
|
174
|
+
layout: true,
|
|
175
|
+
transition: macSoftTransition,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (includesAny(macClassName, ["hd-mac-popup", "hd-mac-popover", "hd-mac-preview-card"])) {
|
|
180
|
+
return fadeScaleDefaults({ opacity: 0, scale: 0.97, y: 4 });
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (macClassName.includes("hd-mac-tooltip")) {
|
|
184
|
+
return fadeScaleDefaults({ opacity: 0, scale: 0.96 }, { opacity: 1, scale: 1 }, macFastTransition);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (macClassName.includes("hd-mac-backdrop")) {
|
|
188
|
+
return fadeScaleDefaults({ opacity: 0 }, { opacity: 1 }, { duration: 0.16, ease: "easeOut" });
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (macClassName.includes("hd-mac-sheet-dialog")) {
|
|
192
|
+
return fadeScaleDefaults({ opacity: 0, y: -18, scale: 0.985 });
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if (macClassName.includes("hd-mac-alert-dialog")) {
|
|
196
|
+
return fadeScaleDefaults({ opacity: 0, scale: 0.94, y: 8 }, { opacity: 1, scale: 1, y: 0 });
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (macClassName.includes("hd-mac-dialog")) {
|
|
200
|
+
return fadeScaleDefaults({ opacity: 0, scale: 0.965, y: 10 });
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (macClassName.includes("hd-mac-sidebar-drawer")) {
|
|
204
|
+
return fadeScaleDefaults({ opacity: 0, x: -22 }, { opacity: 1, x: 0 });
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (macClassName.includes("hd-mac-drawer")) {
|
|
208
|
+
return fadeScaleDefaults({ opacity: 0, y: 18 }, { opacity: 1, y: 0 });
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (includesAny(macClassName, ["hd-mac-accordion-panel", "hd-mac-collapsible-panel", "hd-mac-tab-panel"])) {
|
|
212
|
+
return {
|
|
213
|
+
initial: { opacity: 0, y: 4 },
|
|
214
|
+
animate: { opacity: 1, y: 0 },
|
|
215
|
+
exit: { opacity: 0, y: 4 },
|
|
216
|
+
layout: true,
|
|
217
|
+
transition: macSoftTransition,
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (includesAny(macClassName, ["hd-mac-menu-item", "hd-mac-menu-row"])) {
|
|
222
|
+
return fadeScaleDefaults({ opacity: 0, x: -3 }, { opacity: 1, x: 0 }, macFastTransition);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (includesAny(macClassName, ["hd-mac-menu-item-indicator", "hd-mac-control-icon"])) {
|
|
226
|
+
return fadeScaleDefaults({ opacity: 0, scale: 0.76 }, { opacity: 1, scale: 1 }, macFastTransition);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (includesAny(macClassName, ["hd-mac-avatar", "hd-mac-avatar-image", "hd-mac-avatar-fallback"])) {
|
|
230
|
+
return fadeScaleDefaults({ opacity: 0, scale: 0.92 });
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (includesAny(macClassName, ["hd-mac-error-text", "hd-mac-help-text", "hd-mac-status-text", "hd-mac-validity"])) {
|
|
234
|
+
return fadeScaleDefaults({ opacity: 0, y: -3 }, { opacity: 1, y: 0 }, macFastTransition);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (includesAny(macClassName, ["hd-mac-separator", "hd-mac-fieldset", "hd-mac-form"])) {
|
|
238
|
+
return {
|
|
239
|
+
initial: { opacity: 0 },
|
|
240
|
+
animate: { opacity: 1 },
|
|
241
|
+
transition: { duration: 0.12, ease: "easeOut" },
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return {
|
|
246
|
+
layout: includesAny(macClassName, ["hd-mac-toggle-group", "hd-mac-tabs", "hd-mac-navigation-menu"]),
|
|
247
|
+
transition: macDefaultTransition,
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
|
|
57
251
|
function macPart<C extends AnyComponent>(Component: C, macClassName: string) {
|
|
58
|
-
const
|
|
252
|
+
const BaseWrapped = React.forwardRef<unknown, React.ComponentPropsWithoutRef<C>>((props, ref) => {
|
|
59
253
|
const TypedComponent = Component as AnyComponent;
|
|
60
254
|
const { className, ...rest } = props as Record<string, unknown>;
|
|
61
255
|
return React.createElement(TypedComponent, {
|
|
@@ -65,8 +259,21 @@ function macPart<C extends AnyComponent>(Component: C, macClassName: string) {
|
|
|
65
259
|
});
|
|
66
260
|
});
|
|
67
261
|
|
|
262
|
+
BaseWrapped.displayName = `MacBase${Component.displayName ?? Component.name ?? "BaseUIPart"}`;
|
|
263
|
+
|
|
264
|
+
const MotionPart = motion.create(BaseWrapped as AnyComponent);
|
|
265
|
+
const Wrapped = React.forwardRef<unknown, React.ComponentPropsWithoutRef<C>>((props, ref) => {
|
|
266
|
+
const rest = props as Record<string, unknown>;
|
|
267
|
+
const motionDefaults = getMotionDefaults(macClassName, rest);
|
|
268
|
+
return React.createElement(MotionPart as AnyComponent, {
|
|
269
|
+
...motionDefaults,
|
|
270
|
+
...rest,
|
|
271
|
+
ref,
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
|
|
68
275
|
Wrapped.displayName = `Mac${Component.displayName ?? Component.name ?? "BaseUIPart"}`;
|
|
69
|
-
return Wrapped as unknown as C
|
|
276
|
+
return Wrapped as unknown as MacAnimatedComponent<C>;
|
|
70
277
|
}
|
|
71
278
|
|
|
72
279
|
function macProvider<C extends AnyComponent>(Component: C) {
|
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
MacMenu,
|
|
25
25
|
MacMenubar,
|
|
26
26
|
MacMeter,
|
|
27
|
+
MacMotionProvider,
|
|
27
28
|
MacNavigationMenu,
|
|
28
29
|
MacNumberField,
|
|
29
30
|
MacOTPField,
|
|
@@ -76,7 +77,8 @@ export function MacBaseUIGallery() {
|
|
|
76
77
|
return (
|
|
77
78
|
<MacCSPProvider>
|
|
78
79
|
<MacDirectionProvider direction="ltr">
|
|
79
|
-
<
|
|
80
|
+
<MacMotionProvider>
|
|
81
|
+
<div className="hd-mac hd-mac-gallery">
|
|
80
82
|
<GallerySection title="Buttons">
|
|
81
83
|
<MacButton>Default</MacButton>
|
|
82
84
|
<MacPrimaryButton>Continue</MacPrimaryButton>
|
|
@@ -421,7 +423,8 @@ export function MacBaseUIGallery() {
|
|
|
421
423
|
<MacToast.Viewport />
|
|
422
424
|
</MacToast.Provider>
|
|
423
425
|
</GallerySection>
|
|
424
|
-
|
|
426
|
+
</div>
|
|
427
|
+
</MacMotionProvider>
|
|
425
428
|
</MacDirectionProvider>
|
|
426
429
|
</MacCSPProvider>
|
|
427
430
|
);
|