diff --git a/.agents/skills/widget-audit.md b/.agents/skills/widget-audit.md index d5a04a8a5280..2442a83c1f22 100644 --- a/.agents/skills/widget-audit.md +++ b/.agents/skills/widget-audit.md @@ -83,7 +83,12 @@ assume: namespace, text domain, and the dependency versions the package resolves - Props are a named `type`/`interface` with each field documented on the type, not echoed in `@param`. A component takes one typed tag (`@param {Props} props - The component props.`) — never `@param props.` - blocks; plain functions keep positional `@param`s. + blocks. +- The same one-typed-tag rule applies to ANY function taking an object argument + (hooks, story helpers, test builders): `@param {UseXArgs} args - Hook + arguments.` with fields documented on the args type — never `@param + args.` / `@param root0.` blocks. Only scalar positional + parameters keep plain per-param tags (`@param interval - The interval.`). - Descriptions track the code: referenced symbols still exist, terminology is consistent (`widget.json` ↔ `widget.ts` ↔ rendered strings), `@return` is accurate. - Verify, don't guess: `jsdoc/require-param` is satisfied by that single typed diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 935892d5e397..ea19798a8c26 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4036,11 +4036,11 @@ importers: specifier: 4.50.0 version: 4.50.0 '@wordpress/widget-dashboard': - specifier: 0.2.0 - version: 0.2.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 0.3.1-next.v.202607070741.0 + version: 0.3.1-next.v.202607070741.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@wordpress/widget-primitives': - specifier: 0.2.0 - version: 0.2.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 0.3.1-next.v.202607070741.0 + version: 0.3.1-next.v.202607070741.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) clsx: specifier: 2.1.1 version: 2.1.1 @@ -4091,8 +4091,8 @@ importers: specifier: 10.2.0 version: 10.2.0 '@wordpress/build': - specifier: 0.18.0 - version: 0.18.0(@babel/core@7.29.7)(@wordpress/boot@0.17.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@wordpress/private-apis@1.50.0)(@wordpress/route@0.16.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@wordpress/theme@0.17.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(browserslist@4.28.4) + specifier: 0.19.1-next.v.202607070741.0 + version: 0.19.1-next.v.202607070741.0(@babel/core@7.29.7)(@wordpress/boot@0.17.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@wordpress/private-apis@1.50.0)(@wordpress/route@0.16.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@wordpress/theme@0.17.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(browserslist@4.28.4) browserslist: specifier: 4.28.4 version: 4.28.4 @@ -6947,34 +6947,65 @@ packages: '@ariakit/components@0.1.2': resolution: {integrity: sha512-tvh2P0x1cJnoPXnmDEJwdRk3z7x6cTB8ArctcZdAUXlRg9tuwW/rJoBFJMzD5qMI9CDDlQ3Zctx58HvENw4BYw==} + '@ariakit/components@0.1.5': + resolution: {integrity: sha512-LnvU9bcOU2IkQS3jCFm2rxcULNtG55+M+fh66mFf4EEBHJnDoTdN7zNRtm1dyzcFn6hAn/AoLl3Hyg95RIGUOA==} + '@ariakit/react-components@0.1.2': resolution: {integrity: sha512-SM+SPMAVlOZmGAfWNBza+0k9y4mkA5/dJhDoOyhE96cbNARy665uLdwowSJl1JGuFfcZzuzAwGon7f/rYeyfkQ==} peerDependencies: react: ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 + '@ariakit/react-components@0.3.1': + resolution: {integrity: sha512-SJ/xfL3vj20TX6p/Gx39wbQtfNKL66uQ8MtnW8yU7Mv3DnOr/riFUKZnTuVjl+rMfwCdiGoHK1DdYiFKSaHG5w==} + peerDependencies: + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 + '@ariakit/react-store@0.1.2': resolution: {integrity: sha512-1r1Gn0tqhnOS0LFvHNGzn5/8C5aOANO5vb0Gxh94oR/be4zwCSE2zfQjOjRfpL+BBDhOcProME2+G6UslEJxbg==} peerDependencies: react: ^17.0.0 || ^18.0.0 || ^19.0.0 + '@ariakit/react-store@0.1.5': + resolution: {integrity: sha512-EMB7dG0aD+MqI/0M8dzmwPObGYoWx7lvJK4tKmTDDbuGIW+XwrKfG3n1dMkWgg/TEq5lDNE7S3WbpE8mRfXpPA==} + peerDependencies: + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + '@ariakit/react-utils@0.1.2': resolution: {integrity: sha512-Rnl6D1542Mqu80xK++oUv1JXS0PtNmKXd9nkdud5nyvySiBDTrmPqRW44/D+5GbuZrboreQuY3tPYwKL7a7onQ==} peerDependencies: react: ^17.0.0 || ^18.0.0 || ^19.0.0 + '@ariakit/react-utils@0.2.0': + resolution: {integrity: sha512-tyIx/qxYY5i8ntGSzDYZ5Olak7zZ58QeEYjbbMNSZEywgtrQlKhZXkVnXK72UkGXmCLg7OrrTsesv8Qh6Bx2LQ==} + peerDependencies: + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + '@ariakit/react@0.4.29': resolution: {integrity: sha512-SLXlsddWHSwfUol4Yi0zULlalNWjzWjpS3zg7B7aaPd64saONQ5ktWf9KMxqBklcpjMLeF2dB9BAHAvpPVdCIQ==} peerDependencies: react: ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 + '@ariakit/react@0.4.32': + resolution: {integrity: sha512-ar5lyS/Pp/+p1TdAqsS8gHzL/E9df8uWXYmEsD/Olpv4hp9LVEtwM6FfOu57sn6qaycs2xWFN9GinmXkMd8LWA==} + peerDependencies: + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 + '@ariakit/store@0.1.2': resolution: {integrity: sha512-SS7bV4+a+1q9M9i0WV6DD4P/ypRKlCvII8soo2UMe1yuaxZA/Fc0htHe+EZwjJ6TMLjHfHh2TDSnXyrjC7QImA==} + '@ariakit/store@0.1.4': + resolution: {integrity: sha512-VQDtp5eq4MgIjxzo6M/6NN2sVx8WykiSs9HNMv2AnfAGntF1fMA6cxCuBIFFWkHekNMGWwe/utzbTt3J/mtuiA==} + '@ariakit/utils@0.1.2': resolution: {integrity: sha512-lBJhtBWpKjIck/9i7G8cahvaUgLsyGklI/Pjv+VtY9KTzyuzX5GpRbbLKMS/e1qLnFPS4C3CybYB70b1bVcAkw==} + '@ariakit/utils@0.1.4': + resolution: {integrity: sha512-gIC/FR/gcOtp2FQQDOnRPfxizJjqp4PSQWS7fH2tNr6O6iTwwW8CPao7VUpu8Y8xKeMXrvzHvkOHhBhfBf4OrA==} + '@arraypress/waveform-player@1.2.1': resolution: {integrity: sha512-PsgOZStUN+1GnY0tujbwk2PYE3HMT/Vl3wEvunqH16hIJWzisf8GEngy5EbswTAjQ1aV3Tk4XBkAskc8eslY1A==} engines: {node: '>=14.0.0'} @@ -7804,8 +7835,8 @@ packages: resolution: {integrity: sha512-K8ponJDxBwDHigkeFqaqT5wLGl4bTlwMafR8k7b5CPxr6Ww+UG9ls8Yx6Tcpboxu97eeGVEEyKcHmEyOwN1vSw==} engines: {node: ^22.18.0 || >=24.11.0} - '@base-ui/react@1.5.0': - resolution: {integrity: sha512-z1gSAlced1yY+iM+mHDEtIkD8UI3Ebs52MuBPxvV6f5hRutk+xvCH/wuB7hDqDzK9JG5FoMz5nhrqtSs1wjt1A==} + '@base-ui/react@1.6.0': + resolution: {integrity: sha512-/jzjTWJYXhRFO45Bev9lc3cHbmjzCMpUqbMZ2AgKy/z25mY9B6shGSNcXcjQar9n5doM0KYW1W8fcFv2jZBuMw==} engines: {node: '>=14.0.0'} peerDependencies: '@date-fns/tz': ^1.2.0 @@ -7821,8 +7852,8 @@ packages: date-fns: optional: true - '@base-ui/utils@0.2.9': - resolution: {integrity: sha512-x/PDDCYzoqPpjrdyb3VcyylTI2IjUXEtYDGi5foh7KsnmNJIIaVwA2GLgDH1dps1GgXiJbA60hM+AyuTfQzIvw==} + '@base-ui/utils@0.3.1': + resolution: {integrity: sha512-gFFiltORVmW/N6IILTGxizP3PBpVpysqML1ALY5Vk0mH+7faVkCknOU31goYHN5Aoek2dkjxva1XOD2Ce9WuIg==} peerDependencies: '@types/react': ^17 || ^18 || ^19 react: ^17 || ^18 || ^19 @@ -11257,6 +11288,10 @@ packages: resolution: {integrity: sha512-c/1EeqliArkmxSlRmDzbRoNGGMmhsAiCgenWmvJzpWwF3rVoyjF/DClps5GagAO1sbg+6Q1bsxgg3svCEhLdAg==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} + '@wordpress/a11y@4.50.1-next.v.202607070741.0': + resolution: {integrity: sha512-3Wra8DUZBTVzrDAuNO/O7veLIv+QiThe57Yav6c1jHG4ntixQABsPeHHpIFks9dK25tNIJ/oAmugyN6U7v1cJw==} + engines: {node: '>=18.12.0', npm: '>=8.19.2'} + '@wordpress/admin-ui@2.5.0': resolution: {integrity: sha512-3hAVtby7FBG3pv+OI7UmAPNOjGbi6JKQrUuDDzlkGsyDWfwZqwaeCU+fx69i/RkI7ZI9RsqWmhCIB3GbljQHVw==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} @@ -11299,6 +11334,10 @@ packages: resolution: {integrity: sha512-iDPbyyeUnxLFq4ec+03x87jT8lRoBzK2rDoEg24l2KNAR9ZJ2kwI0z2E/wW0fOZC37A7qr377KJslPHKLtMgyQ==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} + '@wordpress/base-styles@10.3.1-next.v.202607070741.0': + resolution: {integrity: sha512-Wk5/5jdSMiDrPDj5Jldnq1b28K6M3nOOBOAl/E1A/T3AxiMuHEfb/L4+NHcWp+kRW69j3tWDBc3VEtAg73QjFg==} + engines: {node: '>=18.12.0', npm: '>=8.19.2'} + '@wordpress/blob@4.50.0': resolution: {integrity: sha512-eDKSl+kfhq9wcSuOReor2YFDyih1BrvuzzCI0hXJjBv3IStb65AfzYii4/dYmjipqkJEmjsU7crLr5612EMIdw==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} @@ -11373,6 +11412,25 @@ packages: '@wordpress/theme': optional: true + '@wordpress/build@0.19.1-next.v.202607070741.0': + resolution: {integrity: sha512-4b5hAcWKKXHDzh0nWXXvskPXKqxOQW0HXKRV3R0DL5EA5JbQM/owVkqd6LVUP2hJ2LluupSNYKDSjrAMi61ovQ==} + engines: {node: '>=20.10.0', npm: '>=10.2.3'} + hasBin: true + peerDependencies: + '@wordpress/boot': '>=0.3.0 <1.0.0' + '@wordpress/private-apis': ^1.0.0 + '@wordpress/route': '>=0.2.0 <1.0.0' + '@wordpress/theme': '>=0.8.0 <1.0.0' + peerDependenciesMeta: + '@wordpress/boot': + optional: true + '@wordpress/private-apis': + optional: true + '@wordpress/route': + optional: true + '@wordpress/theme': + optional: true + '@wordpress/commands@1.50.0': resolution: {integrity: sha512-5T6VF6BWXbbTwheNwWBYUcUuXeS5xuXVCFTU3WTj+3SWxx/oU7zACSgdML6xCA50zJiRF/17vez/viyXVL+d0g==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} @@ -11380,6 +11438,13 @@ packages: react: ^18.0.0 react-dom: ^18.0.0 + '@wordpress/commands@1.50.1-next.v.202607070741.0': + resolution: {integrity: sha512-0HE+SGXrHN486RDkKWCcQySy0PF9TAHJ6OnHWPPMQzCAor1E+0/aFX/W3BypbT6/OedFMZnQJo40jWeJVARZGA==} + engines: {node: '>=18.12.0', npm: '>=8.19.2'} + peerDependencies: + react: ^18.0.0 + react-dom: ^18.0.0 + '@wordpress/components@36.1.0': resolution: {integrity: sha512-EapV2VXhNIDhWA+yTukQz++IfpqY8gVDvQ9bU8g1RKJqK3dhaVJ9NG2Rqk3TPsFxrmEGNHJwdb+SRUdLFAr3Zg==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} @@ -11391,6 +11456,17 @@ packages: '@types/react': optional: true + '@wordpress/components@37.0.1-next.v.202607070741.0': + resolution: {integrity: sha512-GgunaE/Li4dUU7DnqHwxpSNLM/roXt1UGWODEnnHIfQSt7Gw3FeFpdArGr7BC+cHlmmc+0qRaEVizLlsqZc9zQ==} + engines: {node: '>=18.12.0', npm: '>=8.19.2'} + peerDependencies: + '@types/react': ^18.3.27 + react: ^18.0.0 + react-dom: ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@wordpress/compose@7.46.0': resolution: {integrity: sha512-6Yv9Wb6tlA4JYU9bdWWuIWpTTzBAVA1zrYu1GY9x2/mCOckk9iLcEEfbKULxdjwwcMo3SKqvyby4f6kEUw/Wsw==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} @@ -11407,6 +11483,16 @@ packages: '@types/react': optional: true + '@wordpress/compose@8.3.1-next.v.202607070741.0': + resolution: {integrity: sha512-Lm/a0olJd9Sq5VQ1JRt5j5fWqqpCaJ1CToPLQvbFE+Y1Bp3cy4ze87Eifa/okbGcOXVxq7qGkCsCMg4+R/zHSg==} + engines: {node: '>=18.12.0', npm: '>=8.19.2'} + peerDependencies: + '@types/react': ^18.3.27 + react: ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@wordpress/core-data@7.50.0': resolution: {integrity: sha512-lSCixe7sRuF2dNK+NcklfBSLsTHZ3rM29c32gw/IvweOlyIuhZc1YaRGhX49T+evLwEhY0yHfGiE6AL/azwlBg==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} @@ -11431,6 +11517,13 @@ packages: '@types/react': ^18.3.27 react: ^18.0.0 + '@wordpress/data@10.50.1-next.v.202607070741.0': + resolution: {integrity: sha512-7sz/KnvlNSMAEAIgg7XlMBhN4NeTz8mbBPYHY9I0bGx8MmTw2aBHkbK9TH7W6HNzshOLbnhZrF259X7gTTjbIQ==} + engines: {node: '>=18.12.0', npm: '>=8.19.2'} + peerDependencies: + '@types/react': ^18.3.27 + react: ^18.0.0 + '@wordpress/dataviews@17.1.0': resolution: {integrity: sha512-tI09o5MadPL0EoQQQIkuUOOP5ihB6Wf9FNjqwQoZZj/ig3PDD3Ce7QcxWoDWXXQboSVJZnQigXESGuTxxrMtQA==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} @@ -11441,10 +11534,24 @@ packages: '@types/react': optional: true + '@wordpress/dataviews@17.1.2-next.v.202607070741.0': + resolution: {integrity: sha512-yUE2Vp+cbBj4977OzaApBkiahsQNLr2QFilhxJwfIznN01QG4xShCtBlEsgLomKwS1ljhWYtda0hLpzemfz57w==} + engines: {node: '>=18.12.0', npm: '>=8.19.2'} + peerDependencies: + '@types/react': ^18.3.27 + react: ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@wordpress/date@5.50.0': resolution: {integrity: sha512-cTRKN9dweiDdRj+NUMsZiEQ0EldKXDNahSRLq8ByJR2TTG73o484SYD0UitcbdIL2DryAYzZ9o57AoRpMaGMvA==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} + '@wordpress/date@5.50.1-next.v.202607070741.0': + resolution: {integrity: sha512-su9YQlqEqPxoA23kNSnhiLdJLIw8U9VdyqTwNxBRslikxgaDMMtZElXb5sfazT9SspKj8zv1eGkpbJXgMsv5Zw==} + engines: {node: '>=18.12.0', npm: '>=8.19.2'} + '@wordpress/dependency-extraction-webpack-plugin@6.50.0': resolution: {integrity: sha512-YtYtLkAUdLXTCFwLxB/RbpBb19egvOvrEk/aZWxSXBT+sg6fNvTgYvkRMOqaVjja0CWDHGm9DJosZOnvAxuCDQ==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} @@ -11455,14 +11562,26 @@ packages: resolution: {integrity: sha512-TVJavTbunFoCSo2g64EKtGwmDVJhvlSqsc4T1EM4aBwsYGIJPjHcAzh6KS8Z171QXFnBxZ7We8CCDAvOFU9iaA==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} + '@wordpress/deprecated@4.50.1-next.v.202607070741.0': + resolution: {integrity: sha512-k448i7mpqNtWkj+qKJzSYi2ZHTwyTa4qY/AIaqACxMoyTO6Edt96Bexy29tNhDGNh1aBW7dl8Q345WLVkPauKA==} + engines: {node: '>=18.12.0', npm: '>=8.19.2'} + '@wordpress/dom-ready@4.50.0': resolution: {integrity: sha512-y+nZ8/gm91cV+F6DP1hoQTtYIy+3/YYGQui0lRRgTMOywrlZLt7rDbKBsEsznPOsDo0880LspEOTDX12Qrps8A==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} + '@wordpress/dom-ready@4.50.1-next.v.202607070741.0': + resolution: {integrity: sha512-o6t69QBMVVpSZpZKk4FaS1tT5MF9RyhOdvxeiTo0UpNh2zTheXTUTXqd8egDqp8vlfQbX/p+XyTP8AFPO9PBtg==} + engines: {node: '>=18.12.0', npm: '>=8.19.2'} + '@wordpress/dom@4.50.0': resolution: {integrity: sha512-2Mognc1rwe1+tlIfbSeZPqbuAh6vJagELzw9cLasObiVayWhaG+LCIp0sJz2pPG9ppz8L31gGUgna7zrSRu85Q==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} + '@wordpress/dom@4.50.1-next.v.202607070741.0': + resolution: {integrity: sha512-8tXTbSenBOj4ydApV4ISsqmfs5KUX89PWlfUecPaq0RGerN+q2xAWROZh8zzO8BdH2hBD+UhQmsvzvAJfPHchw==} + engines: {node: '>=18.12.0', npm: '>=8.19.2'} + '@wordpress/e2e-test-utils-playwright@1.50.0': resolution: {integrity: sha512-P55NxY86M8lNnAbEPmpEswbxBoB7BWVhg67KOLRsGwLMeJ4qHbBngmgBIUt72IAH3H2UWVq7jZ1Xm/J1ENOMoQ==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} @@ -11496,10 +11615,18 @@ packages: resolution: {integrity: sha512-cTnKRHUdZbYAd4RaJiUwhDKdQDDWY7VoGiwektCmhiBQF6WTFYlhsxl/dmHE0Sok3q7PJQwAg538XEb8WuTaew==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} + '@wordpress/element@8.2.1-next.v.202607070741.0': + resolution: {integrity: sha512-HtvGY8R+7bjLANSBtVKqzhjgnWMARBqCAG0lhYxBHMn2wkFU4ToHrDwpAepcJcIyXGWMLFl+wxCKvmSHH1qPXA==} + engines: {node: '>=18.12.0', npm: '>=8.19.2'} + '@wordpress/escape-html@3.50.0': resolution: {integrity: sha512-EECt++WB1RNPQBwBS7/6rKO4eUNq2xe6nb6Guv6uT+F74DgtM3+aZtNs7JhKFxRMORPtu7T0LhlAOBa4H5CsPQ==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} + '@wordpress/escape-html@3.50.1-next.v.202607070741.0': + resolution: {integrity: sha512-pc7G7rzzr9jj8q8TndKLYleaulZN+mLzertMhbPZC4F8b6dZ/n9HkzHo2OeWZX1pjSladj2YN5jY5GHqqQizZw==} + engines: {node: '>=18.12.0', npm: '>=8.19.2'} + '@wordpress/eslint-plugin@25.6.0': resolution: {integrity: sha512-TZ1M+S8gk0MltuF2WsiNG4sjIUvaurB036v4QL81HM3DsfjPFOpKykyWswWO/iZv/e0f/ryG4O/aDfMbU+oEHg==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} @@ -11562,8 +11689,8 @@ packages: '@types/react': optional: true - '@wordpress/grid@0.2.0': - resolution: {integrity: sha512-1++AAV+CBN1ydi6cy7x+VPvvK2393G72MdUexgwWoACzCL0Yc6VZ0x8UUOdjoSO57RCI0B5Hd9rNYPYgr4DSXw==} + '@wordpress/grid@0.2.1-next.v.202607070741.0': + resolution: {integrity: sha512-yTNRilk3MAYS5kSjHL/nL2UVPO/lbn145Kvx4cv4beaDl7eWHxWBfUwtlC4U625g2J2NSQCHVtJQncDb7eHpcw==} engines: {node: '>=20.10.0', npm: '>=10.2.3'} peerDependencies: '@types/react': ^18.3.27 @@ -11577,15 +11704,28 @@ packages: resolution: {integrity: sha512-dV/AeP9iH1UydVWoUoCPuM8FUx2XvL1i65dhiwRHmZxK/zz8nR5Rq75WISpwFzRYfsyRThjl4LwUxhFAQnHrDw==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} + '@wordpress/hooks@4.50.1-next.v.202607070741.0': + resolution: {integrity: sha512-oud0j/ZM+rKQKOvPADdQI85Aq577pTiv1ztEptY4lvk5E9B6Byav6mtw26uAsrOzKQ1bKYYA4W/hMoca+9BPXQ==} + engines: {node: '>=18.12.0', npm: '>=8.19.2'} + '@wordpress/html-entities@4.50.0': resolution: {integrity: sha512-RWoT58IXeX82fC7zBLiTNEDdKN/fTAHWlMJbEwMH65UTzJt5jNWtmVdbtTZP248ceyAK3lUsWaXei2t1bqAyNA==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} + '@wordpress/html-entities@4.50.1-next.v.202607070741.0': + resolution: {integrity: sha512-WmNahS+S4ORm3iwkN74zC1dYGbEnHgwr1p1bbKzTeLHmfG6d2h3ByYke/pBmIvdYtrY4166afw6r4m0nqUAYXw==} + engines: {node: '>=18.12.0', npm: '>=8.19.2'} + '@wordpress/i18n@6.23.0': resolution: {integrity: sha512-avuywVdBpOeHm9cghFcNXCKi/VlJhbJ6KN6LydQOy/NqdRbqyRc59/XlKk1Ks+Vb+dWTGKr5gjiSzm9QJETGmA==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} hasBin: true + '@wordpress/i18n@6.23.1-next.v.202607070741.0': + resolution: {integrity: sha512-ZNWVIazhmJLT2r0G73IK3OKbWpPFlky4PMFE3qr3ludN4W6XQSR/yGuZvbxZpcT2CkZnzCBCUjUyar4juh4ctA==} + engines: {node: '>=18.12.0', npm: '>=8.19.2'} + hasBin: true + '@wordpress/icons@10.32.0': resolution: {integrity: sha512-1WvJdT361X1LnetYBpBWUjAVXZzl+pBdIwHbYRAp8ej47EI/igPmNxmq81nFd40s8fer/9qtipielcqSI6H2rA==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} @@ -11602,6 +11742,16 @@ packages: '@types/react': optional: true + '@wordpress/icons@15.1.1-next.v.202607070741.0': + resolution: {integrity: sha512-EpG4sgDcCDOAK3ZpOW921A27WJm8Ni+vReC4vrPUw3IOISf0oLDr9ixLbOuBd77K0kN7bsKYgq7szP7xdR986g==} + engines: {node: '>=18.12.0', npm: '>=8.19.2'} + peerDependencies: + '@types/react': ^18.3.27 + react: ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@wordpress/image-cropper@1.14.0': resolution: {integrity: sha512-Uu441xNKPfGcSr52obC3AoyXr++8t2Iepsk1XG0rXHE5OW7xbEit8fMwrn3lxQL4sZ78UFTI8ojNsieCpKK3RQ==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} @@ -11632,6 +11782,10 @@ packages: resolution: {integrity: sha512-Cq1brW/OhGVNnCqSztHgmKQ1DsNUtEq4F1xIo1awBKVmXDWFggJRxzaWZHWC+sDZmBp7pu03jWqq2u/s+hazSQ==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} + '@wordpress/is-shallow-equal@5.50.1-next.v.202607070741.0': + resolution: {integrity: sha512-KqoOQi9TUt8zyYt0hFnPPeNN5vKQK2VfOwFo2Ttw7DEKtOwSQj3UhEaAC3NCuxslXNoQ+v4iFyZcAAXH8phvHA==} + engines: {node: '>=18.12.0', npm: '>=8.19.2'} + '@wordpress/jest-console@8.50.0': resolution: {integrity: sha512-iV6h5nWylCrL/4Wt7kXvq8YRwhryLgxThliaPLVvMfHb4CM6MJzapoIw5l8YIs1CDRlBU6N9j9oAxLBXvhrHqA==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} @@ -11648,6 +11802,16 @@ packages: '@types/react': optional: true + '@wordpress/keyboard-shortcuts@5.50.1-next.v.202607070741.0': + resolution: {integrity: sha512-4iTk++hN2wOof+wFSagircPWwNaYvCqFNRtZz8zoIYUUX9inPKRUPKMd3ZfusBveKN9s26gXNBo3jNyE9/NQ2g==} + engines: {node: '>=18.12.0', npm: '>=8.19.2'} + peerDependencies: + '@types/react': ^18.3.27 + react: ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@wordpress/keycodes@4.50.0': resolution: {integrity: sha512-BtyCkA7pk5pMMx+dVjT10OuhQwr9ZjYY1LLcXJcYJjhhFsP16be2BiytrBnKDZj/479/icvEYwlooawZCPrxYQ==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} @@ -11657,6 +11821,15 @@ packages: '@types/react': optional: true + '@wordpress/keycodes@4.50.1-next.v.202607070741.0': + resolution: {integrity: sha512-d8znavcgOQ0O2PhoT/G4cDDLI6Bp9HLuaYTPQFedAZuO9BetZ2Gh8r9iE6/KTd6k1wbDMrxQeVqXf8bwTcNc4Q==} + engines: {node: '>=18.12.0', npm: '>=8.19.2'} + peerDependencies: + '@types/react': ^18.3.27 + peerDependenciesMeta: + '@types/react': + optional: true + '@wordpress/latex-to-mathml@1.18.0': resolution: {integrity: sha512-C27RXC8hiq1W5dbBm0AnMgMzN3FcGrGpJxJTxfipk7+Ujp08jonamv/fAzFVuYiGzRKIrzf1TeWgK3pLi+Ahzg==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} @@ -11740,6 +11913,17 @@ packages: '@types/react': optional: true + '@wordpress/preferences@4.50.1-next.v.202607070741.0': + resolution: {integrity: sha512-o8WaY7+eSQ+SfW2wtFaCA16QXqFzH6SbD6DFeoQIwk3CMICR+fIlqDPcU6x7Bh/obor+xltRvgoExpI9AI67pg==} + engines: {node: '>=18.12.0', npm: '>=8.19.2'} + peerDependencies: + '@types/react': ^18.3.27 + react: ^18.0.0 + react-dom: ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@wordpress/prettier-config@4.50.0': resolution: {integrity: sha512-Q48oFBORY0TiVWIebPOG0ynjUAq1Hi9gXKJ69xw2i/UwOwghLOXXFLdAQhS4bJXOw0cdV5xiBaXEQYU+82r5hA==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} @@ -11756,14 +11940,32 @@ packages: '@types/react': optional: true + '@wordpress/primitives@4.50.1-next.v.202607070741.0': + resolution: {integrity: sha512-zPYoxVwUmyuSgRs+d3zk6Ex2iUlzY2hkY360wrwOEZZ8q+IulEyVYLlkAkdqEnd3n2vr4iCr90gCfONl8XSseg==} + engines: {node: '>=18.12.0', npm: '>=8.19.2'} + peerDependencies: + '@types/react': ^18.3.27 + react: ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@wordpress/priority-queue@3.50.0': resolution: {integrity: sha512-OyuAplepKQpNYr8z+nGGGNXWK2v2u9Bqnawkg7V5YkvOKYj/iBJNCiUxiWXOBMeLF1ze36RDR5LEcNDmXRev2Q==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} + '@wordpress/priority-queue@3.50.1-next.v.202607070741.0': + resolution: {integrity: sha512-muYRL5tscYvui3i8SeZH5dPs1cLVeNipygCEZu6HypRRjA+8C3gmvglORfaNfiz6CbIIo2yaixSOW00GXH5eWw==} + engines: {node: '>=18.12.0', npm: '>=8.19.2'} + '@wordpress/private-apis@1.50.0': resolution: {integrity: sha512-bCVLL9YuWfnPNNqlhl4eTKPipjWbJ8MzAlasJ/SR+h979MyeMFjNPapxKqsPqnJOhDEVSdCTkRN/Wa+Xk8qFdw==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} + '@wordpress/private-apis@1.50.1-next.v.202607070741.0': + resolution: {integrity: sha512-yvaBi1v7UAT6LT1pexCMDWEOwVEGKNZidizTdwpCvSOrhxBsv9zlc1WVmje2K9TZgthabsXICb59YleiV0tMng==} + engines: {node: '>=18.12.0', npm: '>=8.19.2'} + '@wordpress/react-i18n@4.48.0': resolution: {integrity: sha512-/aBgnGBZS/Km7+sYeQTWrQNq3oNFukvem84+LwzSp7f7ylwIXqikF4DulPLDm/Fjlmt62nWTAtvIK3YQrxykiw==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} @@ -11774,6 +11976,12 @@ packages: peerDependencies: redux: '>=4' + '@wordpress/redux-routine@5.50.1-next.v.202607070741.0': + resolution: {integrity: sha512-TNYUiC/euLWq28VepLNm4VX516tK6+dB2l7B7VHWGCBLZ/B9qN4GhwDmReTZa+J3OHtaC4PxxEbRCBb5itUVwQ==} + engines: {node: '>=18.12.0', npm: '>=8.19.2'} + peerDependencies: + redux: '>=4' + '@wordpress/reusable-blocks@5.50.0': resolution: {integrity: sha512-vMVodLA2Oy7+rzAdCe+UDwT2kT+Gj8K1Vi3CKYjfXRu4Aeu7BQzRMY0H3BEkTQZlkiQs7ebgEFuVC0SEkrJfrA==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} @@ -11791,6 +11999,16 @@ packages: '@types/react': optional: true + '@wordpress/rich-text@7.50.1-next.v.202607070741.0': + resolution: {integrity: sha512-BNpSoShaeIaB7Yse3V/DwuyUV61r7+ju+GhdBWGsVSJSzCzod5tK9AJBSSffX6fxyCXCZzfSzT3vAey8+1MQQA==} + engines: {node: '>=18.12.0', npm: '>=8.19.2'} + peerDependencies: + '@types/react': ^18.3.27 + react: ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@wordpress/route@0.16.0': resolution: {integrity: sha512-H4JzPDmrujjo0k5vHomCNPibsnatEEQdR9+xbEc8DRIpL77SO9o5h6yKVxuOgaj+uYSWGrQNnISSRfhQqq3+Pg==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} @@ -11839,6 +12057,10 @@ packages: resolution: {integrity: sha512-PSNzFecFRJ7gmah5YxHFv0a0ZUwZOdeO9/B8GNyv2LgC/ZLXS8CtsAblOKVRO3W7ExwazbHwexaTAOzU/+7Mug==} engines: {node: '>=20.10.0', npm: '>=10.2.3'} + '@wordpress/style-runtime@0.6.1-next.v.202607070741.0': + resolution: {integrity: sha512-duPKM/x/sZBhpEcpxF8jiXQriTB4Opu2B9IZiAcye/5W2fSonbpdDBbEAJP+Nk+m/4f82gYrt5Kzc5xrBznnEA==} + engines: {node: '>=20.10.0', npm: '>=10.2.3'} + '@wordpress/stylelint-config@23.42.0': resolution: {integrity: sha512-k9lNU4sK3fdipdhHI2d/Rzd/NnfznPmOZ60ok8O8QhfCMZw2Jd1M8ckYqaIrHTKU62ZrcsugdfJlHodsdrxEzA==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} @@ -11874,6 +12096,29 @@ packages: vite: optional: true + '@wordpress/theme@0.17.2-next.v.202607070741.0': + resolution: {integrity: sha512-oKSGqj5H2Hhb+OcsYKkSU7NdKKL6RTQU+wuYmXn7jxPMjK758mTjsuq/JwAEShEHLL04Tq9ys4pilh3FR3mY1g==} + engines: {node: '>=18.12.0', npm: '>=8.19.2'} + peerDependencies: + '@types/react': ^18.3.27 + esbuild: ^0.27.2 + postcss: ^8.0.0 + react: ^18.0.0 + react-dom: ^18.0.0 + stylelint: '>=16.8.2' + vite: '*' + peerDependenciesMeta: + '@types/react': + optional: true + esbuild: + optional: true + postcss: + optional: true + stylelint: + optional: true + vite: + optional: true + '@wordpress/token-list@3.50.0': resolution: {integrity: sha512-NgmApEUrObbO67/9GHoYpmO4gS/iWpfiYt56JohFXUSbk3h3DJ1kILkxL3k0KDfeLoQRtwWiPnB6Q4Ez89IUjQ==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} @@ -11889,10 +12134,25 @@ packages: '@types/react': optional: true + '@wordpress/ui@0.18.1-next.v.202607070741.0': + resolution: {integrity: sha512-X9+C4ybGN+2NXgixsgvX/OnvJsQcCs1QkVZXzsQR2jZZT+y7IriWy0qbOD5tOK8gRzqx7LoNTiXjQ8/KVSjqgA==} + engines: {node: '>=20.10.0', npm: '>=10.2.3'} + peerDependencies: + '@types/react': ^18.3.27 + react: ^18.0.0 + react-dom: ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@wordpress/undo-manager@1.50.0': resolution: {integrity: sha512-599I3GPXSMpmAE2jqzHteqypI7rdt5HPDAw8GrHMkDWR1T9gK2L3gObv8I1Hs4eSDM88wgAB0Ifnqpy7zPn5rw==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} + '@wordpress/undo-manager@1.50.1-next.v.202607070741.0': + resolution: {integrity: sha512-x9Qo7JHVmpr0QwF7kYshArlbjqz7/rWY4+ddDLZsW+XCrwFCs7wkC09EJA8/OiksHtaKXc9fX3y+QR+f+lXAzw==} + engines: {node: '>=18.12.0', npm: '>=8.19.2'} + '@wordpress/upload-media@0.35.0': resolution: {integrity: sha512-Xpka03EVJZd0BORFsgYZhGnrSHwolwXkDR+g4S+VQoWOCbhZSX9VRPgEiPSxzp3i4HTCvgXyeEo6sEKNrhlllg==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} @@ -11918,6 +12178,16 @@ packages: '@types/react': optional: true + '@wordpress/viewport@6.50.1-next.v.202607070741.0': + resolution: {integrity: sha512-HKXsYeCiquoYM2jInR+YcnrHJv3+HNC2mdQEzavtchGBOzxpP2V523S9HA/u88OjOBC+dFJrgLM7g69EqUv6Pg==} + engines: {node: '>=18.12.0', npm: '>=8.19.2'} + peerDependencies: + '@types/react': ^18.3.27 + react: ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@wordpress/views@1.17.0': resolution: {integrity: sha512-vYjzvAMJPRxu920QL6x6ZedJX5uf3gg0VKoUMYrRNUUS21atyndSBAB+SJ03VQHlwysyN5tvhtxiN/OwiF5rQQ==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} @@ -11930,8 +12200,12 @@ packages: resolution: {integrity: sha512-6X3ioKOGfmRuZFngmG2QZZW9CBVMTBr5FXqs6Q3li5ryhnAqn3u/ocqsx556YnB5dYdVxK14TiH9o7DDElt8gw==} engines: {node: '>=18.12.0', npm: '>=8.19.2'} - '@wordpress/widget-dashboard@0.2.0': - resolution: {integrity: sha512-j7h12agsQYgw/mZrtz676uxP3PP+kUDF6FIOgwKWFJmziG19FlShnfjX1ISYQuH+wegHn68qFCI7s2VuFnjTtw==} + '@wordpress/warning@3.50.1-next.v.202607070741.0': + resolution: {integrity: sha512-abTVJOjfN/1GxvmC3k1/PHz6YquchPhEkE+PitAqbvVkpgVGK/4rkl5vKHuAbx/YKd8atTqAfnXdPALAHrYc9Q==} + engines: {node: '>=18.12.0', npm: '>=8.19.2'} + + '@wordpress/widget-dashboard@0.3.1-next.v.202607070741.0': + resolution: {integrity: sha512-/3AtbE4RgQH1L3DyynFtmOSPuULAxFUkeS7M50+NEuV/hh5vzEZU5GU/2HCa5YwowWdyuMQrRzOYLYamvi4dpw==} engines: {node: '>=20.10.0', npm: '>=10.2.3'} peerDependencies: '@types/react': ^18.3.27 @@ -11941,8 +12215,8 @@ packages: '@types/react': optional: true - '@wordpress/widget-primitives@0.2.0': - resolution: {integrity: sha512-r2MoNh3K1264LRJIKsevGvP011O5ZGFu/nBQEU0E5a7o4TmJP7oYt+Fot+ZDBKqrFZYL3bJFiqrHf/aFEYzXjQ==} + '@wordpress/widget-primitives@0.3.1-next.v.202607070741.0': + resolution: {integrity: sha512-O1cqafmqnaVb246Z769ry4tbxi55BBvMQZ87nALDqSe0vtX+syK8keq8vNs2qG9fZClhUq1IUAHE61dqvX2y/Q==} engines: {node: '>=20.10.0', npm: '>=10.2.3'} peerDependencies: '@types/react': ^18.3.27 @@ -18751,6 +19025,11 @@ snapshots: '@ariakit/store': 0.1.2 '@ariakit/utils': 0.1.2 + '@ariakit/components@0.1.5': + dependencies: + '@ariakit/store': 0.1.4 + '@ariakit/utils': 0.1.4 + '@ariakit/react-components@0.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@ariakit/components': 0.1.2 @@ -18762,6 +19041,17 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + '@ariakit/react-components@0.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@ariakit/components': 0.1.5 + '@ariakit/react-store': 0.1.5(react@18.3.1) + '@ariakit/react-utils': 0.2.0(react@18.3.1) + '@ariakit/store': 0.1.4 + '@ariakit/utils': 0.1.4 + '@floating-ui/dom': 1.7.6 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + '@ariakit/react-store@0.1.2(react@18.3.1)': dependencies: '@ariakit/react-utils': 0.1.2(react@18.3.1) @@ -18770,24 +19060,50 @@ snapshots: react: 18.3.1 use-sync-external-store: 1.6.0(react@18.3.1) + '@ariakit/react-store@0.1.5(react@18.3.1)': + dependencies: + '@ariakit/react-utils': 0.2.0(react@18.3.1) + '@ariakit/store': 0.1.4 + '@ariakit/utils': 0.1.4 + react: 18.3.1 + use-sync-external-store: 1.6.0(react@18.3.1) + '@ariakit/react-utils@0.1.2(react@18.3.1)': dependencies: '@ariakit/store': 0.1.2 '@ariakit/utils': 0.1.2 react: 18.3.1 + '@ariakit/react-utils@0.2.0(react@18.3.1)': + dependencies: + '@ariakit/store': 0.1.4 + '@ariakit/utils': 0.1.4 + react: 18.3.1 + '@ariakit/react@0.4.29(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@ariakit/react-components': 0.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + '@ariakit/react@0.4.32(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@ariakit/react-components': 0.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + '@ariakit/store@0.1.2': dependencies: '@ariakit/utils': 0.1.2 + '@ariakit/store@0.1.4': + dependencies: + '@ariakit/utils': 0.1.4 + '@ariakit/utils@0.1.2': {} + '@ariakit/utils@0.1.4': {} + '@arraypress/waveform-player@1.2.1': {} '@asamuzakjp/css-color@4.1.2': @@ -19994,10 +20310,10 @@ snapshots: '@babel/helper-string-parser': 8.0.0 '@babel/helper-validator-identifier': 8.0.0 - '@base-ui/react@1.5.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@base-ui/react@1.6.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.29.7 - '@base-ui/utils': 0.2.9(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@base-ui/utils': 0.3.1(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@floating-ui/react-dom': 2.1.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@floating-ui/utils': 0.2.11 react: 18.3.1 @@ -20008,10 +20324,10 @@ snapshots: '@types/react': 18.3.28 date-fns: 4.1.0 - '@base-ui/react@1.5.0(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@base-ui/react@1.6.0(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.29.7 - '@base-ui/utils': 0.2.9(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@base-ui/utils': 0.3.1(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@floating-ui/react-dom': 2.1.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@floating-ui/utils': 0.2.11 react: 18.3.1 @@ -20021,10 +20337,10 @@ snapshots: '@types/react': 18.3.28 date-fns: 4.1.0 - '@base-ui/react@1.5.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@base-ui/react@1.6.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.29.7 - '@base-ui/utils': 0.2.9(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@base-ui/utils': 0.3.1(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@floating-ui/react-dom': 2.1.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@floating-ui/utils': 0.2.11 react: 18.3.1 @@ -20033,7 +20349,7 @@ snapshots: optionalDependencies: '@types/react': 18.3.28 - '@base-ui/utils@0.2.9(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@base-ui/utils@0.3.1(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.29.7 '@floating-ui/utils': 0.2.11 @@ -23886,6 +24202,11 @@ snapshots: '@wordpress/dom-ready': 4.50.0 '@wordpress/i18n': 6.23.0 + '@wordpress/a11y@4.50.1-next.v.202607070741.0': + dependencies: + '@wordpress/dom-ready': 4.50.1-next.v.202607070741.0 + '@wordpress/i18n': 6.23.1-next.v.202607070741.0 + '@wordpress/admin-ui@2.5.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@wordpress/components': 36.1.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -24049,6 +24370,8 @@ snapshots: '@wordpress/base-styles@10.2.0': {} + '@wordpress/base-styles@10.3.1-next.v.202607070741.0': {} + '@wordpress/blob@4.50.0': {} '@wordpress/block-editor@15.23.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': @@ -24919,7 +25242,7 @@ snapshots: '@wordpress/browserslist-config@6.50.0': {} - '@wordpress/build@0.18.0(@babel/core@7.29.7)(@wordpress/boot@0.17.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@wordpress/private-apis@1.50.0)(@wordpress/route@0.16.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@wordpress/theme@0.17.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(browserslist@4.28.4)': + '@wordpress/build@0.18.0(@babel/core@7.29.7)(@wordpress/boot@0.17.0(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(postcss@8.5.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@wordpress/route@0.16.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@wordpress/theme@0.17.0(@types/react@18.3.28)(postcss@8.5.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(browserslist@4.28.4)': dependencies: '@emotion/babel-plugin': 11.13.5 '@wordpress/style-runtime': 0.6.0 @@ -24938,16 +25261,15 @@ snapshots: rtlcss: 4.3.0 sass-embedded: 1.97.3 optionalDependencies: - '@wordpress/boot': 0.17.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@wordpress/private-apis': 1.50.0 + '@wordpress/boot': 0.17.0(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(postcss@8.5.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@wordpress/route': 0.16.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@wordpress/theme': 0.17.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@wordpress/theme': 0.17.0(@types/react@18.3.28)(postcss@8.5.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) transitivePeerDependencies: - '@babel/core' - browserslist - supports-color - '@wordpress/build@0.18.0(@babel/core@7.29.7)(@wordpress/boot@0.17.0(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(postcss@8.5.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@wordpress/route@0.16.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@wordpress/theme@0.17.0(@types/react@18.3.28)(postcss@8.5.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(browserslist@4.28.4)': + '@wordpress/build@0.18.0(@babel/core@7.29.7)(@wordpress/boot@0.17.0(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@wordpress/private-apis@1.50.0)(@wordpress/route@0.16.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@wordpress/theme@0.17.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(browserslist@4.28.4)': dependencies: '@emotion/babel-plugin': 11.13.5 '@wordpress/style-runtime': 0.6.0 @@ -24966,15 +25288,16 @@ snapshots: rtlcss: 4.3.0 sass-embedded: 1.97.3 optionalDependencies: - '@wordpress/boot': 0.17.0(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(postcss@8.5.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@wordpress/boot': 0.17.0(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@wordpress/private-apis': 1.50.0 '@wordpress/route': 0.16.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@wordpress/theme': 0.17.0(@types/react@18.3.28)(postcss@8.5.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@wordpress/theme': 0.17.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) transitivePeerDependencies: - '@babel/core' - browserslist - supports-color - '@wordpress/build@0.18.0(@babel/core@7.29.7)(@wordpress/boot@0.17.0(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@wordpress/private-apis@1.50.0)(@wordpress/route@0.16.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@wordpress/theme@0.17.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(browserslist@4.28.4)': + '@wordpress/build@0.18.0(@babel/core@7.29.7)(@wordpress/boot@0.17.0(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@wordpress/route@0.16.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@wordpress/theme@0.17.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(browserslist@4.28.4)': dependencies: '@emotion/babel-plugin': 11.13.5 '@wordpress/style-runtime': 0.6.0 @@ -24994,7 +25317,6 @@ snapshots: sass-embedded: 1.97.3 optionalDependencies: '@wordpress/boot': 0.17.0(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@wordpress/private-apis': 1.50.0 '@wordpress/route': 0.16.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@wordpress/theme': 0.17.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) transitivePeerDependencies: @@ -25002,7 +25324,7 @@ snapshots: - browserslist - supports-color - '@wordpress/build@0.18.0(@babel/core@7.29.7)(@wordpress/boot@0.17.0(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@wordpress/route@0.16.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@wordpress/theme@0.17.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(browserslist@4.28.4)': + '@wordpress/build@0.18.0(@babel/core@7.29.7)(@wordpress/boot@0.17.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@wordpress/private-apis@1.50.0)(@wordpress/route@0.16.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@wordpress/theme@0.17.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(browserslist@4.28.4)': dependencies: '@emotion/babel-plugin': 11.13.5 '@wordpress/style-runtime': 0.6.0 @@ -25021,7 +25343,8 @@ snapshots: rtlcss: 4.3.0 sass-embedded: 1.97.3 optionalDependencies: - '@wordpress/boot': 0.17.0(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@wordpress/boot': 0.17.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@wordpress/private-apis': 1.50.0 '@wordpress/route': 0.16.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@wordpress/theme': 0.17.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) transitivePeerDependencies: @@ -25029,7 +25352,7 @@ snapshots: - browserslist - supports-color - '@wordpress/build@0.18.0(@babel/core@7.29.7)(@wordpress/boot@0.17.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@wordpress/private-apis@1.50.0)(@wordpress/route@0.16.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@wordpress/theme@0.17.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(browserslist@4.28.4)': + '@wordpress/build@0.18.0(@babel/core@7.29.7)(@wordpress/route@0.16.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@wordpress/theme@0.17.0(@types/react@18.3.28)(postcss@8.5.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(browserslist@4.28.4)': dependencies: '@emotion/babel-plugin': 11.13.5 '@wordpress/style-runtime': 0.6.0 @@ -25048,16 +25371,14 @@ snapshots: rtlcss: 4.3.0 sass-embedded: 1.97.3 optionalDependencies: - '@wordpress/boot': 0.17.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@wordpress/private-apis': 1.50.0 '@wordpress/route': 0.16.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@wordpress/theme': 0.17.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@wordpress/theme': 0.17.0(@types/react@18.3.28)(postcss@8.5.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) transitivePeerDependencies: - '@babel/core' - browserslist - supports-color - '@wordpress/build@0.18.0(@babel/core@7.29.7)(@wordpress/route@0.16.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@wordpress/theme@0.17.0(@types/react@18.3.28)(postcss@8.5.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(browserslist@4.28.4)': + '@wordpress/build@0.18.0(@babel/core@7.29.7)(@wordpress/route@0.16.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@wordpress/theme@0.17.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(browserslist@4.28.4)': dependencies: '@emotion/babel-plugin': 11.13.5 '@wordpress/style-runtime': 0.6.0 @@ -25077,16 +25398,16 @@ snapshots: sass-embedded: 1.97.3 optionalDependencies: '@wordpress/route': 0.16.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@wordpress/theme': 0.17.0(@types/react@18.3.28)(postcss@8.5.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@wordpress/theme': 0.17.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) transitivePeerDependencies: - '@babel/core' - browserslist - supports-color - '@wordpress/build@0.18.0(@babel/core@7.29.7)(@wordpress/route@0.16.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@wordpress/theme@0.17.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(browserslist@4.28.4)': + '@wordpress/build@0.19.1-next.v.202607070741.0(@babel/core@7.29.7)(@wordpress/boot@0.17.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@wordpress/private-apis@1.50.0)(@wordpress/route@0.16.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@wordpress/theme@0.17.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(browserslist@4.28.4)': dependencies: '@emotion/babel-plugin': 11.13.5 - '@wordpress/style-runtime': 0.6.0 + '@wordpress/style-runtime': 0.6.1-next.v.202607070741.0 autoprefixer: 10.5.0(postcss@8.5.14) browserslist-to-esbuild: 2.1.1(browserslist@4.28.4) change-case: 4.1.2 @@ -25102,6 +25423,8 @@ snapshots: rtlcss: 4.3.0 sass-embedded: 1.97.3 optionalDependencies: + '@wordpress/boot': 0.17.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@wordpress/private-apis': 1.50.0 '@wordpress/route': 0.16.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@wordpress/theme': 0.17.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) transitivePeerDependencies: @@ -25298,6 +25621,33 @@ snapshots: - supports-color - vite + '@wordpress/commands@1.50.1-next.v.202607070741.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@wordpress/base-styles': 10.3.1-next.v.202607070741.0 + '@wordpress/components': 37.0.1-next.v.202607070741.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@wordpress/data': 10.50.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1) + '@wordpress/element': 8.2.1-next.v.202607070741.0 + '@wordpress/i18n': 6.23.1-next.v.202607070741.0 + '@wordpress/icons': 15.1.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1) + '@wordpress/keyboard-shortcuts': 5.50.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1) + '@wordpress/preferences': 4.50.1-next.v.202607070741.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@wordpress/private-apis': 1.50.1-next.v.202607070741.0 + '@wordpress/warning': 3.50.1-next.v.202607070741.0 + clsx: 2.1.1 + cmdk: 1.1.1(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + transitivePeerDependencies: + - '@date-fns/tz' + - '@emotion/is-prop-valid' + - '@types/react' + - '@types/react-dom' + - esbuild + - postcss + - stylelint + - supports-color + - vite + '@wordpress/components@36.1.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(postcss@8.5.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@ariakit/react': 0.4.29(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -25688,6 +26038,71 @@ snapshots: - supports-color - vite + '@wordpress/components@37.0.1-next.v.202607070741.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@ariakit/react': 0.4.32(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@date-fns/utc': 2.1.1 + '@emotion/cache': 11.14.0 + '@emotion/css': 11.13.5 + '@emotion/react': 11.14.0(@types/react@18.3.28)(react@18.3.1) + '@emotion/serialize': 1.3.3 + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@18.3.28)(react@18.3.1))(@types/react@18.3.28)(react@18.3.1) + '@emotion/utils': 1.4.2 + '@floating-ui/react-dom': 2.1.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@types/gradient-parser': 1.1.0 + '@types/highlight-words-core': 1.2.1 + '@use-gesture/react': 10.3.1(react@18.3.1) + '@wordpress/a11y': 4.50.1-next.v.202607070741.0 + '@wordpress/base-styles': 10.3.1-next.v.202607070741.0 + '@wordpress/compose': 8.3.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1) + '@wordpress/date': 5.50.1-next.v.202607070741.0 + '@wordpress/deprecated': 4.50.1-next.v.202607070741.0 + '@wordpress/dom': 4.50.1-next.v.202607070741.0 + '@wordpress/element': 8.2.1-next.v.202607070741.0 + '@wordpress/escape-html': 3.50.1-next.v.202607070741.0 + '@wordpress/hooks': 4.50.1-next.v.202607070741.0 + '@wordpress/html-entities': 4.50.1-next.v.202607070741.0 + '@wordpress/i18n': 6.23.1-next.v.202607070741.0 + '@wordpress/icons': 15.1.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1) + '@wordpress/is-shallow-equal': 5.50.1-next.v.202607070741.0 + '@wordpress/keycodes': 4.50.1-next.v.202607070741.0(@types/react@18.3.28) + '@wordpress/primitives': 4.50.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1) + '@wordpress/private-apis': 1.50.1-next.v.202607070741.0 + '@wordpress/rich-text': 7.50.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1) + '@wordpress/style-runtime': 0.6.1-next.v.202607070741.0 + '@wordpress/ui': 0.18.1-next.v.202607070741.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@wordpress/warning': 3.50.1-next.v.202607070741.0 + change-case: 4.1.2 + clsx: 2.1.1 + colord: 2.9.3 + csstype: 3.2.3 + date-fns: 4.1.0 + deepmerge: 4.3.1 + fast-deep-equal: 3.1.3 + framer-motion: 11.18.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + gradient-parser: 1.1.1 + highlight-words-core: 1.2.3 + is-plain-object: 5.0.0 + memize: 2.1.1 + path-to-regexp: 6.3.0 + re-resizable: 6.11.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-colorful: 5.7.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-day-picker: 9.14.0(react@18.3.1) + react-dom: 18.3.1(react@18.3.1) + remove-accents: 0.5.0 + uuid: 14.0.0 + optionalDependencies: + '@types/react': 18.3.28 + transitivePeerDependencies: + - '@date-fns/tz' + - '@emotion/is-prop-valid' + - esbuild + - postcss + - stylelint + - supports-color + - vite + '@wordpress/compose@7.46.0(@types/react@18.3.28)(react@18.3.1)': dependencies: '@types/mousetrap': 1.6.15 @@ -25739,6 +26154,24 @@ snapshots: react: 18.3.1 use-memo-one: 1.1.3(react@18.3.1) + '@wordpress/compose@8.3.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1)': + dependencies: + '@types/mousetrap': 1.6.15 + '@wordpress/deprecated': 4.50.1-next.v.202607070741.0 + '@wordpress/dom': 4.50.1-next.v.202607070741.0 + '@wordpress/element': 8.2.1-next.v.202607070741.0 + '@wordpress/is-shallow-equal': 5.50.1-next.v.202607070741.0 + '@wordpress/keycodes': 4.50.1-next.v.202607070741.0(@types/react@18.3.28) + '@wordpress/priority-queue': 3.50.1-next.v.202607070741.0 + '@wordpress/private-apis': 1.50.1-next.v.202607070741.0 + '@wordpress/undo-manager': 1.50.1-next.v.202607070741.0 + change-case: 4.1.2 + mousetrap: 1.6.5 + react: 18.3.1 + use-memo-one: 1.1.3(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.28 + '@wordpress/core-data@7.50.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@wordpress/api-fetch': 7.50.0 @@ -25989,9 +26422,28 @@ snapshots: rememo: 4.0.2 use-memo-one: 1.1.3(react@18.3.1) + '@wordpress/data@10.50.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1)': + dependencies: + '@types/react': 18.3.28 + '@wordpress/compose': 8.3.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1) + '@wordpress/deprecated': 4.50.1-next.v.202607070741.0 + '@wordpress/element': 8.2.1-next.v.202607070741.0 + '@wordpress/is-shallow-equal': 5.50.1-next.v.202607070741.0 + '@wordpress/priority-queue': 3.50.1-next.v.202607070741.0 + '@wordpress/private-apis': 1.50.1-next.v.202607070741.0 + '@wordpress/redux-routine': 5.50.1-next.v.202607070741.0(redux@5.0.1) + deepmerge: 4.3.1 + equivalent-key-map: 0.2.2 + is-plain-object: 5.0.0 + is-promise: 4.0.0 + react: 18.3.1 + redux: 5.0.1 + rememo: 4.0.2 + use-memo-one: 1.1.3(react@18.3.1) + '@wordpress/dataviews@17.1.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(postcss@8.5.14)(react@18.3.1)': dependencies: - '@ariakit/react': 0.4.29(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@ariakit/react': 0.4.32(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@wordpress/base-styles': 10.2.0 '@wordpress/components': 36.1.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(postcss@8.5.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@wordpress/compose': 8.3.0(@types/react@18.3.28)(react@18.3.1) @@ -26009,7 +26461,7 @@ snapshots: react: 18.3.1 remove-accents: 0.5.0 optionalDependencies: - '@base-ui/react': 1.5.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@base-ui/react': 1.6.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@emotion/cache': 11.14.0 '@emotion/css': 11.13.5 '@emotion/react': 11.14.0(@types/react@18.3.28)(react@18.3.1) @@ -26046,7 +26498,7 @@ snapshots: '@wordpress/dataviews@17.1.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(react@18.3.1)': dependencies: - '@ariakit/react': 0.4.29(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@ariakit/react': 0.4.32(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@wordpress/base-styles': 10.2.0 '@wordpress/components': 36.1.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@wordpress/compose': 8.3.0(@types/react@18.3.28)(react@18.3.1) @@ -26064,7 +26516,7 @@ snapshots: react: 18.3.1 remove-accents: 0.5.0 optionalDependencies: - '@base-ui/react': 1.5.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@base-ui/react': 1.6.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@emotion/cache': 11.14.0 '@emotion/css': 11.13.5 '@emotion/react': 11.14.0(@types/react@18.3.28)(react@18.3.1) @@ -26101,7 +26553,7 @@ snapshots: '@wordpress/dataviews@17.1.0(@types/react@18.3.28)(postcss@8.5.14)(react@18.3.1)': dependencies: - '@ariakit/react': 0.4.29(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@ariakit/react': 0.4.32(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@wordpress/base-styles': 10.2.0 '@wordpress/components': 36.1.0(@types/react@18.3.28)(postcss@8.5.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@wordpress/compose': 8.3.0(@types/react@18.3.28)(react@18.3.1) @@ -26119,7 +26571,7 @@ snapshots: react: 18.3.1 remove-accents: 0.5.0 optionalDependencies: - '@base-ui/react': 1.5.0(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@base-ui/react': 1.6.0(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@emotion/cache': 11.14.0 '@emotion/css': 11.13.5 '@emotion/react': 11.14.0(@types/react@18.3.28)(react@18.3.1) @@ -26156,7 +26608,7 @@ snapshots: '@wordpress/dataviews@17.1.0(@types/react@18.3.28)(postcss@8.5.14)(react@18.3.1)(vite@8.0.16(sass-embedded@1.97.3))': dependencies: - '@ariakit/react': 0.4.29(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@ariakit/react': 0.4.32(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@wordpress/base-styles': 10.2.0 '@wordpress/components': 36.1.0(@types/react@18.3.28)(postcss@8.5.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@8.0.16(sass-embedded@1.97.3)) '@wordpress/compose': 8.3.0(@types/react@18.3.28)(react@18.3.1) @@ -26174,7 +26626,7 @@ snapshots: react: 18.3.1 remove-accents: 0.5.0 optionalDependencies: - '@base-ui/react': 1.5.0(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@base-ui/react': 1.6.0(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@emotion/cache': 11.14.0 '@emotion/css': 11.13.5 '@emotion/react': 11.14.0(@types/react@18.3.28)(react@18.3.1) @@ -26211,7 +26663,7 @@ snapshots: '@wordpress/dataviews@17.1.0(@types/react@18.3.28)(react@18.3.1)': dependencies: - '@ariakit/react': 0.4.29(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@ariakit/react': 0.4.32(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@wordpress/base-styles': 10.2.0 '@wordpress/components': 36.1.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@wordpress/compose': 8.3.0(@types/react@18.3.28)(react@18.3.1) @@ -26229,7 +26681,7 @@ snapshots: react: 18.3.1 remove-accents: 0.5.0 optionalDependencies: - '@base-ui/react': 1.5.0(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@base-ui/react': 1.6.0(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@emotion/cache': 11.14.0 '@emotion/css': 11.13.5 '@emotion/react': 11.14.0(@types/react@18.3.28)(react@18.3.1) @@ -26264,12 +26716,73 @@ snapshots: - supports-color - vite + '@wordpress/dataviews@17.1.2-next.v.202607070741.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(react@18.3.1)': + dependencies: + '@ariakit/react': 0.4.32(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@wordpress/base-styles': 10.3.1-next.v.202607070741.0 + '@wordpress/components': 37.0.1-next.v.202607070741.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@wordpress/compose': 8.3.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1) + '@wordpress/data': 10.50.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1) + '@wordpress/deprecated': 4.50.1-next.v.202607070741.0 + '@wordpress/element': 8.2.1-next.v.202607070741.0 + '@wordpress/i18n': 6.23.1-next.v.202607070741.0 + '@wordpress/icons': 15.1.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1) + '@wordpress/keycodes': 4.50.1-next.v.202607070741.0(@types/react@18.3.28) + '@wordpress/primitives': 4.50.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1) + '@wordpress/private-apis': 1.50.1-next.v.202607070741.0 + '@wordpress/ui': 0.18.1-next.v.202607070741.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@wordpress/warning': 3.50.1-next.v.202607070741.0 + clsx: 2.1.1 + react: 18.3.1 + remove-accents: 0.5.0 + optionalDependencies: + '@base-ui/react': 1.6.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@emotion/cache': 11.14.0 + '@emotion/css': 11.13.5 + '@emotion/react': 11.14.0(@types/react@18.3.28)(react@18.3.1) + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@18.3.28)(react@18.3.1))(@types/react@18.3.28)(react@18.3.1) + '@emotion/utils': 1.4.2 + '@floating-ui/react-dom': 2.1.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@types/react': 18.3.28 + '@use-gesture/react': 10.3.1(react@18.3.1) + '@wordpress/date': 5.50.1-next.v.202607070741.0 + '@wordpress/hooks': 4.50.1-next.v.202607070741.0 + change-case: 4.1.2 + colord: 2.9.3 + colorjs.io: 0.6.1 + date-fns: 4.1.0 + deepmerge: 4.3.1 + fast-deep-equal: 3.1.3 + framer-motion: 11.18.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + highlight-words-core: 1.2.3 + is-plain-object: 5.0.0 + memize: 2.1.1 + react-colorful: 5.7.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-day-picker: 9.14.0(react@18.3.1) + react-dom: 18.3.1(react@18.3.1) + use-memo-one: 1.1.3(react@18.3.1) + uuid: 14.0.0 + transitivePeerDependencies: + - '@date-fns/tz' + - '@emotion/is-prop-valid' + - esbuild + - postcss + - stylelint + - supports-color + - vite + '@wordpress/date@5.50.0': dependencies: '@wordpress/deprecated': 4.50.0 moment: 2.30.1 moment-timezone: 0.5.48 + '@wordpress/date@5.50.1-next.v.202607070741.0': + dependencies: + '@wordpress/deprecated': 4.50.1-next.v.202607070741.0 + moment: 2.30.1 + moment-timezone: 0.5.48 + '@wordpress/dependency-extraction-webpack-plugin@6.50.0(webpack@5.107.2)': dependencies: json2php: 0.0.9 @@ -26279,12 +26792,22 @@ snapshots: dependencies: '@wordpress/hooks': 4.50.0 + '@wordpress/deprecated@4.50.1-next.v.202607070741.0': + dependencies: + '@wordpress/hooks': 4.50.1-next.v.202607070741.0 + '@wordpress/dom-ready@4.50.0': {} + '@wordpress/dom-ready@4.50.1-next.v.202607070741.0': {} + '@wordpress/dom@4.50.0': dependencies: '@wordpress/deprecated': 4.50.0 + '@wordpress/dom@4.50.1-next.v.202607070741.0': + dependencies: + '@wordpress/deprecated': 4.50.1-next.v.202607070741.0 + '@wordpress/e2e-test-utils-playwright@1.50.0(@playwright/test@1.60.0)(@types/node@24.13.1)': dependencies: '@playwright/test': 1.60.0 @@ -26826,8 +27349,21 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + '@wordpress/element@8.2.1-next.v.202607070741.0': + dependencies: + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7(@types/react@18.3.28) + '@wordpress/deprecated': 4.50.1-next.v.202607070741.0 + '@wordpress/escape-html': 3.50.1-next.v.202607070741.0 + change-case: 4.1.2 + is-plain-object: 5.0.0 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + '@wordpress/escape-html@3.50.0': {} + '@wordpress/escape-html@3.50.1-next.v.202607070741.0': {} + '@wordpress/eslint-plugin@25.6.0(@babel/core@7.29.7)(@wordpress/theme@0.17.0(postcss@8.5.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(stylelint@17.7.0(typescript@5.9.3)))(eslint-config-prettier@10.1.8(eslint@10.4.1))(eslint-plugin-import@2.32.0)(eslint-plugin-jest@29.15.2(eslint@10.4.1)(jest@30.4.2)(typescript@5.9.3))(eslint-plugin-jsdoc@63.0.0(eslint@10.4.1))(eslint-plugin-jsx-a11y@6.10.2(eslint@10.4.1))(eslint-plugin-playwright@2.10.4(eslint@10.4.1))(eslint-plugin-prettier@5.5.6(eslint-config-prettier@10.1.8(eslint@10.4.1))(eslint@10.4.1)(wp-prettier@3.0.3))(eslint-plugin-react-hooks@7.1.1(eslint@10.4.1))(eslint-plugin-react@7.37.5(eslint@10.4.1))(eslint@10.4.1)(typescript@5.9.3)(wp-prettier@3.0.3)': dependencies: '@babel/core': 7.29.7 @@ -27325,14 +27861,14 @@ snapshots: - supports-color - vite - '@wordpress/grid@0.2.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@wordpress/grid@0.2.1-next.v.202607070741.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@dnd-kit/core': 6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@dnd-kit/sortable': 10.0.0(@dnd-kit/core@6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@dnd-kit/utilities': 3.2.2(react@18.3.1) - '@wordpress/compose': 8.3.0(@types/react@18.3.28)(react@18.3.1) - '@wordpress/element': 8.2.0 - '@wordpress/style-runtime': 0.6.0 + '@wordpress/compose': 8.3.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1) + '@wordpress/element': 8.2.1-next.v.202607070741.0 + '@wordpress/style-runtime': 0.6.1-next.v.202607070741.0 clsx: 2.1.1 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -27341,8 +27877,12 @@ snapshots: '@wordpress/hooks@4.50.0': {} + '@wordpress/hooks@4.50.1-next.v.202607070741.0': {} + '@wordpress/html-entities@4.50.0': {} + '@wordpress/html-entities@4.50.1-next.v.202607070741.0': {} + '@wordpress/i18n@6.23.0': dependencies: '@tannin/sprintf': 1.3.3 @@ -27351,6 +27891,14 @@ snapshots: memize: 2.1.1 tannin: 1.2.0 + '@wordpress/i18n@6.23.1-next.v.202607070741.0': + dependencies: + '@tannin/sprintf': 1.3.3 + '@wordpress/hooks': 4.50.1-next.v.202607070741.0 + gettext-parser: 1.4.0 + memize: 2.1.1 + tannin: 1.2.0 + '@wordpress/icons@10.32.0(@types/react@18.3.28)(react@18.3.1)': dependencies: '@babel/runtime': 7.29.7 @@ -27369,6 +27917,15 @@ snapshots: optionalDependencies: '@types/react': 18.3.28 + '@wordpress/icons@15.1.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1)': + dependencies: + '@wordpress/element': 8.2.1-next.v.202607070741.0 + '@wordpress/primitives': 4.50.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1) + change-case: 4.1.2 + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.28 + '@wordpress/image-cropper@1.14.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(postcss@8.5.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@wordpress/components': 36.1.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(postcss@8.5.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -27562,6 +28119,8 @@ snapshots: '@wordpress/is-shallow-equal@5.50.0': {} + '@wordpress/is-shallow-equal@5.50.1-next.v.202607070741.0': {} + '@wordpress/jest-console@8.50.0(jest@30.4.2)': dependencies: jest: 30.4.2 @@ -27577,6 +28136,15 @@ snapshots: optionalDependencies: '@types/react': 18.3.28 + '@wordpress/keyboard-shortcuts@5.50.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1)': + dependencies: + '@wordpress/data': 10.50.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1) + '@wordpress/element': 8.2.1-next.v.202607070741.0 + '@wordpress/keycodes': 4.50.1-next.v.202607070741.0(@types/react@18.3.28) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.28 + '@wordpress/keycodes@4.50.0': dependencies: '@wordpress/i18n': 6.23.0 @@ -27587,6 +28155,12 @@ snapshots: optionalDependencies: '@types/react': 18.3.28 + '@wordpress/keycodes@4.50.1-next.v.202607070741.0(@types/react@18.3.28)': + dependencies: + '@wordpress/i18n': 6.23.1-next.v.202607070741.0 + optionalDependencies: + '@types/react': 18.3.28 + '@wordpress/latex-to-mathml@1.18.0': dependencies: temml: 0.10.34 @@ -28965,6 +29539,32 @@ snapshots: - supports-color - vite + '@wordpress/preferences@4.50.1-next.v.202607070741.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@wordpress/a11y': 4.50.1-next.v.202607070741.0 + '@wordpress/base-styles': 10.3.1-next.v.202607070741.0 + '@wordpress/components': 37.0.1-next.v.202607070741.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@wordpress/compose': 8.3.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1) + '@wordpress/data': 10.50.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1) + '@wordpress/deprecated': 4.50.1-next.v.202607070741.0 + '@wordpress/element': 8.2.1-next.v.202607070741.0 + '@wordpress/i18n': 6.23.1-next.v.202607070741.0 + '@wordpress/icons': 15.1.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1) + '@wordpress/private-apis': 1.50.1-next.v.202607070741.0 + clsx: 2.1.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.28 + transitivePeerDependencies: + - '@date-fns/tz' + - '@emotion/is-prop-valid' + - esbuild + - postcss + - stylelint + - supports-color + - vite + '@wordpress/prettier-config@4.50.0(wp-prettier@3.0.3)': dependencies: prettier: wp-prettier@3.0.3 @@ -28977,12 +29577,26 @@ snapshots: optionalDependencies: '@types/react': 18.3.28 + '@wordpress/primitives@4.50.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1)': + dependencies: + '@wordpress/element': 8.2.1-next.v.202607070741.0 + clsx: 2.1.1 + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.28 + '@wordpress/priority-queue@3.50.0': dependencies: requestidlecallback: 0.3.0 + '@wordpress/priority-queue@3.50.1-next.v.202607070741.0': + dependencies: + requestidlecallback: 0.3.0 + '@wordpress/private-apis@1.50.0': {} + '@wordpress/private-apis@1.50.1-next.v.202607070741.0': {} + '@wordpress/react-i18n@4.48.0': dependencies: '@wordpress/element': 8.2.0 @@ -28996,6 +29610,13 @@ snapshots: redux: 5.0.1 rungen: 0.3.2 + '@wordpress/redux-routine@5.50.1-next.v.202607070741.0(redux@5.0.1)': + dependencies: + is-plain-object: 5.0.0 + is-promise: 4.0.0 + redux: 5.0.1 + rungen: 0.3.2 + '@wordpress/reusable-blocks@5.50.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@wordpress/base-styles': 10.2.0 @@ -29266,6 +29887,24 @@ snapshots: optionalDependencies: '@types/react': 18.3.28 + '@wordpress/rich-text@7.50.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1)': + dependencies: + '@wordpress/a11y': 4.50.1-next.v.202607070741.0 + '@wordpress/compose': 8.3.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1) + '@wordpress/data': 10.50.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1) + '@wordpress/deprecated': 4.50.1-next.v.202607070741.0 + '@wordpress/dom': 4.50.1-next.v.202607070741.0 + '@wordpress/element': 8.2.1-next.v.202607070741.0 + '@wordpress/escape-html': 3.50.1-next.v.202607070741.0 + '@wordpress/i18n': 6.23.1-next.v.202607070741.0 + '@wordpress/keycodes': 4.50.1-next.v.202607070741.0(@types/react@18.3.28) + '@wordpress/private-apis': 1.50.1-next.v.202607070741.0 + colord: 2.9.3 + memize: 2.1.1 + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.28 + '@wordpress/route@0.16.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@tanstack/history': 1.162.0 @@ -29397,6 +30036,8 @@ snapshots: '@wordpress/style-runtime@0.6.0': {} + '@wordpress/style-runtime@0.6.1-next.v.202607070741.0': {} + '@wordpress/stylelint-config@23.42.0(@wordpress/theme@0.17.0(postcss@8.5.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(stylelint@17.7.0(typescript@5.9.3)))(postcss@8.5.14)(stylelint-scss@7.0.0(stylelint@17.7.0(typescript@5.9.3)))(stylelint@17.7.0(typescript@5.9.3))': dependencies: '@stylistic/stylelint-plugin': 5.2.0(stylelint@17.7.0(typescript@5.9.3)) @@ -29507,11 +30148,25 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + '@wordpress/theme@0.17.2-next.v.202607070741.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@wordpress/compose': 8.3.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1) + '@wordpress/deprecated': 4.50.1-next.v.202607070741.0 + '@wordpress/element': 8.2.1-next.v.202607070741.0 + '@wordpress/private-apis': 1.50.1-next.v.202607070741.0 + '@wordpress/style-runtime': 0.6.1-next.v.202607070741.0 + colorjs.io: 0.6.1 + memize: 2.1.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.28 + '@wordpress/token-list@3.50.0': {} '@wordpress/ui@0.17.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(date-fns@4.1.0)(postcss@8.5.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@base-ui/react': 1.5.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@base-ui/react': 1.6.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@wordpress/a11y': 4.50.0 '@wordpress/compose': 8.3.0(@types/react@18.3.28)(react@18.3.1) '@wordpress/element': 8.2.0 @@ -29538,7 +30193,7 @@ snapshots: '@wordpress/ui@0.17.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@base-ui/react': 1.5.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@base-ui/react': 1.6.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@wordpress/a11y': 4.50.0 '@wordpress/compose': 8.3.0(@types/react@18.3.28)(react@18.3.1) '@wordpress/element': 8.2.0 @@ -29565,7 +30220,7 @@ snapshots: '@wordpress/ui@0.17.0(@types/react@18.3.28)(date-fns@4.1.0)(postcss@8.5.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@base-ui/react': 1.5.0(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@base-ui/react': 1.6.0(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@wordpress/a11y': 4.50.0 '@wordpress/compose': 8.3.0(@types/react@18.3.28)(react@18.3.1) '@wordpress/element': 8.2.0 @@ -29592,7 +30247,7 @@ snapshots: '@wordpress/ui@0.17.0(@types/react@18.3.28)(date-fns@4.1.0)(postcss@8.5.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@8.0.16(sass-embedded@1.97.3))': dependencies: - '@base-ui/react': 1.5.0(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@base-ui/react': 1.6.0(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@wordpress/a11y': 4.50.0 '@wordpress/compose': 8.3.0(@types/react@18.3.28)(react@18.3.1) '@wordpress/element': 8.2.0 @@ -29619,7 +30274,7 @@ snapshots: '@wordpress/ui@0.17.0(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@base-ui/react': 1.5.0(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@base-ui/react': 1.6.0(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@wordpress/a11y': 4.50.0 '@wordpress/compose': 8.3.0(@types/react@18.3.28)(react@18.3.1) '@wordpress/element': 8.2.0 @@ -29646,7 +30301,7 @@ snapshots: '@wordpress/ui@0.17.0(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@8.0.16(sass-embedded@1.97.3))': dependencies: - '@base-ui/react': 1.5.0(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@base-ui/react': 1.6.0(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@wordpress/a11y': 4.50.0 '@wordpress/compose': 8.3.0(@types/react@18.3.28)(react@18.3.1) '@wordpress/element': 8.2.0 @@ -29673,7 +30328,7 @@ snapshots: '@wordpress/ui@0.17.0(@types/react@18.3.28)(postcss@8.5.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@base-ui/react': 1.5.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@base-ui/react': 1.6.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@wordpress/a11y': 4.50.0 '@wordpress/compose': 8.3.0(@types/react@18.3.28)(react@18.3.1) '@wordpress/element': 8.2.0 @@ -29700,7 +30355,7 @@ snapshots: '@wordpress/ui@0.17.0(@types/react@18.3.28)(postcss@8.5.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@8.0.16(sass-embedded@1.97.3))': dependencies: - '@base-ui/react': 1.5.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@base-ui/react': 1.6.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@wordpress/a11y': 4.50.0 '@wordpress/compose': 8.3.0(@types/react@18.3.28)(react@18.3.1) '@wordpress/element': 8.2.0 @@ -29727,7 +30382,7 @@ snapshots: '@wordpress/ui@0.17.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@base-ui/react': 1.5.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@base-ui/react': 1.6.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@wordpress/a11y': 4.50.0 '@wordpress/compose': 8.3.0(@types/react@18.3.28)(react@18.3.1) '@wordpress/element': 8.2.0 @@ -29754,7 +30409,7 @@ snapshots: '@wordpress/ui@0.17.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vite@8.0.16(sass-embedded@1.97.3))': dependencies: - '@base-ui/react': 1.5.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@base-ui/react': 1.6.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@wordpress/a11y': 4.50.0 '@wordpress/compose': 8.3.0(@types/react@18.3.28)(react@18.3.1) '@wordpress/element': 8.2.0 @@ -29779,10 +30434,41 @@ snapshots: - stylelint - vite + '@wordpress/ui@0.18.1-next.v.202607070741.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@base-ui/react': 1.6.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@wordpress/a11y': 4.50.1-next.v.202607070741.0 + '@wordpress/compose': 8.3.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1) + '@wordpress/element': 8.2.1-next.v.202607070741.0 + '@wordpress/i18n': 6.23.1-next.v.202607070741.0 + '@wordpress/icons': 15.1.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1) + '@wordpress/keycodes': 4.50.1-next.v.202607070741.0(@types/react@18.3.28) + '@wordpress/primitives': 4.50.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1) + '@wordpress/private-apis': 1.50.1-next.v.202607070741.0 + '@wordpress/style-runtime': 0.6.1-next.v.202607070741.0 + '@wordpress/theme': 0.17.2-next.v.202607070741.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + clsx: 2.1.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + tabbable: 6.4.0 + optionalDependencies: + '@types/react': 18.3.28 + transitivePeerDependencies: + - '@date-fns/tz' + - date-fns + - esbuild + - postcss + - stylelint + - vite + '@wordpress/undo-manager@1.50.0': dependencies: '@wordpress/is-shallow-equal': 5.50.0 + '@wordpress/undo-manager@1.50.1-next.v.202607070741.0': + dependencies: + '@wordpress/is-shallow-equal': 5.50.1-next.v.202607070741.0 + '@wordpress/upload-media@0.35.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(postcss@8.5.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@wordpress/blob': 4.50.0 @@ -29946,6 +30632,15 @@ snapshots: optionalDependencies: '@types/react': 18.3.28 + '@wordpress/viewport@6.50.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1)': + dependencies: + '@wordpress/compose': 8.3.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1) + '@wordpress/data': 10.50.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1) + '@wordpress/element': 8.2.1-next.v.202607070741.0 + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.28 + '@wordpress/views@1.17.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@wordpress/core-data': 7.50.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -30114,23 +30809,25 @@ snapshots: '@wordpress/warning@3.50.0': {} - '@wordpress/widget-dashboard@0.2.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@wordpress/commands': 1.50.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@wordpress/components': 36.1.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@wordpress/compose': 8.3.0(@types/react@18.3.28)(react@18.3.1) - '@wordpress/data': 10.50.0(@types/react@18.3.28)(react@18.3.1) - '@wordpress/dataviews': 17.1.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(react@18.3.1) - '@wordpress/element': 8.2.0 - '@wordpress/grid': 0.2.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@wordpress/i18n': 6.23.0 - '@wordpress/icons': 15.1.0(@types/react@18.3.28)(react@18.3.1) - '@wordpress/primitives': 4.50.0(@types/react@18.3.28)(react@18.3.1) - '@wordpress/private-apis': 1.50.0 - '@wordpress/style-runtime': 0.6.0 - '@wordpress/ui': 0.17.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@wordpress/viewport': 6.50.0(@types/react@18.3.28)(react@18.3.1) - '@wordpress/widget-primitives': 0.2.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@wordpress/warning@3.50.1-next.v.202607070741.0': {} + + '@wordpress/widget-dashboard@0.3.1-next.v.202607070741.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@wordpress/commands': 1.50.1-next.v.202607070741.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@wordpress/components': 37.0.1-next.v.202607070741.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@wordpress/compose': 8.3.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1) + '@wordpress/data': 10.50.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1) + '@wordpress/dataviews': 17.1.2-next.v.202607070741.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(react@18.3.1) + '@wordpress/element': 8.2.1-next.v.202607070741.0 + '@wordpress/grid': 0.2.1-next.v.202607070741.0(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@wordpress/i18n': 6.23.1-next.v.202607070741.0 + '@wordpress/icons': 15.1.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1) + '@wordpress/primitives': 4.50.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1) + '@wordpress/private-apis': 1.50.1-next.v.202607070741.0 + '@wordpress/style-runtime': 0.6.1-next.v.202607070741.0 + '@wordpress/ui': 0.18.1-next.v.202607070741.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(date-fns@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@wordpress/viewport': 6.50.1-next.v.202607070741.0(@types/react@18.3.28)(react@18.3.1) + '@wordpress/widget-primitives': 0.3.1-next.v.202607070741.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) clsx: 2.1.1 fast-deep-equal: 3.1.3 react: 18.3.1 @@ -30149,10 +30846,10 @@ snapshots: - supports-color - vite - '@wordpress/widget-primitives@0.2.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@wordpress/widget-primitives@0.3.1-next.v.202607070741.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@wordpress/dataviews': 17.1.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(react@18.3.1) - '@wordpress/element': 8.2.0 + '@wordpress/dataviews': 17.1.2-next.v.202607070741.0(@date-fns/tz@1.4.1)(@types/react@18.3.28)(react@18.3.1) + '@wordpress/element': 8.2.1-next.v.202607070741.0 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: diff --git a/projects/packages/premium-analytics/changelog/update-widget-typed-attributes b/projects/packages/premium-analytics/changelog/update-widget-typed-attributes new file mode 100644 index 000000000000..cb273e8364da --- /dev/null +++ b/projects/packages/premium-analytics/changelog/update-widget-typed-attributes @@ -0,0 +1,4 @@ +Significance: patch +Type: changed + +Type widget attribute fields with WidgetAttributeField, export attribute types from widget.ts, and unify component JSDoc to single typed param tags across all widgets. diff --git a/projects/packages/premium-analytics/changelog/update-wp-build-and-widget-packages-next-snapshots b/projects/packages/premium-analytics/changelog/update-wp-build-and-widget-packages-next-snapshots new file mode 100644 index 000000000000..3b2de7d05cb6 --- /dev/null +++ b/projects/packages/premium-analytics/changelog/update-wp-build-and-widget-packages-next-snapshots @@ -0,0 +1,4 @@ +Significance: patch +Type: changed + +Pin @wordpress/build to 0.19.1-next and the widget packages (@wordpress/widget-primitives, @wordpress/widget-dashboard) to 0.3.1-next development snapshots, scoped to this package. diff --git a/projects/packages/premium-analytics/package.json b/projects/packages/premium-analytics/package.json index 593fe52aa597..8fefa7334099 100644 --- a/projects/packages/premium-analytics/package.json +++ b/projects/packages/premium-analytics/package.json @@ -71,8 +71,8 @@ "@wordpress/theme": "0.17.0", "@wordpress/ui": "0.17.0", "@wordpress/url": "4.50.0", - "@wordpress/widget-dashboard": "0.2.0", - "@wordpress/widget-primitives": "0.2.0", + "@wordpress/widget-dashboard": "0.3.1-next.v.202607070741.0", + "@wordpress/widget-primitives": "0.3.1-next.v.202607070741.0", "clsx": "2.1.1", "date-fns": "4.1.0", "fast-deep-equal": "^3.1.3", @@ -91,7 +91,7 @@ "@types/react": "18.3.28", "@typescript/native-preview": "7.0.0-dev.20260225.1", "@wordpress/base-styles": "10.2.0", - "@wordpress/build": "0.18.0", + "@wordpress/build": "0.19.1-next.v.202607070741.0", "browserslist": "4.28.4", "jest": "30.4.2", "storybook": "10.4.6", diff --git a/projects/packages/premium-analytics/packages/widgets-toolkit/src/components/chart-empty-state/stories/chart-empty-state.stories.tsx b/projects/packages/premium-analytics/packages/widgets-toolkit/src/components/chart-empty-state/stories/chart-empty-state.stories.tsx index 6e6d6a51883d..fa153948e4a7 100644 --- a/projects/packages/premium-analytics/packages/widgets-toolkit/src/components/chart-empty-state/stories/chart-empty-state.stories.tsx +++ b/projects/packages/premium-analytics/packages/widgets-toolkit/src/components/chart-empty-state/stories/chart-empty-state.stories.tsx @@ -54,7 +54,7 @@ const WidgetCard = ( { height, border: '1px solid var(--wpds-color-stroke-surface-neutral-weak, #e0e0e0)', borderRadius: 'var(--wpds-border-radius-md, 8px)', - background: 'var(--wpds-color-background-surface-neutral-strong, #fff)', + background: 'var(--wpds-color-background-surface-neutral, #fff)', display: 'flex', flexDirection: 'column', overflow: 'hidden', diff --git a/projects/packages/premium-analytics/routes/dashboard/stage.tsx b/projects/packages/premium-analytics/routes/dashboard/stage.tsx index 4b63cdc2bf02..694665c4184c 100644 --- a/projects/packages/premium-analytics/routes/dashboard/stage.tsx +++ b/projects/packages/premium-analytics/routes/dashboard/stage.tsx @@ -31,7 +31,7 @@ function Dashboard(): JSX.Element { DASHBOARD_NAME, activeSection ); - const [ gridSettings, setGridSettings ] = useDashboardGridSettings(); + const [ gridSettings ] = useDashboardGridSettings(); const widgetModules = useSelect( select => @@ -74,7 +74,6 @@ function Dashboard(): JSX.Element { onLayoutChange={ setLayout } onLayoutReset={ resetLayout } gridSettings={ gridSettings } - onGridSettingsChange={ setGridSettings } editMode={ editMode } onEditChange={ setEditMode } > diff --git a/projects/packages/premium-analytics/routes/post-detail/stage.tsx b/projects/packages/premium-analytics/routes/post-detail/stage.tsx index 66392a512911..99e4fbc0d8ba 100644 --- a/projects/packages/premium-analytics/routes/post-detail/stage.tsx +++ b/projects/packages/premium-analytics/routes/post-detail/stage.tsx @@ -37,7 +37,7 @@ function PostDetail(): JSX.Element { const tabs = useMemo( () => getPostDetailTabs(), [] ); const [ activeTab, setActiveTab ] = useActiveTab(); const [ layout, setLayout, resetLayout ] = usePostDetailTabLayout( activeTab ); - const [ gridSettings, setGridSettings ] = useDashboardGridSettings(); + const [ gridSettings ] = useDashboardGridSettings(); const summary = usePostSummary( postId ); @@ -92,7 +92,6 @@ function PostDetail(): JSX.Element { onLayoutChange={ setLayout } onLayoutReset={ resetLayout } gridSettings={ gridSettings } - onGridSettingsChange={ setGridSettings } editMode={ editMode } onEditChange={ setEditMode } > diff --git a/projects/packages/premium-analytics/widgets/all-time-stats/package.json b/projects/packages/premium-analytics/widgets/all-time-stats/package.json index d8901826fc01..ecd8795e059c 100644 --- a/projects/packages/premium-analytics/widgets/all-time-stats/package.json +++ b/projects/packages/premium-analytics/widgets/all-time-stats/package.json @@ -9,8 +9,7 @@ "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", "@wordpress/ui": "0.17.0", - "@wordpress/widget-primitives": "next", - "date-fns": "4.1.0", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" }, "devDependencies": { diff --git a/projects/packages/premium-analytics/widgets/all-time-stats/render.tsx b/projects/packages/premium-analytics/widgets/all-time-stats/render.tsx index 308c63ddd3a9..30b116d08fc1 100644 --- a/projects/packages/premium-analytics/widgets/all-time-stats/render.tsx +++ b/projects/packages/premium-analytics/widgets/all-time-stats/render.tsx @@ -23,6 +23,7 @@ import type { WidgetRenderProps } from '@wordpress/widget-primitives'; // totals are all-time: the summary query takes no date params, so the picker's // range and comparison state do not change what this widget shows. type AllTimeStatsRenderAttributes = AllTimeStatsAttributes & Partial< ReportParamsFieldAttributes >; +type AllTimeStatsWidgetProps = WidgetRenderProps< AllTimeStatsRenderAttributes >; /** * The all-time summary carries dynamic WPCOM keys (`views`, `visitors`, @@ -130,13 +131,10 @@ function AllTimeStatsReport() { * range; report params still flow into WidgetRoot for parity with the other * Stats widgets. * - * @param props - Render props supplied by the widget host. - * @param props.attributes - Widget attributes. + * @param {AllTimeStatsWidgetProps} props - The widget render props. * @return The rendered widget. */ -export default function AllTimeStats( { - attributes = {}, -}: WidgetRenderProps< AllTimeStatsRenderAttributes > ) { +export default function AllTimeStats( { attributes = {} }: AllTimeStatsWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/all-time-stats/stories/all-time-stats-widget.stories.tsx b/projects/packages/premium-analytics/widgets/all-time-stats/stories/all-time-stats-widget.stories.tsx index 7369d2e3fd51..ed5c13dc8e85 100644 --- a/projects/packages/premium-analytics/widgets/all-time-stats/stories/all-time-stats-widget.stories.tsx +++ b/projects/packages/premium-analytics/widgets/all-time-stats/stories/all-time-stats-widget.stories.tsx @@ -32,6 +32,9 @@ registerReportMocks(); const ALL_TIME_STATS_RENDER_MODULE = 'storybook/all-time-stats'; interface AllTimeStatsStoryControls { + /** + * Whether to include comparison report params. + */ withComparison: boolean; } @@ -39,8 +42,7 @@ interface AllTimeStatsStoryControls { * Renders the data-connected widget with report params derived from the * date-range picker preset. * - * @param props - The story controls. - * @param props.withComparison - Whether to include comparison report params. + * @param {AllTimeStatsStoryControls} props - The story controls. * @return The rendered widget. */ function renderAllTimeStats( { withComparison }: AllTimeStatsStoryControls ) { @@ -105,8 +107,7 @@ interface AllTimeStatsDashboardStoryProps * Renders the data-connected widget through the shared dashboard harness, so it * appears exactly as it does in product (framed card, sizing, edit mode). * - * @param props - The dashboard story controls. - * @param props.withComparison - Whether to include comparison report params. + * @param {AllTimeStatsDashboardStoryProps} props - The dashboard story controls. * @return The widget mounted inside the real `WidgetDashboard`. */ function AllTimeStatsDashboardStory( { diff --git a/projects/packages/premium-analytics/widgets/annual-highlights/package.json b/projects/packages/premium-analytics/widgets/annual-highlights/package.json index 71ed90a0894d..43f59b546080 100644 --- a/projects/packages/premium-analytics/widgets/annual-highlights/package.json +++ b/projects/packages/premium-analytics/widgets/annual-highlights/package.json @@ -9,7 +9,7 @@ "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", "@wordpress/ui": "0.17.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" } } diff --git a/projects/packages/premium-analytics/widgets/annual-highlights/render.tsx b/projects/packages/premium-analytics/widgets/annual-highlights/render.tsx index cffd0a454efb..1677f2f0f2ad 100644 --- a/projects/packages/premium-analytics/widgets/annual-highlights/render.tsx +++ b/projects/packages/premium-analytics/widgets/annual-highlights/render.tsx @@ -13,7 +13,7 @@ import { type DataFormat, type ReportParamsFieldAttributes, } from '@jetpack-premium-analytics/widgets-toolkit'; -import { __, sprintf } from '@wordpress/i18n'; +import { __ } from '@wordpress/i18n'; import { arrowLeft, arrowRight, comment, paragraph, postList, starEmpty } from '@wordpress/icons'; import { Button, Icon, Text } from '@wordpress/ui'; import { useCallback, useMemo, useState } from 'react'; @@ -29,6 +29,12 @@ import type { WidgetRenderProps } from '@wordpress/widget-primitives'; // boundary (and Storybook may inject them) so the host contract holds. type AnnualHighlightsRenderAttributes = AnnualHighlightsAttributes & Partial< ReportParamsFieldAttributes >; +type AnnualHighlightsWidgetProps = WidgetRenderProps< AnnualHighlightsRenderAttributes >; + +/** + * The enabled-metric flags from widget attributes, with defaults applied. + */ +type AnnualHighlightsReportProps = Required< AnnualHighlightsAttributes >; const COUNT_FORMAT: DataFormat = { type: 'number', @@ -53,11 +59,7 @@ function sortYearsDescending( data?: StatsInsightsResponse ): StatsInsightsYear[ * comparison period, so each tile shows a bare formatted count. Which tiles * appear is controlled by the per-metric visibility attributes. * - * @param props - The enabled-metric flags from widget attributes. - * @param props.showPosts - Whether the Posts tile is shown. - * @param props.showWords - Whether the Words tile is shown. - * @param props.showLikes - Whether the Likes tile is shown. - * @param props.showComments - Whether the Comments tile is shown. + * @param {AnnualHighlightsReportProps} props - The component props. * @return The widget content. */ function AnnualHighlightsReport( { @@ -65,7 +67,7 @@ function AnnualHighlightsReport( { showWords, showLikes, showComments, -}: Required< AnnualHighlightsAttributes > ) { +}: AnnualHighlightsReportProps ) { const { data, isLoading, isError } = useStatsInsights(); const years = useMemo( () => sortYearsDescending( data ), [ data ] ); @@ -151,40 +153,34 @@ function AnnualHighlightsReport( { return (
-
- } className={ styles.title }> - { sprintf( - /* translators: %s is a calendar year, e.g. "2026". */ - __( '%s in review', 'jetpack-premium-analytics' ), - year.year - ) } - -
- - -
+
+ + + { year.year } + +
{ tiles.length === 0 ? ( @@ -219,13 +215,10 @@ function AnnualHighlightsReport( { * inner report. Host attributes are forwarded so any injected report params are * preserved even though the insights endpoint is not period-scoped. * - * @param props - Render props supplied by the widget host. - * @param props.attributes - Widget attributes. + * @param {AnnualHighlightsWidgetProps} props - The widget render props. * @return The rendered widget. */ -export default function AnnualHighlights( { - attributes = {}, -}: WidgetRenderProps< AnnualHighlightsRenderAttributes > ) { +export default function AnnualHighlights( { attributes = {} }: AnnualHighlightsWidgetProps ) { return ( item.showComments ?? true, }, - ], + ] as WidgetAttributeField< AnnualHighlightsAttributes >[], example: { attributes: { showPosts: true, diff --git a/projects/packages/premium-analytics/widgets/authors/__tests__/build-top-authors-data.test.ts b/projects/packages/premium-analytics/widgets/authors/__tests__/build-top-authors-data.test.ts index 0347297bd089..2e008c0b6bb1 100644 --- a/projects/packages/premium-analytics/widgets/authors/__tests__/build-top-authors-data.test.ts +++ b/projects/packages/premium-analytics/widgets/authors/__tests__/build-top-authors-data.test.ts @@ -12,22 +12,32 @@ type PostSeed = { }; type AuthorSeed = { + /** + * Stable author id. + */ id?: string | number; + /** + * Display label (defaults to `Author`). + */ label?: string; + /** + * View count for the period. + */ views: number; + /** + * Avatar URL (defaults to none). + */ avatar?: string | null; + /** + * The author's posts (defaults to none). + */ posts?: PostSeed[]; }; /** * Builds a single normalized top-authors item from a compact seed. * - * @param seed - The author seed. - * @param seed.id - Stable author id. - * @param seed.label - Display label (defaults to `Author`). - * @param seed.views - View count for the period. - * @param seed.avatar - Avatar URL (defaults to none). - * @param seed.posts - The author's posts (defaults to none). + * @param {AuthorSeed} seed - The author seed. * @return A normalized top-authors item. */ function makeAuthor( { diff --git a/projects/packages/premium-analytics/widgets/authors/package.json b/projects/packages/premium-analytics/widgets/authors/package.json index d60d4135e54b..65ebbd1d5f56 100644 --- a/projects/packages/premium-analytics/widgets/authors/package.json +++ b/projects/packages/premium-analytics/widgets/authors/package.json @@ -9,7 +9,7 @@ "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", "@wordpress/ui": "0.17.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" } } diff --git a/projects/packages/premium-analytics/widgets/authors/render.tsx b/projects/packages/premium-analytics/widgets/authors/render.tsx index db11e4feb647..bcfbbd81e133 100644 --- a/projects/packages/premium-analytics/widgets/authors/render.tsx +++ b/projects/packages/premium-analytics/widgets/authors/render.tsx @@ -35,7 +35,10 @@ const DEFAULT_MAX = 7; // also pass them via `attributes`. Compose the render-only shape to cover both. type AuthorsRenderAttributes = AuthorsAttributes & Partial< ReportParamsFieldAttributes >; -type AuthorsRenderProps = WidgetRenderProps< AuthorsRenderAttributes > & { +type AuthorsWidgetProps = WidgetRenderProps< AuthorsRenderAttributes > & { + /** + * Dashboard error handler. + */ setError?: ComponentProps< typeof WidgetRoot >[ 'setError' ]; }; @@ -87,12 +90,7 @@ export type AuthorsLeaderboardProps = { * is no Stats backend in Storybook, so the data-connected entry point would * only ever show chrome. * - * @param props - Component props. - * @param props.rows - Author rows to render. - * @param props.isLoading - Whether to render the initial loading overlay. - * @param props.isRefetching - Whether to layer a loading overlay over the chart. - * @param props.withComparison - Whether to render previous-period deltas. - * @param props.legendLabels - Custom labels for the current/comparison periods. + * @param {AuthorsLeaderboardProps} props - The component props. * @return The rendered leaderboard. */ export function AuthorsLeaderboard( { @@ -241,15 +239,21 @@ export function AuthorsLeaderboard( { ); } +type AuthorsReportProps = { + /** + * Maximum number of authors to display. + */ + max: number; +}; + /** * Fetches the top-authors report through the Jetpack Stats hook, builds the * leaderboard rows, and hands them to the presentational `AuthorsLeaderboard`. * - * @param props - Component props. - * @param props.max - Maximum number of authors to display. + * @param {AuthorsReportProps} props - The component props. * @return The widget content. */ -function AuthorsReport( { max }: { max: number } ) { +function AuthorsReport( { max }: AuthorsReportProps ) { const { reportParams } = useWidgetRootContext(); const statsParams = useMemo( () => ( { ...reportParams, max } ), [ reportParams, max ] ); @@ -304,12 +308,10 @@ function AuthorsReport( { max }: { max: number } ) { * `attributes.reportParams` directly. The widget's own `max` is forwarded to * the inner component. * - * @param props - Render props. - * @param props.attributes - Widget attributes. - * @param props.setError - Dashboard error handler. + * @param {AuthorsWidgetProps} props - The widget render props. * @return The rendered Authors widget. */ -export default function Authors( { attributes = {}, setError }: AuthorsRenderProps ) { +export default function Authors( { attributes = {}, setError }: AuthorsWidgetProps ) { return (
diff --git a/projects/packages/premium-analytics/widgets/authors/widget.ts b/projects/packages/premium-analytics/widgets/authors/widget.ts index a133ab04da2c..eec5f0e94af8 100644 --- a/projects/packages/premium-analytics/widgets/authors/widget.ts +++ b/projects/packages/premium-analytics/widgets/authors/widget.ts @@ -3,6 +3,7 @@ */ import { __ } from '@wordpress/i18n'; import { postAuthor } from '@wordpress/icons'; +import type { WidgetAttributeField } from '@wordpress/widget-primitives'; /** * Configurable attributes for the Authors widget. Mirrors the `attributes` @@ -29,7 +30,7 @@ export default { label: __( 'Maximum authors', 'jetpack-premium-analytics' ), type: 'integer', }, - ], + ] as WidgetAttributeField< AuthorsAttributes >[], example: { attributes: { max: 7, diff --git a/projects/packages/premium-analytics/widgets/average-items-per-order/package.json b/projects/packages/premium-analytics/widgets/average-items-per-order/package.json index 9d2d778b6b12..90ee7d6e4aad 100644 --- a/projects/packages/premium-analytics/widgets/average-items-per-order/package.json +++ b/projects/packages/premium-analytics/widgets/average-items-per-order/package.json @@ -7,8 +7,7 @@ "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", - "@wordpress/ui": "0.17.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" } } diff --git a/projects/packages/premium-analytics/widgets/average-items-per-order/render.tsx b/projects/packages/premium-analytics/widgets/average-items-per-order/render.tsx index 9c4299699246..0875e7d5cd8b 100644 --- a/projects/packages/premium-analytics/widgets/average-items-per-order/render.tsx +++ b/projects/packages/premium-analytics/widgets/average-items-per-order/render.tsx @@ -18,7 +18,10 @@ import type { ComponentProps } from 'react'; type AverageItemsPerOrderRenderAttributes = AverageItemsPerOrderAttributes & Partial< ReportParamsFieldAttributes >; -type AverageItemsPerOrderRenderProps = WidgetRenderProps< AverageItemsPerOrderRenderAttributes > & { +type AverageItemsPerOrderWidgetProps = WidgetRenderProps< AverageItemsPerOrderRenderAttributes > & { + /** + * Dashboard error handler. + */ setError?: ComponentProps< typeof WidgetRoot >[ 'setError' ]; }; @@ -29,11 +32,14 @@ type AverageItemsPerOrderRenderProps = WidgetRenderProps< AverageItemsPerOrderRe * client, chart theme, and resolved report params; OrderMetricWidget fetches * the orders report and renders the avg_items metric with a comparison delta * and sparkline. + * + * @param {AverageItemsPerOrderWidgetProps} props - The widget render props. + * @return The rendered widget. */ export default function AverageItemsPerOrderRender( { attributes = {}, setError, -}: AverageItemsPerOrderRenderProps ) { +}: AverageItemsPerOrderWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/average-items-per-order/widget.json b/projects/packages/premium-analytics/widgets/average-items-per-order/widget.json index 5547536c1e47..8936a40bad51 100644 --- a/projects/packages/premium-analytics/widgets/average-items-per-order/widget.json +++ b/projects/packages/premium-analytics/widgets/average-items-per-order/widget.json @@ -2,5 +2,6 @@ "name": "jpa/average-items-per-order", "title": "Average items per order", "description": "Show the average number of products per order over a set period of time.", - "category": "orders" + "category": "orders", + "presentation": "framed" } diff --git a/projects/packages/premium-analytics/widgets/average-order-value/package.json b/projects/packages/premium-analytics/widgets/average-order-value/package.json index d0c2839b9b2c..3e6894719263 100644 --- a/projects/packages/premium-analytics/widgets/average-order-value/package.json +++ b/projects/packages/premium-analytics/widgets/average-order-value/package.json @@ -7,7 +7,7 @@ "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" } } diff --git a/projects/packages/premium-analytics/widgets/average-order-value/render.tsx b/projects/packages/premium-analytics/widgets/average-order-value/render.tsx index d0477e3bb3d8..81939e9d3956 100644 --- a/projects/packages/premium-analytics/widgets/average-order-value/render.tsx +++ b/projects/packages/premium-analytics/widgets/average-order-value/render.tsx @@ -15,7 +15,10 @@ import type { ComponentProps } from 'react'; type AverageOrderValueRenderAttributes = AverageOrderValueAttributes & Partial< ReportParamsFieldAttributes >; -type AverageOrderValueRenderProps = WidgetRenderProps< AverageOrderValueRenderAttributes > & { +type AverageOrderValueWidgetProps = WidgetRenderProps< AverageOrderValueRenderAttributes > & { + /** + * Dashboard error handler. + */ setError?: ComponentProps< typeof WidgetRoot >[ 'setError' ]; }; @@ -26,11 +29,14 @@ type AverageOrderValueRenderProps = WidgetRenderProps< AverageOrderValueRenderAt * client, chart theme, and resolved report params; OrderMetricWidget fetches * the orders report and renders the average_order_value metric with a * comparison delta and sparkline. + * + * @param {AverageOrderValueWidgetProps} props - The widget render props. + * @return The rendered widget. */ export default function AverageOrderValueRender( { attributes = {}, setError, -}: AverageOrderValueRenderProps ) { +}: AverageOrderValueWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/average-order-value/widget.json b/projects/packages/premium-analytics/widgets/average-order-value/widget.json index 0f0ec57dad76..3691d7499fcf 100644 --- a/projects/packages/premium-analytics/widgets/average-order-value/widget.json +++ b/projects/packages/premium-analytics/widgets/average-order-value/widget.json @@ -2,5 +2,6 @@ "name": "jpa/average-order-value", "title": "Average order value", "description": "Track the average value of each order over a set period of time.", - "category": "orders" + "category": "orders", + "presentation": "framed" } diff --git a/projects/packages/premium-analytics/widgets/bookings-by-device/package.json b/projects/packages/premium-analytics/widgets/bookings-by-device/package.json index 48de6491d069..446f94b38f06 100644 --- a/projects/packages/premium-analytics/widgets/bookings-by-device/package.json +++ b/projects/packages/premium-analytics/widgets/bookings-by-device/package.json @@ -7,7 +7,7 @@ "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" } } diff --git a/projects/packages/premium-analytics/widgets/bookings-by-device/render.tsx b/projects/packages/premium-analytics/widgets/bookings-by-device/render.tsx index 12e7e8247aa4..19158bbbd037 100644 --- a/projects/packages/premium-analytics/widgets/bookings-by-device/render.tsx +++ b/projects/packages/premium-analytics/widgets/bookings-by-device/render.tsx @@ -19,7 +19,10 @@ import type { ComponentProps } from 'react'; type BookingsByDeviceRenderAttributes = BookingsByDeviceAttributes & Partial< ReportParamsFieldAttributes >; -type BookingsByDeviceRenderProps = WidgetRenderProps< BookingsByDeviceRenderAttributes > & { +type BookingsByDeviceWidgetProps = WidgetRenderProps< BookingsByDeviceRenderAttributes > & { + /** + * Dashboard error handler. + */ setError?: ComponentProps< typeof WidgetRoot >[ 'setError' ]; }; @@ -33,11 +36,14 @@ function BookingsByDeviceWidget() { * Thin composition over the widgets-toolkit: WidgetRoot provides the query * client, chart theme, and resolved report params; SalesByDeviceWidget fetches * the filtered bookings attribution report and renders the device breakdown. + * + * @param {BookingsByDeviceWidgetProps} props - The widget render props. + * @return The rendered widget. */ export default function BookingsByDeviceRender( { attributes = {}, setError, -}: BookingsByDeviceRenderProps ) { +}: BookingsByDeviceWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/bookings-by-device/widget.json b/projects/packages/premium-analytics/widgets/bookings-by-device/widget.json index 972cbe1ffb94..964066e3bbdb 100644 --- a/projects/packages/premium-analytics/widgets/bookings-by-device/widget.json +++ b/projects/packages/premium-analytics/widgets/bookings-by-device/widget.json @@ -2,5 +2,6 @@ "name": "jpa/bookings-by-device", "title": "Bookings by device", "description": "See which devices your customers are using to make bookings in your store.", - "category": "bookings" + "category": "bookings", + "presentation": "framed" } diff --git a/projects/packages/premium-analytics/widgets/bookings-by-status/package.json b/projects/packages/premium-analytics/widgets/bookings-by-status/package.json index f61c90957b12..b8f9da19209b 100644 --- a/projects/packages/premium-analytics/widgets/bookings-by-status/package.json +++ b/projects/packages/premium-analytics/widgets/bookings-by-status/package.json @@ -7,7 +7,7 @@ "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" } } diff --git a/projects/packages/premium-analytics/widgets/bookings-by-status/render.tsx b/projects/packages/premium-analytics/widgets/bookings-by-status/render.tsx index fa79e7bf1d75..ce78fb4836e4 100644 --- a/projects/packages/premium-analytics/widgets/bookings-by-status/render.tsx +++ b/projects/packages/premium-analytics/widgets/bookings-by-status/render.tsx @@ -18,7 +18,10 @@ import type { ComponentProps } from 'react'; type BookingsByStatusRenderAttributes = BookingsByStatusAttributes & Partial< ReportParamsFieldAttributes >; -type BookingsByStatusRenderProps = WidgetRenderProps< BookingsByStatusRenderAttributes > & { +type BookingsByStatusWidgetProps = WidgetRenderProps< BookingsByStatusRenderAttributes > & { + /** + * Dashboard error handler. + */ setError?: ComponentProps< typeof WidgetRoot >[ 'setError' ]; }; @@ -28,11 +31,14 @@ type BookingsByStatusRenderProps = WidgetRenderProps< BookingsByStatusRenderAttr * Thin composition over the widgets-toolkit: WidgetRoot provides the query * client, chart theme, and resolved report params; BookingsByAttendanceWidget * fetches the bookings report and renders the status breakdown. + * + * @param {BookingsByStatusWidgetProps} props - The widget render props. + * @return The rendered widget. */ export default function BookingsByStatusRender( { attributes = {}, setError, -}: BookingsByStatusRenderProps ) { +}: BookingsByStatusWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/bookings-by-status/widget.json b/projects/packages/premium-analytics/widgets/bookings-by-status/widget.json index 46a177bc0d0a..58e73ef6d28f 100644 --- a/projects/packages/premium-analytics/widgets/bookings-by-status/widget.json +++ b/projects/packages/premium-analytics/widgets/bookings-by-status/widget.json @@ -2,5 +2,6 @@ "name": "jpa/bookings-by-status", "title": "Bookings by status", "description": "Number of bookings by status over the selected time period.", - "category": "bookings" + "category": "bookings", + "presentation": "framed" } diff --git a/projects/packages/premium-analytics/widgets/bookings-over-time/package.json b/projects/packages/premium-analytics/widgets/bookings-over-time/package.json index d23715b4dec3..c052d0a22ed4 100644 --- a/projects/packages/premium-analytics/widgets/bookings-over-time/package.json +++ b/projects/packages/premium-analytics/widgets/bookings-over-time/package.json @@ -7,7 +7,7 @@ "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" } } diff --git a/projects/packages/premium-analytics/widgets/bookings-over-time/render.tsx b/projects/packages/premium-analytics/widgets/bookings-over-time/render.tsx index 6cf4d6e08e1a..e65601e4b6dd 100644 --- a/projects/packages/premium-analytics/widgets/bookings-over-time/render.tsx +++ b/projects/packages/premium-analytics/widgets/bookings-over-time/render.tsx @@ -18,7 +18,10 @@ import type { ComponentProps } from 'react'; type BookingsOverTimeRenderAttributes = BookingsOverTimeAttributes & Partial< ReportParamsFieldAttributes >; -type BookingsOverTimeRenderProps = WidgetRenderProps< BookingsOverTimeRenderAttributes > & { +type BookingsOverTimeWidgetProps = WidgetRenderProps< BookingsOverTimeRenderAttributes > & { + /** + * Dashboard error handler. + */ setError?: ComponentProps< typeof WidgetRoot >[ 'setError' ]; }; @@ -28,11 +31,14 @@ type BookingsOverTimeRenderProps = WidgetRenderProps< BookingsOverTimeRenderAttr * Thin composition over the widgets-toolkit: WidgetRoot provides the query * client, chart theme, and resolved report params; BookingOrderMetricWidget * fetches the bookings report and renders the order count metric over time. + * + * @param {BookingsOverTimeWidgetProps} props - The widget render props. + * @return The rendered widget. */ export default function BookingsOverTimeRender( { attributes = {}, setError, -}: BookingsOverTimeRenderProps ) { +}: BookingsOverTimeWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/bookings-over-time/widget.json b/projects/packages/premium-analytics/widgets/bookings-over-time/widget.json index 92b8aeb77057..d3a50d3afb21 100644 --- a/projects/packages/premium-analytics/widgets/bookings-over-time/widget.json +++ b/projects/packages/premium-analytics/widgets/bookings-over-time/widget.json @@ -2,5 +2,6 @@ "name": "jpa/bookings-over-time", "title": "Bookings over time", "description": "See a breakdown of when bookings are placed to identify peak selling periods.", - "category": "bookings" + "category": "bookings", + "presentation": "framed" } diff --git a/projects/packages/premium-analytics/widgets/bookings-revenue-by-customer-type/package.json b/projects/packages/premium-analytics/widgets/bookings-revenue-by-customer-type/package.json index 76819ab07b9d..2711e8c1eb2c 100644 --- a/projects/packages/premium-analytics/widgets/bookings-revenue-by-customer-type/package.json +++ b/projects/packages/premium-analytics/widgets/bookings-revenue-by-customer-type/package.json @@ -7,7 +7,7 @@ "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" } } diff --git a/projects/packages/premium-analytics/widgets/bookings-revenue-by-customer-type/render.tsx b/projects/packages/premium-analytics/widgets/bookings-revenue-by-customer-type/render.tsx index daff178de16f..5b0d2316978f 100644 --- a/projects/packages/premium-analytics/widgets/bookings-revenue-by-customer-type/render.tsx +++ b/projects/packages/premium-analytics/widgets/bookings-revenue-by-customer-type/render.tsx @@ -18,8 +18,11 @@ import type { ComponentProps } from 'react'; type BookingsRevenueByCustomerTypeRenderAttributes = BookingsRevenueByCustomerTypeAttributes & Partial< ReportParamsFieldAttributes >; -type BookingsRevenueByCustomerTypeRenderProps = +type BookingsRevenueByCustomerTypeWidgetProps = WidgetRenderProps< BookingsRevenueByCustomerTypeRenderAttributes > & { + /** + * Dashboard error handler. + */ setError?: ComponentProps< typeof WidgetRoot >[ 'setError' ]; }; @@ -29,11 +32,14 @@ type BookingsRevenueByCustomerTypeRenderProps = * Thin composition over the widgets-toolkit: WidgetRoot provides the query * client, chart theme, and resolved report params; BookingsRevenueByCustomerTypeWidget * fetches the bookings customers report and renders the revenue breakdown. + * + * @param {BookingsRevenueByCustomerTypeWidgetProps} props - The widget render props. + * @return The rendered widget. */ export default function BookingsRevenueByCustomerTypeRender( { attributes = {}, setError, -}: BookingsRevenueByCustomerTypeRenderProps ) { +}: BookingsRevenueByCustomerTypeWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/bookings-revenue-by-customer-type/widget.json b/projects/packages/premium-analytics/widgets/bookings-revenue-by-customer-type/widget.json index 4dd682090e64..420d05e24f51 100644 --- a/projects/packages/premium-analytics/widgets/bookings-revenue-by-customer-type/widget.json +++ b/projects/packages/premium-analytics/widgets/bookings-revenue-by-customer-type/widget.json @@ -2,5 +2,6 @@ "name": "jpa/bookings-revenue-by-customer-type", "title": "Bookings revenue by customer type", "description": "Revenue breakdown from new customers vs returning customers for bookings over the selected time period.", - "category": "bookings" + "category": "bookings", + "presentation": "framed" } diff --git a/projects/packages/premium-analytics/widgets/clicks/package.json b/projects/packages/premium-analytics/widgets/clicks/package.json index a09e6bfcf300..299235340934 100644 --- a/projects/packages/premium-analytics/widgets/clicks/package.json +++ b/projects/packages/premium-analytics/widgets/clicks/package.json @@ -10,6 +10,6 @@ "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", "@wordpress/ui": "0.17.0", - "@wordpress/widget-primitives": "next" + "@wordpress/widget-primitives": "0.2.0" } } diff --git a/projects/packages/premium-analytics/widgets/clicks/render.tsx b/projects/packages/premium-analytics/widgets/clicks/render.tsx index 6bb0f14efc89..30e00f9c6c08 100644 --- a/projects/packages/premium-analytics/widgets/clicks/render.tsx +++ b/projects/packages/premium-analytics/widgets/clicks/render.tsx @@ -29,6 +29,7 @@ import { type ClicksAttributes } from './widget'; import type { WidgetRenderProps } from '@wordpress/widget-primitives'; type ClicksRenderAttributes = ClicksAttributes & Partial< ReportParamsFieldAttributes >; +type ClicksWidgetProps = WidgetRenderProps< ClicksRenderAttributes >; const DATA_FORMAT = { type: 'number' as const, options: { useMultipliers: true, decimals: 0 } }; @@ -175,7 +176,20 @@ export function toClickRows( return sliced.map( toClickRow ); } -function ClickLabel( { row }: { row: ClickRow } ) { +type ClickLabelProps = { + /** + * The normalized click row whose favicon and label to render. + */ + row: ClickRow; +}; + +/** + * Renders a click row's favicon and label. + * + * @param {ClickLabelProps} props - The component props. + * @return The rendered label content. + */ +function ClickLabel( { row }: ClickLabelProps ) { return ( { row.icon && } @@ -242,22 +256,32 @@ function buildLeaderboardData( } export type ClicksLeaderboardProps = { + /** + * Normalized click rows. + */ rows?: ClickRow[]; + /** + * When true, show a loading overlay. + */ isLoading?: boolean; + /** + * When true, show an error message. + */ isError?: boolean; + /** + * When true, render comparison deltas. + */ withComparison?: boolean; + /** + * Callback fired when a row with child links is selected. + */ onDrillDown?: ( row: ClickRow ) => void; }; /** * Presentational leaderboard for the Clicks widget. * - * @param props - Component props. - * @param props.rows - Normalized click rows. - * @param props.isLoading - When true, show a loading overlay. - * @param props.isError - When true, show an error message. - * @param props.withComparison - When true, render comparison deltas. - * @param props.onDrillDown - Callback fired when a row with child links is selected. + * @param {ClicksLeaderboardProps} props - The component props. * @return The rendered leaderboard. */ export function ClicksLeaderboard( { @@ -292,7 +316,21 @@ export function ClicksLeaderboard( { ); } -function ClicksInner( { max }: { max: number } ) { +type ClicksInnerProps = { + /** + * Maximum rows to display. 0 means all rows returned by the API. + */ + max: number; +}; + +/** + * Clicks widget inner component. Reads report params from WidgetRoot context + * and renders the leaderboard, with drill-down into a link's child clicks. + * + * @param {ClicksInnerProps} props - The component props. + * @return The rendered widget content. + */ +function ClicksInner( { max }: ClicksInnerProps ) { const { reportParams } = useWidgetRootContext(); const { drillDownItem: selectedClickLabel, @@ -357,13 +395,10 @@ function ClicksInner( { max }: { max: number } ) { * Shows the most-clicked external links as a ranked leaderboard. Date range * comes from the shared dashboard date picker via WidgetRoot. * - * @param props - Render props. - * @param props.attributes - Widget attributes. + * @param {ClicksWidgetProps} props - The widget render props. * @return The rendered widget content. */ -export default function ClicksWidget( { - attributes = {}, -}: WidgetRenderProps< ClicksRenderAttributes > ) { +export default function ClicksWidget( { attributes = {} }: ClicksWidgetProps ) { const max = attributes?.max ?? 10; return ( diff --git a/projects/packages/premium-analytics/widgets/clicks/widget.ts b/projects/packages/premium-analytics/widgets/clicks/widget.ts index 811fd0af629e..6b3882fc8dc9 100644 --- a/projects/packages/premium-analytics/widgets/clicks/widget.ts +++ b/projects/packages/premium-analytics/widgets/clicks/widget.ts @@ -3,6 +3,7 @@ */ import { __ } from '@wordpress/i18n'; import { chartBar } from '@wordpress/icons'; +import type { WidgetAttributeField } from '@wordpress/widget-primitives'; /** * Configurable attributes for the Clicks widget. @@ -28,9 +29,9 @@ export default { { id: 'max', label: __( 'Number of results', 'jetpack-premium-analytics' ), - type: 'integer' as const, + type: 'integer', }, - ], + ] as WidgetAttributeField< ClicksAttributes >[], example: { attributes: { max: 10, diff --git a/projects/packages/premium-analytics/widgets/conversion-rate/package.json b/projects/packages/premium-analytics/widgets/conversion-rate/package.json index 314bf3d4dd48..3e725a5af2b6 100644 --- a/projects/packages/premium-analytics/widgets/conversion-rate/package.json +++ b/projects/packages/premium-analytics/widgets/conversion-rate/package.json @@ -7,8 +7,7 @@ "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", - "@wordpress/ui": "0.17.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" } } diff --git a/projects/packages/premium-analytics/widgets/conversion-rate/render.tsx b/projects/packages/premium-analytics/widgets/conversion-rate/render.tsx index 944d0b62051a..0dd04d20d78a 100644 --- a/projects/packages/premium-analytics/widgets/conversion-rate/render.tsx +++ b/projects/packages/premium-analytics/widgets/conversion-rate/render.tsx @@ -18,7 +18,7 @@ import type { ComponentProps } from 'react'; type ConversionRateRenderAttributes = ConversionRateAttributes & Partial< ReportParamsFieldAttributes >; -type ConversionRateRenderProps = WidgetRenderProps< ConversionRateRenderAttributes > & { +type ConversionRateWidgetProps = WidgetRenderProps< ConversionRateRenderAttributes > & { setError?: ComponentProps< typeof WidgetRoot >[ 'setError' ]; }; @@ -28,11 +28,14 @@ type ConversionRateRenderProps = WidgetRenderProps< ConversionRateRenderAttribut * Thin composition over WidgetRoot: WidgetRoot provides the query client, * chart theme, and resolved report params; ConversionRateWidget fetches the * conversion-rate report and renders the funnel. + * + * @param {ConversionRateWidgetProps} props - The widget render props. + * @return The rendered widget. */ export default function ConversionRateRender( { attributes = {}, setError, -}: ConversionRateRenderProps ) { +}: ConversionRateWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/conversion-rate/stories/conversion-rate-widget.stories.tsx b/projects/packages/premium-analytics/widgets/conversion-rate/stories/conversion-rate-widget.stories.tsx index e461fb8c391b..adb5b0fb797a 100644 --- a/projects/packages/premium-analytics/widgets/conversion-rate/stories/conversion-rate-widget.stories.tsx +++ b/projects/packages/premium-analytics/widgets/conversion-rate/stories/conversion-rate-widget.stories.tsx @@ -76,14 +76,14 @@ function registerConversionRateMocks(): void { registerReportMocks(); registerConversionRateMocks(); -type ConversionRateRenderProps = ComponentProps< typeof ConversionRateRender >; +type ConversionRateWidgetProps = ComponentProps< typeof ConversionRateRender >; interface ConversionRateStoryControls { withComparison: boolean; preset: SelectablePresetId; } -type ConversionRateStoryProps = ConversionRateRenderProps & ConversionRateStoryControls; +type ConversionRateStoryProps = ConversionRateWidgetProps & ConversionRateStoryControls; interface ConversionRateDashboardStoryProps extends WidgetDashboardWithWidgetControls, @@ -98,7 +98,7 @@ const withWidgetCanvas: Decorator = Story => ( function getConversionRateAttributes( withComparison = false, preset: SelectablePresetId = DEFAULT_PRESET -): ConversionRateRenderProps[ 'attributes' ] { +): ConversionRateWidgetProps[ 'attributes' ] { const reportParams = getDefaultQueryParams( withComparison, preset ); conversionRatePrimaryTo = reportParams.to; diff --git a/projects/packages/premium-analytics/widgets/conversion-rate/widget.json b/projects/packages/premium-analytics/widgets/conversion-rate/widget.json index 97a7a7e5693f..6f1062968c4a 100644 --- a/projects/packages/premium-analytics/widgets/conversion-rate/widget.json +++ b/projects/packages/premium-analytics/widgets/conversion-rate/widget.json @@ -2,5 +2,6 @@ "name": "jpa/conversion-rate", "title": "Store conversion rate", "description": "Store conversion rate over the selected time period.", - "category": "store" + "category": "store", + "presentation": "framed" } diff --git a/projects/packages/premium-analytics/widgets/coupon-usage-over-time/package.json b/projects/packages/premium-analytics/widgets/coupon-usage-over-time/package.json index e337f06739e2..a682ee39616e 100644 --- a/projects/packages/premium-analytics/widgets/coupon-usage-over-time/package.json +++ b/projects/packages/premium-analytics/widgets/coupon-usage-over-time/package.json @@ -7,7 +7,7 @@ "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" } } diff --git a/projects/packages/premium-analytics/widgets/coupon-usage-over-time/render.tsx b/projects/packages/premium-analytics/widgets/coupon-usage-over-time/render.tsx index 1b53bb683383..04b24e29dd27 100644 --- a/projects/packages/premium-analytics/widgets/coupon-usage-over-time/render.tsx +++ b/projects/packages/premium-analytics/widgets/coupon-usage-over-time/render.tsx @@ -18,7 +18,7 @@ import type { ComponentProps } from 'react'; type CouponUsageOverTimeRenderAttributes = CouponUsageOverTimeAttributes & Partial< ReportParamsFieldAttributes >; -type CouponUsageOverTimeRenderProps = WidgetRenderProps< CouponUsageOverTimeRenderAttributes > & { +type CouponUsageOverTimeWidgetProps = WidgetRenderProps< CouponUsageOverTimeRenderAttributes > & { setError?: ComponentProps< typeof WidgetRoot >[ 'setError' ]; }; @@ -28,11 +28,14 @@ type CouponUsageOverTimeRenderProps = WidgetRenderProps< CouponUsageOverTimeRend * Thin composition over the widgets-toolkit: WidgetRoot provides the query * client, chart theme, and resolved report params; CouponUseWidget fetches the * coupons-by-date report and renders the coupon usage breakdown. + * + * @param {CouponUsageOverTimeWidgetProps} props - The widget render props. + * @return The rendered widget. */ export default function CouponUsageOverTimeRender( { attributes = {}, setError, -}: CouponUsageOverTimeRenderProps ) { +}: CouponUsageOverTimeWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/coupon-usage-over-time/stories/coupon-usage-over-time-widget.stories.tsx b/projects/packages/premium-analytics/widgets/coupon-usage-over-time/stories/coupon-usage-over-time-widget.stories.tsx index c664e9b9deae..8c51730a385e 100644 --- a/projects/packages/premium-analytics/widgets/coupon-usage-over-time/stories/coupon-usage-over-time-widget.stories.tsx +++ b/projects/packages/premium-analytics/widgets/coupon-usage-over-time/stories/coupon-usage-over-time-widget.stories.tsx @@ -19,14 +19,14 @@ const COUPON_USAGE_OVER_TIME_RENDER_MODULE = 'storybook/coupon-usage-over-time'; const DEFAULT_PRESET = 'last-30-days' satisfies SelectablePresetId; const PRESET_OPTIONS = SELECTABLE_PRESETS; -type CouponUsageOverTimeRenderProps = ComponentProps< typeof CouponUsageOverTimeRender >; +type CouponUsageOverTimeWidgetProps = ComponentProps< typeof CouponUsageOverTimeRender >; interface CouponUsageOverTimeStoryControls { withComparison: boolean; preset: SelectablePresetId; } -type CouponUsageOverTimeStoryProps = CouponUsageOverTimeRenderProps & +type CouponUsageOverTimeStoryProps = CouponUsageOverTimeWidgetProps & CouponUsageOverTimeStoryControls; interface CouponUsageOverTimeDashboardStoryProps @@ -42,7 +42,7 @@ const withWidgetCanvas: Decorator = Story => ( function getCouponUsageOverTimeAttributes( withComparison = false, preset: SelectablePresetId = DEFAULT_PRESET -): CouponUsageOverTimeRenderProps[ 'attributes' ] { +): CouponUsageOverTimeWidgetProps[ 'attributes' ] { return { reportParams: getDefaultQueryParams( withComparison, preset ), }; diff --git a/projects/packages/premium-analytics/widgets/coupon-usage-over-time/widget.json b/projects/packages/premium-analytics/widgets/coupon-usage-over-time/widget.json index 277ac6b67697..26624f4d1e13 100644 --- a/projects/packages/premium-analytics/widgets/coupon-usage-over-time/widget.json +++ b/projects/packages/premium-analytics/widgets/coupon-usage-over-time/widget.json @@ -2,5 +2,6 @@ "name": "jpa/coupon-usage-over-time", "title": "Coupon usage over time", "description": "Coupon usage over the selected time period.", - "category": "coupons" + "category": "coupons", + "presentation": "framed" } diff --git a/projects/packages/premium-analytics/widgets/devices/package.json b/projects/packages/premium-analytics/widgets/devices/package.json index 98be9097805d..79bdfe95d1ad 100644 --- a/projects/packages/premium-analytics/widgets/devices/package.json +++ b/projects/packages/premium-analytics/widgets/devices/package.json @@ -10,6 +10,6 @@ "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", "@wordpress/ui": "0.17.0", - "@wordpress/widget-primitives": "next" + "@wordpress/widget-primitives": "0.2.0" } } diff --git a/projects/packages/premium-analytics/widgets/devices/render.tsx b/projects/packages/premium-analytics/widgets/devices/render.tsx index 0438e5a4e7c0..d0b792ca7c4e 100644 --- a/projects/packages/premium-analytics/widgets/devices/render.tsx +++ b/projects/packages/premium-analytics/widgets/devices/render.tsx @@ -41,14 +41,20 @@ function toRatio( percentage: number ) { return percentage / 100; } +type DevicesInnerProps = { + /** + * Max rows to display. + */ + max: number; +}; + /** * Inner component — rendered inside WidgetRoot. * - * @param props - Props. - * @param props.max - Max rows to display. + * @param {DevicesInnerProps} props - The component props. * @return The rendered semi-circle chart or state placeholder. */ -function DevicesInner( { max }: { max: number } ) { +function DevicesInner( { max }: DevicesInnerProps ) { const { reportParams } = useWidgetRootContext(); const { data, comparisonData, hasComparison, isLoading, isError, errorReason } = useDeviceViews( { reportParams, @@ -139,8 +145,7 @@ function DevicesInner( { max }: { max: number } ) { * * Shows screen size breakdown (Desktop / Mobile / Tablet) as a semi-circle chart. * - * @param props - Render props. - * @param props.attributes - Widget attributes (max). + * @param {DevicesWidgetProps} props - The widget render props. * @return The rendered widget content. */ export default function DevicesWidget( { attributes = {} }: DevicesWidgetProps ) { diff --git a/projects/packages/premium-analytics/widgets/devices/use-device-views.ts b/projects/packages/premium-analytics/widgets/devices/use-device-views.ts index cb20967a8b34..311f153fc55b 100644 --- a/projects/packages/premium-analytics/widgets/devices/use-device-views.ts +++ b/projects/packages/premium-analytics/widgets/devices/use-device-views.ts @@ -21,8 +21,17 @@ export interface DeviceView { } interface UseDeviceViewsArgs { + /** + * PA ReportParams injected by the host via attributes. + */ reportParams: ReportParams; + /** + * Maximum rows to display (0 = all). + */ max: number; + /** + * Device dimension to break down by. + */ deviceProperty?: StatsDeviceProperty; } @@ -65,10 +74,7 @@ function toDeviceView( item: StatsDevicesItem ): DeviceView { /** * Fetch device percentages for the Devices widget via the shared Stats data layer. * - * @param args - Hook arguments. - * @param args.reportParams - PA ReportParams injected by the host via attributes. - * @param args.max - Maximum rows to display (0 = all). - * @param args.deviceProperty - Device dimension to break down by. + * @param {UseDeviceViewsArgs} args - Hook arguments. * @return The current data/loading/error state. */ export default function useDeviceViews( { diff --git a/projects/packages/premium-analytics/widgets/devices/widget.ts b/projects/packages/premium-analytics/widgets/devices/widget.ts index c518ab5ca43f..a2bcf4a25415 100644 --- a/projects/packages/premium-analytics/widgets/devices/widget.ts +++ b/projects/packages/premium-analytics/widgets/devices/widget.ts @@ -3,13 +3,15 @@ */ import { __ } from '@wordpress/i18n'; import { desktop } from '@wordpress/icons'; +import type { WidgetAttributeField } from '@wordpress/widget-primitives'; /** * Widget attributes shape. - * - * @property max - Maximum rows to display (0 = all). Defaults to 5. */ export type DevicesAttributes = { + /** + * Maximum rows to display (0 = all). Defaults to 5. + */ max?: number; }; @@ -30,7 +32,7 @@ export default { label: __( 'Max rows', 'jetpack-premium-analytics' ), type: 'number', }, - ], + ] as WidgetAttributeField< DevicesAttributes >[], example: { attributes: { max: 5, diff --git a/projects/packages/premium-analytics/widgets/emails/package.json b/projects/packages/premium-analytics/widgets/emails/package.json index 058b43e2042a..9c641877f1a7 100644 --- a/projects/packages/premium-analytics/widgets/emails/package.json +++ b/projects/packages/premium-analytics/widgets/emails/package.json @@ -6,11 +6,10 @@ "dependencies": { "@jetpack-premium-analytics/data": "link:../../packages/data", "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", - "@wordpress/components": "36.1.0", "@wordpress/element": "8.2.0", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", "@wordpress/ui": "0.17.0", - "@wordpress/widget-primitives": "next" + "@wordpress/widget-primitives": "0.2.0" } } diff --git a/projects/packages/premium-analytics/widgets/emails/render.tsx b/projects/packages/premium-analytics/widgets/emails/render.tsx index 52cb57e4ebe3..f52195eb51fb 100644 --- a/projects/packages/premium-analytics/widgets/emails/render.tsx +++ b/projects/packages/premium-analytics/widgets/emails/render.tsx @@ -9,24 +9,18 @@ import { type LeaderboardChartData, type ReportParamsFieldAttributes, } from '@jetpack-premium-analytics/widgets-toolkit'; -import { SelectControl } from '@wordpress/components'; -import { useCallback, useMemo, useState } from '@wordpress/element'; +import { useMemo } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; -import { Icon, Stack, Text } from '@wordpress/ui'; +import { Stack, Text } from '@wordpress/ui'; /** * Internal dependencies */ import styles from './style.module.css'; -import widgetDefinition, { type EmailsAttributes } from './widget'; +import { type EmailMetric, type EmailsAttributes } from './widget'; import type { WidgetRenderProps } from '@wordpress/widget-primitives'; type EmailsRenderAttributes = EmailsAttributes & Partial< ReportParamsFieldAttributes >; - -/** - * Which rate the leaderboard displays. Rows stay in newest-first order - * regardless; this only changes the value shown and the overlay bar width. - */ -export type EmailMetric = 'opens' | 'clicks'; +type EmailsWidgetProps = WidgetRenderProps< EmailsRenderAttributes >; /** * A single normalized email row, flattened from the `useStatsEmailSummary` @@ -89,23 +83,6 @@ function buildLeaderboardData( rows: EmailRow[], metric: EmailMetric ): Leaderbo } ); } -/** - * Widget header title: the envelope icon plus the "Emails" label. Rendered by - * the widget itself (not the host) because the widget is `full-bleed`, so the - * header sits on the same row as the metric selector — matching the Locations - * widget's layout. - * - * @return The header title. - */ -function EmailsHeaderTitle() { - return ( - - - { __( 'Emails', 'jetpack-premium-analytics' ) } - - ); -} - type EmailsLeaderboardProps = { /** * Normalized email rows to render. When omitted, the empty state is shown @@ -127,17 +104,17 @@ type EmailsLeaderboardProps = { */ isError?: boolean; /** - * Initial metric. Defaults to `opens`. + * Which rate to display. Defaults to `opens`. */ - initialMetric?: EmailMetric; + metric?: EmailMetric; }; /** * Presentational leaderboard for the "Emails" widget. Lists the most recently - * sent emails with a selector to switch between open rate and click rate. + * sent emails with their open or click rate. * - * Takes already-fetched rows via props and owns only the metric selection plus - * the loading, error, empty, and populated states. Exported so Storybook can + * Takes already-fetched rows and the active metric via props and owns only the + * loading, error, empty, and populated states. Exported so Storybook can * exercise those states with fixture rows (there is no analytics backend in * Storybook, so the data-connected entry point would only ever show chrome). * @@ -149,15 +126,8 @@ export const EmailsLeaderboard = ( { isLoading = false, isFetching = false, isError = false, - initialMetric = 'opens', + metric = 'opens', }: EmailsLeaderboardProps ) => { - const [ metric, setMetric ] = useState< EmailMetric >( initialMetric ); - - const handleMetricChange = useCallback( - ( value: string ) => setMetric( value as EmailMetric ), - [] - ); - const data = useMemo( () => buildLeaderboardData( rows, metric ), [ rows, metric ] ); let body; @@ -190,29 +160,7 @@ export const EmailsLeaderboard = ( { ); } - return ( - - - - - - - -
{ body }
-
- ); + return
{ body }
; }; /** @@ -250,6 +198,7 @@ type EmailsReportProps = { */ function EmailsReport( { attributes }: EmailsReportProps ) { const max = attributes?.max ?? 10; + const metric = attributes?.metric ?? 'opens'; // The summary endpoint accepts 1–30 rows and resets anything outside that // range to 10, so request its maximum when the widget wants "all rows". const quantity = max > 0 ? Math.min( max, 30 ) : 30; @@ -264,6 +213,7 @@ function EmailsReport( { attributes }: EmailsReportProps ) { isLoading={ isLoading } isFetching={ isFetching } isError={ isError } + metric={ metric } /> ); } @@ -271,13 +221,14 @@ function EmailsReport( { attributes }: EmailsReportProps ) { /** * Widget render entry point. * - * Passes host attributes into `WidgetRoot` for the widget contract. The email - * summary still reads `max` from props because it does not use report params. + * The displayed rate is the `metric` attribute (`relevance: 'high'`), exposed + * as a control by the widget host. The email summary still reads `max` from + * props because it does not use report params. * - * @param {WidgetRenderProps< EmailsRenderAttributes >} props - The render props supplied by the widget host. + * @param {EmailsWidgetProps} props - The widget render props. * @return The rendered widget. */ -export default function Emails( { attributes = {} }: WidgetRenderProps< EmailsRenderAttributes > ) { +export default function Emails( { attributes = {} }: EmailsWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/emails/stories/emails-widget.stories.tsx b/projects/packages/premium-analytics/widgets/emails/stories/emails-widget.stories.tsx index 2b7d1b323064..658902c07257 100644 --- a/projects/packages/premium-analytics/widgets/emails/stories/emails-widget.stories.tsx +++ b/projects/packages/premium-analytics/widgets/emails/stories/emails-widget.stories.tsx @@ -34,7 +34,7 @@ const meta: Meta< typeof EmailsLeaderboard > = { docs: { description: { component: - 'The "Emails" widget. Lists the most recently sent emails with a selector to switch between open rate and click rate, rendered as a leaderboard. The close-up stories drive the presentational `EmailsLeaderboard` with fixtures; `WidgetDashboardWithWidget` mounts the real dashboard with the data-connected widget (fed by a mocked `stats/emails/summary` response).', + 'The "Emails" widget. Lists the most recently sent emails with their open or click rate, rendered as a leaderboard. The displayed rate is the `metric` attribute (`relevance: \'high\'`), exposed as a control by the widget host. The close-up stories drive the presentational `EmailsLeaderboard` with fixtures; `WidgetDashboardWithWidget` mounts the real dashboard with the data-connected widget (fed by a mocked `stats/emails/summary` response).', }, }, }, @@ -121,12 +121,12 @@ export const Default: Story = { }; /** - * Click-rate view — the selector defaults to click rate instead of open rate. + * Click-rate view — the `metric` attribute set to click rate instead of open rate. */ export const ByClickRate: Story = { args: { rows: mockRows, - initialMetric: 'clicks', + metric: 'clicks', }, decorators: [ withWidgetCanvas ], }; @@ -232,14 +232,11 @@ function EmailsDashboardStory( props: WidgetDashboardWithWidgetControls ) { name: widgetDefinition.name, title: widgetDefinition.title, icon: widgetDefinition.icon, - // Matches widget.json so the host hides its card title (full-bleed), - // exactly as it does on the real dashboard — the widget renders its - // own header with the title next to the metric selector. - presentation: 'full-bleed', + presentation: 'framed', } } renderModule={ EMAILS_RENDER_MODULE } renderComponent={ EmailsRender as ComponentType< WidgetRenderProps< unknown > > } - attributes={ { max: 6 } } + attributes={ { max: 6, metric: 'opens' } } /> ); } diff --git a/projects/packages/premium-analytics/widgets/emails/style.module.css b/projects/packages/premium-analytics/widgets/emails/style.module.css index 3394f9928db5..0c56dacf0c4c 100644 --- a/projects/packages/premium-analytics/widgets/emails/style.module.css +++ b/projects/packages/premium-analytics/widgets/emails/style.module.css @@ -3,61 +3,14 @@ display: flex; flex-direction: column; height: 100%; - min-height: 0; + min-block-size: 0; overflow: hidden; } -.header { - flex-wrap: wrap; - gap: var(--wpds-dimension-gap-sm, 8px); - padding: var(--wpds-dimension-padding-md) var(--wpds-dimension-padding-lg); - min-height: 32px; -} - -.title { +.leaderboard { flex: 1 1 0; min-inline-size: 0; - font-size: 13px; - line-height: 20px; - font-weight: 500; /* design spec was 499; 500 is the nearest valid CSS value */ - color: inherit; -} - -.title * { - font-weight: inherit; -} - -.headerTitle { - display: inline-flex; - align-items: center; - min-inline-size: 0; - gap: var(--wpds-dimension-gap-xs, 4px); - line-height: inherit; -} - -.headerIcon { - flex: 0 0 auto; -} - -.metricSelect { - flex: 0 1 220px; - inline-size: min(100%, 220px); - max-inline-size: 100%; - min-inline-size: 0; -} - -.content { - position: relative; - display: flex; - flex-direction: column; - padding: 0 var(--wpds-dimension-padding-lg) var(--wpds-dimension-padding-lg); - flex: 1 1 0; - min-height: 0; -} - -.leaderboard { - min-width: 0; - min-height: 0; + min-block-size: 0; overflow: hidden; } diff --git a/projects/packages/premium-analytics/widgets/emails/widget.json b/projects/packages/premium-analytics/widgets/emails/widget.json index a5e4d2d849a7..03242bc0be01 100644 --- a/projects/packages/premium-analytics/widgets/emails/widget.json +++ b/projects/packages/premium-analytics/widgets/emails/widget.json @@ -3,5 +3,5 @@ "title": "Emails", "description": "Open and click rates for your latest emails.", "category": "stats", - "presentation": "full-bleed" + "presentation": "framed" } diff --git a/projects/packages/premium-analytics/widgets/emails/widget.ts b/projects/packages/premium-analytics/widgets/emails/widget.ts index f41b70f551c2..742eff6a894e 100644 --- a/projects/packages/premium-analytics/widgets/emails/widget.ts +++ b/projects/packages/premium-analytics/widgets/emails/widget.ts @@ -3,6 +3,13 @@ */ import { __ } from '@wordpress/i18n'; import { envelope } from '@wordpress/icons'; +import type { WidgetAttributeField } from '@wordpress/widget-primitives'; + +/** + * Which rate the leaderboard displays. Rows stay in newest-first order + * regardless; this only changes the value shown and the overlay bar width. + */ +export type EmailMetric = 'opens' | 'clicks'; /** * Configurable attributes for the Emails widget. Mirrors the `attributes` @@ -14,15 +21,20 @@ export type EmailsAttributes = { * Number of emails to show. `0` means as many as the endpoint returns (max 30). */ max?: number; + /** + * Which rate to display. Defaults to `opens`. + */ + metric?: EmailMetric; }; /** * Widget type definition. * * Ported from the Jetpack Stats "Emails" module. Lists the most recently sent - * emails with their open and click rates; a selector switches the displayed - * metric. The summary endpoint reports across the whole lifetime of the site, - * so there is no date range or comparison period. + * emails with their open and click rates. The displayed rate is the `metric` + * attribute (`relevance: 'high'`), so the widget host renders its control. + * The summary endpoint reports across the whole lifetime of the site, so + * there is no date range or comparison period. */ export default { name: 'jpa/stats-emails', @@ -34,10 +46,27 @@ export default { label: __( 'Number of results', 'jetpack-premium-analytics' ), type: 'integer', }, - ], + { + id: 'metric', + label: __( 'View by', 'jetpack-premium-analytics' ), + type: 'text', + elements: [ + { + label: __( 'Open rate', 'jetpack-premium-analytics' ), + value: 'opens', + }, + { + label: __( 'Click rate', 'jetpack-premium-analytics' ), + value: 'clicks', + }, + ], + relevance: 'high', + }, + ] as WidgetAttributeField< EmailsAttributes >[], example: { attributes: { max: 10, + metric: 'opens', }, }, }; diff --git a/projects/packages/premium-analytics/widgets/file-downloads/package.json b/projects/packages/premium-analytics/widgets/file-downloads/package.json index b2b7184cd7b3..3c7082e8c4ed 100644 --- a/projects/packages/premium-analytics/widgets/file-downloads/package.json +++ b/projects/packages/premium-analytics/widgets/file-downloads/package.json @@ -6,9 +6,10 @@ "dependencies": { "@jetpack-premium-analytics/data": "link:../../packages/data", "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", + "@wordpress/element": "8.2.0", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", "@wordpress/ui": "0.17.0", - "@wordpress/widget-primitives": "next" + "@wordpress/widget-primitives": "0.2.0" } } diff --git a/projects/packages/premium-analytics/widgets/file-downloads/render.tsx b/projects/packages/premium-analytics/widgets/file-downloads/render.tsx index 13eb818a9472..7ea90f8f40fc 100644 --- a/projects/packages/premium-analytics/widgets/file-downloads/render.tsx +++ b/projects/packages/premium-analytics/widgets/file-downloads/render.tsx @@ -220,10 +220,25 @@ function toFileDownloadRows( * Props for `FileDownloadsLeaderboard`. */ export type FileDownloadsLeaderboardProps = { + /** + * Normalized download rows to render. + */ rows?: FileDownloadRow[]; + /** + * When true, show a loading overlay. + */ isLoading?: boolean; + /** + * When true, show an error message. + */ isError?: boolean; + /** + * When true, render previous-period deltas. + */ withComparison?: boolean; + /** + * Custom error message to show when `isError` is true. + */ errorMessage?: string; }; @@ -234,12 +249,7 @@ export type FileDownloadsLeaderboardProps = { * populated states. Exported so Storybook can exercise those states with * fixture rows without needing a live WordPress backend. * - * @param props - Component props. - * @param props.rows - Normalized download rows to render. - * @param props.isLoading - When true, show a loading overlay. - * @param props.isError - When true, show an error message. - * @param props.withComparison - When true, render previous-period deltas. - * @param props.errorMessage - Custom error message to show when `isError` is true. + * @param {FileDownloadsLeaderboardProps} props - The component props. * @return The rendered leaderboard. */ export function FileDownloadsLeaderboard( { @@ -277,14 +287,20 @@ export function FileDownloadsLeaderboard( { ); } +type FileDownloadsInnerProps = { + /** + * Max rows to display. + */ + max: number; +}; + /** * Inner component — rendered inside WidgetRoot, reads dashboard context. * - * @param props - Props. - * @param props.max - Max rows to display. + * @param {FileDownloadsInnerProps} props - The component props. * @return The rendered leaderboard or state placeholder. */ -function FileDownloadsInner( { max }: { max: number } ) { +function FileDownloadsInner( { max }: FileDownloadsInnerProps ) { const { reportParams } = useWidgetRootContext(); const { primary, comparison, hasComparison, isLoading, isFetching, hasData, isError, error } = useStatsFileDownloads( reportParams as StatsReportParams ); @@ -323,8 +339,7 @@ function FileDownloadsInner( { max }: { max: number } ) { * Shows the most-downloaded files as a ranked leaderboard. Date range comes * from the shared dashboard date picker via WidgetRoot. * - * @param props - Render props. - * @param props.attributes - Widget attributes (max). + * @param {FileDownloadsWidgetProps} props - The widget render props. * @return The rendered widget content. */ export default function FileDownloadsWidget( { attributes = {} }: FileDownloadsWidgetProps ) { diff --git a/projects/packages/premium-analytics/widgets/file-downloads/widget.ts b/projects/packages/premium-analytics/widgets/file-downloads/widget.ts index 4f029f38ade5..07619675cbaf 100644 --- a/projects/packages/premium-analytics/widgets/file-downloads/widget.ts +++ b/projects/packages/premium-analytics/widgets/file-downloads/widget.ts @@ -3,13 +3,15 @@ */ import { __ } from '@wordpress/i18n'; import { download } from '@wordpress/icons'; +import type { WidgetAttributeField } from '@wordpress/widget-primitives'; /** * Configurable attributes for the File downloads widget. - * - * @property max - Maximum rows to display (0 = all). Defaults to 10. */ export type FileDownloadsAttributes = { + /** + * Maximum rows to display (0 = all). Defaults to 10. + */ max?: number; }; @@ -30,7 +32,7 @@ export default { label: __( 'Max rows', 'jetpack-premium-analytics' ), type: 'number', }, - ], + ] as WidgetAttributeField< FileDownloadsAttributes >[], example: { attributes: { max: 10, diff --git a/projects/packages/premium-analytics/widgets/gross-sales-over-time/package.json b/projects/packages/premium-analytics/widgets/gross-sales-over-time/package.json index ec83ef64a443..97f18f61d881 100644 --- a/projects/packages/premium-analytics/widgets/gross-sales-over-time/package.json +++ b/projects/packages/premium-analytics/widgets/gross-sales-over-time/package.json @@ -7,7 +7,7 @@ "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" } } diff --git a/projects/packages/premium-analytics/widgets/gross-sales-over-time/render.tsx b/projects/packages/premium-analytics/widgets/gross-sales-over-time/render.tsx index 3c2992063539..f31466eeeabd 100644 --- a/projects/packages/premium-analytics/widgets/gross-sales-over-time/render.tsx +++ b/projects/packages/premium-analytics/widgets/gross-sales-over-time/render.tsx @@ -18,7 +18,7 @@ import type { ComponentProps } from 'react'; type GrossSalesOverTimeRenderAttributes = GrossSalesOverTimeAttributes & Partial< ReportParamsFieldAttributes >; -type GrossSalesOverTimeRenderProps = WidgetRenderProps< GrossSalesOverTimeRenderAttributes > & { +type GrossSalesOverTimeWidgetProps = WidgetRenderProps< GrossSalesOverTimeRenderAttributes > & { setError?: ComponentProps< typeof WidgetRoot >[ 'setError' ]; }; @@ -28,11 +28,14 @@ type GrossSalesOverTimeRenderProps = WidgetRenderProps< GrossSalesOverTimeRender * Thin composition over the widgets-toolkit: WidgetRoot provides the query * client, chart theme, and resolved report params; OrderMetricWidget fetches * the orders report and renders the gross sales metric over time. + * + * @param {GrossSalesOverTimeWidgetProps} props - The widget render props. + * @return The rendered widget. */ export default function GrossSalesOverTimeRender( { attributes = {}, setError, -}: GrossSalesOverTimeRenderProps ) { +}: GrossSalesOverTimeWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/gross-sales-over-time/stories/gross-sales-over-time-widget.stories.tsx b/projects/packages/premium-analytics/widgets/gross-sales-over-time/stories/gross-sales-over-time-widget.stories.tsx index 9d6ff033b736..85093afc2161 100644 --- a/projects/packages/premium-analytics/widgets/gross-sales-over-time/stories/gross-sales-over-time-widget.stories.tsx +++ b/projects/packages/premium-analytics/widgets/gross-sales-over-time/stories/gross-sales-over-time-widget.stories.tsx @@ -22,14 +22,14 @@ const PRESET_OPTIONS = SELECTABLE_PRESETS; // Static Storybook builds need this source import before ComparativeLineChart reads LineChart.Legend. const ensureLineChartComposition = () => LineChart.Legend; -type GrossSalesOverTimeRenderProps = ComponentProps< typeof GrossSalesOverTimeRender >; +type GrossSalesOverTimeWidgetProps = ComponentProps< typeof GrossSalesOverTimeRender >; interface GrossSalesOverTimeStoryControls { withComparison: boolean; preset: SelectablePresetId; } -type GrossSalesOverTimeStoryProps = GrossSalesOverTimeRenderProps & GrossSalesOverTimeStoryControls; +type GrossSalesOverTimeStoryProps = GrossSalesOverTimeWidgetProps & GrossSalesOverTimeStoryControls; interface GrossSalesOverTimeDashboardStoryProps extends WidgetDashboardWithWidgetControls, @@ -44,7 +44,7 @@ const withWidgetCanvas: Decorator = Story => ( function getGrossSalesOverTimeAttributes( withComparison = false, preset: SelectablePresetId = DEFAULT_PRESET -): GrossSalesOverTimeRenderProps[ 'attributes' ] { +): GrossSalesOverTimeWidgetProps[ 'attributes' ] { return { reportParams: getDefaultQueryParams( withComparison, preset ), }; diff --git a/projects/packages/premium-analytics/widgets/gross-sales-over-time/widget.json b/projects/packages/premium-analytics/widgets/gross-sales-over-time/widget.json index 5aee1e1bf477..72c93df4a3c5 100644 --- a/projects/packages/premium-analytics/widgets/gross-sales-over-time/widget.json +++ b/projects/packages/premium-analytics/widgets/gross-sales-over-time/widget.json @@ -2,5 +2,6 @@ "name": "jpa/gross-sales-over-time", "title": "Gross sales over time", "description": "Gross sales over the selected time period.", - "category": "store" + "category": "store", + "presentation": "framed" } diff --git a/projects/packages/premium-analytics/widgets/hello-world/package.json b/projects/packages/premium-analytics/widgets/hello-world/package.json index 318b28a8cde0..27368548b6b4 100644 --- a/projects/packages/premium-analytics/widgets/hello-world/package.json +++ b/projects/packages/premium-analytics/widgets/hello-world/package.json @@ -7,10 +7,10 @@ "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", "@wordpress/ui": "0.17.0", - "@wordpress/widget-primitives": "next" + "@wordpress/widget-primitives": "0.2.0" }, "devDependencies": { "@wordpress/element": "8.2.0", - "@wordpress/widget-dashboard": "next" + "@wordpress/widget-dashboard": "0.2.0" } } diff --git a/projects/packages/premium-analytics/widgets/hello-world/render.tsx b/projects/packages/premium-analytics/widgets/hello-world/render.tsx index 5af6b333de46..129df40ec836 100644 --- a/projects/packages/premium-analytics/widgets/hello-world/render.tsx +++ b/projects/packages/premium-analytics/widgets/hello-world/render.tsx @@ -10,15 +10,15 @@ import styles from './style.module.css'; import type { HelloWorldAttributes } from './widget'; import type { WidgetRenderProps } from '@wordpress/widget-primitives'; -type HelloWorldRenderProps = WidgetRenderProps< HelloWorldAttributes >; +type HelloWorldWidgetProps = WidgetRenderProps< HelloWorldAttributes >; /** * Renders the Hello World widget. * - * @param {HelloWorldRenderProps} props - Component props + * @param {HelloWorldWidgetProps} props - The widget render props. * @return The rendered widget. */ -export default function HelloWorld( { attributes = {} }: HelloWorldRenderProps ) { +export default function HelloWorld( { attributes = {} }: HelloWorldWidgetProps ) { return ( }> diff --git a/projects/packages/premium-analytics/widgets/hello-world/stories/dashboard-sections-grid.stories.tsx b/projects/packages/premium-analytics/widgets/hello-world/stories/dashboard-sections-grid.stories.tsx index 38953e52d645..3529c80c1a2e 100644 --- a/projects/packages/premium-analytics/widgets/hello-world/stories/dashboard-sections-grid.stories.tsx +++ b/projects/packages/premium-analytics/widgets/hello-world/stories/dashboard-sections-grid.stories.tsx @@ -15,6 +15,8 @@ type StoryWidgetAttributes = { title: string; }; +type StoryWidgetProps = WidgetRenderProps< StoryWidgetAttributes >; + const widgetTypes: WidgetType< StoryWidgetAttributes >[] = [ { apiVersion: 1, @@ -60,11 +62,10 @@ const initialLayout: DashboardWidget[] = [ /** * Story-only widget renderer. * - * @param props - Widget render props. - * @param props.attributes - Story widget attributes. + * @param {StoryWidgetProps} props - Widget render props. * @return Rendered story widget. */ -function StoryWidget( { attributes }: WidgetRenderProps< StoryWidgetAttributes > ) { +function StoryWidget( { attributes }: StoryWidgetProps ) { return (
[], example: { attributes: { message: __( 'Hello World', 'jetpack-premium-analytics' ), diff --git a/projects/packages/premium-analytics/widgets/latest-post/package.json b/projects/packages/premium-analytics/widgets/latest-post/package.json index 3b3c09e81bc3..ba629d0df495 100644 --- a/projects/packages/premium-analytics/widgets/latest-post/package.json +++ b/projects/packages/premium-analytics/widgets/latest-post/package.json @@ -9,7 +9,7 @@ "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", "@wordpress/ui": "0.17.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "date-fns": "4.1.0" } } diff --git a/projects/packages/premium-analytics/widgets/latest-post/render.tsx b/projects/packages/premium-analytics/widgets/latest-post/render.tsx index 914971f2f628..c17bae2208ae 100644 --- a/projects/packages/premium-analytics/widgets/latest-post/render.tsx +++ b/projects/packages/premium-analytics/widgets/latest-post/render.tsx @@ -22,6 +22,7 @@ import type { WidgetRenderProps } from '@wordpress/widget-primitives'; // Report params are dashboard-driven, but this widget reports lifetime totals // and ignores the date range; the host (and Storybook) may still inject them. type LatestPostRenderAttributes = LatestPostAttributes & Partial< ReportParamsFieldAttributes >; +type LatestPostWidgetProps = WidgetRenderProps< LatestPostRenderAttributes >; const METRIC_FORMAT: DataFormat = { type: 'number', @@ -196,12 +197,10 @@ function LatestPostReport() { * relies on. This widget has no own attributes and ignores the dashboard date * range, but host attributes are still passed through for the widget contract. * - * @param {WidgetRenderProps< LatestPostRenderAttributes >} props - The render props supplied by the widget host. + * @param {LatestPostWidgetProps} props - The widget render props. * @return The rendered widget. */ -export default function LatestPost( { - attributes = {}, -}: WidgetRenderProps< LatestPostRenderAttributes > ) { +export default function LatestPost( { attributes = {} }: LatestPostWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/latest-post/widget.ts b/projects/packages/premium-analytics/widgets/latest-post/widget.ts index 374980be7cca..98a7036bb187 100644 --- a/projects/packages/premium-analytics/widgets/latest-post/widget.ts +++ b/projects/packages/premium-analytics/widgets/latest-post/widget.ts @@ -3,6 +3,7 @@ */ import { __ } from '@wordpress/i18n'; import { postList } from '@wordpress/icons'; +import type { WidgetAttributeField } from '@wordpress/widget-primitives'; /** * The Latest post widget has no configurable attributes: it always shows the @@ -24,7 +25,7 @@ export default { name: 'jpa/latest-post', title: __( 'Latest post', 'jetpack-premium-analytics' ), icon: postList, - attributes: [], + attributes: [] as WidgetAttributeField< LatestPostAttributes >[], example: { attributes: {}, }, diff --git a/projects/packages/premium-analytics/widgets/locations/package.json b/projects/packages/premium-analytics/widgets/locations/package.json index 8f7fcad6df73..a4b9b38f2978 100644 --- a/projects/packages/premium-analytics/widgets/locations/package.json +++ b/projects/packages/premium-analytics/widgets/locations/package.json @@ -6,12 +6,11 @@ "dependencies": { "@jetpack-premium-analytics/data": "link:../../packages/data", "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", - "@wordpress/components": "36.1.0", "@wordpress/element": "8.2.0", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", "@wordpress/ui": "0.17.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "clsx": "^2.1.1" } } diff --git a/projects/packages/premium-analytics/widgets/locations/render.tsx b/projects/packages/premium-analytics/widgets/locations/render.tsx index 5bd680b18d84..8600ae8895eb 100644 --- a/projects/packages/premium-analytics/widgets/locations/render.tsx +++ b/projects/packages/premium-analytics/widgets/locations/render.tsx @@ -18,8 +18,7 @@ import { type LeaderboardChartData, type ReportParamsFieldAttributes, } from '@jetpack-premium-analytics/widgets-toolkit'; -import { SelectControl } from '@wordpress/components'; -import { useCallback, useMemo, useState } from '@wordpress/element'; +import { useEffect, useMemo } from '@wordpress/element'; import { __, sprintf } from '@wordpress/i18n'; import { Stack, Text } from '@wordpress/ui'; import clsx from 'clsx'; @@ -40,30 +39,28 @@ type LocationsWidgetProps = WidgetRenderProps< LocationsRenderAttributes >; /** * Locations widget inner component. Reads report params from WidgetRoot context. * - * @param root0 - Component props. - * @param root0.max - Maximum rows to display. + * @param {LocationsAttributes} attributes - The widget attributes. * @return The rendered widget content. */ -function LocationsInner( { max }: { max: number } ) { +function LocationsInner( { max, geoGranularity }: LocationsAttributes ) { const { reportParams } = useWidgetRootContext(); - const [ topMode, setTopMode ] = useState< 'country' | 'city' >( 'country' ); const { drillDownItem: selectedCountry, drillDown: selectCountry, resetDrillDown: clearSelectedCountry, } = useWidgetDrillDown< { code: string; name: string } >(); - const handleModeChange = useCallback( - ( value: string ) => { - setTopMode( value as 'country' | 'city' ); - clearSelectedCountry(); - }, - [ clearSelectedCountry ] - ); + // The "View by" control lives in the widget host header (the + // `relevance: 'high'` attribute); changing it resets any drill-down. + useEffect( () => { + clearSelectedCountry(); + }, [ geoGranularity, clearSelectedCountry ] ); - // Drill-down (region) takes priority over topMode; city mode disables drill-down. - const geoMode: GeoMode = selectedCountry ? 'region' : topMode; + // City mode disables drill-down; in country mode a selected country switches + // the report to its regions. City wins while the reset effect above settles. + const drillMode: GeoMode = selectedCountry ? 'region' : 'country'; + const geoMode: GeoMode = geoGranularity === 'city' ? 'city' : drillMode; const { data, comparisonData, hasComparison, isLoading, isFetching, hasData, isError } = useLocationViews( { @@ -76,7 +73,7 @@ function LocationsInner( { max }: { max: number } ) { const geoData = useMemo( (): GeoData => { const header: GoogleDataTableColumn[] = [ - geoMode === 'region' || geoMode === 'city' + geoMode === 'city' ? __( 'Location', 'jetpack-premium-analytics' ) : __( 'Country', 'jetpack-premium-analytics' ), __( 'Views', 'jetpack-premium-analytics' ), @@ -149,51 +146,27 @@ function LocationsInner( { max }: { max: number } ) { /> ) : null; - const bodyHeader = ( - - { backLink } - - - ); - if ( isLoading && data.length === 0 ) { - return ( -
- { bodyHeader } - -
- ); + return ; } if ( isError ) { return ( -
- { bodyHeader } + <> + { backLink } { __( 'Could not load location data.', 'jetpack-premium-analytics' ) } -
+ ); } // Explicit empty branch (rather than emptyStateText on LeaderboardChart) keeps the - // header and "View by" selector visible so users can switch mode or drill back up. + // back link visible so users can drill back up from an empty region view. if ( ! data.length ) { return ( -
- { bodyHeader } + <> + { backLink } { __( @@ -202,14 +175,14 @@ function LocationsInner( { max }: { max: number } ) { ) } -
+ ); } return ( -
- { bodyHeader } + <> { showLoading && } + { backLink }
+ { geoMode !== 'city' && (
) }
-
+ ); } @@ -242,17 +216,17 @@ function LocationsInner( { max }: { max: number } ) { * leaderboard. Click a country to drill into its regions. Ported from the * Jetpack Stats Locations module. * - * @param root0 - Render props. - * @param root0.attributes - Widget attributes (max). + * @param {LocationsWidgetProps} props - The widget render props. * @return The rendered Locations widget. */ export default function Locations( { attributes = {} }: LocationsWidgetProps ) { const max = attributes?.max ?? 10; + const geoGranularity = attributes?.geoGranularity ?? 'country'; return (
- +
); diff --git a/projects/packages/premium-analytics/widgets/locations/style.module.css b/projects/packages/premium-analytics/widgets/locations/style.module.css index b9df56eb2653..64f0d80aa3ee 100644 --- a/projects/packages/premium-analytics/widgets/locations/style.module.css +++ b/projects/packages/premium-analytics/widgets/locations/style.module.css @@ -15,39 +15,12 @@ text-align: center; } -.modeSelect { - order: 2; - flex: 0 1 220px; - inline-size: min(100%, 220px); - max-inline-size: 100%; - min-inline-size: min(100%, 160px); -} - .backLink { - order: 1; - align-self: center; + align-self: flex-start; min-inline-size: 0; - margin-inline-end: auto; margin-block-end: 0; } -.content { - position: relative; - display: flex; - flex-direction: column; - flex: 1 1 0; - min-height: 0; -} - -.bodyHeader { - position: relative; - z-index: 2; - flex-wrap: wrap; - justify-content: flex-end; - gap: var(--wpds-dimension-gap-sm, 8px) var(--wpds-dimension-gap-lg, 16px); - margin-block-end: var(--wpds-dimension-gap-md, 12px); -} - .chartArea { display: grid; grid-template-columns: 280fr 400fr; @@ -101,20 +74,6 @@ * the map. */ @container (max-width: 431px) { - .bodyHeader { - align-items: stretch; - } - - .backLink { - order: 2; - } - - .modeSelect { - order: 1; - flex-basis: 100%; - inline-size: 100%; - } - .geoChart { display: none; } diff --git a/projects/packages/premium-analytics/widgets/locations/use-location-views.ts b/projects/packages/premium-analytics/widgets/locations/use-location-views.ts index 7aa247bfa9f1..9d231de76da4 100644 --- a/projects/packages/premium-analytics/widgets/locations/use-location-views.ts +++ b/projects/packages/premium-analytics/widgets/locations/use-location-views.ts @@ -23,9 +23,21 @@ export interface LocationView { } interface UseLocationViewsArgs { + /** + * PA ReportParams from WidgetRoot context. + */ reportParams: ReportParams; + /** + * Maximum rows to display. + */ max: number; + /** + * 'country' (default), 'region', or 'city'. + */ geoMode?: GeoMode; + /** + * ISO country code to filter regions by (region mode). + */ countryFilter?: string; } @@ -68,11 +80,7 @@ function toLocationView( item: StatsLocationsItem ): LocationView | null { * Delegates fetching, caching, and normalization to `useStatsLocations` from * `@jetpack-premium-analytics/data`. * - * @param args - Hook arguments. - * @param args.reportParams - PA ReportParams from WidgetRoot context. - * @param args.max - Maximum rows to display. - * @param args.geoMode - 'country' (default), 'region', or 'city'. - * @param args.countryFilter - ISO country code to filter regions by (region mode). + * @param {UseLocationViewsArgs} args - Hook arguments. * @return The current data/loading/error state. */ export default function useLocationViews( { diff --git a/projects/packages/premium-analytics/widgets/locations/widget.ts b/projects/packages/premium-analytics/widgets/locations/widget.ts index 0973de0af44c..a41bc21d4f66 100644 --- a/projects/packages/premium-analytics/widgets/locations/widget.ts +++ b/projects/packages/premium-analytics/widgets/locations/widget.ts @@ -3,9 +3,11 @@ */ import { __ } from '@wordpress/i18n'; import { mapMarker } from '@wordpress/icons'; +import type { WidgetAttributeField } from '@wordpress/widget-primitives'; export type LocationsAttributes = { max?: number; + geoGranularity?: 'country' | 'city'; }; /** @@ -33,10 +35,27 @@ export default { label: __( 'Number of results', 'jetpack-premium-analytics' ), type: 'integer', }, - ], + { + id: 'geoGranularity', + label: __( 'View by', 'jetpack-premium-analytics' ), + type: 'text', + elements: [ + { + label: __( 'Countries', 'jetpack-premium-analytics' ), + value: 'country', + }, + { + label: __( 'Cities', 'jetpack-premium-analytics' ), + value: 'city', + }, + ], + relevance: 'high', + }, + ] as WidgetAttributeField< LocationsAttributes >[], example: { attributes: { max: 10, + geoGranularity: 'country', }, }, }; diff --git a/projects/packages/premium-analytics/widgets/most-popular-day/package.json b/projects/packages/premium-analytics/widgets/most-popular-day/package.json index f9660a9d84b1..8da3af81be43 100644 --- a/projects/packages/premium-analytics/widgets/most-popular-day/package.json +++ b/projects/packages/premium-analytics/widgets/most-popular-day/package.json @@ -10,8 +10,7 @@ "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", "@wordpress/ui": "0.17.0", - "@wordpress/widget-primitives": "next", - "date-fns": "4.1.0", - "react": "18.3.1" + "@wordpress/widget-primitives": "0.2.0", + "date-fns": "4.1.0" } } diff --git a/projects/packages/premium-analytics/widgets/most-popular-day/render.tsx b/projects/packages/premium-analytics/widgets/most-popular-day/render.tsx index b4acd527ee13..fd40856b37cd 100644 --- a/projects/packages/premium-analytics/widgets/most-popular-day/render.tsx +++ b/projects/packages/premium-analytics/widgets/most-popular-day/render.tsx @@ -23,6 +23,7 @@ import type { WidgetRenderProps } from '@wordpress/widget-primitives'; // Storybook) may still inject them via `attributes`, so accept them here. type MostPopularDayRenderAttributes = MostPopularDayAttributes & Partial< ReportParamsFieldAttributes >; +type MostPopularDayWidgetProps = WidgetRenderProps< MostPopularDayRenderAttributes >; type MostPopularDayHighlightProps = { /** @@ -198,12 +199,10 @@ function MostPopularDayReport() { * attributes are passed through for the widget contract even though this * highlight ignores report params. * - * @param {WidgetRenderProps< MostPopularDayRenderAttributes >} props - The render props supplied by the widget host. + * @param {MostPopularDayWidgetProps} props - The widget render props. * @return The rendered widget. */ -export default function MostPopularDay( { - attributes = {}, -}: WidgetRenderProps< MostPopularDayRenderAttributes > ) { +export default function MostPopularDay( { attributes = {} }: MostPopularDayWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/most-popular-time/package.json b/projects/packages/premium-analytics/widgets/most-popular-time/package.json index 8ea36f9d7552..d411edb11551 100644 --- a/projects/packages/premium-analytics/widgets/most-popular-time/package.json +++ b/projects/packages/premium-analytics/widgets/most-popular-time/package.json @@ -9,9 +9,7 @@ "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", "@wordpress/ui": "0.17.0", - "@wordpress/widget-primitives": "next", - "date-fns": "4.1.0", - "react": "18.3.1" + "@wordpress/widget-primitives": "0.2.0" }, "devDependencies": { "@wordpress/api-fetch": "7.50.0" diff --git a/projects/packages/premium-analytics/widgets/most-popular-time/render.tsx b/projects/packages/premium-analytics/widgets/most-popular-time/render.tsx index d1719d4e3c22..fb89bead76ba 100644 --- a/projects/packages/premium-analytics/widgets/most-popular-time/render.tsx +++ b/projects/packages/premium-analytics/widgets/most-popular-time/render.tsx @@ -21,18 +21,31 @@ import type { WidgetRenderProps } from '@wordpress/widget-primitives'; // comparison period), but WidgetRoot still expects them on `attributes`. type MostPopularTimeRenderAttributes = MostPopularTimeAttributes & Partial< ReportParamsFieldAttributes >; +type MostPopularTimeWidgetProps = WidgetRenderProps< MostPopularTimeRenderAttributes >; + +type HighlightProps = { + /** + * The highlight label (e.g. "Best day"). + */ + label: string; + /** + * The peak value (e.g. "Tuesday" or "3:00 PM"). + */ + value: string; + /** + * The value's share of total views, as a whole percent. + */ + percent: number; +}; /** * A single "best day" / "best hour" highlight: a label, the peak value rendered * as a large display figure, and its share of total views. * - * @param props - The highlight props. - * @param props.label - The highlight label (e.g. "Best day"). - * @param props.value - The peak value (e.g. "Tuesday" or "3:00 PM"). - * @param props.percent - The value's share of total views, as a whole percent. + * @param {HighlightProps} props - The component props. * @return The highlight block. */ -function Highlight( { label, value, percent }: { label: string; value: string; percent: number } ) { +function Highlight( { label, value, percent }: HighlightProps ) { return ( } className={ styles.label }> @@ -109,12 +122,10 @@ function MostPopularTimeReport() { * report takes no parameters, so the inner component reads nothing from * `attributes`. * - * @param {WidgetRenderProps< MostPopularTimeRenderAttributes >} props - The render props supplied by the widget host. + * @param {MostPopularTimeWidgetProps} props - The widget render props. * @return The rendered widget. */ -export default function MostPopularTime( { - attributes = {}, -}: WidgetRenderProps< MostPopularTimeRenderAttributes > ) { +export default function MostPopularTime( { attributes = {} }: MostPopularTimeWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/net-sales-over-time/package.json b/projects/packages/premium-analytics/widgets/net-sales-over-time/package.json index 84e0982f28da..c4ca05c6c7d0 100644 --- a/projects/packages/premium-analytics/widgets/net-sales-over-time/package.json +++ b/projects/packages/premium-analytics/widgets/net-sales-over-time/package.json @@ -7,7 +7,7 @@ "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" } } diff --git a/projects/packages/premium-analytics/widgets/net-sales-over-time/render.tsx b/projects/packages/premium-analytics/widgets/net-sales-over-time/render.tsx index f98afad22c53..1044720b9501 100644 --- a/projects/packages/premium-analytics/widgets/net-sales-over-time/render.tsx +++ b/projects/packages/premium-analytics/widgets/net-sales-over-time/render.tsx @@ -18,7 +18,7 @@ import type { ComponentProps } from 'react'; type NetSalesOverTimeRenderAttributes = NetSalesOverTimeAttributes & Partial< ReportParamsFieldAttributes >; -type NetSalesOverTimeRenderProps = WidgetRenderProps< NetSalesOverTimeRenderAttributes > & { +type NetSalesOverTimeWidgetProps = WidgetRenderProps< NetSalesOverTimeRenderAttributes > & { setError?: ComponentProps< typeof WidgetRoot >[ 'setError' ]; }; @@ -28,11 +28,14 @@ type NetSalesOverTimeRenderProps = WidgetRenderProps< NetSalesOverTimeRenderAttr * Thin composition over the widgets-toolkit: WidgetRoot provides the query * client, chart theme, and resolved report params; OrderMetricWidget fetches * the orders report and renders the net sales metric over time. + * + * @param {NetSalesOverTimeWidgetProps} props - The widget render props. + * @return The rendered widget. */ export default function NetSalesOverTimeRender( { attributes = {}, setError, -}: NetSalesOverTimeRenderProps ) { +}: NetSalesOverTimeWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/net-sales-over-time/stories/net-sales-over-time-widget.stories.tsx b/projects/packages/premium-analytics/widgets/net-sales-over-time/stories/net-sales-over-time-widget.stories.tsx index a12033d4eb73..5cce2f25ea44 100644 --- a/projects/packages/premium-analytics/widgets/net-sales-over-time/stories/net-sales-over-time-widget.stories.tsx +++ b/projects/packages/premium-analytics/widgets/net-sales-over-time/stories/net-sales-over-time-widget.stories.tsx @@ -22,14 +22,14 @@ const PRESET_OPTIONS = SELECTABLE_PRESETS; // Static Storybook builds need this source import before ComparativeLineChart reads LineChart.Legend. const ensureLineChartComposition = () => LineChart.Legend; -type NetSalesOverTimeRenderProps = ComponentProps< typeof NetSalesOverTimeRender >; +type NetSalesOverTimeWidgetProps = ComponentProps< typeof NetSalesOverTimeRender >; interface NetSalesOverTimeStoryControls { withComparison: boolean; preset: SelectablePresetId; } -type NetSalesOverTimeStoryProps = NetSalesOverTimeRenderProps & NetSalesOverTimeStoryControls; +type NetSalesOverTimeStoryProps = NetSalesOverTimeWidgetProps & NetSalesOverTimeStoryControls; interface NetSalesOverTimeDashboardStoryProps extends WidgetDashboardWithWidgetControls, @@ -44,7 +44,7 @@ const withWidgetCanvas: Decorator = Story => ( function getNetSalesOverTimeAttributes( withComparison = false, preset: SelectablePresetId = DEFAULT_PRESET -): NetSalesOverTimeRenderProps[ 'attributes' ] { +): NetSalesOverTimeWidgetProps[ 'attributes' ] { return { reportParams: getDefaultQueryParams( withComparison, preset ), }; diff --git a/projects/packages/premium-analytics/widgets/net-sales-over-time/widget.json b/projects/packages/premium-analytics/widgets/net-sales-over-time/widget.json index 6a3afdeef15e..fbbd8b3e9d78 100644 --- a/projects/packages/premium-analytics/widgets/net-sales-over-time/widget.json +++ b/projects/packages/premium-analytics/widgets/net-sales-over-time/widget.json @@ -2,5 +2,6 @@ "name": "jpa/net-sales-over-time", "title": "Net sales over time", "description": "Monitor your total revenue after discounts, returns, or adjustments over a set period of time.", - "category": "orders" + "category": "orders", + "presentation": "framed" } diff --git a/projects/packages/premium-analytics/widgets/new-vs-returning-customer/package.json b/projects/packages/premium-analytics/widgets/new-vs-returning-customer/package.json index 1e8903d97813..2d5dc5cc92a6 100644 --- a/projects/packages/premium-analytics/widgets/new-vs-returning-customer/package.json +++ b/projects/packages/premium-analytics/widgets/new-vs-returning-customer/package.json @@ -7,7 +7,7 @@ "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" } } diff --git a/projects/packages/premium-analytics/widgets/new-vs-returning-customer/render.tsx b/projects/packages/premium-analytics/widgets/new-vs-returning-customer/render.tsx index 17f0b4d26abc..58daa1e332bb 100644 --- a/projects/packages/premium-analytics/widgets/new-vs-returning-customer/render.tsx +++ b/projects/packages/premium-analytics/widgets/new-vs-returning-customer/render.tsx @@ -18,7 +18,7 @@ import type { ComponentProps } from 'react'; type NewVsReturningCustomerRenderAttributes = NewVsReturningCustomerAttributes & Partial< ReportParamsFieldAttributes >; -type NewVsReturningCustomerRenderProps = +type NewVsReturningCustomerWidgetProps = WidgetRenderProps< NewVsReturningCustomerRenderAttributes > & { setError?: ComponentProps< typeof WidgetRoot >[ 'setError' ]; }; @@ -29,11 +29,14 @@ type NewVsReturningCustomerRenderProps = * Thin composition over WidgetRoot: WidgetRoot provides the query client, chart * theme, and resolved report params; NewVsReturningCustomerWidget renders the * customer breakdown donut chart. + * + * @param {NewVsReturningCustomerWidgetProps} props - The widget render props. + * @return The rendered widget. */ export default function NewVsReturningCustomerRender( { attributes = {}, setError, -}: NewVsReturningCustomerRenderProps ) { +}: NewVsReturningCustomerWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/new-vs-returning-customer/stories/new-vs-returning-customer-widget.stories.tsx b/projects/packages/premium-analytics/widgets/new-vs-returning-customer/stories/new-vs-returning-customer-widget.stories.tsx index 7f4a71095389..db30ee0850b4 100644 --- a/projects/packages/premium-analytics/widgets/new-vs-returning-customer/stories/new-vs-returning-customer-widget.stories.tsx +++ b/projects/packages/premium-analytics/widgets/new-vs-returning-customer/stories/new-vs-returning-customer-widget.stories.tsx @@ -19,14 +19,14 @@ const NEW_VS_RETURNING_CUSTOMER_RENDER_MODULE = 'storybook/new-vs-returning-cust const DEFAULT_PRESET = 'last-30-days' satisfies SelectablePresetId; const PRESET_OPTIONS = SELECTABLE_PRESETS; -type NewVsReturningCustomerRenderProps = ComponentProps< typeof NewVsReturningCustomerRender >; +type NewVsReturningCustomerWidgetProps = ComponentProps< typeof NewVsReturningCustomerRender >; interface NewVsReturningCustomerStoryControls { withComparison: boolean; preset: SelectablePresetId; } -type NewVsReturningCustomerStoryProps = NewVsReturningCustomerRenderProps & +type NewVsReturningCustomerStoryProps = NewVsReturningCustomerWidgetProps & NewVsReturningCustomerStoryControls; interface NewVsReturningCustomerDashboardStoryProps @@ -42,7 +42,7 @@ const withWidgetCanvas: Decorator = Story => ( function getNewVsReturningCustomerAttributes( withComparison = false, preset: SelectablePresetId = DEFAULT_PRESET -): NewVsReturningCustomerRenderProps[ 'attributes' ] { +): NewVsReturningCustomerWidgetProps[ 'attributes' ] { return { reportParams: getDefaultQueryParams( withComparison, preset ), }; diff --git a/projects/packages/premium-analytics/widgets/new-vs-returning-customer/widget.json b/projects/packages/premium-analytics/widgets/new-vs-returning-customer/widget.json index 3d18932090ef..ebdf13973a0f 100644 --- a/projects/packages/premium-analytics/widgets/new-vs-returning-customer/widget.json +++ b/projects/packages/premium-analytics/widgets/new-vs-returning-customer/widget.json @@ -2,5 +2,6 @@ "name": "jpa/new-vs-returning-customer", "title": "New vs returning customer", "description": "Unique customer counts broken down by new vs returning customers over the selected time period.", - "category": "store" + "category": "store", + "presentation": "framed" } diff --git a/projects/packages/premium-analytics/widgets/orders-fulfillment/package.json b/projects/packages/premium-analytics/widgets/orders-fulfillment/package.json index 3489ecca9c22..b8608c3bd144 100644 --- a/projects/packages/premium-analytics/widgets/orders-fulfillment/package.json +++ b/projects/packages/premium-analytics/widgets/orders-fulfillment/package.json @@ -7,7 +7,7 @@ "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" } } diff --git a/projects/packages/premium-analytics/widgets/orders-fulfillment/render.tsx b/projects/packages/premium-analytics/widgets/orders-fulfillment/render.tsx index 7fd71c4c152a..263938ab35c2 100644 --- a/projects/packages/premium-analytics/widgets/orders-fulfillment/render.tsx +++ b/projects/packages/premium-analytics/widgets/orders-fulfillment/render.tsx @@ -18,7 +18,7 @@ import type { ComponentProps } from 'react'; type OrdersFulfillmentRenderAttributes = OrdersFulfillmentAttributes & Partial< ReportParamsFieldAttributes >; -type OrdersFulfillmentRenderProps = WidgetRenderProps< OrdersFulfillmentRenderAttributes > & { +type OrdersFulfillmentWidgetProps = WidgetRenderProps< OrdersFulfillmentRenderAttributes > & { setError?: ComponentProps< typeof WidgetRoot >[ 'setError' ]; }; @@ -28,11 +28,14 @@ type OrdersFulfillmentRenderProps = WidgetRenderProps< OrdersFulfillmentRenderAt * Thin composition over WidgetRoot: WidgetRoot provides the query client, chart * theme, and resolved report params; OrdersFulfillmentWidget renders the * fulfilled vs unfulfilled orders donut chart. + * + * @param {OrdersFulfillmentWidgetProps} props - The widget render props. + * @return The rendered widget. */ export default function OrdersFulfillmentRender( { attributes = {}, setError, -}: OrdersFulfillmentRenderProps ) { +}: OrdersFulfillmentWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/orders-fulfillment/stories/orders-fulfillment-widget.stories.tsx b/projects/packages/premium-analytics/widgets/orders-fulfillment/stories/orders-fulfillment-widget.stories.tsx index 5681c580c48a..cfe1d7bef5e1 100644 --- a/projects/packages/premium-analytics/widgets/orders-fulfillment/stories/orders-fulfillment-widget.stories.tsx +++ b/projects/packages/premium-analytics/widgets/orders-fulfillment/stories/orders-fulfillment-widget.stories.tsx @@ -19,14 +19,14 @@ const ORDERS_FULFILLMENT_RENDER_MODULE = 'storybook/orders-fulfillment'; const DEFAULT_PRESET = 'last-30-days' satisfies SelectablePresetId; const PRESET_OPTIONS = SELECTABLE_PRESETS; -type OrdersFulfillmentRenderProps = ComponentProps< typeof OrdersFulfillmentRender >; +type OrdersFulfillmentWidgetProps = ComponentProps< typeof OrdersFulfillmentRender >; interface OrdersFulfillmentStoryControls { withComparison: boolean; preset: SelectablePresetId; } -type OrdersFulfillmentStoryProps = OrdersFulfillmentRenderProps & OrdersFulfillmentStoryControls; +type OrdersFulfillmentStoryProps = OrdersFulfillmentWidgetProps & OrdersFulfillmentStoryControls; interface OrdersFulfillmentDashboardStoryProps extends WidgetDashboardWithWidgetControls, @@ -41,7 +41,7 @@ const withWidgetCanvas: Decorator = Story => ( function getOrdersFulfillmentAttributes( withComparison = false, preset: SelectablePresetId = DEFAULT_PRESET -): OrdersFulfillmentRenderProps[ 'attributes' ] { +): OrdersFulfillmentWidgetProps[ 'attributes' ] { return { reportParams: getDefaultQueryParams( withComparison, preset ), }; diff --git a/projects/packages/premium-analytics/widgets/orders-fulfillment/widget.json b/projects/packages/premium-analytics/widgets/orders-fulfillment/widget.json index b8a992eda516..cdc91a6823bc 100644 --- a/projects/packages/premium-analytics/widgets/orders-fulfillment/widget.json +++ b/projects/packages/premium-analytics/widgets/orders-fulfillment/widget.json @@ -2,5 +2,6 @@ "name": "jpa/orders-fulfillment", "title": "Orders fulfillment", "description": "Shows the breakdown of fulfilled vs unfulfilled order counts over the selected time period.", - "category": "store" + "category": "store", + "presentation": "framed" } diff --git a/projects/packages/premium-analytics/widgets/orders-over-time/package.json b/projects/packages/premium-analytics/widgets/orders-over-time/package.json index 9dd74dd2f08a..06c013a91f5f 100644 --- a/projects/packages/premium-analytics/widgets/orders-over-time/package.json +++ b/projects/packages/premium-analytics/widgets/orders-over-time/package.json @@ -7,7 +7,7 @@ "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" } } diff --git a/projects/packages/premium-analytics/widgets/orders-over-time/render.tsx b/projects/packages/premium-analytics/widgets/orders-over-time/render.tsx index 0f601efe4a04..08169cacbcea 100644 --- a/projects/packages/premium-analytics/widgets/orders-over-time/render.tsx +++ b/projects/packages/premium-analytics/widgets/orders-over-time/render.tsx @@ -18,7 +18,7 @@ import type { ComponentProps } from 'react'; type OrdersOverTimeRenderAttributes = OrdersOverTimeAttributes & Partial< ReportParamsFieldAttributes >; -type OrdersOverTimeRenderProps = WidgetRenderProps< OrdersOverTimeRenderAttributes > & { +type OrdersOverTimeWidgetProps = WidgetRenderProps< OrdersOverTimeRenderAttributes > & { setError?: ComponentProps< typeof WidgetRoot >[ 'setError' ]; }; @@ -28,11 +28,14 @@ type OrdersOverTimeRenderProps = WidgetRenderProps< OrdersOverTimeRenderAttribut * Thin composition over the widgets-toolkit: WidgetRoot provides the query * client, chart theme, and resolved report params; OrderMetricWidget fetches * the orders report and renders the order count metric over time. + * + * @param {OrdersOverTimeWidgetProps} props - The widget render props. + * @return The rendered widget. */ export default function OrdersOverTimeRender( { attributes = {}, setError, -}: OrdersOverTimeRenderProps ) { +}: OrdersOverTimeWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/orders-over-time/stories/orders-over-time-widget.stories.tsx b/projects/packages/premium-analytics/widgets/orders-over-time/stories/orders-over-time-widget.stories.tsx index 75fb4e64bb73..e6c580c8df21 100644 --- a/projects/packages/premium-analytics/widgets/orders-over-time/stories/orders-over-time-widget.stories.tsx +++ b/projects/packages/premium-analytics/widgets/orders-over-time/stories/orders-over-time-widget.stories.tsx @@ -23,14 +23,14 @@ const PRESET_OPTIONS = SELECTABLE_PRESETS; // Static Storybook builds need this source import before ComparativeLineChart reads LineChart.Legend. const ensureLineChartComposition = () => LineChart.Legend; -type OrdersOverTimeRenderProps = ComponentProps< typeof OrdersOverTimeRender >; +type OrdersOverTimeWidgetProps = ComponentProps< typeof OrdersOverTimeRender >; interface OrdersOverTimeStoryControls { withComparison: boolean; preset: SelectablePresetId; } -type OrdersOverTimeStoryProps = OrdersOverTimeRenderProps & OrdersOverTimeStoryControls; +type OrdersOverTimeStoryProps = OrdersOverTimeWidgetProps & OrdersOverTimeStoryControls; interface OrdersOverTimeDashboardStoryProps extends WidgetDashboardWithWidgetControls, @@ -45,7 +45,7 @@ const withWidgetCanvas: Decorator = Story => ( function getOrdersOverTimeAttributes( withComparison = false, preset: SelectablePresetId = DEFAULT_PRESET -): OrdersOverTimeRenderProps[ 'attributes' ] { +): OrdersOverTimeWidgetProps[ 'attributes' ] { return { reportParams: getDefaultQueryParams( withComparison, preset ), }; diff --git a/projects/packages/premium-analytics/widgets/orders-over-time/widget.json b/projects/packages/premium-analytics/widgets/orders-over-time/widget.json index 5d926c7c45f7..a0b31b3a67f3 100644 --- a/projects/packages/premium-analytics/widgets/orders-over-time/widget.json +++ b/projects/packages/premium-analytics/widgets/orders-over-time/widget.json @@ -2,5 +2,6 @@ "name": "jpa/orders-over-time", "title": "Orders over time", "description": "See a breakdown of when orders are placed to identify peak selling periods.", - "category": "orders" + "category": "orders", + "presentation": "framed" } diff --git a/projects/packages/premium-analytics/widgets/payment-status/package.json b/projects/packages/premium-analytics/widgets/payment-status/package.json index 6609f7ab315b..bc6862c8b2e1 100644 --- a/projects/packages/premium-analytics/widgets/payment-status/package.json +++ b/projects/packages/premium-analytics/widgets/payment-status/package.json @@ -10,7 +10,7 @@ "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", "@wordpress/ui": "0.17.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" } } diff --git a/projects/packages/premium-analytics/widgets/payment-status/render.tsx b/projects/packages/premium-analytics/widgets/payment-status/render.tsx index 8d9d1c2988f7..de0ef1b39b38 100644 --- a/projects/packages/premium-analytics/widgets/payment-status/render.tsx +++ b/projects/packages/premium-analytics/widgets/payment-status/render.tsx @@ -18,7 +18,7 @@ import type { ComponentProps } from 'react'; type PaymentStatusRenderAttributes = PaymentStatusAttributes & Partial< ReportParamsFieldAttributes >; -type PaymentStatusRenderProps = WidgetRenderProps< PaymentStatusRenderAttributes > & { +type PaymentStatusWidgetProps = WidgetRenderProps< PaymentStatusRenderAttributes > & { setError?: ComponentProps< typeof WidgetRoot >[ 'setError' ]; }; @@ -28,11 +28,14 @@ type PaymentStatusRenderProps = WidgetRenderProps< PaymentStatusRenderAttributes * Thin composition over WidgetRoot: WidgetRoot provides the query client, * chart theme, and resolved report params; PaymentStatusWidget renders the * paid vs unpaid order revenue donut chart. + * + * @param {PaymentStatusWidgetProps} props - The widget render props. + * @return The rendered widget. */ export default function PaymentStatusRender( { attributes = {}, setError, -}: PaymentStatusRenderProps ) { +}: PaymentStatusWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/payment-status/stories/payment-status-widget.stories.tsx b/projects/packages/premium-analytics/widgets/payment-status/stories/payment-status-widget.stories.tsx index b1405db60ae6..20fcb2b79991 100644 --- a/projects/packages/premium-analytics/widgets/payment-status/stories/payment-status-widget.stories.tsx +++ b/projects/packages/premium-analytics/widgets/payment-status/stories/payment-status-widget.stories.tsx @@ -19,14 +19,14 @@ const PAYMENT_STATUS_RENDER_MODULE = 'storybook/payment-status'; const DEFAULT_PRESET = 'last-30-days' satisfies SelectablePresetId; const PRESET_OPTIONS = SELECTABLE_PRESETS; -type PaymentStatusRenderProps = ComponentProps< typeof PaymentStatusRender >; +type PaymentStatusWidgetProps = ComponentProps< typeof PaymentStatusRender >; interface PaymentStatusStoryControls { withComparison: boolean; preset: SelectablePresetId; } -type PaymentStatusStoryProps = PaymentStatusRenderProps & PaymentStatusStoryControls; +type PaymentStatusStoryProps = PaymentStatusWidgetProps & PaymentStatusStoryControls; interface PaymentStatusDashboardStoryProps extends WidgetDashboardWithWidgetControls, @@ -41,7 +41,7 @@ const withWidgetCanvas: Decorator = Story => ( function getPaymentStatusAttributes( withComparison = false, preset: SelectablePresetId = DEFAULT_PRESET -): PaymentStatusRenderProps[ 'attributes' ] { +): PaymentStatusWidgetProps[ 'attributes' ] { return { reportParams: getDefaultQueryParams( withComparison, preset ), }; diff --git a/projects/packages/premium-analytics/widgets/payment-status/widget.json b/projects/packages/premium-analytics/widgets/payment-status/widget.json index a323bd531d61..aea54d02b0cd 100644 --- a/projects/packages/premium-analytics/widgets/payment-status/widget.json +++ b/projects/packages/premium-analytics/widgets/payment-status/widget.json @@ -2,5 +2,6 @@ "name": "jpa/payment-status", "title": "Payment status", "description": "Shows the breakdown of paid vs unpaid order revenue over the selected time period.", - "category": "store" + "category": "store", + "presentation": "framed" } diff --git a/projects/packages/premium-analytics/widgets/posting-activity/package.json b/projects/packages/premium-analytics/widgets/posting-activity/package.json index 4e572cd6c414..eb3c9cbad055 100644 --- a/projects/packages/premium-analytics/widgets/posting-activity/package.json +++ b/projects/packages/premium-analytics/widgets/posting-activity/package.json @@ -9,8 +9,7 @@ "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", "@wordpress/ui": "0.17.0", - "@wordpress/widget-primitives": "next", - "date-fns": "4.1.0", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" }, "devDependencies": { diff --git a/projects/packages/premium-analytics/widgets/posting-activity/render.tsx b/projects/packages/premium-analytics/widgets/posting-activity/render.tsx index 22efccf966e6..dd5e3a8e8903 100644 --- a/projects/packages/premium-analytics/widgets/posting-activity/render.tsx +++ b/projects/packages/premium-analytics/widgets/posting-activity/render.tsx @@ -25,6 +25,7 @@ import type { WidgetRenderProps } from '@wordpress/widget-primitives'; // picker — but the host (and Storybook) may also inject them via `attributes`. type PostingActivityRenderAttributes = PostingActivityAttributes & Partial< ReportParamsFieldAttributes >; +type PostingActivityWidgetProps = WidgetRenderProps< PostingActivityRenderAttributes >; /** * Fetches the posting-activity streak through the designated `useStatsStreak` @@ -113,13 +114,10 @@ function PostingActivityInner() { * via context, the same way the other Stats widgets read them. This widget has * no own settings, so nothing is forwarded to the inner component. * - * @param props - Render props supplied by the widget host. - * @param props.attributes - Widget attributes. + * @param {PostingActivityWidgetProps} props - The widget render props. * @return The rendered widget. */ -export default function PostingActivity( { - attributes = {}, -}: WidgetRenderProps< PostingActivityRenderAttributes > ) { +export default function PostingActivity( { attributes = {} }: PostingActivityWidgetProps ) { return (
diff --git a/projects/packages/premium-analytics/widgets/react-query-dev-tool/package.json b/projects/packages/premium-analytics/widgets/react-query-dev-tool/package.json index 841884d8240d..fd1b9077c3b3 100644 --- a/projects/packages/premium-analytics/widgets/react-query-dev-tool/package.json +++ b/projects/packages/premium-analytics/widgets/react-query-dev-tool/package.json @@ -7,7 +7,6 @@ "@jetpack-premium-analytics/data": "link:../../packages/data", "@tanstack/react-query-devtools": "5.90.2", "@wordpress/i18n": "^6.9.0", - "@wordpress/icons": "^15.0.0", - "react": "18.3.1" + "@wordpress/icons": "^15.0.0" } } diff --git a/projects/packages/premium-analytics/widgets/react-query-dev-tool/widget.ts b/projects/packages/premium-analytics/widgets/react-query-dev-tool/widget.ts index bdc86cfe9220..16c8b2d4e719 100644 --- a/projects/packages/premium-analytics/widgets/react-query-dev-tool/widget.ts +++ b/projects/packages/premium-analytics/widgets/react-query-dev-tool/widget.ts @@ -4,6 +4,12 @@ import { __ } from '@wordpress/i18n'; import { bug } from '@wordpress/icons'; +/** + * The widget has no user-configurable attributes: the devtools panel takes no + * configuration and binds directly to the shared query client. + */ +export type ReactQueryDevToolAttributes = Record< never, never >; + /** * Widget type definition. * diff --git a/projects/packages/premium-analytics/widgets/revenue-by-customer-type/package.json b/projects/packages/premium-analytics/widgets/revenue-by-customer-type/package.json index 752cb5059a5e..a7b482bcd50a 100644 --- a/projects/packages/premium-analytics/widgets/revenue-by-customer-type/package.json +++ b/projects/packages/premium-analytics/widgets/revenue-by-customer-type/package.json @@ -7,7 +7,7 @@ "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" } } diff --git a/projects/packages/premium-analytics/widgets/revenue-by-customer-type/render.tsx b/projects/packages/premium-analytics/widgets/revenue-by-customer-type/render.tsx index b8614b1be16a..79d21cd6889f 100644 --- a/projects/packages/premium-analytics/widgets/revenue-by-customer-type/render.tsx +++ b/projects/packages/premium-analytics/widgets/revenue-by-customer-type/render.tsx @@ -18,7 +18,7 @@ import type { ComponentProps } from 'react'; type RevenueByCustomerTypeRenderAttributes = RevenueByCustomerTypeAttributes & Partial< ReportParamsFieldAttributes >; -type RevenueByCustomerTypeRenderProps = +type RevenueByCustomerTypeWidgetProps = WidgetRenderProps< RevenueByCustomerTypeRenderAttributes > & { setError?: ComponentProps< typeof WidgetRoot >[ 'setError' ]; }; @@ -29,11 +29,14 @@ type RevenueByCustomerTypeRenderProps = * Thin composition over WidgetRoot: WidgetRoot provides the query client, * chart theme, and resolved report params; RevenueByCustomerTypeWidget fetches * the customers report and renders the new vs returning revenue breakdown. + * + * @param {RevenueByCustomerTypeWidgetProps} props - The widget render props. + * @return The rendered widget. */ export default function RevenueByCustomerTypeRender( { attributes = {}, setError, -}: RevenueByCustomerTypeRenderProps ) { +}: RevenueByCustomerTypeWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/revenue-by-customer-type/widget.json b/projects/packages/premium-analytics/widgets/revenue-by-customer-type/widget.json index 45c771cf5a87..e5fc849d2502 100644 --- a/projects/packages/premium-analytics/widgets/revenue-by-customer-type/widget.json +++ b/projects/packages/premium-analytics/widgets/revenue-by-customer-type/widget.json @@ -2,5 +2,6 @@ "name": "jpa/revenue-by-customer-type", "title": "Revenue by customer type", "description": "Shows the breakdown of order revenue from new and returning customers over the selected time period.", - "category": "store" + "category": "store", + "presentation": "framed" } diff --git a/projects/packages/premium-analytics/widgets/sales-by-coupon-usage/package.json b/projects/packages/premium-analytics/widgets/sales-by-coupon-usage/package.json index c4bb2e9bb926..fa43ee9a464c 100644 --- a/projects/packages/premium-analytics/widgets/sales-by-coupon-usage/package.json +++ b/projects/packages/premium-analytics/widgets/sales-by-coupon-usage/package.json @@ -7,7 +7,7 @@ "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" } } diff --git a/projects/packages/premium-analytics/widgets/sales-by-coupon-usage/render.tsx b/projects/packages/premium-analytics/widgets/sales-by-coupon-usage/render.tsx index c9b53b2e0212..0568e3b83fb8 100644 --- a/projects/packages/premium-analytics/widgets/sales-by-coupon-usage/render.tsx +++ b/projects/packages/premium-analytics/widgets/sales-by-coupon-usage/render.tsx @@ -18,7 +18,7 @@ import type { ComponentProps } from 'react'; type SalesByCouponUsageRenderAttributes = SalesByCouponUsageAttributes & Partial< ReportParamsFieldAttributes >; -type SalesByCouponUsageRenderProps = WidgetRenderProps< SalesByCouponUsageRenderAttributes > & { +type SalesByCouponUsageWidgetProps = WidgetRenderProps< SalesByCouponUsageRenderAttributes > & { setError?: ComponentProps< typeof WidgetRoot >[ 'setError' ]; }; @@ -28,11 +28,14 @@ type SalesByCouponUsageRenderProps = WidgetRenderProps< SalesByCouponUsageRender * Thin composition over the widgets-toolkit: WidgetRoot provides the query * client, chart theme, and resolved report params; SalesByCouponWidget fetches * the coupons report and renders the coupon sales breakdown. + * + * @param {SalesByCouponUsageWidgetProps} props - The widget render props. + * @return The rendered widget. */ export default function SalesByCouponUsageRender( { attributes = {}, setError, -}: SalesByCouponUsageRenderProps ) { +}: SalesByCouponUsageWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/sales-by-coupon-usage/stories/sales-by-coupon-usage-widget.stories.tsx b/projects/packages/premium-analytics/widgets/sales-by-coupon-usage/stories/sales-by-coupon-usage-widget.stories.tsx index 0634c71e6154..fcb4e0018176 100644 --- a/projects/packages/premium-analytics/widgets/sales-by-coupon-usage/stories/sales-by-coupon-usage-widget.stories.tsx +++ b/projects/packages/premium-analytics/widgets/sales-by-coupon-usage/stories/sales-by-coupon-usage-widget.stories.tsx @@ -19,14 +19,14 @@ const SALES_BY_COUPON_USAGE_RENDER_MODULE = 'storybook/sales-by-coupon-usage'; const DEFAULT_PRESET = 'last-30-days' satisfies SelectablePresetId; const PRESET_OPTIONS = SELECTABLE_PRESETS; -type SalesByCouponUsageRenderProps = ComponentProps< typeof SalesByCouponUsageRender >; +type SalesByCouponUsageWidgetProps = ComponentProps< typeof SalesByCouponUsageRender >; interface SalesByCouponUsageStoryControls { withComparison: boolean; preset: SelectablePresetId; } -type SalesByCouponUsageStoryProps = SalesByCouponUsageRenderProps & SalesByCouponUsageStoryControls; +type SalesByCouponUsageStoryProps = SalesByCouponUsageWidgetProps & SalesByCouponUsageStoryControls; interface SalesByCouponUsageDashboardStoryProps extends WidgetDashboardWithWidgetControls, @@ -41,7 +41,7 @@ const withWidgetCanvas: Decorator = Story => ( function getSalesByCouponUsageAttributes( withComparison = false, preset: SelectablePresetId = DEFAULT_PRESET -): SalesByCouponUsageRenderProps[ 'attributes' ] { +): SalesByCouponUsageWidgetProps[ 'attributes' ] { return { reportParams: getDefaultQueryParams( withComparison, preset ), }; diff --git a/projects/packages/premium-analytics/widgets/sales-by-coupon-usage/widget.json b/projects/packages/premium-analytics/widgets/sales-by-coupon-usage/widget.json index 9cc727bd3dbc..bf3321bdfe96 100644 --- a/projects/packages/premium-analytics/widgets/sales-by-coupon-usage/widget.json +++ b/projects/packages/premium-analytics/widgets/sales-by-coupon-usage/widget.json @@ -2,5 +2,6 @@ "name": "jpa/sales-by-coupon-usage", "title": "Sales by coupon usage", "description": "Sales by coupon usage over the selected time period.", - "category": "coupons" + "category": "coupons", + "presentation": "framed" } diff --git a/projects/packages/premium-analytics/widgets/sales-by-coupon/package.json b/projects/packages/premium-analytics/widgets/sales-by-coupon/package.json index ff7de3ff2217..932554096c99 100644 --- a/projects/packages/premium-analytics/widgets/sales-by-coupon/package.json +++ b/projects/packages/premium-analytics/widgets/sales-by-coupon/package.json @@ -7,7 +7,7 @@ "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" } } diff --git a/projects/packages/premium-analytics/widgets/sales-by-coupon/render.tsx b/projects/packages/premium-analytics/widgets/sales-by-coupon/render.tsx index 98adc4b36aae..f905270e74ea 100644 --- a/projects/packages/premium-analytics/widgets/sales-by-coupon/render.tsx +++ b/projects/packages/premium-analytics/widgets/sales-by-coupon/render.tsx @@ -18,7 +18,7 @@ import type { ComponentProps } from 'react'; type SalesByCouponRenderAttributes = SalesByCouponAttributes & Partial< ReportParamsFieldAttributes >; -type SalesByCouponRenderProps = WidgetRenderProps< SalesByCouponRenderAttributes > & { +type SalesByCouponWidgetProps = WidgetRenderProps< SalesByCouponRenderAttributes > & { setError?: ComponentProps< typeof WidgetRoot >[ 'setError' ]; }; @@ -28,11 +28,14 @@ type SalesByCouponRenderProps = WidgetRenderProps< SalesByCouponRenderAttributes * Thin composition over the widgets-toolkit: WidgetRoot provides the query * client, chart theme, and resolved report params; SalesByCouponWidget fetches * the coupons report and renders the coupon revenue breakdown. + * + * @param {SalesByCouponWidgetProps} props - The widget render props. + * @return The rendered widget. */ export default function SalesByCouponRender( { attributes = {}, setError, -}: SalesByCouponRenderProps ) { +}: SalesByCouponWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/sales-by-coupon/stories/sales-by-coupon-widget.stories.tsx b/projects/packages/premium-analytics/widgets/sales-by-coupon/stories/sales-by-coupon-widget.stories.tsx index a29fa01bc119..55319fcc126e 100644 --- a/projects/packages/premium-analytics/widgets/sales-by-coupon/stories/sales-by-coupon-widget.stories.tsx +++ b/projects/packages/premium-analytics/widgets/sales-by-coupon/stories/sales-by-coupon-widget.stories.tsx @@ -19,15 +19,21 @@ const SALES_BY_COUPON_RENDER_MODULE = 'storybook/sales-by-coupon'; const DEFAULT_PRESET = 'last-30-days' satisfies SelectablePresetId; const PRESET_OPTIONS = SELECTABLE_PRESETS; -type SalesByCouponRenderProps = ComponentProps< typeof SalesByCouponRender >; -const setStoryError: SalesByCouponRenderProps[ 'setError' ] = () => undefined; +type SalesByCouponWidgetProps = ComponentProps< typeof SalesByCouponRender >; +const setStoryError: SalesByCouponWidgetProps[ 'setError' ] = () => undefined; interface SalesByCouponStoryControls { + /** + * Whether comparison report params are enabled. + */ withComparison: boolean; + /** + * Date-range preset used for report params. + */ preset: SelectablePresetId; } -type SalesByCouponStoryProps = SalesByCouponRenderProps & SalesByCouponStoryControls; +type SalesByCouponStoryProps = SalesByCouponWidgetProps & SalesByCouponStoryControls; interface SalesByCouponDashboardStoryProps extends WidgetDashboardWithWidgetControls, @@ -42,7 +48,7 @@ const withWidgetCanvas: Decorator = Story => ( function getSalesByCouponAttributes( withComparison = false, preset: SelectablePresetId = DEFAULT_PRESET -): SalesByCouponRenderProps[ 'attributes' ] { +): SalesByCouponWidgetProps[ 'attributes' ] { return { reportParams: getDefaultQueryParams( withComparison, preset ), }; @@ -60,9 +66,7 @@ function renderSalesByCoupon( { withComparison, preset }: SalesByCouponStoryCont /** * Storybook dashboard wrapper for the Sales by coupon widget. * - * @param props - Story controls. - * @param props.withComparison - Whether comparison report params are enabled. - * @param props.preset - Date-range preset used for report params. + * @param {SalesByCouponDashboardStoryProps} props - Story controls. * @return The dashboard story surface with the widget rendered inside it. */ function SalesByCouponDashboardStory( { diff --git a/projects/packages/premium-analytics/widgets/sales-by-coupon/widget.json b/projects/packages/premium-analytics/widgets/sales-by-coupon/widget.json index 35987bb0ba1d..780fce68b55e 100644 --- a/projects/packages/premium-analytics/widgets/sales-by-coupon/widget.json +++ b/projects/packages/premium-analytics/widgets/sales-by-coupon/widget.json @@ -2,5 +2,6 @@ "name": "jpa/sales-by-coupon", "title": "Sales by coupon", "description": "Shows the top coupon codes by order revenue over the selected time period.", - "category": "store" + "category": "store", + "presentation": "framed" } diff --git a/projects/packages/premium-analytics/widgets/sales-by-device/package.json b/projects/packages/premium-analytics/widgets/sales-by-device/package.json index c662e2046f8f..f44a3d7d8c21 100644 --- a/projects/packages/premium-analytics/widgets/sales-by-device/package.json +++ b/projects/packages/premium-analytics/widgets/sales-by-device/package.json @@ -7,7 +7,7 @@ "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" } } diff --git a/projects/packages/premium-analytics/widgets/sales-by-device/render.tsx b/projects/packages/premium-analytics/widgets/sales-by-device/render.tsx index 1c055a5103ff..5e601c74ad4c 100644 --- a/projects/packages/premium-analytics/widgets/sales-by-device/render.tsx +++ b/projects/packages/premium-analytics/widgets/sales-by-device/render.tsx @@ -18,7 +18,7 @@ import type { ComponentProps } from 'react'; type SalesByDeviceRenderAttributes = SalesByDeviceAttributes & Partial< ReportParamsFieldAttributes >; -type SalesByDeviceRenderProps = WidgetRenderProps< SalesByDeviceRenderAttributes > & { +type SalesByDeviceWidgetProps = WidgetRenderProps< SalesByDeviceRenderAttributes > & { setError?: ComponentProps< typeof WidgetRoot >[ 'setError' ]; }; @@ -28,11 +28,14 @@ type SalesByDeviceRenderProps = WidgetRenderProps< SalesByDeviceRenderAttributes * Thin composition over the widgets-toolkit: WidgetRoot provides the query * client, chart theme, and resolved report params; SalesByDeviceWidget fetches * the order-attribution report and renders the device revenue breakdown. + * + * @param {SalesByDeviceWidgetProps} props - The widget render props. + * @return The rendered widget. */ export default function SalesByDeviceRender( { attributes = {}, setError, -}: SalesByDeviceRenderProps ) { +}: SalesByDeviceWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/sales-by-device/stories/sales-by-device-widget.stories.tsx b/projects/packages/premium-analytics/widgets/sales-by-device/stories/sales-by-device-widget.stories.tsx index 20ced2ff0c13..2d717d1abeb0 100644 --- a/projects/packages/premium-analytics/widgets/sales-by-device/stories/sales-by-device-widget.stories.tsx +++ b/projects/packages/premium-analytics/widgets/sales-by-device/stories/sales-by-device-widget.stories.tsx @@ -19,14 +19,20 @@ const SALES_BY_DEVICE_RENDER_MODULE = 'storybook/sales-by-device'; const DEFAULT_PRESET = 'last-30-days' satisfies SelectablePresetId; const PRESET_OPTIONS = SELECTABLE_PRESETS; -type SalesByDeviceRenderProps = ComponentProps< typeof SalesByDeviceRender >; +type SalesByDeviceWidgetProps = ComponentProps< typeof SalesByDeviceRender >; interface SalesByDeviceStoryControls { + /** + * Whether to include comparison report params. + */ withComparison: boolean; + /** + * Date-range preset used for report params. + */ preset: SelectablePresetId; } -type SalesByDeviceStoryProps = SalesByDeviceRenderProps & SalesByDeviceStoryControls; +type SalesByDeviceStoryProps = SalesByDeviceWidgetProps & SalesByDeviceStoryControls; interface SalesByDeviceDashboardStoryProps extends WidgetDashboardWithWidgetControls, @@ -41,7 +47,7 @@ const withWidgetCanvas: Decorator = Story => ( function getSalesByDeviceAttributes( withComparison = false, preset: SelectablePresetId = DEFAULT_PRESET -): SalesByDeviceRenderProps[ 'attributes' ] { +): SalesByDeviceWidgetProps[ 'attributes' ] { return { reportParams: getDefaultQueryParams( withComparison, preset ), }; @@ -84,9 +90,7 @@ function renderSalesByDevice( { withComparison, preset }: SalesByDeviceStoryCont /** * Story wrapper for rendering the sales by device widget in dashboard chrome. * - * @param root0 - Story controls. - * @param root0.withComparison - Whether to include comparison report params. - * @param root0.preset - Date-range preset used for report params. + * @param {SalesByDeviceDashboardStoryProps} props - Story controls. * @return The rendered Storybook story. */ function SalesByDeviceDashboardStory( { diff --git a/projects/packages/premium-analytics/widgets/sales-by-device/widget.json b/projects/packages/premium-analytics/widgets/sales-by-device/widget.json index 431bb812de89..1b5a19558f08 100644 --- a/projects/packages/premium-analytics/widgets/sales-by-device/widget.json +++ b/projects/packages/premium-analytics/widgets/sales-by-device/widget.json @@ -2,5 +2,6 @@ "name": "jpa/sales-by-device", "title": "Sales by device", "description": "Shows the sales breakdown by device type over the selected time period.", - "category": "store" + "category": "store", + "presentation": "framed" } diff --git a/projects/packages/premium-analytics/widgets/sales-by-utm-campaign/package.json b/projects/packages/premium-analytics/widgets/sales-by-utm-campaign/package.json index 8e049340d76f..9fc84f8e12bf 100644 --- a/projects/packages/premium-analytics/widgets/sales-by-utm-campaign/package.json +++ b/projects/packages/premium-analytics/widgets/sales-by-utm-campaign/package.json @@ -9,7 +9,7 @@ "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" } } diff --git a/projects/packages/premium-analytics/widgets/sales-by-utm-campaign/render.tsx b/projects/packages/premium-analytics/widgets/sales-by-utm-campaign/render.tsx index cdd8df049e65..634ed291b4ef 100644 --- a/projects/packages/premium-analytics/widgets/sales-by-utm-campaign/render.tsx +++ b/projects/packages/premium-analytics/widgets/sales-by-utm-campaign/render.tsx @@ -18,7 +18,7 @@ import type { WidgetRenderProps } from '@wordpress/widget-primitives'; type SalesByUtmCampaignRenderAttributes = SalesByUtmCampaignAttributes & Partial< ReportParamsFieldAttributes >; -type SalesByUtmCampaignRenderProps = WidgetRenderProps< SalesByUtmCampaignRenderAttributes > & { +type SalesByUtmCampaignWidgetProps = WidgetRenderProps< SalesByUtmCampaignRenderAttributes > & { setError?: ComponentProps< typeof WidgetRoot >[ 'setError' ]; }; @@ -27,11 +27,14 @@ type SalesByUtmCampaignRenderProps = WidgetRenderProps< SalesByUtmCampaignRender * * WidgetRoot provides the query client, chart theme, and resolved report params; * the shared SalesByUtmWidget renders the campaign leaderboard. + * + * @param {SalesByUtmCampaignWidgetProps} props - The widget render props. + * @return The rendered widget. */ export default function SalesByUtmCampaignRender( { attributes = {}, setError, -}: SalesByUtmCampaignRenderProps ) { +}: SalesByUtmCampaignWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/sales-by-utm-campaign/stories/sales-by-utm-campaign-widget.stories.tsx b/projects/packages/premium-analytics/widgets/sales-by-utm-campaign/stories/sales-by-utm-campaign-widget.stories.tsx index 3555cb8b94e0..8ba1a4b34abb 100644 --- a/projects/packages/premium-analytics/widgets/sales-by-utm-campaign/stories/sales-by-utm-campaign-widget.stories.tsx +++ b/projects/packages/premium-analytics/widgets/sales-by-utm-campaign/stories/sales-by-utm-campaign-widget.stories.tsx @@ -19,14 +19,20 @@ const SALES_BY_UTM_CAMPAIGN_RENDER_MODULE = 'storybook/sales-by-utm-campaign'; const DEFAULT_PRESET = 'last-30-days' satisfies SelectablePresetId; const PRESET_OPTIONS = SELECTABLE_PRESETS; -type SalesByUtmCampaignRenderProps = ComponentProps< typeof SalesByUtmCampaignRender >; +type SalesByUtmCampaignWidgetProps = ComponentProps< typeof SalesByUtmCampaignRender >; interface SalesByUtmCampaignStoryControls { + /** + * Whether to include comparison report params. + */ withComparison: boolean; + /** + * Date-range preset used to generate report params. + */ preset: SelectablePresetId; } -type SalesByUtmCampaignStoryProps = SalesByUtmCampaignRenderProps & SalesByUtmCampaignStoryControls; +type SalesByUtmCampaignStoryProps = SalesByUtmCampaignWidgetProps & SalesByUtmCampaignStoryControls; interface SalesByUtmCampaignDashboardStoryProps extends WidgetDashboardWithWidgetControls, @@ -41,7 +47,7 @@ const withWidgetCanvas: Decorator = Story => ( function getSalesByUtmCampaignAttributes( withComparison = false, preset: SelectablePresetId = DEFAULT_PRESET -): SalesByUtmCampaignRenderProps[ 'attributes' ] { +): SalesByUtmCampaignWidgetProps[ 'attributes' ] { return { reportParams: getDefaultQueryParams( withComparison, preset ), }; @@ -86,9 +92,7 @@ function renderSalesByUtmCampaign( { withComparison, preset }: SalesByUtmCampaig /** * Story wrapper for rendering the sales by UTM campaign widget in dashboard chrome. * - * @param root0 - Story controls. - * @param root0.withComparison - Whether to include comparison report params. - * @param root0.preset - Date-range preset used to generate report params. + * @param {SalesByUtmCampaignDashboardStoryProps} props - Story controls. * @return The rendered Storybook story. */ function SalesByUtmCampaignDashboardStory( { diff --git a/projects/packages/premium-analytics/widgets/sales-by-utm-campaign/widget.json b/projects/packages/premium-analytics/widgets/sales-by-utm-campaign/widget.json index d0ff650231a2..b925f029494c 100644 --- a/projects/packages/premium-analytics/widgets/sales-by-utm-campaign/widget.json +++ b/projects/packages/premium-analytics/widgets/sales-by-utm-campaign/widget.json @@ -2,5 +2,6 @@ "name": "jpa/sales-by-utm-campaign", "title": "Sales by UTM campaign", "description": "Shows the top UTM campaigns by order revenue over the selected time period.", - "category": "store" + "category": "store", + "presentation": "framed" } diff --git a/projects/packages/premium-analytics/widgets/sales-by-utm-channel/package.json b/projects/packages/premium-analytics/widgets/sales-by-utm-channel/package.json index 9957e0016650..e8521d133a2a 100644 --- a/projects/packages/premium-analytics/widgets/sales-by-utm-channel/package.json +++ b/projects/packages/premium-analytics/widgets/sales-by-utm-channel/package.json @@ -9,7 +9,7 @@ "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" } } diff --git a/projects/packages/premium-analytics/widgets/sales-by-utm-channel/render.tsx b/projects/packages/premium-analytics/widgets/sales-by-utm-channel/render.tsx index 3c88c4a9bae8..aeff482db2c5 100644 --- a/projects/packages/premium-analytics/widgets/sales-by-utm-channel/render.tsx +++ b/projects/packages/premium-analytics/widgets/sales-by-utm-channel/render.tsx @@ -18,7 +18,7 @@ import type { WidgetRenderProps } from '@wordpress/widget-primitives'; type SalesByUtmChannelRenderAttributes = SalesByUtmChannelAttributes & Partial< ReportParamsFieldAttributes >; -type SalesByUtmChannelRenderProps = WidgetRenderProps< SalesByUtmChannelRenderAttributes > & { +type SalesByUtmChannelWidgetProps = WidgetRenderProps< SalesByUtmChannelRenderAttributes > & { setError?: ComponentProps< typeof WidgetRoot >[ 'setError' ]; }; @@ -27,11 +27,14 @@ type SalesByUtmChannelRenderProps = WidgetRenderProps< SalesByUtmChannelRenderAt * * WidgetRoot provides the query client, chart theme, and resolved report params; * the shared SalesByUtmWidget renders the channel leaderboard. + * + * @param {SalesByUtmChannelWidgetProps} props - The widget render props. + * @return The rendered widget. */ export default function SalesByUtmChannelRender( { attributes = {}, setError, -}: SalesByUtmChannelRenderProps ) { +}: SalesByUtmChannelWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/sales-by-utm-channel/stories/sales-by-utm-channel-widget.stories.tsx b/projects/packages/premium-analytics/widgets/sales-by-utm-channel/stories/sales-by-utm-channel-widget.stories.tsx index e40d5c9b2bf3..60acaabdf27c 100644 --- a/projects/packages/premium-analytics/widgets/sales-by-utm-channel/stories/sales-by-utm-channel-widget.stories.tsx +++ b/projects/packages/premium-analytics/widgets/sales-by-utm-channel/stories/sales-by-utm-channel-widget.stories.tsx @@ -19,14 +19,14 @@ const SALES_BY_UTM_CHANNEL_RENDER_MODULE = 'storybook/sales-by-utm-channel'; const DEFAULT_PRESET = 'last-30-days' satisfies SelectablePresetId; const PRESET_OPTIONS = SELECTABLE_PRESETS; -type SalesByUtmChannelRenderProps = ComponentProps< typeof SalesByUtmChannelRender >; +type SalesByUtmChannelWidgetProps = ComponentProps< typeof SalesByUtmChannelRender >; interface SalesByUtmChannelStoryControls { withComparison: boolean; preset: SelectablePresetId; } -type SalesByUtmChannelStoryProps = SalesByUtmChannelRenderProps & SalesByUtmChannelStoryControls; +type SalesByUtmChannelStoryProps = SalesByUtmChannelWidgetProps & SalesByUtmChannelStoryControls; interface SalesByUtmChannelDashboardStoryProps extends WidgetDashboardWithWidgetControls, @@ -41,7 +41,7 @@ const withWidgetCanvas: Decorator = Story => ( function getSalesByUtmChannelAttributes( withComparison = false, preset: SelectablePresetId = DEFAULT_PRESET -): SalesByUtmChannelRenderProps[ 'attributes' ] { +): SalesByUtmChannelWidgetProps[ 'attributes' ] { return { reportParams: getDefaultQueryParams( withComparison, preset ), }; diff --git a/projects/packages/premium-analytics/widgets/sales-by-utm-channel/widget.json b/projects/packages/premium-analytics/widgets/sales-by-utm-channel/widget.json index b9dca91e3719..12b33ed7d8ae 100644 --- a/projects/packages/premium-analytics/widgets/sales-by-utm-channel/widget.json +++ b/projects/packages/premium-analytics/widgets/sales-by-utm-channel/widget.json @@ -2,5 +2,6 @@ "name": "jpa/sales-by-utm-channel", "title": "Sales by UTM channel", "description": "Shows the top UTM channels by order revenue over the selected time period.", - "category": "store" + "category": "store", + "presentation": "framed" } diff --git a/projects/packages/premium-analytics/widgets/sales-by-utm-source/package.json b/projects/packages/premium-analytics/widgets/sales-by-utm-source/package.json index e47d7e64830e..253e37e08df9 100644 --- a/projects/packages/premium-analytics/widgets/sales-by-utm-source/package.json +++ b/projects/packages/premium-analytics/widgets/sales-by-utm-source/package.json @@ -9,7 +9,7 @@ "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" } } diff --git a/projects/packages/premium-analytics/widgets/sales-by-utm-source/render.tsx b/projects/packages/premium-analytics/widgets/sales-by-utm-source/render.tsx index 90b3a5c47109..3759f271c060 100644 --- a/projects/packages/premium-analytics/widgets/sales-by-utm-source/render.tsx +++ b/projects/packages/premium-analytics/widgets/sales-by-utm-source/render.tsx @@ -18,7 +18,7 @@ import type { WidgetRenderProps } from '@wordpress/widget-primitives'; type SalesByUtmSourceRenderAttributes = SalesByUtmSourceAttributes & Partial< ReportParamsFieldAttributes >; -type SalesByUtmSourceRenderProps = WidgetRenderProps< SalesByUtmSourceRenderAttributes > & { +type SalesByUtmSourceWidgetProps = WidgetRenderProps< SalesByUtmSourceRenderAttributes > & { setError?: ComponentProps< typeof WidgetRoot >[ 'setError' ]; }; @@ -27,11 +27,14 @@ type SalesByUtmSourceRenderProps = WidgetRenderProps< SalesByUtmSourceRenderAttr * * WidgetRoot provides the query client, chart theme, and resolved report params; * the shared SalesByUtmWidget renders the source leaderboard. + * + * @param {SalesByUtmSourceWidgetProps} props - The widget render props. + * @return The rendered widget. */ export default function SalesByUtmSourceRender( { attributes = {}, setError, -}: SalesByUtmSourceRenderProps ) { +}: SalesByUtmSourceWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/sales-by-utm-source/stories/sales-by-utm-source-widget.stories.tsx b/projects/packages/premium-analytics/widgets/sales-by-utm-source/stories/sales-by-utm-source-widget.stories.tsx index 44688cd492f2..d85bccbc9927 100644 --- a/projects/packages/premium-analytics/widgets/sales-by-utm-source/stories/sales-by-utm-source-widget.stories.tsx +++ b/projects/packages/premium-analytics/widgets/sales-by-utm-source/stories/sales-by-utm-source-widget.stories.tsx @@ -19,14 +19,14 @@ const SALES_BY_UTM_SOURCE_RENDER_MODULE = 'storybook/sales-by-utm-source'; const DEFAULT_PRESET = 'last-30-days' satisfies SelectablePresetId; const PRESET_OPTIONS = SELECTABLE_PRESETS; -type SalesByUtmSourceRenderProps = ComponentProps< typeof SalesByUtmSourceRender >; +type SalesByUtmSourceWidgetProps = ComponentProps< typeof SalesByUtmSourceRender >; interface SalesByUtmSourceStoryControls { withComparison: boolean; preset: SelectablePresetId; } -type SalesByUtmSourceStoryProps = SalesByUtmSourceRenderProps & SalesByUtmSourceStoryControls; +type SalesByUtmSourceStoryProps = SalesByUtmSourceWidgetProps & SalesByUtmSourceStoryControls; interface SalesByUtmSourceDashboardStoryProps extends WidgetDashboardWithWidgetControls, @@ -41,7 +41,7 @@ const withWidgetCanvas: Decorator = Story => ( function getSalesByUtmSourceAttributes( withComparison = false, preset: SelectablePresetId = DEFAULT_PRESET -): SalesByUtmSourceRenderProps[ 'attributes' ] { +): SalesByUtmSourceWidgetProps[ 'attributes' ] { return { reportParams: getDefaultQueryParams( withComparison, preset ), }; diff --git a/projects/packages/premium-analytics/widgets/sales-by-utm-source/widget.json b/projects/packages/premium-analytics/widgets/sales-by-utm-source/widget.json index 68ec9cf06623..232713c1f218 100644 --- a/projects/packages/premium-analytics/widgets/sales-by-utm-source/widget.json +++ b/projects/packages/premium-analytics/widgets/sales-by-utm-source/widget.json @@ -2,5 +2,6 @@ "name": "jpa/sales-by-utm-source", "title": "Sales by UTM source", "description": "Shows the top UTM sources by order revenue over the selected time period.", - "category": "store" + "category": "store", + "presentation": "framed" } diff --git a/projects/packages/premium-analytics/widgets/search-terms/package.json b/projects/packages/premium-analytics/widgets/search-terms/package.json index 1b0eeadc6ea7..56e89835b9e0 100644 --- a/projects/packages/premium-analytics/widgets/search-terms/package.json +++ b/projects/packages/premium-analytics/widgets/search-terms/package.json @@ -10,6 +10,6 @@ "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", "@wordpress/ui": "0.17.0", - "@wordpress/widget-primitives": "next" + "@wordpress/widget-primitives": "0.2.0" } } diff --git a/projects/packages/premium-analytics/widgets/search-terms/render.tsx b/projects/packages/premium-analytics/widgets/search-terms/render.tsx index 4fbb6d6ddd3b..bf91503b3673 100644 --- a/projects/packages/premium-analytics/widgets/search-terms/render.tsx +++ b/projects/packages/premium-analytics/widgets/search-terms/render.tsx @@ -27,11 +27,10 @@ type SearchTermsWidgetProps = WidgetRenderProps< SearchTermsRenderAttributes >; /** * Search Terms widget inner component. Reads report params from WidgetRoot context. * - * @param props - Render props. - * @param props.max - Maximum number of rows to display. + * @param {SearchTermsAttributes} attributes - The widget attributes. * @return The rendered widget content. */ -function SearchTermsInner( { max = 10 }: { max?: number } ) { +function SearchTermsInner( { max = 10 }: SearchTermsAttributes ) { const { reportParams } = useWidgetRootContext(); const { data, isLoading, isError, hasComparison } = useSearchTermViews( { reportParams, max } ); @@ -101,8 +100,7 @@ function SearchTermsInner( { max = 10 }: { max?: number } ) { * Search Terms widget: the top search queries visitors used to reach the site, * ranked by view count. Ported from the Jetpack Stats "Search Terms" module. * - * @param props - Render props. - * @param props.attributes - Widget attributes (max, reportParams). + * @param {SearchTermsWidgetProps} props - The widget render props. * @return The rendered Search Terms widget. */ export default function SearchTerms( { attributes = {} }: SearchTermsWidgetProps ) { diff --git a/projects/packages/premium-analytics/widgets/search-terms/use-search-term-views.ts b/projects/packages/premium-analytics/widgets/search-terms/use-search-term-views.ts index cd4f791b6f50..ebc28f29917d 100644 --- a/projects/packages/premium-analytics/widgets/search-terms/use-search-term-views.ts +++ b/projects/packages/premium-analytics/widgets/search-terms/use-search-term-views.ts @@ -15,7 +15,13 @@ export interface SearchTermView { } interface UseSearchTermViewsArgs { + /** + * PA ReportParams from WidgetRoot context. + */ reportParams: ReportParams; + /** + * Maximum rows to display. + */ max: number; } @@ -37,9 +43,7 @@ function itemLabel( item: StatsSearchTermsItem ): string { * `@jetpack-premium-analytics/data`. When comparison params are present, the hook * fetches both periods and pairs each primary term with its comparison view count. * - * @param args - Hook arguments. - * @param args.reportParams - PA ReportParams from WidgetRoot context. - * @param args.max - Maximum rows to display. + * @param {UseSearchTermViewsArgs} args - Hook arguments. * @return The current data/loading/error state. */ export default function useSearchTermViews( { diff --git a/projects/packages/premium-analytics/widgets/search-terms/widget.ts b/projects/packages/premium-analytics/widgets/search-terms/widget.ts index a920e67c3dfe..cfa0a173d0b4 100644 --- a/projects/packages/premium-analytics/widgets/search-terms/widget.ts +++ b/projects/packages/premium-analytics/widgets/search-terms/widget.ts @@ -3,10 +3,14 @@ */ import { __ } from '@wordpress/i18n'; import { search } from '@wordpress/icons'; +import type { WidgetAttributeField } from '@wordpress/widget-primitives'; -export interface SearchTermsAttributes { +export type SearchTermsAttributes = { + /** + * Maximum number of rows to display. + */ max?: number; -} +}; /** * Widget type definition for the Search Terms widget. @@ -25,9 +29,9 @@ export default { { id: 'max', label: __( 'Number of results', 'jetpack-premium-analytics' ), - type: 'integer' as const, + type: 'integer', }, - ], + ] as WidgetAttributeField< SearchTermsAttributes >[], example: { attributes: { max: 10, diff --git a/projects/packages/premium-analytics/widgets/sessions-by-device/package.json b/projects/packages/premium-analytics/widgets/sessions-by-device/package.json index 754e0464db18..ff645bda9366 100644 --- a/projects/packages/premium-analytics/widgets/sessions-by-device/package.json +++ b/projects/packages/premium-analytics/widgets/sessions-by-device/package.json @@ -7,7 +7,7 @@ "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" } } diff --git a/projects/packages/premium-analytics/widgets/sessions-by-device/render.tsx b/projects/packages/premium-analytics/widgets/sessions-by-device/render.tsx index 6c1af7ff08a0..9e6f61934217 100644 --- a/projects/packages/premium-analytics/widgets/sessions-by-device/render.tsx +++ b/projects/packages/premium-analytics/widgets/sessions-by-device/render.tsx @@ -18,7 +18,7 @@ import type { ComponentProps } from 'react'; type SessionsByDeviceRenderAttributes = SessionsByDeviceAttributes & Partial< ReportParamsFieldAttributes >; -type SessionsByDeviceRenderProps = WidgetRenderProps< SessionsByDeviceRenderAttributes > & { +type SessionsByDeviceWidgetProps = WidgetRenderProps< SessionsByDeviceRenderAttributes > & { setError?: ComponentProps< typeof WidgetRoot >[ 'setError' ]; }; @@ -28,11 +28,14 @@ type SessionsByDeviceRenderProps = WidgetRenderProps< SessionsByDeviceRenderAttr * Thin composition over the widgets-toolkit: WidgetRoot provides the query * client, chart theme, and resolved report params; SessionsByDeviceWidget * fetches the sessions-by-device report and renders the device breakdown. + * + * @param {SessionsByDeviceWidgetProps} props - The widget render props. + * @return The rendered widget. */ export default function SessionsByDeviceRender( { attributes = {}, setError, -}: SessionsByDeviceRenderProps ) { +}: SessionsByDeviceWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/sessions-by-device/stories/sessions-by-device-widget.stories.tsx b/projects/packages/premium-analytics/widgets/sessions-by-device/stories/sessions-by-device-widget.stories.tsx index 46a2fec3578e..7a679cbf3fc0 100644 --- a/projects/packages/premium-analytics/widgets/sessions-by-device/stories/sessions-by-device-widget.stories.tsx +++ b/projects/packages/premium-analytics/widgets/sessions-by-device/stories/sessions-by-device-widget.stories.tsx @@ -19,14 +19,14 @@ const SESSIONS_BY_DEVICE_RENDER_MODULE = 'storybook/sessions-by-device'; const DEFAULT_PRESET = 'last-30-days' satisfies SelectablePresetId; const PRESET_OPTIONS = SELECTABLE_PRESETS; -type SessionsByDeviceRenderProps = ComponentProps< typeof SessionsByDeviceRender >; +type SessionsByDeviceWidgetProps = ComponentProps< typeof SessionsByDeviceRender >; interface SessionsByDeviceStoryControls { withComparison: boolean; preset: SelectablePresetId; } -type SessionsByDeviceStoryProps = SessionsByDeviceRenderProps & SessionsByDeviceStoryControls; +type SessionsByDeviceStoryProps = SessionsByDeviceWidgetProps & SessionsByDeviceStoryControls; interface SessionsByDeviceDashboardStoryProps extends WidgetDashboardWithWidgetControls, @@ -41,7 +41,7 @@ const withWidgetCanvas: Decorator = Story => ( function getSessionsByDeviceAttributes( withComparison = false, preset: SelectablePresetId = DEFAULT_PRESET -): SessionsByDeviceRenderProps[ 'attributes' ] { +): SessionsByDeviceWidgetProps[ 'attributes' ] { return { reportParams: getDefaultQueryParams( withComparison, preset ), }; diff --git a/projects/packages/premium-analytics/widgets/sessions-by-device/widget.json b/projects/packages/premium-analytics/widgets/sessions-by-device/widget.json index 9f463b8c7c10..9b576e6c04aa 100644 --- a/projects/packages/premium-analytics/widgets/sessions-by-device/widget.json +++ b/projects/packages/premium-analytics/widgets/sessions-by-device/widget.json @@ -2,5 +2,6 @@ "name": "jpa/sessions-by-device", "title": "Sessions by device", "description": "Shows the sessions breakdown by device type over the selected time period.", - "category": "store" + "category": "store", + "presentation": "framed" } diff --git a/projects/packages/premium-analytics/widgets/store-conversion-rate-bookings/package.json b/projects/packages/premium-analytics/widgets/store-conversion-rate-bookings/package.json index 8fedfc884dd6..6a0c6f033605 100644 --- a/projects/packages/premium-analytics/widgets/store-conversion-rate-bookings/package.json +++ b/projects/packages/premium-analytics/widgets/store-conversion-rate-bookings/package.json @@ -7,7 +7,7 @@ "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" } } diff --git a/projects/packages/premium-analytics/widgets/store-conversion-rate-bookings/render.tsx b/projects/packages/premium-analytics/widgets/store-conversion-rate-bookings/render.tsx index 16c3ae0d29d0..fbd3f9a9fa49 100644 --- a/projects/packages/premium-analytics/widgets/store-conversion-rate-bookings/render.tsx +++ b/projects/packages/premium-analytics/widgets/store-conversion-rate-bookings/render.tsx @@ -18,7 +18,7 @@ import type { ComponentProps } from 'react'; type StoreConversionRateBookingsRenderAttributes = StoreConversionRateBookingsAttributes & Partial< ReportParamsFieldAttributes >; -type StoreConversionRateBookingsRenderProps = +type StoreConversionRateBookingsWidgetProps = WidgetRenderProps< StoreConversionRateBookingsRenderAttributes > & { setError?: ComponentProps< typeof WidgetRoot >[ 'setError' ]; }; @@ -30,11 +30,14 @@ type StoreConversionRateBookingsRenderProps = * client, chart theme, and resolved report params; BookingConversionRateWidget * fetches the conversion-rate report with bookings filters and renders the * funnel. + * + * @param {StoreConversionRateBookingsWidgetProps} props - The widget render props. + * @return The rendered widget. */ export default function StoreConversionRateBookingsRender( { attributes = {}, setError, -}: StoreConversionRateBookingsRenderProps ) { +}: StoreConversionRateBookingsWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/store-conversion-rate-bookings/stories/store-conversion-rate-bookings-widget.stories.tsx b/projects/packages/premium-analytics/widgets/store-conversion-rate-bookings/stories/store-conversion-rate-bookings-widget.stories.tsx index ab1783fa6bdd..7fbe34cb4b60 100644 --- a/projects/packages/premium-analytics/widgets/store-conversion-rate-bookings/stories/store-conversion-rate-bookings-widget.stories.tsx +++ b/projects/packages/premium-analytics/widgets/store-conversion-rate-bookings/stories/store-conversion-rate-bookings-widget.stories.tsx @@ -24,16 +24,22 @@ const PRESET_OPTIONS = SELECTABLE_PRESETS; let conversionRateMocksRegistered = false; let conversionRateRequestCount = 0; -type StoreConversionRateBookingsRenderProps = ComponentProps< +type StoreConversionRateBookingsWidgetProps = ComponentProps< typeof StoreConversionRateBookingsRender >; interface StoreConversionRateBookingsStoryControls { + /** + * Whether to include comparison report params. + */ withComparison: boolean; + /** + * Date-range preset to use for report params. + */ preset: SelectablePresetId; } -type StoreConversionRateBookingsStoryProps = StoreConversionRateBookingsRenderProps & +type StoreConversionRateBookingsStoryProps = StoreConversionRateBookingsWidgetProps & StoreConversionRateBookingsStoryControls; interface StoreConversionRateBookingsDashboardStoryProps @@ -104,7 +110,7 @@ function registerConversionRateMocks(): void { function getStoreConversionRateBookingsAttributes( withComparison = false, preset: SelectablePresetId = DEFAULT_PRESET -): StoreConversionRateBookingsRenderProps[ 'attributes' ] { +): StoreConversionRateBookingsWidgetProps[ 'attributes' ] { return { reportParams: getDefaultQueryParams( withComparison, preset ), }; @@ -143,9 +149,7 @@ function getStoreConversionRateBookingsSource( /** * Renders the standalone store conversion rate bookings widget story. * - * @param props - Story controls. - * @param props.withComparison - Whether to include comparison report params. - * @param props.preset - Date-range preset to use for report params. + * @param {StoreConversionRateBookingsStoryControls} props - Story controls. * @return Store conversion rate bookings widget story element. */ function renderStoreConversionRateBookings( { @@ -162,9 +166,7 @@ function renderStoreConversionRateBookings( { /** * Renders the store conversion rate bookings widget inside the dashboard story shell. * - * @param props - Story controls. - * @param props.withComparison - Whether to include comparison report params. - * @param props.preset - Date-range preset to use for report params. + * @param {StoreConversionRateBookingsDashboardStoryProps} props - Story controls. * @return Store conversion rate bookings dashboard story element. */ function StoreConversionRateBookingsDashboardStory( { diff --git a/projects/packages/premium-analytics/widgets/store-conversion-rate-bookings/widget.json b/projects/packages/premium-analytics/widgets/store-conversion-rate-bookings/widget.json index 366a9f1346b1..5cff5b9991b5 100644 --- a/projects/packages/premium-analytics/widgets/store-conversion-rate-bookings/widget.json +++ b/projects/packages/premium-analytics/widgets/store-conversion-rate-bookings/widget.json @@ -2,5 +2,6 @@ "name": "jpa/store-conversion-rate-bookings", "title": "Store conversion rate - Bookings", "description": "Store conversion rate for booking products over the selected time period.", - "category": "bookings" + "category": "bookings", + "presentation": "framed" } diff --git a/projects/packages/premium-analytics/widgets/subscribers-chart/package.json b/projects/packages/premium-analytics/widgets/subscribers-chart/package.json index 288e283762bc..fa3d1ff5770c 100644 --- a/projects/packages/premium-analytics/widgets/subscribers-chart/package.json +++ b/projects/packages/premium-analytics/widgets/subscribers-chart/package.json @@ -6,13 +6,10 @@ "dependencies": { "@jetpack-premium-analytics/data": "link:../../packages/data", "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", - "@wordpress/components": "36.1.0", "@wordpress/element": "8.2.0", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", - "@wordpress/ui": "0.17.0", - "@wordpress/widget-primitives": "next", - "date-fns": "4.1.0", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" } } diff --git a/projects/packages/premium-analytics/widgets/subscribers-chart/render.tsx b/projects/packages/premium-analytics/widgets/subscribers-chart/render.tsx index e85348fe6cf8..83c9579602b8 100644 --- a/projects/packages/premium-analytics/widgets/subscribers-chart/render.tsx +++ b/projects/packages/premium-analytics/widgets/subscribers-chart/render.tsx @@ -7,9 +7,9 @@ import { useWidgetError, useWidgetRootContext, type MetricTab, + type ReportParamsFieldAttributes, } from '@jetpack-premium-analytics/widgets-toolkit'; -import { SelectControl } from '@wordpress/components'; -import { useCallback, useMemo, useState } from '@wordpress/element'; +import { useMemo } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; /** * Internal dependencies @@ -20,12 +20,18 @@ import useSubscribersChart, { type SubscribersChartState, type SubscribersPeriod, } from './use-subscribers-chart'; +import type { SubscribersChartAttributes, SubscribersChartGranularity } from './widget'; +import type { WidgetRenderProps } from '@wordpress/widget-primitives'; import type { ComponentProps } from 'react'; -type SubscribersChartRenderProps = Pick< - ComponentProps< typeof WidgetRoot >, - 'attributes' | 'setError' ->; +type SubscribersChartRenderAttributes = SubscribersChartAttributes & + Partial< ReportParamsFieldAttributes >; +type SubscribersChartWidgetProps = WidgetRenderProps< SubscribersChartRenderAttributes > & { + /** + * Host callback to surface a widget error in the dashboard frame. + */ + setError?: ComponentProps< typeof WidgetRoot >[ 'setError' ]; +}; const DATA_FORMAT = { type: 'number' as const, @@ -111,32 +117,31 @@ function buildMetrics( state: SubscribersChartState ): MetricTab[] { } ) ); } +type SubscribersChartInnerProps = { + /** + * Selected granularity; `auto` follows the dashboard range. + */ + granularity: SubscribersChartGranularity; +}; + /** * Subscribers chart inner component. Reads the dashboard date range + comparison - * state from `useWidgetRootContext()`, owns the granularity dropdown (which only - * chooses the bucket size within that range), and hands the metric tabs - * (Subscribers, Paid subscribers) to the shared `MetricTabsChart`. + * state from `useWidgetRootContext()` and hands the metric tabs (Subscribers, + * Paid subscribers) to the shared `MetricTabsChart`. The "Group by" control is + * the `granularity` attribute (`relevance: 'high'`), rendered by the widget + * host; it only chooses the bucket size within the dashboard range. * + * @param {SubscribersChartInnerProps} props - The component props. * @return The widget body. */ -function SubscribersChartInner() { +function SubscribersChartInner( { granularity }: SubscribersChartInnerProps ) { const { reportParams } = useWidgetRootContext(); - // `null` means "follow the dashboard range"; a value is an explicit user - // override that then sticks across range changes. This keeps a wide range - // from staying stuck on `day` granularity (and blowing up the bucket count) - // while the user hasn't picked a granularity themselves. - const [ periodOverride, setPeriodOverride ] = useState< SubscribersPeriod | null >( null ); - const period = periodOverride ?? defaultPeriodForInterval( reportParams.interval ); - const handlePeriodChange = useCallback( - ( value: string ) => setPeriodOverride( value as SubscribersPeriod ), - [] - ); - - const periodOptions = [ - { label: __( 'By days', 'jetpack-premium-analytics' ), value: 'day' }, - { label: __( 'By weeks', 'jetpack-premium-analytics' ), value: 'week' }, - { label: __( 'By months', 'jetpack-premium-analytics' ), value: 'month' }, - ]; + // `auto` means "follow the dashboard range"; an explicit value sticks + // across range changes. This keeps a wide range from staying stuck on + // `day` granularity (and blowing up the bucket count) while the user + // hasn't picked a granularity themselves. + const period: SubscribersPeriod = + granularity === 'auto' ? defaultPeriodForInterval( reportParams.interval ) : granularity; const state = useSubscribersChart( reportParams, period ); const metrics = useMemo( () => buildMetrics( state ), [ state ] ); @@ -153,18 +158,6 @@ function SubscribersChartInner() { dataFormat={ DATA_FORMAT } loading={ state.isFetching } groupLabel={ __( 'Subscriber metric', 'jetpack-premium-analytics' ) } - controls={ - - } />
); @@ -174,18 +167,22 @@ function SubscribersChartInner() { * Widget render entry point. * * `WidgetRoot` provides the analytics query client and resolves the dashboard's - * `reportParams`; the inner component reads that range/comparison state and - * layers its own granularity control on top. + * `reportParams`; the inner component reads that range/comparison state. The + * granularity is the `granularity` attribute (`relevance: 'high'`), exposed as + * a control by the widget host. * - * @param props - Render props supplied by the widget host. - * @param props.attributes - Widget attributes, carrying host-provided report params. - * @param props.setError - Host callback to surface a widget error in the dashboard frame. + * @param {SubscribersChartWidgetProps} props - The widget render props. * @return The rendered widget. */ -export default function SubscribersChart( { attributes, setError }: SubscribersChartRenderProps ) { +export default function SubscribersChart( { + attributes = {}, + setError, +}: SubscribersChartWidgetProps ) { + const granularity = attributes.granularity ?? 'auto'; + return ( - + ); } diff --git a/projects/packages/premium-analytics/widgets/subscribers-chart/stories/subscribers-chart-widget.stories.tsx b/projects/packages/premium-analytics/widgets/subscribers-chart/stories/subscribers-chart-widget.stories.tsx index a9b7d6109d77..05ee8116347a 100644 --- a/projects/packages/premium-analytics/widgets/subscribers-chart/stories/subscribers-chart-widget.stories.tsx +++ b/projects/packages/premium-analytics/widgets/subscribers-chart/stories/subscribers-chart-widget.stories.tsx @@ -52,7 +52,7 @@ const meta = { docs: { description: { component: - 'Subscriber growth over time. The date range and previous-period comparison follow the dashboard picker; the in-body "Group by" dropdown chooses the bucket size (day/week/month) within that range. When comparison is on, the previous period is overlaid as a same-colour dashed line and the headline shows the period-over-period delta. Paid subscribers render as a second line when present. Data comes from `useStatsSubscribersReport`; in Storybook it is served by `registerReportMocks`.', + 'Subscriber growth over time. The date range and previous-period comparison follow the dashboard picker; the "Group by" control is the `granularity` attribute (`relevance: \'high\'`), exposed by the widget host, and chooses the bucket size (day/week/month) within that range. When comparison is on, the previous period is overlaid as a same-colour dashed line and the headline shows the period-over-period delta. Paid subscribers render as a second line when present. Data comes from `useStatsSubscribersReport`; in Storybook it is served by `registerReportMocks`.', }, }, }, diff --git a/projects/packages/premium-analytics/widgets/subscribers-chart/style.module.css b/projects/packages/premium-analytics/widgets/subscribers-chart/style.module.css index fc73c3222af9..43e0770b2062 100644 --- a/projects/packages/premium-analytics/widgets/subscribers-chart/style.module.css +++ b/projects/packages/premium-analytics/widgets/subscribers-chart/style.module.css @@ -7,10 +7,6 @@ overflow: hidden; } -.periodSelect { - flex-shrink: 0; -} - /* Constrain the picker preview tile to a 4:3 aspect ratio. The picker's * .preview wrapper uses height: 125% of an auto-height parent, so height: 100% * on .root also resolves to auto, leaving aspect-ratio with no anchor. diff --git a/projects/packages/premium-analytics/widgets/subscribers-chart/widget.ts b/projects/packages/premium-analytics/widgets/subscribers-chart/widget.ts index 1e83d5c733f4..07ac86877511 100644 --- a/projects/packages/premium-analytics/widgets/subscribers-chart/widget.ts +++ b/projects/packages/premium-analytics/widgets/subscribers-chart/widget.ts @@ -3,14 +3,35 @@ */ import { __ } from '@wordpress/i18n'; import { trendingUp } from '@wordpress/icons'; +import type { WidgetAttributeField } from '@wordpress/widget-primitives'; + +/** + * Granularity the chart can be grouped by. `auto` follows the dashboard date + * range (a wide range buckets by month, a narrow one by day); an explicit + * value sticks across range changes. + */ +export type SubscribersChartGranularity = 'auto' | 'day' | 'week' | 'month'; + +/** + * Configurable attributes for the Subscribers chart widget. Report params + * still reach it through WidgetRoot: the dashboard date range, or + * `attributes.reportParams` when a host injects them (e.g. Storybook and + * dashboard previews). + * + * @property granularity - Bucket size within the dashboard range. Defaults to `auto`. + */ +export type SubscribersChartAttributes = { + granularity?: SubscribersChartGranularity; +}; /** * Widget type definition. * * Ported from the Jetpack Stats `stats-subscribers-chart-section` card in * wp-calypso. The date range and previous-period comparison follow the - * dashboard picker; the legacy interval segmented control becomes the in-body - * "Group by" dropdown, which only chooses the bucket size within that range. + * dashboard picker; the legacy interval segmented control is the + * `granularity` attribute (`relevance: 'high'`), so the widget host renders + * its control. It only chooses the bucket size within that range. */ export default { name: 'jpa/subscribers-chart', @@ -20,4 +41,35 @@ export default { 'jetpack-premium-analytics' ), icon: trendingUp, + attributes: [ + { + id: 'granularity', + label: __( 'Group by', 'jetpack-premium-analytics' ), + type: 'text', + elements: [ + { + label: __( 'Auto', 'jetpack-premium-analytics' ), + value: 'auto', + }, + { + label: __( 'By days', 'jetpack-premium-analytics' ), + value: 'day', + }, + { + label: __( 'By weeks', 'jetpack-premium-analytics' ), + value: 'week', + }, + { + label: __( 'By months', 'jetpack-premium-analytics' ), + value: 'month', + }, + ], + relevance: 'high', + }, + ] as WidgetAttributeField< SubscribersChartAttributes >[], + example: { + attributes: { + granularity: 'auto', + }, + }, }; diff --git a/projects/packages/premium-analytics/widgets/subscribers-list/package.json b/projects/packages/premium-analytics/widgets/subscribers-list/package.json index c155a5cd9faa..4cce2430d5c8 100644 --- a/projects/packages/premium-analytics/widgets/subscribers-list/package.json +++ b/projects/packages/premium-analytics/widgets/subscribers-list/package.json @@ -10,7 +10,7 @@ "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", "@wordpress/ui": "0.17.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" } } diff --git a/projects/packages/premium-analytics/widgets/subscribers-list/render.tsx b/projects/packages/premium-analytics/widgets/subscribers-list/render.tsx index e3cfda901dc2..f12835ab09f9 100644 --- a/projects/packages/premium-analytics/widgets/subscribers-list/render.tsx +++ b/projects/packages/premium-analytics/widgets/subscribers-list/render.tsx @@ -10,6 +10,7 @@ import { formatRelativeSince } from '@jetpack-premium-analytics/datetime'; import { SubscriberList, WidgetRoot, + type ReportParamsFieldAttributes, type SubscriberListItem, } from '@jetpack-premium-analytics/widgets-toolkit'; import { __ } from '@wordpress/i18n'; @@ -98,15 +99,21 @@ export const SubscribersRoster = ( { ); }; +type SubscribersReportProps = { + /** + * Widget attributes. + */ + attributes?: SubscribersListAttributes; +}; + /** * Fetches the latest subscribers through the designated `useStatsFollowers` * Stats hook and hands the normalized rows to the presentational roster. * - * @param props - Component props. - * @param props.attributes - Widget attributes. + * @param {SubscribersReportProps} props - The component props. * @return The widget content. */ -function SubscribersReport( { attributes }: { attributes?: SubscribersListAttributes } ) { +function SubscribersReport( { attributes }: SubscribersReportProps ) { // Show six rows by default (matching the card design). A missing or // non-positive setting falls back to that default — `?? 6` alone wouldn't, // since an explicit `0` from the number field is not nullish. @@ -132,22 +139,24 @@ function SubscribersReport( { attributes }: { attributes?: SubscribersListAttrib ); } +type SubscribersListRenderAttributes = SubscribersListAttributes & + Partial< ReportParamsFieldAttributes >; +type SubscribersListWidgetProps = WidgetRenderProps< SubscribersListRenderAttributes >; + /** * Widget render entry point. * * Mirrors the other Stats widgets: attributes flow to the inner component via * props (the dashboard's WC-shaped `reportParams` context does not fit the - * followers query), and `WidgetRoot` provides the analytics query client. + * followers query), and `WidgetRoot` provides the analytics query client and + * receives host attributes for the widget contract. * - * @param props - Render props supplied by the widget host. - * @param props.attributes - Widget attributes. + * @param {SubscribersListWidgetProps} props - The widget render props. * @return The rendered widget. */ -export default function SubscribersList( { - attributes = {}, -}: WidgetRenderProps< SubscribersListAttributes > ) { +export default function SubscribersList( { attributes = {} }: SubscribersListWidgetProps ) { return ( - + ); diff --git a/projects/packages/premium-analytics/widgets/subscribers-list/widget.ts b/projects/packages/premium-analytics/widgets/subscribers-list/widget.ts index 4cdcbaf03c2e..194507d015c3 100644 --- a/projects/packages/premium-analytics/widgets/subscribers-list/widget.ts +++ b/projects/packages/premium-analytics/widgets/subscribers-list/widget.ts @@ -3,6 +3,7 @@ */ import { __ } from '@wordpress/i18n'; import { people } from '@wordpress/icons'; +import type { WidgetAttributeField } from '@wordpress/widget-primitives'; /** * Configurable attributes for the Latest Subscribers widget. Mirrors the @@ -30,9 +31,9 @@ export default { { id: 'num', label: __( 'Number of results', 'jetpack-premium-analytics' ), - type: 'integer' as const, + type: 'integer', }, - ], + ] as WidgetAttributeField< SubscribersListAttributes >[], example: { attributes: { num: 6, diff --git a/projects/packages/premium-analytics/widgets/top-performing-bookings/package.json b/projects/packages/premium-analytics/widgets/top-performing-bookings/package.json index 21298035bdb6..d4ef4066ea87 100644 --- a/projects/packages/premium-analytics/widgets/top-performing-bookings/package.json +++ b/projects/packages/premium-analytics/widgets/top-performing-bookings/package.json @@ -7,7 +7,7 @@ "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" } } diff --git a/projects/packages/premium-analytics/widgets/top-performing-bookings/render.tsx b/projects/packages/premium-analytics/widgets/top-performing-bookings/render.tsx index 4e28414c959f..a0b00bab3547 100644 --- a/projects/packages/premium-analytics/widgets/top-performing-bookings/render.tsx +++ b/projects/packages/premium-analytics/widgets/top-performing-bookings/render.tsx @@ -18,7 +18,7 @@ import type { ComponentProps } from 'react'; type TopPerformingBookingsRenderAttributes = TopPerformingBookingsAttributes & Partial< ReportParamsFieldAttributes >; -type TopPerformingBookingsRenderProps = +type TopPerformingBookingsWidgetProps = WidgetRenderProps< TopPerformingBookingsRenderAttributes > & { setError?: ComponentProps< typeof WidgetRoot >[ 'setError' ]; }; @@ -29,11 +29,14 @@ type TopPerformingBookingsRenderProps = * Thin composition over the widgets-toolkit: WidgetRoot provides the query * client, chart theme, and resolved report params; TopPerformingBookingsWidget * fetches booking product data and renders a revenue leaderboard. + * + * @param {TopPerformingBookingsWidgetProps} props - The widget render props. + * @return The rendered widget. */ export default function TopPerformingBookingsRender( { attributes = {}, setError, -}: TopPerformingBookingsRenderProps ) { +}: TopPerformingBookingsWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/top-performing-bookings/stories/top-performing-bookings-widget.stories.tsx b/projects/packages/premium-analytics/widgets/top-performing-bookings/stories/top-performing-bookings-widget.stories.tsx index 2dfd465d9dd1..6be3259cac03 100644 --- a/projects/packages/premium-analytics/widgets/top-performing-bookings/stories/top-performing-bookings-widget.stories.tsx +++ b/projects/packages/premium-analytics/widgets/top-performing-bookings/stories/top-performing-bookings-widget.stories.tsx @@ -136,14 +136,20 @@ const TOP_PERFORMING_BOOKINGS_RENDER_MODULE = 'storybook/top-performing-bookings const DEFAULT_PRESET = 'last-30-days' satisfies SelectablePresetId; const PRESET_OPTIONS = SELECTABLE_PRESETS; -type TopPerformingBookingsRenderProps = ComponentProps< typeof TopPerformingBookingsRender >; +type TopPerformingBookingsWidgetProps = ComponentProps< typeof TopPerformingBookingsRender >; interface TopPerformingBookingsStoryControls { + /** + * Whether to include comparison report params. + */ withComparison: boolean; + /** + * Date-range preset used for report params. + */ preset: SelectablePresetId; } -type TopPerformingBookingsStoryProps = TopPerformingBookingsRenderProps & +type TopPerformingBookingsStoryProps = TopPerformingBookingsWidgetProps & TopPerformingBookingsStoryControls; interface TopPerformingBookingsDashboardStoryProps @@ -159,7 +165,7 @@ const withWidgetCanvas: Decorator = Story => ( function getTopPerformingBookingsAttributes( withComparison = false, preset: SelectablePresetId = DEFAULT_PRESET -): TopPerformingBookingsRenderProps[ 'attributes' ] { +): TopPerformingBookingsWidgetProps[ 'attributes' ] { return { reportParams: getDefaultQueryParams( withComparison, preset ), }; @@ -207,9 +213,7 @@ function renderTopPerformingBookings( { /** * Story wrapper for rendering the top performing bookings widget in dashboard chrome. * - * @param root0 - Story controls. - * @param root0.withComparison - Whether to include comparison report params. - * @param root0.preset - Date-range preset used for report params. + * @param {TopPerformingBookingsDashboardStoryProps} props - Story controls. * @return The rendered Storybook story. */ function TopPerformingBookingsDashboardStory( { diff --git a/projects/packages/premium-analytics/widgets/top-performing-bookings/widget.json b/projects/packages/premium-analytics/widgets/top-performing-bookings/widget.json index e1ea4e6b48b6..c3bbc45a25ca 100644 --- a/projects/packages/premium-analytics/widgets/top-performing-bookings/widget.json +++ b/projects/packages/premium-analytics/widgets/top-performing-bookings/widget.json @@ -2,5 +2,6 @@ "name": "jpa/top-performing-bookings", "title": "Top performing bookings", "description": "Shows the top booking products by net revenue over the selected time period.", - "category": "store" + "category": "store", + "presentation": "framed" } diff --git a/projects/packages/premium-analytics/widgets/top-performing-products/package.json b/projects/packages/premium-analytics/widgets/top-performing-products/package.json index c22d87a3f863..4bc22b1df75d 100644 --- a/projects/packages/premium-analytics/widgets/top-performing-products/package.json +++ b/projects/packages/premium-analytics/widgets/top-performing-products/package.json @@ -7,7 +7,7 @@ "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" } } diff --git a/projects/packages/premium-analytics/widgets/top-performing-products/render.tsx b/projects/packages/premium-analytics/widgets/top-performing-products/render.tsx index 17a3222a742e..d2f2b0c2209f 100644 --- a/projects/packages/premium-analytics/widgets/top-performing-products/render.tsx +++ b/projects/packages/premium-analytics/widgets/top-performing-products/render.tsx @@ -18,7 +18,7 @@ import type { ComponentProps } from 'react'; type TopPerformingProductsRenderAttributes = TopPerformingProductsAttributes & Partial< ReportParamsFieldAttributes >; -type TopPerformingProductsRenderProps = +type TopPerformingProductsWidgetProps = WidgetRenderProps< TopPerformingProductsRenderAttributes > & { setError?: ComponentProps< typeof WidgetRoot >[ 'setError' ]; }; @@ -29,11 +29,14 @@ type TopPerformingProductsRenderProps = * Thin composition over the widgets-toolkit: WidgetRoot provides the query * client, chart theme, and resolved report params; TopPerformingProductsWidget * fetches physical product data and renders a revenue leaderboard. + * + * @param {TopPerformingProductsWidgetProps} props - The widget render props. + * @return The rendered widget. */ export default function TopPerformingProductsRender( { attributes = {}, setError, -}: TopPerformingProductsRenderProps ) { +}: TopPerformingProductsWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/top-performing-products/stories/top-performing-products-widget.stories.tsx b/projects/packages/premium-analytics/widgets/top-performing-products/stories/top-performing-products-widget.stories.tsx index 6423fd4edc07..cc1a50cf6bad 100644 --- a/projects/packages/premium-analytics/widgets/top-performing-products/stories/top-performing-products-widget.stories.tsx +++ b/projects/packages/premium-analytics/widgets/top-performing-products/stories/top-performing-products-widget.stories.tsx @@ -136,15 +136,15 @@ const TOP_PERFORMING_PRODUCTS_RENDER_MODULE = 'storybook/top-performing-products const DEFAULT_PRESET = 'last-30-days' satisfies SelectablePresetId; const PRESET_OPTIONS = SELECTABLE_PRESETS; -type TopPerformingProductsRenderProps = ComponentProps< typeof TopPerformingProductsRender >; -const noopSetError: TopPerformingProductsRenderProps[ 'setError' ] = () => undefined; +type TopPerformingProductsWidgetProps = ComponentProps< typeof TopPerformingProductsRender >; +const noopSetError: TopPerformingProductsWidgetProps[ 'setError' ] = () => undefined; interface TopPerformingProductsStoryControls { withComparison: boolean; preset: SelectablePresetId; } -type TopPerformingProductsStoryProps = TopPerformingProductsRenderProps & +type TopPerformingProductsStoryProps = TopPerformingProductsWidgetProps & TopPerformingProductsStoryControls; interface TopPerformingProductsDashboardStoryProps @@ -160,7 +160,7 @@ const withWidgetCanvas: Decorator = Story => ( function getTopPerformingProductsAttributes( withComparison = false, preset: SelectablePresetId = DEFAULT_PRESET -): TopPerformingProductsRenderProps[ 'attributes' ] { +): TopPerformingProductsWidgetProps[ 'attributes' ] { return { reportParams: getDefaultQueryParams( withComparison, preset ), }; diff --git a/projects/packages/premium-analytics/widgets/top-performing-products/widget.json b/projects/packages/premium-analytics/widgets/top-performing-products/widget.json index 9f9f94eb63aa..2bf55acc9f7d 100644 --- a/projects/packages/premium-analytics/widgets/top-performing-products/widget.json +++ b/projects/packages/premium-analytics/widgets/top-performing-products/widget.json @@ -2,5 +2,6 @@ "name": "jpa/top-performing-products", "title": "Top performing products", "description": "Shows the top products by net revenue over the selected time period.", - "category": "store" + "category": "store", + "presentation": "framed" } diff --git a/projects/packages/premium-analytics/widgets/top-platforms/package.json b/projects/packages/premium-analytics/widgets/top-platforms/package.json index 4054869f5742..54499a2769b2 100644 --- a/projects/packages/premium-analytics/widgets/top-platforms/package.json +++ b/projects/packages/premium-analytics/widgets/top-platforms/package.json @@ -6,11 +6,9 @@ "dependencies": { "@jetpack-premium-analytics/data": "link:../../packages/data", "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", - "@wordpress/components": "36.1.0", - "@wordpress/element": "8.2.0", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", "@wordpress/ui": "0.17.0", - "@wordpress/widget-primitives": "next" + "@wordpress/widget-primitives": "0.2.0" } } diff --git a/projects/packages/premium-analytics/widgets/top-platforms/render.tsx b/projects/packages/premium-analytics/widgets/top-platforms/render.tsx index f15ef226e324..78350403bf74 100644 --- a/projects/packages/premium-analytics/widgets/top-platforms/render.tsx +++ b/projects/packages/premium-analytics/widgets/top-platforms/render.tsx @@ -1,8 +1,6 @@ /** * WordPress dependencies */ -import { SelectControl } from '@wordpress/components'; -import { useCallback, useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { Stack, Text } from '@wordpress/ui'; import { @@ -30,75 +28,53 @@ type TopPlatformsWidgetProps = WidgetRenderProps< TopPlatformsRenderAttributes > const DATA_FORMAT = { type: 'number' as const, options: { useMultipliers: true, decimals: 0 } }; -const MODE_OPTIONS = [ - { label: __( 'Browser', 'jetpack-premium-analytics' ), value: 'browser' }, - { label: __( 'OS', 'jetpack-premium-analytics' ), value: 'platform' }, -] as const; - type PlatformMode = 'browser' | 'platform'; +type TopPlatformsInnerProps = { + /** + * Max rows to display. + */ + max: number; + /** + * Device dimension to rank: browsers or operating systems. + */ + platformDimension: PlatformMode; +}; + /** * Inner component — rendered inside WidgetRoot. * - * @param props - Props. - * @param props.max - Max rows to display. + * @param {TopPlatformsInnerProps} props - The component props. * @return The rendered leaderboard or state placeholder. */ -function TopPlatformsInner( { max }: { max: number } ) { +function TopPlatformsInner( { max, platformDimension }: TopPlatformsInnerProps ) { const { reportParams } = useWidgetRootContext(); - const [ mode, setMode ] = useState< PlatformMode >( 'browser' ); - - const handleModeChange = useCallback( ( value: string ) => { - setMode( value as PlatformMode ); - }, [] ); const { data, comparisonData, hasComparison, isLoading, isError, errorReason } = usePlatformViews( { reportParams, max, - deviceProperty: mode, + deviceProperty: platformDimension, } ); - const bodyHeader = ( - - - - ); - if ( isError ) { return ( -
- { bodyHeader } - - - { errorReason === 'upgrade-required' - ? __( - 'Platform stats are not included in your current plan.', - 'jetpack-premium-analytics' - ) - : __( 'Could not load platform data.', 'jetpack-premium-analytics' ) } - - -
+ + + { errorReason === 'upgrade-required' + ? __( + 'Platform stats are not included in your current plan.', + 'jetpack-premium-analytics' + ) + : __( 'Could not load platform data.', 'jetpack-premium-analytics' ) } + + ); } if ( isLoading && data.length === 0 ) { - return ( -
- { bodyHeader } - -
- ); + return ; } const maxViews = Math.max( ...data.map( d => d.views ), 0 ); @@ -122,18 +98,15 @@ function TopPlatformsInner( { max }: { max: number } ) { } ) ); return ( -
- { bodyHeader } - -
+ ); } @@ -141,19 +114,20 @@ function TopPlatformsInner( { max }: { max: number } ) { * Top Platforms widget render component. * * Shows browser or OS breakdown as a ranked leaderboard. The active - * dimension is switched via a runtime dropdown in the widget body. + * dimension is the `platformDimension` attribute (`relevance: 'high'`), + * exposed as a control by the widget host. * - * @param props - Render props. - * @param props.attributes - Widget attributes (max). + * @param {TopPlatformsWidgetProps} props - The widget render props. * @return The rendered widget content. */ export default function TopPlatformsWidget( { attributes }: TopPlatformsWidgetProps ) { const max = attributes?.max ?? 10; + const platformDimension = attributes?.platformDimension ?? 'browser'; return (
- +
); diff --git a/projects/packages/premium-analytics/widgets/top-platforms/style.module.css b/projects/packages/premium-analytics/widgets/top-platforms/style.module.css index 96fe2b71bada..9fc6e9ad0d9c 100644 --- a/projects/packages/premium-analytics/widgets/top-platforms/style.module.css +++ b/projects/packages/premium-analytics/widgets/top-platforms/style.module.css @@ -14,26 +14,6 @@ text-align: center; } -.modeSelect { - flex-shrink: 0; -} - -.content { - position: relative; - display: flex; - flex-direction: column; - flex: 1 1 0; - min-height: 0; -} - -.bodyHeader { - position: relative; - z-index: 2; - flex-wrap: wrap; - gap: var(--wpds-dimension-gap-sm, 8px); - margin-block-end: var(--wpds-dimension-gap-md, 12px); -} - .itemLabel { padding: var(--wpds-dimension-padding-sm); } diff --git a/projects/packages/premium-analytics/widgets/top-platforms/use-platform-views.ts b/projects/packages/premium-analytics/widgets/top-platforms/use-platform-views.ts index a5e8e4c3c6be..51eac5404970 100644 --- a/projects/packages/premium-analytics/widgets/top-platforms/use-platform-views.ts +++ b/projects/packages/premium-analytics/widgets/top-platforms/use-platform-views.ts @@ -20,8 +20,17 @@ export interface PlatformView { } interface UsePlatformViewsArgs { + /** + * PA ReportParams from WidgetRoot context. + */ reportParams: ReportParams; + /** + * Maximum rows to display (0 = all). + */ max: number; + /** + * 'browser' or 'platform' (OS). + */ deviceProperty: 'browser' | 'platform'; } @@ -79,10 +88,7 @@ function toPlatformView( /** * Fetch platform views (browser or OS) via the shared Stats data layer. * - * @param args - Hook arguments. - * @param args.reportParams - PA ReportParams from WidgetRoot context. - * @param args.max - Maximum rows to display (0 = all). - * @param args.deviceProperty - 'browser' or 'platform' (OS). + * @param {UsePlatformViewsArgs} args - Hook arguments. * @return The current data/loading/error state. */ export default function usePlatformViews( { diff --git a/projects/packages/premium-analytics/widgets/top-platforms/widget.ts b/projects/packages/premium-analytics/widgets/top-platforms/widget.ts index 713e65871a69..1875334a8e9d 100644 --- a/projects/packages/premium-analytics/widgets/top-platforms/widget.ts +++ b/projects/packages/premium-analytics/widgets/top-platforms/widget.ts @@ -3,22 +3,25 @@ */ import { __ } from '@wordpress/i18n'; import { chartBar } from '@wordpress/icons'; +import type { WidgetAttributeField } from '@wordpress/widget-primitives'; -/** - * Widget attributes shape. - * - * @property max - Maximum rows to display (0 = all). Defaults to 10. - */ export type TopPlatformsAttributes = { + /** + * Maximum rows to display (0 = all). Defaults to 10. + */ max?: number; + /** + * Device dimension to rank: browsers or operating systems. + */ + platformDimension?: 'browser' | 'platform'; }; /** * Top Platforms widget type definition. * * Shows Browser and OS breakdown as a ranked leaderboard. The active - * dimension (browser / platform) is controlled by a runtime dropdown, - * not stored as a widget attribute. + * dimension is the `platformDimension` attribute (`relevance: 'high'`), + * so the widget host renders its control. */ export default { name: 'jpa/top-platforms', @@ -30,10 +33,27 @@ export default { label: __( 'Max rows', 'jetpack-premium-analytics' ), type: 'number', }, - ], + { + id: 'platformDimension', + label: __( 'View by', 'jetpack-premium-analytics' ), + type: 'text', + elements: [ + { + label: __( 'Browser', 'jetpack-premium-analytics' ), + value: 'browser', + }, + { + label: __( 'OS', 'jetpack-premium-analytics' ), + value: 'platform', + }, + ], + relevance: 'high', + }, + ] as WidgetAttributeField< TopPlatformsAttributes >[], example: { attributes: { max: 10, + platformDimension: 'browser', }, }, }; diff --git a/projects/packages/premium-analytics/widgets/top-posts/package.json b/projects/packages/premium-analytics/widgets/top-posts/package.json index 53729456885e..fecf9acc790b 100644 --- a/projects/packages/premium-analytics/widgets/top-posts/package.json +++ b/projects/packages/premium-analytics/widgets/top-posts/package.json @@ -9,8 +9,7 @@ "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", "@wordpress/ui": "0.17.0", - "@wordpress/widget-primitives": "next", - "date-fns": "4.1.0", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" }, "devDependencies": { diff --git a/projects/packages/premium-analytics/widgets/top-posts/render.tsx b/projects/packages/premium-analytics/widgets/top-posts/render.tsx index f71ffd10700d..f241987b31a8 100644 --- a/projects/packages/premium-analytics/widgets/top-posts/render.tsx +++ b/projects/packages/premium-analytics/widgets/top-posts/render.tsx @@ -60,6 +60,7 @@ export type TopPostRow = { // Report params are dashboard-driven — WidgetRoot resolves them from the date // picker — but the host (and Storybook) may also inject them via `attributes`. type TopPostsRenderAttributes = TopPostsAttributes & Partial< ReportParamsFieldAttributes >; +type TopPostsWidgetProps = WidgetRenderProps< TopPostsRenderAttributes >; type TopPostsReportProps = Pick< TopPostsAttributes, 'num' | 'postType' >; @@ -217,9 +218,7 @@ function toTopPostRows( * `TopPostsLeaderboard`. The date range and comparison period come from the * dashboard picker via `reportParams`. * - * @param props - Component props. - * @param props.num - Maximum number of posts to display. - * @param props.postType - Post type(s) to keep, or undefined/empty for all. + * @param {TopPostsReportProps} props - The component props. * @return The widget content. */ function TopPostsReport( { num = 10, postType }: TopPostsReportProps ) { @@ -297,13 +296,10 @@ function TopPostsReport( { num = 10, postType }: TopPostsReportProps ) { * range via context, the same way the other Stats widgets read them. The * widget's own `num`/`postType` settings are forwarded to the inner component. * - * @param props - Render props supplied by the widget host. - * @param props.attributes - Widget attributes. + * @param {TopPostsWidgetProps} props - The widget render props. * @return The rendered widget. */ -export default function TopPosts( { - attributes = {}, -}: WidgetRenderProps< TopPostsRenderAttributes > ) { +export default function TopPosts( { attributes = {} }: TopPostsWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/top-posts/widget.ts b/projects/packages/premium-analytics/widgets/top-posts/widget.ts index 9d1ba9492671..dd396da61c92 100644 --- a/projects/packages/premium-analytics/widgets/top-posts/widget.ts +++ b/projects/packages/premium-analytics/widgets/top-posts/widget.ts @@ -3,6 +3,7 @@ */ import { __ } from '@wordpress/i18n'; import { chartBar } from '@wordpress/icons'; +import type { WidgetAttributeField } from '@wordpress/widget-primitives'; /** * Configurable attributes for the Top posts & pages widget. Mirrors the @@ -11,6 +12,9 @@ import { chartBar } from '@wordpress/icons'; * dashboard picker and read from report params, not from attributes. */ export type TopPostsAttributes = { + /** + * Maximum number of posts to display. + */ num?: number; /** * Post type(s) to keep. When undefined or empty, all types are shown. @@ -44,7 +48,7 @@ export default { { label: __( 'Pages', 'jetpack-premium-analytics' ), value: 'page' }, ], }, - ], + ] as WidgetAttributeField< TopPostsAttributes >[], example: { attributes: { num: 10, diff --git a/projects/packages/premium-analytics/widgets/total-returns/package.json b/projects/packages/premium-analytics/widgets/total-returns/package.json index 46cffa99f497..2b6ea9d99ad4 100644 --- a/projects/packages/premium-analytics/widgets/total-returns/package.json +++ b/projects/packages/premium-analytics/widgets/total-returns/package.json @@ -7,7 +7,7 @@ "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" } } diff --git a/projects/packages/premium-analytics/widgets/total-returns/render.tsx b/projects/packages/premium-analytics/widgets/total-returns/render.tsx index 699fd7a3dbda..80fd13bb4ad0 100644 --- a/projects/packages/premium-analytics/widgets/total-returns/render.tsx +++ b/projects/packages/premium-analytics/widgets/total-returns/render.tsx @@ -17,7 +17,7 @@ import type { ComponentProps } from 'react'; // also pass them via `attributes`. Compose the render-only shape to cover both. type TotalReturnsRenderAttributes = TotalReturnsAttributes & Partial< ReportParamsFieldAttributes >; -type TotalReturnsRenderProps = WidgetRenderProps< TotalReturnsRenderAttributes > & { +type TotalReturnsWidgetProps = WidgetRenderProps< TotalReturnsRenderAttributes > & { setError?: ComponentProps< typeof WidgetRoot >[ 'setError' ]; }; @@ -27,11 +27,14 @@ type TotalReturnsRenderProps = WidgetRenderProps< TotalReturnsRenderAttributes > * Thin composition over the widgets-toolkit: WidgetRoot provides the query * client, chart theme, and resolved report params; TotalReturnsWidget renders * refunds and net sales for the selected period. + * + * @param {TotalReturnsWidgetProps} props - The widget render props. + * @return The rendered widget. */ export default function TotalReturnsRender( { attributes = {}, setError, -}: TotalReturnsRenderProps ) { +}: TotalReturnsWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/total-returns/stories/total-returns-widget.stories.tsx b/projects/packages/premium-analytics/widgets/total-returns/stories/total-returns-widget.stories.tsx index 355facba92bf..49625c08f090 100644 --- a/projects/packages/premium-analytics/widgets/total-returns/stories/total-returns-widget.stories.tsx +++ b/projects/packages/premium-analytics/widgets/total-returns/stories/total-returns-widget.stories.tsx @@ -19,15 +19,15 @@ const TOTAL_RETURNS_RENDER_MODULE = 'storybook/total-returns'; const DEFAULT_PRESET = 'last-30-days' satisfies SelectablePresetId; const PRESET_OPTIONS = SELECTABLE_PRESETS; -type TotalReturnsRenderProps = ComponentProps< typeof TotalReturnsRender >; -const noopSetError: TotalReturnsRenderProps[ 'setError' ] = () => undefined; +type TotalReturnsWidgetProps = ComponentProps< typeof TotalReturnsRender >; +const noopSetError: TotalReturnsWidgetProps[ 'setError' ] = () => undefined; interface TotalReturnsStoryControls { withComparison: boolean; preset: SelectablePresetId; } -type TotalReturnsStoryProps = TotalReturnsRenderProps & TotalReturnsStoryControls; +type TotalReturnsStoryProps = TotalReturnsWidgetProps & TotalReturnsStoryControls; interface TotalReturnsDashboardStoryProps extends WidgetDashboardWithWidgetControls, @@ -42,7 +42,7 @@ const withWidgetCanvas: Decorator = Story => ( function getTotalReturnsAttributes( withComparison = false, preset: SelectablePresetId = DEFAULT_PRESET -): TotalReturnsRenderProps[ 'attributes' ] { +): TotalReturnsWidgetProps[ 'attributes' ] { return { reportParams: getDefaultQueryParams( withComparison, preset ), }; diff --git a/projects/packages/premium-analytics/widgets/total-returns/widget.json b/projects/packages/premium-analytics/widgets/total-returns/widget.json index 7ce3e8c031f2..736f0cacb965 100644 --- a/projects/packages/premium-analytics/widgets/total-returns/widget.json +++ b/projects/packages/premium-analytics/widgets/total-returns/widget.json @@ -2,5 +2,6 @@ "name": "jpa/total-returns", "title": "Total returns", "description": "Shows refunds and net sales over the selected time period.", - "category": "store" + "category": "store", + "presentation": "framed" } diff --git a/projects/packages/premium-analytics/widgets/total-sales-over-time/package.json b/projects/packages/premium-analytics/widgets/total-sales-over-time/package.json index 4d9349a70384..1794a524ffda 100644 --- a/projects/packages/premium-analytics/widgets/total-sales-over-time/package.json +++ b/projects/packages/premium-analytics/widgets/total-sales-over-time/package.json @@ -7,7 +7,7 @@ "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" } } diff --git a/projects/packages/premium-analytics/widgets/total-sales-over-time/render.tsx b/projects/packages/premium-analytics/widgets/total-sales-over-time/render.tsx index 7e030cfd33bc..64995e04f493 100644 --- a/projects/packages/premium-analytics/widgets/total-sales-over-time/render.tsx +++ b/projects/packages/premium-analytics/widgets/total-sales-over-time/render.tsx @@ -18,7 +18,7 @@ import type { ComponentProps } from 'react'; type TotalSalesOverTimeRenderAttributes = TotalSalesOverTimeAttributes & Partial< ReportParamsFieldAttributes >; -type TotalSalesOverTimeRenderProps = WidgetRenderProps< TotalSalesOverTimeRenderAttributes > & { +type TotalSalesOverTimeWidgetProps = WidgetRenderProps< TotalSalesOverTimeRenderAttributes > & { setError?: ComponentProps< typeof WidgetRoot >[ 'setError' ]; }; @@ -28,11 +28,14 @@ type TotalSalesOverTimeRenderProps = WidgetRenderProps< TotalSalesOverTimeRender * Thin composition over the widgets-toolkit: WidgetRoot provides the query * client, chart theme, and resolved report params; OrderMetricWidget fetches * the orders report and renders total sales over time. + * + * @param {TotalSalesOverTimeWidgetProps} props - The widget render props. + * @return The rendered widget. */ export default function TotalSalesOverTimeRender( { attributes = {}, setError, -}: TotalSalesOverTimeRenderProps ) { +}: TotalSalesOverTimeWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/total-sales-over-time/stories/total-sales-over-time-widget.stories.tsx b/projects/packages/premium-analytics/widgets/total-sales-over-time/stories/total-sales-over-time-widget.stories.tsx index 7ab4071cbcda..b5ac23369dc8 100644 --- a/projects/packages/premium-analytics/widgets/total-sales-over-time/stories/total-sales-over-time-widget.stories.tsx +++ b/projects/packages/premium-analytics/widgets/total-sales-over-time/stories/total-sales-over-time-widget.stories.tsx @@ -22,14 +22,14 @@ const ensureLineChartComposition = () => LineChart.Legend; const DEFAULT_PRESET = 'last-30-days' satisfies SelectablePresetId; const PRESET_OPTIONS = SELECTABLE_PRESETS; -type TotalSalesOverTimeRenderProps = ComponentProps< typeof TotalSalesOverTimeRender >; +type TotalSalesOverTimeWidgetProps = ComponentProps< typeof TotalSalesOverTimeRender >; interface TotalSalesOverTimeStoryControls { withComparison: boolean; preset: SelectablePresetId; } -type TotalSalesOverTimeStoryProps = TotalSalesOverTimeRenderProps & TotalSalesOverTimeStoryControls; +type TotalSalesOverTimeStoryProps = TotalSalesOverTimeWidgetProps & TotalSalesOverTimeStoryControls; interface TotalSalesOverTimeDashboardStoryProps extends WidgetDashboardWithWidgetControls, @@ -44,7 +44,7 @@ const withWidgetCanvas: Decorator = Story => ( function getTotalSalesOverTimeAttributes( withComparison = false, preset: SelectablePresetId = DEFAULT_PRESET -): TotalSalesOverTimeRenderProps[ 'attributes' ] { +): TotalSalesOverTimeWidgetProps[ 'attributes' ] { return { reportParams: getDefaultQueryParams( withComparison, preset ), }; diff --git a/projects/packages/premium-analytics/widgets/total-sales-over-time/widget.json b/projects/packages/premium-analytics/widgets/total-sales-over-time/widget.json index 06a13065fc2b..127b859446f0 100644 --- a/projects/packages/premium-analytics/widgets/total-sales-over-time/widget.json +++ b/projects/packages/premium-analytics/widgets/total-sales-over-time/widget.json @@ -2,5 +2,6 @@ "name": "jpa/total-sales-over-time", "title": "Total sales over time", "description": "Track total sales including all orders and transactions.", - "category": "store" + "category": "store", + "presentation": "framed" } diff --git a/projects/packages/premium-analytics/widgets/traffic-chart/package.json b/projects/packages/premium-analytics/widgets/traffic-chart/package.json index 9d146f806589..5ff9b4eb00b2 100644 --- a/projects/packages/premium-analytics/widgets/traffic-chart/package.json +++ b/projects/packages/premium-analytics/widgets/traffic-chart/package.json @@ -6,12 +6,10 @@ "dependencies": { "@jetpack-premium-analytics/data": "link:../../packages/data", "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", - "@wordpress/components": "36.1.0", "@wordpress/element": "8.2.0", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", - "@wordpress/ui": "0.17.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" } } diff --git a/projects/packages/premium-analytics/widgets/traffic-chart/render.tsx b/projects/packages/premium-analytics/widgets/traffic-chart/render.tsx index c86d45b4cd90..0a72b1ae4b2e 100644 --- a/projects/packages/premium-analytics/widgets/traffic-chart/render.tsx +++ b/projects/packages/premium-analytics/widgets/traffic-chart/render.tsx @@ -8,20 +8,21 @@ import { useWidgetRootContext, type ReportParamsFieldAttributes, } from '@jetpack-premium-analytics/widgets-toolkit'; -import { SelectControl } from '@wordpress/components'; -import { useCallback, useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ import styles from './style.module.css'; import useTrafficChart, { type TrafficPeriod } from './use-traffic-chart'; +import type { TrafficChartAttributes, TrafficChartGranularity } from './widget'; import type { WidgetRenderProps } from '@wordpress/widget-primitives'; import type { ComponentProps } from 'react'; -// The widget has no own attributes; report params arrive from the host (or -// WidgetRoot's URL fallback), so the render shape is host fields only. -type TrafficChartRenderProps = WidgetRenderProps< Partial< ReportParamsFieldAttributes > > & { +type TrafficChartRenderAttributes = TrafficChartAttributes & Partial< ReportParamsFieldAttributes >; +type TrafficChartWidgetProps = WidgetRenderProps< TrafficChartRenderAttributes > & { + /** + * Host callback to surface a widget error in the dashboard frame. + */ setError?: ComponentProps< typeof WidgetRoot >[ 'setError' ]; }; @@ -31,7 +32,7 @@ const DATA_FORMAT = { }; /** - * Default granularity for the dashboard interval: opens the dropdown at the + * Default granularity for the dashboard interval: opens the control at the * granularity the range implies (and, until the user picks one explicitly, * keeps following the range). The dropdown only offers day/week/month, so * finer/coarser dashboard intervals collapse onto those. @@ -52,32 +53,31 @@ function defaultPeriodForInterval( interval?: string ): TrafficPeriod { } } +type TrafficChartInnerProps = { + /** + * Selected granularity; `auto` follows the dashboard range. + */ + granularity: TrafficChartGranularity; +}; + /** * Traffic chart inner component. Reads the dashboard date range + comparison - * state from `useWidgetRootContext()`, owns the granularity dropdown (which only - * chooses the bucket size within that range), and hands the per-metric tabs - * (Views, Visitors, Likes, Comments) to the shared `MetricTabsChart`. + * state from `useWidgetRootContext()` and hands the per-metric tabs (Views, + * Visitors, Likes, Comments) to the shared `MetricTabsChart`. The "Group by" + * control is the `granularity` attribute (`relevance: 'high'`), rendered by + * the widget host; it only chooses the bucket size within the dashboard range. * + * @param {TrafficChartInnerProps} props - The component props. * @return The widget body. */ -function TrafficChartInner() { +function TrafficChartInner( { granularity }: TrafficChartInnerProps ) { const { reportParams } = useWidgetRootContext(); - // `null` means "follow the dashboard range"; a value is an explicit user - // override that then sticks across range changes, so a wide range doesn't - // stay stuck on `day` granularity (and blow up the bucket count) while the - // user hasn't picked a granularity themselves. - const [ periodOverride, setPeriodOverride ] = useState< TrafficPeriod | null >( null ); - const period = periodOverride ?? defaultPeriodForInterval( reportParams.interval ); - const handlePeriodChange = useCallback( - ( value: string ) => setPeriodOverride( value as TrafficPeriod ), - [] - ); - - const periodOptions = [ - { label: __( 'Days', 'jetpack-premium-analytics' ), value: 'day' }, - { label: __( 'Weeks', 'jetpack-premium-analytics' ), value: 'week' }, - { label: __( 'Months', 'jetpack-premium-analytics' ), value: 'month' }, - ]; + // `auto` means "follow the dashboard range"; an explicit value sticks + // across range changes, so a wide range doesn't stay stuck on `day` + // granularity (and blow up the bucket count) while the user hasn't picked + // a granularity themselves. + const period: TrafficPeriod = + granularity === 'auto' ? defaultPeriodForInterval( reportParams.interval ) : granularity; const { metrics, isFetching, isError, error, refetch } = useTrafficChart( reportParams, period ); @@ -93,18 +93,6 @@ function TrafficChartInner() { dataFormat={ DATA_FORMAT } loading={ isFetching } groupLabel={ __( 'Traffic metric', 'jetpack-premium-analytics' ) } - controls={ - - } />
); @@ -114,18 +102,19 @@ function TrafficChartInner() { * Widget render entry point. * * `WidgetRoot` provides the analytics query client and resolves the dashboard's - * report params (date range + comparison); the inner component reads them from - * context and fetches the traffic series. + * `reportParams`; the inner component reads that range/comparison state. The + * granularity is the `granularity` attribute (`relevance: 'high'`), exposed as + * a control by the widget host. * - * @param props - Render props supplied by the widget host. - * @param props.attributes - Widget attributes; the date range/comparison arrive here from the host. - * @param props.setError - Host callback to surface a widget error in the dashboard frame. + * @param {TrafficChartWidgetProps} props - The widget render props. * @return The rendered widget. */ -export default function TrafficChart( { attributes = {}, setError }: TrafficChartRenderProps ) { +export default function TrafficChart( { attributes = {}, setError }: TrafficChartWidgetProps ) { + const granularity = attributes.granularity ?? 'auto'; + return ( - + ); } diff --git a/projects/packages/premium-analytics/widgets/traffic-chart/stories/traffic-chart-widget.stories.tsx b/projects/packages/premium-analytics/widgets/traffic-chart/stories/traffic-chart-widget.stories.tsx index 903d060363b7..75bb13d4752f 100644 --- a/projects/packages/premium-analytics/widgets/traffic-chart/stories/traffic-chart-widget.stories.tsx +++ b/projects/packages/premium-analytics/widgets/traffic-chart/stories/traffic-chart-widget.stories.tsx @@ -47,7 +47,7 @@ const meta = { docs: { description: { component: - 'Traffic over the selected period as selectable metric tabs — Views, Visitors, Likes, and Comments — over a comparative line chart. The date range and comparison come from the dashboard controls; when comparison is on the previous period is overlaid as a same-colour dashed line and each tab shows its period-over-period delta. Views/visitors and likes/comments are fetched as two parallel requests (mirroring Calypso) to keep latency down. Data comes from the `useStatsVisits` hook; in Storybook it is served by `registerReportMocks`.', + 'Traffic over the selected period as selectable metric tabs — Views, Visitors, Likes, and Comments — over a comparative line chart. The date range and comparison come from the dashboard controls; the "Group by" control is the `granularity` attribute (`relevance: \'high\'`), exposed by the widget host, and chooses the bucket size within that range. When comparison is on the previous period is overlaid as a same-colour dashed line and each tab shows its period-over-period delta. Views/visitors and likes/comments are fetched as two parallel requests (mirroring Calypso) to keep latency down. Data comes from the `useStatsVisits` hook; in Storybook it is served by `registerReportMocks`.', }, }, }, diff --git a/projects/packages/premium-analytics/widgets/traffic-chart/style.module.css b/projects/packages/premium-analytics/widgets/traffic-chart/style.module.css index fc73c3222af9..43e0770b2062 100644 --- a/projects/packages/premium-analytics/widgets/traffic-chart/style.module.css +++ b/projects/packages/premium-analytics/widgets/traffic-chart/style.module.css @@ -7,10 +7,6 @@ overflow: hidden; } -.periodSelect { - flex-shrink: 0; -} - /* Constrain the picker preview tile to a 4:3 aspect ratio. The picker's * .preview wrapper uses height: 125% of an auto-height parent, so height: 100% * on .root also resolves to auto, leaving aspect-ratio with no anchor. diff --git a/projects/packages/premium-analytics/widgets/traffic-chart/widget.ts b/projects/packages/premium-analytics/widgets/traffic-chart/widget.ts index 5fe18bd723c3..4b141812ea87 100644 --- a/projects/packages/premium-analytics/widgets/traffic-chart/widget.ts +++ b/projects/packages/premium-analytics/widgets/traffic-chart/widget.ts @@ -3,15 +3,36 @@ */ import { __ } from '@wordpress/i18n'; import { chartBar } from '@wordpress/icons'; +import type { WidgetAttributeField } from '@wordpress/widget-primitives'; + +/** + * Granularity the chart can be grouped by. `auto` follows the dashboard date + * range (a wide range buckets by month, a narrow one by day); an explicit + * value sticks across range changes. + */ +export type TrafficChartGranularity = 'auto' | 'day' | 'week' | 'month'; + +/** + * Configurable attributes for the Traffic chart widget. Report params still + * reach it through WidgetRoot: the dashboard date range, or + * `attributes.reportParams` when a host injects them (e.g. Storybook and + * dashboard previews). + * + * @property granularity - Bucket size within the dashboard range. Defaults to `auto`. + */ +export type TrafficChartAttributes = { + granularity?: TrafficChartGranularity; +}; /** * Widget type definition. * * Ported from the Jetpack Stats `stats-chart-tabs` card in wp-calypso (the chart * above the Traffic page). Renders the selected period's Views, Visitors, Likes, - * and Comments as selectable metric tabs over a comparative line chart. It exposes - * no configurable attributes — the date range and comparison state come from the - * dashboard via `reportParams`, not persisted attributes. + * and Comments as selectable metric tabs over a comparative line chart. The date + * range and comparison state come from the dashboard via `reportParams`; the + * `granularity` attribute (`relevance: 'high'`) chooses the bucket size within + * that range. */ export default { name: 'jpa/traffic-chart', @@ -21,4 +42,35 @@ export default { 'jetpack-premium-analytics' ), icon: chartBar, + attributes: [ + { + id: 'granularity', + label: __( 'Group by', 'jetpack-premium-analytics' ), + type: 'text', + elements: [ + { + label: __( 'Auto', 'jetpack-premium-analytics' ), + value: 'auto', + }, + { + label: __( 'By days', 'jetpack-premium-analytics' ), + value: 'day', + }, + { + label: __( 'By weeks', 'jetpack-premium-analytics' ), + value: 'week', + }, + { + label: __( 'By months', 'jetpack-premium-analytics' ), + value: 'month', + }, + ], + relevance: 'high', + }, + ] as WidgetAttributeField< TrafficChartAttributes >[], + example: { + attributes: { + granularity: 'auto', + }, + }, }; diff --git a/projects/packages/premium-analytics/widgets/utm-insights/package.json b/projects/packages/premium-analytics/widgets/utm-insights/package.json index 9f97d91cb523..0ef08d7e9a43 100644 --- a/projects/packages/premium-analytics/widgets/utm-insights/package.json +++ b/projects/packages/premium-analytics/widgets/utm-insights/package.json @@ -6,11 +6,10 @@ "dependencies": { "@jetpack-premium-analytics/data": "link:../../packages/data", "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", - "@wordpress/components": "36.1.0", "@wordpress/element": "8.2.0", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", "@wordpress/ui": "0.17.0", - "@wordpress/widget-primitives": "next" + "@wordpress/widget-primitives": "0.2.0" } } diff --git a/projects/packages/premium-analytics/widgets/utm-insights/render.tsx b/projects/packages/premium-analytics/widgets/utm-insights/render.tsx index 95e857935e5b..83859c83db90 100644 --- a/projects/packages/premium-analytics/widgets/utm-insights/render.tsx +++ b/projects/packages/premium-analytics/widgets/utm-insights/render.tsx @@ -1,8 +1,7 @@ /** * WordPress dependencies */ -import { SelectControl } from '@wordpress/components'; -import { useCallback, useEffect, useMemo, useState } from '@wordpress/element'; +import { useEffect, useMemo } from '@wordpress/element'; import { __, sprintf } from '@wordpress/i18n'; import { Stack, Text } from '@wordpress/ui'; import { @@ -29,71 +28,49 @@ import type { StatsUtmParam } from '@jetpack-premium-analytics/data'; import type { WidgetRenderProps } from '@wordpress/widget-primitives'; type UtmInsightsRenderAttributes = UtmInsightsAttributes & Partial< ReportParamsFieldAttributes >; +type UtmInsightsWidgetProps = WidgetRenderProps< UtmInsightsRenderAttributes >; const DATA_FORMAT = { type: 'number' as const, options: { useMultipliers: true, decimals: 0 } }; -const DEFAULT_UTM_PARAM: StatsUtmParam = 'utm_source,utm_medium'; - -const UTM_PARAM_OPTIONS: { label: string; value: StatsUtmParam }[] = [ - { - label: __( 'Source / Medium', 'jetpack-premium-analytics' ), - value: 'utm_source,utm_medium', - }, - { - label: __( 'Campaign / Source / Medium', 'jetpack-premium-analytics' ), - value: 'utm_campaign,utm_source,utm_medium', - }, - { label: __( 'Source', 'jetpack-premium-analytics' ), value: 'utm_source' }, - { label: __( 'Medium', 'jetpack-premium-analytics' ), value: 'utm_medium' }, - { label: __( 'Campaign', 'jetpack-premium-analytics' ), value: 'utm_campaign' }, -]; +const DEFAULT_UTM_DIMENSION: StatsUtmParam = 'utm_source,utm_medium'; type UtmInsightsInnerProps = { - utmParam: StatsUtmParam; + /** + * Active UTM dimension. + */ + utmDimension: StatsUtmParam; + /** + * Max rows to display. + */ max: number; - setAttributes?: NonNullable< - WidgetRenderProps< UtmInsightsRenderAttributes >[ 'setAttributes' ] - >; }; /** * Inner component — rendered inside WidgetRoot. * - * @param props - Props. - * @param props.utmParam - Active UTM dimension. - * @param props.max - Max rows to display. - * @param props.setAttributes - Optional widget attribute setter (persists utmParam selection). + * @param {UtmInsightsInnerProps} props - The component props. * @return The rendered leaderboard or state placeholder. */ -function UtmInsightsInner( { utmParam, max, setAttributes }: UtmInsightsInnerProps ) { +function UtmInsightsInner( { utmDimension, max }: UtmInsightsInnerProps ) { const { reportParams } = useWidgetRootContext(); - const [ activeUtmParam, setActiveUtmParam ] = useState< StatsUtmParam >( utmParam ); const { drillDownItem: selectedUtmLabel, drillDown: selectUtmLabel, resetDrillDown: clearSelectedUtm, } = useWidgetDrillDown< string >(); + // The "UTM parameter" control lives in the widget host header (the + // `relevance: 'high'` attribute); changing it resets any drill-down. useEffect( () => { - setActiveUtmParam( utmParam ); clearSelectedUtm(); - }, [ clearSelectedUtm, utmParam ] ); - - const handleParamChange = useCallback( - ( value: string ) => { - const nextUtmParam = value as StatsUtmParam; - clearSelectedUtm(); - setActiveUtmParam( nextUtmParam ); - setAttributes?.( { utmParam: nextUtmParam } ); - }, - [ clearSelectedUtm, setAttributes ] - ); + }, [ clearSelectedUtm, utmDimension ] ); const { data, hasComparison, isLoading, isFetching, hasData, isError } = useUtmInsights( { reportParams, - utmParam: activeUtmParam, + utmParam: utmDimension, max, } ); + const showLoading = isLoading || ( isFetching && hasData ); const selectedUtm = useMemo( () => data.find( item => item.label === selectedUtmLabel ) ?? null, @@ -146,45 +123,29 @@ function UtmInsightsInner( { utmParam, max, setAttributes }: UtmInsightsInnerPro /> ) : null; - const bodyHeader = ( - - { backLink } - - - ); - if ( isError ) { return ( -
- { bodyHeader } + <> + { backLink } { __( 'Could not load UTM data.', 'jetpack-premium-analytics' ) } -
+ ); } if ( isLoading && data.length === 0 ) { return ( -
- { bodyHeader } + <> + { backLink } -
+ ); } return ( -
- { bodyHeader } + <> + { backLink } -
+ ); } @@ -202,25 +164,20 @@ function UtmInsightsInner( { utmParam, max, setAttributes }: UtmInsightsInnerPro * UTM Insights widget render component. * * Shows traffic breakdown by UTM parameter as a ranked leaderboard. The active - * dimension (source/medium, campaign, etc.) is switched via a dropdown in the - * widget header and persisted in widget attributes. + * dimension (source/medium, campaign, etc.) is the `utmDimension` attribute + * (`relevance: 'high'`), exposed as a control by the widget host. * - * @param props - Render props. - * @param props.attributes - Widget attributes (utmParam, max). - * @param props.setAttributes - Attribute setter. + * @param {UtmInsightsWidgetProps} props - The widget render props. * @return The rendered widget content. */ -export default function UtmInsightsWidget( { - attributes = {}, - setAttributes, -}: WidgetRenderProps< UtmInsightsRenderAttributes > ) { - const utmParam = attributes.utmParam ?? DEFAULT_UTM_PARAM; +export default function UtmInsightsWidget( { attributes = {} }: UtmInsightsWidgetProps ) { + const utmDimension = attributes.utmDimension ?? DEFAULT_UTM_DIMENSION; const max = attributes.max ?? 10; return (
- +
); diff --git a/projects/packages/premium-analytics/widgets/utm-insights/stories/utm-insights-widget.stories.tsx b/projects/packages/premium-analytics/widgets/utm-insights/stories/utm-insights-widget.stories.tsx index 5880e619840c..5420bbad57ea 100644 --- a/projects/packages/premium-analytics/widgets/utm-insights/stories/utm-insights-widget.stories.tsx +++ b/projects/packages/premium-analytics/widgets/utm-insights/stories/utm-insights-widget.stories.tsx @@ -68,7 +68,7 @@ export const Default: Story = { render: ( { withComparison } ) => ( ( ( > } attributes={ { - utmParam: 'utm_source,utm_medium', + utmDimension: 'utm_source,utm_medium', max: 10, reportParams: getDefaultQueryParams( withComparison ), } } diff --git a/projects/packages/premium-analytics/widgets/utm-insights/style.module.css b/projects/packages/premium-analytics/widgets/utm-insights/style.module.css index 1363ac3032b5..65780576b662 100644 --- a/projects/packages/premium-analytics/widgets/utm-insights/style.module.css +++ b/projects/packages/premium-analytics/widgets/utm-insights/style.module.css @@ -15,22 +15,17 @@ text-align: center; } -.paramSelect { - order: 2; - flex: 0 1 280px; - inline-size: min(100%, 280px); - max-inline-size: 100%; - min-inline-size: min(100%, 220px); -} - .backLink { - order: 1; - align-self: center; + align-self: flex-start; min-inline-size: 0; - margin-inline-end: auto; margin-block-end: 0; } +.leaderboard { + flex: 1 1 0; + min-block-size: 0; +} + .itemLabel { min-inline-size: 0; padding-block: var(--wpds-dimension-padding-md, 12px); @@ -43,37 +38,3 @@ white-space: nowrap; text-overflow: ellipsis; } - -.content { - position: relative; - display: flex; - flex-direction: column; - flex: 1 1 0; - min-height: 0; -} - -.bodyHeader { - position: relative; - z-index: 2; - flex-wrap: wrap; - justify-content: flex-end; - gap: var(--wpds-dimension-gap-sm, 8px) var(--wpds-dimension-gap-lg, 16px); - margin-block-end: var(--wpds-dimension-gap-md, 12px); -} - -@container (max-width: 479px) { - - .bodyHeader { - align-items: stretch; - } - - .backLink { - order: 2; - } - - .paramSelect { - order: 1; - flex-basis: 100%; - inline-size: 100%; - } -} diff --git a/projects/packages/premium-analytics/widgets/utm-insights/use-utm-insights.ts b/projects/packages/premium-analytics/widgets/utm-insights/use-utm-insights.ts index 24f13c26a681..f8d304f74ee7 100644 --- a/projects/packages/premium-analytics/widgets/utm-insights/use-utm-insights.ts +++ b/projects/packages/premium-analytics/widgets/utm-insights/use-utm-insights.ts @@ -23,8 +23,17 @@ export interface UtmInsightsRow { } interface UseUtmInsightsArgs { + /** + * PA ReportParams injected by the host via attributes. + */ reportParams: ReportParams; + /** + * UTM dimension to break down by. + */ utmParam: StatsUtmParam; + /** + * Maximum rows to display (0 = all). + */ max: number; } @@ -48,10 +57,7 @@ function getChildKey( item: StatsUtmTopPostItem ): string { /** * Fetch UTM insights for the UTM Insights widget via the shared Stats data layer. * - * @param args - Hook arguments. - * @param args.reportParams - PA ReportParams injected by the host via attributes. - * @param args.utmParam - UTM dimension to break down by. - * @param args.max - Maximum rows to display (0 = all). + * @param {UseUtmInsightsArgs} args - Hook arguments. * @return The current data/loading/error state. */ export default function useUtmInsights( { diff --git a/projects/packages/premium-analytics/widgets/utm-insights/widget.ts b/projects/packages/premium-analytics/widgets/utm-insights/widget.ts index 47ee3c40b0cf..b1029d05859e 100644 --- a/projects/packages/premium-analytics/widgets/utm-insights/widget.ts +++ b/projects/packages/premium-analytics/widgets/utm-insights/widget.ts @@ -3,6 +3,7 @@ */ import { __ } from '@wordpress/i18n'; import { trendingUp } from '@wordpress/icons'; +import type { WidgetAttributeField } from '@wordpress/widget-primitives'; /** * Internal dependencies */ @@ -11,11 +12,11 @@ import type { StatsUtmParam } from '@jetpack-premium-analytics/data'; /** * Widget attributes shape. * - * @property utmParam - UTM dimension to break down by. Defaults to 'utm_source,utm_medium'. - * @property max - Maximum rows to display (0 = all). Defaults to 10. + * @property utmDimension - UTM dimension to break down by. Defaults to 'utm_source,utm_medium'. + * @property max - Maximum rows to display (0 = all). Defaults to 10. */ export type UtmInsightsAttributes = { - utmParam?: StatsUtmParam; + utmDimension?: StatsUtmParam; max?: number; }; @@ -23,10 +24,10 @@ export type UtmInsightsAttributes = { * UTM Insights widget type definition. * * Shows traffic breakdown by UTM parameter via the PA proxy at - * `stats/utm/{utmParam}`. The active dimension is stored in widget - * attributes so it persists per widget instance across sessions. - * Date range comes from WidgetRoot's reportParams (the shared - * dashboard date picker). + * `stats/utm/{utmParam}`. The active dimension is the `utmDimension` + * attribute (`relevance: 'high'`), so the widget host renders its + * control. Date range comes from WidgetRoot's reportParams (the + * shared dashboard date picker). */ export default { name: 'jpa/utm-insights', @@ -34,19 +35,42 @@ export default { icon: trendingUp, attributes: [ { - id: 'utmParam', + id: 'utmDimension', label: __( 'UTM parameter', 'jetpack-premium-analytics' ), - type: 'string', + type: 'text', + elements: [ + { + label: __( 'Source / Medium', 'jetpack-premium-analytics' ), + value: 'utm_source,utm_medium', + }, + { + label: __( 'Campaign / Source / Medium', 'jetpack-premium-analytics' ), + value: 'utm_campaign,utm_source,utm_medium', + }, + { + label: __( 'Source', 'jetpack-premium-analytics' ), + value: 'utm_source', + }, + { + label: __( 'Medium', 'jetpack-premium-analytics' ), + value: 'utm_medium', + }, + { + label: __( 'Campaign', 'jetpack-premium-analytics' ), + value: 'utm_campaign', + }, + ], + relevance: 'high', }, { id: 'max', label: __( 'Max rows', 'jetpack-premium-analytics' ), type: 'number', }, - ], + ] as WidgetAttributeField< UtmInsightsAttributes >[], example: { attributes: { - utmParam: 'utm_source,utm_medium', + utmDimension: 'utm_source,utm_medium', max: 10, }, }, diff --git a/projects/packages/premium-analytics/widgets/videos/__tests__/build-video-plays-data.test.ts b/projects/packages/premium-analytics/widgets/videos/__tests__/build-video-plays-data.test.ts index 85dfb29bb0c0..93f463772a06 100644 --- a/projects/packages/premium-analytics/widgets/videos/__tests__/build-video-plays-data.test.ts +++ b/projects/packages/premium-analytics/widgets/videos/__tests__/build-video-plays-data.test.ts @@ -5,20 +5,28 @@ import { buildVideoPlaysData } from '../build-video-plays-data'; import type { StatsNormalizedReport, StatsVideoPlaysItem } from '@jetpack-premium-analytics/data'; type VideoSeed = { + /** + * Stable post ID (omitted when testing the link/label fallback). + */ id?: string | number; + /** + * Display label (defaults to `Video`). + */ label?: string; + /** + * Play count for the period. + */ plays: number; + /** + * Video URL (used as the alignment key when `id` is absent). + */ link?: string | null; }; /** * Builds a single normalized video-plays item from a compact seed. * - * @param seed - The video seed. - * @param seed.id - Stable post ID (omitted when testing the link/label fallback). - * @param seed.label - Display label (defaults to `Video`). - * @param seed.plays - Play count for the period. - * @param seed.link - Video URL (used as the alignment key when `id` is absent). + * @param {VideoSeed} seed - The video seed. * @return A normalized video-plays item. */ function makeVideo( { id, label = 'Video', plays, link = null }: VideoSeed ): StatsVideoPlaysItem { diff --git a/projects/packages/premium-analytics/widgets/videos/package.json b/projects/packages/premium-analytics/widgets/videos/package.json index 952501c4e082..afc7fe233738 100644 --- a/projects/packages/premium-analytics/widgets/videos/package.json +++ b/projects/packages/premium-analytics/widgets/videos/package.json @@ -8,7 +8,7 @@ "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" } } diff --git a/projects/packages/premium-analytics/widgets/videos/render.tsx b/projects/packages/premium-analytics/widgets/videos/render.tsx index d9d3ee2eddc6..385ce9b457f0 100644 --- a/projects/packages/premium-analytics/widgets/videos/render.tsx +++ b/projects/packages/premium-analytics/widgets/videos/render.tsx @@ -30,7 +30,10 @@ const DEFAULT_MAX = 7; // `reportParams`; the widget's own settings come from `VideosAttributes`. type VideosRenderAttributes = VideosAttributes & Partial< ReportParamsFieldAttributes >; -type VideosRenderProps = WidgetRenderProps< VideosRenderAttributes > & { +type VideosWidgetProps = WidgetRenderProps< VideosRenderAttributes > & { + /** + * Dashboard error handler. + */ setError?: ComponentProps< typeof WidgetRoot >[ 'setError' ]; }; @@ -73,12 +76,7 @@ type VideosLeaderboardProps = { * played videos and is responsible only for the loading, empty, and populated * states. * - * @param props - Component props. - * @param props.data - Leaderboard rows to render. - * @param props.isLoading - Whether to render the initial loading overlay. - * @param props.isRefetching - Whether to layer a loading overlay over the chart. - * @param props.withComparison - Whether to render previous-period deltas. - * @param props.legendLabels - Custom labels for the current/comparison periods. + * @param {VideosLeaderboardProps} props - The component props. * @return The rendered leaderboard. */ function VideosLeaderboard( { @@ -113,15 +111,21 @@ function VideosLeaderboard( { ); } +type VideosReportProps = { + /** + * Maximum number of videos to display. + */ + max: number; +}; + /** * Fetches the video-plays report through the Jetpack Stats hook, builds the * leaderboard rows, and hands them to the presentational `VideosLeaderboard`. * - * @param props - Component props. - * @param props.max - Maximum number of videos to display. + * @param {VideosReportProps} props - The component props. * @return The widget content. */ -function VideosReport( { max }: { max: number } ) { +function VideosReport( { max }: VideosReportProps ) { const { reportParams } = useWidgetRootContext(); const statsParams = useMemo( () => ( { ...reportParams, max } ), [ reportParams, max ] ); @@ -174,12 +178,10 @@ function VideosReport( { max }: { max: number } ) { * params consumed by the inner leaderboard — resolved from the dashboard date * range via context, the same way the other Stats widgets read them. * - * @param props - Render props. - * @param props.attributes - Widget attributes. - * @param props.setError - Dashboard error handler. + * @param {VideosWidgetProps} props - The widget render props. * @return The rendered Videos widget. */ -export default function Videos( { attributes = {}, setError }: VideosRenderProps ) { +export default function Videos( { attributes = {}, setError }: VideosWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/videos/stories/videos-widget.stories.tsx b/projects/packages/premium-analytics/widgets/videos/stories/videos-widget.stories.tsx index 1d737eb789d8..b9be2e1c0c49 100644 --- a/projects/packages/premium-analytics/widgets/videos/stories/videos-widget.stories.tsx +++ b/projects/packages/premium-analytics/widgets/videos/stories/videos-widget.stories.tsx @@ -26,6 +26,9 @@ const DEFAULT_MAX = 7; // Widget-specific story control: toggles the previous-period comparison. interface VideosStoryControls { + /** + * Whether to request the previous-period comparison. + */ withComparison: boolean; } @@ -34,8 +37,7 @@ interface VideosStoryControls { * `withComparison` control, so the close-up stories exercise the real data flow * (served by `registerReportMocks`). * - * @param props - Story controls. - * @param props.withComparison - Whether to request the previous-period comparison. + * @param {VideosStoryControls} props - Story controls. * @return The rendered widget. */ function renderVideos( { withComparison }: VideosStoryControls ) { @@ -102,8 +104,7 @@ interface VideosDashboardStoryProps * it appears exactly as it does in product, inheriting the size / edit-mode / * host-environment controls. * - * @param props - Story controls. - * @param props.withComparison - Whether to request the previous-period comparison. + * @param {VideosDashboardStoryProps} props - Story controls. * @return The widget mounted in the dashboard harness. */ function VideosDashboardStory( { withComparison, ...dashboardArgs }: VideosDashboardStoryProps ) { diff --git a/projects/packages/premium-analytics/widgets/videos/widget.ts b/projects/packages/premium-analytics/widgets/videos/widget.ts index c76f5307389e..76dbb946a758 100644 --- a/projects/packages/premium-analytics/widgets/videos/widget.ts +++ b/projects/packages/premium-analytics/widgets/videos/widget.ts @@ -3,6 +3,7 @@ */ import { __ } from '@wordpress/i18n'; import { video } from '@wordpress/icons'; +import type { WidgetAttributeField } from '@wordpress/widget-primitives'; /** * Configurable attributes for the Videos widget. Mirrors the `attributes` @@ -29,9 +30,9 @@ export default { { id: 'max', label: __( 'Maximum videos', 'jetpack-premium-analytics' ), - type: 'integer' as const, + type: 'integer', }, - ], + ] as WidgetAttributeField< VideosAttributes >[], example: { attributes: { max: 7, diff --git a/projects/packages/premium-analytics/widgets/visitors-by-location/package.json b/projects/packages/premium-analytics/widgets/visitors-by-location/package.json index 20048ded1c95..c5fab01e8303 100644 --- a/projects/packages/premium-analytics/widgets/visitors-by-location/package.json +++ b/projects/packages/premium-analytics/widgets/visitors-by-location/package.json @@ -7,7 +7,7 @@ "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" } } diff --git a/projects/packages/premium-analytics/widgets/visitors-by-location/render.tsx b/projects/packages/premium-analytics/widgets/visitors-by-location/render.tsx index ba6dee483e94..3bedae682d3c 100644 --- a/projects/packages/premium-analytics/widgets/visitors-by-location/render.tsx +++ b/projects/packages/premium-analytics/widgets/visitors-by-location/render.tsx @@ -18,7 +18,7 @@ import type { ComponentProps } from 'react'; type VisitorsByLocationRenderAttributes = VisitorsByLocationAttributes & Partial< ReportParamsFieldAttributes >; -type VisitorsByLocationRenderProps = WidgetRenderProps< VisitorsByLocationRenderAttributes > & { +type VisitorsByLocationWidgetProps = WidgetRenderProps< VisitorsByLocationRenderAttributes > & { setError?: ComponentProps< typeof WidgetRoot >[ 'setError' ]; }; @@ -28,11 +28,14 @@ type VisitorsByLocationRenderProps = WidgetRenderProps< VisitorsByLocationRender * Thin composition over the widgets-toolkit: WidgetRoot provides the query * client, chart theme, and resolved report params; VisitorsByLocationWidget * fetches the visitors-by-location reports and renders the location map. + * + * @param {VisitorsByLocationWidgetProps} props - The widget render props. + * @return The rendered widget. */ export default function VisitorsByLocationRender( { attributes = {}, setError, -}: VisitorsByLocationRenderProps ) { +}: VisitorsByLocationWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/visitors-by-location/stories/visitors-by-location-widget.stories.tsx b/projects/packages/premium-analytics/widgets/visitors-by-location/stories/visitors-by-location-widget.stories.tsx index 059260137304..4a3e0ba20a00 100644 --- a/projects/packages/premium-analytics/widgets/visitors-by-location/stories/visitors-by-location-widget.stories.tsx +++ b/projects/packages/premium-analytics/widgets/visitors-by-location/stories/visitors-by-location-widget.stories.tsx @@ -19,14 +19,14 @@ const VISITORS_BY_LOCATION_RENDER_MODULE = 'storybook/visitors-by-location'; const DEFAULT_PRESET = 'last-30-days' satisfies SelectablePresetId; const PRESET_OPTIONS = SELECTABLE_PRESETS; -type VisitorsByLocationRenderProps = ComponentProps< typeof VisitorsByLocationRender >; +type VisitorsByLocationWidgetProps = ComponentProps< typeof VisitorsByLocationRender >; interface VisitorsByLocationStoryControls { withComparison: boolean; preset: SelectablePresetId; } -type VisitorsByLocationStoryProps = VisitorsByLocationRenderProps & VisitorsByLocationStoryControls; +type VisitorsByLocationStoryProps = VisitorsByLocationWidgetProps & VisitorsByLocationStoryControls; interface VisitorsByLocationDashboardStoryProps extends WidgetDashboardWithWidgetControls, @@ -43,7 +43,7 @@ const withWidgetCanvas: Decorator = Story => ( function getVisitorsByLocationAttributes( withComparison = false, preset: SelectablePresetId = DEFAULT_PRESET -): VisitorsByLocationRenderProps[ 'attributes' ] { +): VisitorsByLocationWidgetProps[ 'attributes' ] { return { reportParams: getDefaultQueryParams( withComparison, preset ), }; diff --git a/projects/packages/premium-analytics/widgets/visitors-by-location/widget.json b/projects/packages/premium-analytics/widgets/visitors-by-location/widget.json index 0e0234d2c0cc..84afa6f0684d 100644 --- a/projects/packages/premium-analytics/widgets/visitors-by-location/widget.json +++ b/projects/packages/premium-analytics/widgets/visitors-by-location/widget.json @@ -2,5 +2,6 @@ "name": "jpa/visitors-by-location", "title": "Visitors by location", "description": "See where your store visitors are located geographically.", - "category": "visitors" + "category": "visitors", + "presentation": "framed" } diff --git a/projects/packages/premium-analytics/widgets/visitors-over-time/package.json b/projects/packages/premium-analytics/widgets/visitors-over-time/package.json index 3fb6ed31e53d..945594b6b420 100644 --- a/projects/packages/premium-analytics/widgets/visitors-over-time/package.json +++ b/projects/packages/premium-analytics/widgets/visitors-over-time/package.json @@ -8,7 +8,7 @@ "@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit", "@wordpress/i18n": "^6.9.0", "@wordpress/icons": "^15.0.0", - "@wordpress/widget-primitives": "next", + "@wordpress/widget-primitives": "0.2.0", "react": "18.3.1" } } diff --git a/projects/packages/premium-analytics/widgets/visitors-over-time/render.tsx b/projects/packages/premium-analytics/widgets/visitors-over-time/render.tsx index d95c5c22282e..402b7b681f2a 100644 --- a/projects/packages/premium-analytics/widgets/visitors-over-time/render.tsx +++ b/projects/packages/premium-analytics/widgets/visitors-over-time/render.tsx @@ -18,7 +18,7 @@ import type { ComponentProps } from 'react'; type VisitorsOverTimeRenderAttributes = VisitorsOverTimeAttributes & Partial< ReportParamsFieldAttributes >; -type VisitorsOverTimeRenderProps = WidgetRenderProps< VisitorsOverTimeRenderAttributes > & { +type VisitorsOverTimeWidgetProps = WidgetRenderProps< VisitorsOverTimeRenderAttributes > & { setError?: ComponentProps< typeof WidgetRoot >[ 'setError' ]; }; @@ -28,11 +28,14 @@ type VisitorsOverTimeRenderProps = WidgetRenderProps< VisitorsOverTimeRenderAttr * Thin composition over WidgetRoot: WidgetRoot provides the query client, * chart theme, and resolved report params; VisitorMetricWidget fetches the * visitors report and renders visitor trends over time. + * + * @param {VisitorsOverTimeWidgetProps} props - The widget render props. + * @return The rendered widget. */ export default function VisitorsOverTimeRender( { attributes = {}, setError, -}: VisitorsOverTimeRenderProps ) { +}: VisitorsOverTimeWidgetProps ) { return ( diff --git a/projects/packages/premium-analytics/widgets/visitors-over-time/stories/visitors-over-time-widget.stories.tsx b/projects/packages/premium-analytics/widgets/visitors-over-time/stories/visitors-over-time-widget.stories.tsx index 60c9b7eb23fe..e74072d0202a 100644 --- a/projects/packages/premium-analytics/widgets/visitors-over-time/stories/visitors-over-time-widget.stories.tsx +++ b/projects/packages/premium-analytics/widgets/visitors-over-time/stories/visitors-over-time-widget.stories.tsx @@ -22,15 +22,15 @@ const PRESET_OPTIONS = SELECTABLE_PRESETS; // Static Storybook builds need this source import before ComparativeLineChart reads LineChart.Legend. const ensureLineChartComposition = () => LineChart.Legend; -type VisitorsOverTimeRenderProps = ComponentProps< typeof VisitorsOverTimeRender >; -const noopSetError: VisitorsOverTimeRenderProps[ 'setError' ] = () => {}; +type VisitorsOverTimeWidgetProps = ComponentProps< typeof VisitorsOverTimeRender >; +const noopSetError: VisitorsOverTimeWidgetProps[ 'setError' ] = () => {}; interface VisitorsOverTimeStoryControls { withComparison: boolean; preset: SelectablePresetId; } -type VisitorsOverTimeStoryProps = VisitorsOverTimeRenderProps & VisitorsOverTimeStoryControls; +type VisitorsOverTimeStoryProps = VisitorsOverTimeWidgetProps & VisitorsOverTimeStoryControls; interface VisitorsOverTimeDashboardStoryProps extends WidgetDashboardWithWidgetControls, @@ -45,7 +45,7 @@ const withWidgetCanvas: Decorator = Story => ( function getVisitorsOverTimeAttributes( withComparison = false, preset: SelectablePresetId = DEFAULT_PRESET -): VisitorsOverTimeRenderProps[ 'attributes' ] { +): VisitorsOverTimeWidgetProps[ 'attributes' ] { return { reportParams: getDefaultQueryParams( withComparison, preset ), }; diff --git a/projects/packages/premium-analytics/widgets/visitors-over-time/widget.json b/projects/packages/premium-analytics/widgets/visitors-over-time/widget.json index aea7bd4d73dd..405f264a8481 100644 --- a/projects/packages/premium-analytics/widgets/visitors-over-time/widget.json +++ b/projects/packages/premium-analytics/widgets/visitors-over-time/widget.json @@ -2,5 +2,6 @@ "name": "jpa/visitors-over-time", "title": "Visitors over time", "description": "Track website visitor trends and monitor traffic patterns over time.", - "category": "visitors" + "category": "visitors", + "presentation": "framed" }