From df302595c019214ba0fba41fb48b4fe05dc73804 Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Fri, 31 Jul 2026 22:14:31 -0700 Subject: [PATCH] Upgrade react-zen and migrate attribution and menu controls to updated components --- package.json | 2 +- patches/@umami__react-zen@0.247.0.patch | 74 ------------------- pnpm-lock.yaml | 13 ++-- pnpm-workspace.yaml | 4 +- .../(reports)/attribution/AttributionPage.tsx | 28 +++---- src/components/common/ControlledDialog.tsx | 2 +- src/components/input/TeamsButton.tsx | 55 +++++++------- 7 files changed, 48 insertions(+), 130 deletions(-) delete mode 100644 patches/@umami__react-zen@0.247.0.patch diff --git a/package.json b/package.json index 11310090f..70fb7c4f5 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "@prisma/extension-read-replicas": "^0.5.0", "@svgr/cli": "^8.1.0", "@tanstack/react-query": "^5.101.4", - "@umami/react-zen": "^0.247.0", + "@umami/react-zen": "^0.248.0", "bcryptjs": "^3.0.2", "chalk": "^5.6.2", "chart.js": "^4.5.1", diff --git a/patches/@umami__react-zen@0.247.0.patch b/patches/@umami__react-zen@0.247.0.patch deleted file mode 100644 index 2caf21ae2..000000000 --- a/patches/@umami__react-zen@0.247.0.patch +++ /dev/null @@ -1,74 +0,0 @@ -diff --git a/dist/index.js b/dist/index.js -index 2dd4992d4f033c22be13a8846637d48ef235c57f..cf5264a8ea0b6803b6fb9a950d35e7bd1ed0f959 100644 ---- a/dist/index.js -+++ b/dist/index.js -@@ -6600,6 +6600,23 @@ function SearchField({ - ] }) - ] }); - } -+function getSelectItemLabel(children, selectedValue) { -+ let label; -+ react.Children.forEach(children, (child) => { -+ if (label !== void 0 || !react.isValidElement(child)) { -+ return; -+ } -+ if (child.type === ListItem) { -+ const itemValue = child.props.value ?? child.props.id ?? (typeof child.props.children === "string" ? child.props.children : ""); -+ if (itemValue === selectedValue) { -+ label = child.props.children; -+ } -+ return; -+ } -+ label = getSelectItemLabel(child.props.children, selectedValue); -+ }); -+ return label; -+} - function Select({ - value, - defaultValue, -@@ -6666,7 +6683,7 @@ function Select({ - ), - children: [ - /* @__PURE__ */ jsxRuntime.jsx(select.Select.Value, { placeholder, children: (selected) => { -- const defaultChildren = selected ?? placeholder; -+ const defaultChildren = selected == null ? placeholder : getSelectItemLabel(collection, selected) ?? selected; - return typeof renderValue === "function" ? renderValue({ - defaultChildren, - isPlaceholder: selected == null -diff --git a/dist/index.mjs b/dist/index.mjs -index 448a673d0ef00587ba6a233d5e5f8e99efc8215e..f0c0f4e7a5a9f0e2066225e1598f944fbc033c6e 100644 ---- a/dist/index.mjs -+++ b/dist/index.mjs -@@ -6575,6 +6575,23 @@ function SearchField({ - ] }) - ] }); - } -+function getSelectItemLabel(children, selectedValue) { -+ let label; -+ Children.forEach(children, (child) => { -+ if (label !== void 0 || !isValidElement(child)) { -+ return; -+ } -+ if (child.type === ListItem) { -+ const itemValue = child.props.value ?? child.props.id ?? (typeof child.props.children === "string" ? child.props.children : ""); -+ if (itemValue === selectedValue) { -+ label = child.props.children; -+ } -+ return; -+ } -+ label = getSelectItemLabel(child.props.children, selectedValue); -+ }); -+ return label; -+} - function Select({ - value, - defaultValue, -@@ -6641,7 +6658,7 @@ function Select({ - ), - children: [ - /* @__PURE__ */ jsx(Select$1.Value, { placeholder, children: (selected) => { -- const defaultChildren = selected ?? placeholder; -+ const defaultChildren = selected == null ? placeholder : getSelectItemLabel(collection, selected) ?? selected; - return typeof renderValue === "function" ? renderValue({ - defaultChildren, - isPlaceholder: selected == null diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b61bf9059..0a111a113 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,9 +4,6 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false -patchedDependencies: - '@umami/react-zen@0.247.0': 7a13e402d0a59d203f92fa4c64c8511aa38c5cd914092f5232c6271c606c9126 - importers: .: @@ -39,8 +36,8 @@ importers: specifier: ^5.101.4 version: 5.101.4(react@19.2.8) '@umami/react-zen': - specifier: ^0.247.0 - version: 0.247.0(patch_hash=7a13e402d0a59d203f92fa4c64c8511aa38c5cd914092f5232c6271c606c9126)(@date-fns/tz@1.5.0)(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(date-fns@4.4.0)(immer@11.1.15)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(tailwindcss@4.1.18)(use-sync-external-store@1.6.0(react@19.2.8)) + specifier: ^0.248.0 + version: 0.248.0(@date-fns/tz@1.5.0)(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(date-fns@4.4.0)(immer@11.1.15)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(tailwindcss@4.1.18)(use-sync-external-store@1.6.0(react@19.2.8)) bcryptjs: specifier: ^3.0.2 version: 3.0.3 @@ -2930,8 +2927,8 @@ packages: '@types/yargs@17.0.35': resolution: {integrity: sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==} - '@umami/react-zen@0.247.0': - resolution: {integrity: sha512-3I8kCsSX3DEDX2D0ft+2g9fUdmXm5+BWR6mMkbOxYy9bColbL5gTF7UOcl+wuN4ETOh7bo9Lxk5CM6hDyZX6uA==} + '@umami/react-zen@0.248.0': + resolution: {integrity: sha512-sCEA+nVko+7cETmnmF+HvKyP54Bn/9S0GPexyA7QCDoYITu5X4FS2TT422kKM2UX6eVmuiq8slMdeZfAlUEynw==} peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 @@ -8268,7 +8265,7 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 - '@umami/react-zen@0.247.0(patch_hash=7a13e402d0a59d203f92fa4c64c8511aa38c5cd914092f5232c6271c606c9126)(@date-fns/tz@1.5.0)(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(date-fns@4.4.0)(immer@11.1.15)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(tailwindcss@4.1.18)(use-sync-external-store@1.6.0(react@19.2.8))': + '@umami/react-zen@0.248.0(@date-fns/tz@1.5.0)(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(date-fns@4.4.0)(immer@11.1.15)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(tailwindcss@4.1.18)(use-sync-external-store@1.6.0(react@19.2.8))': dependencies: '@base-ui/react': 1.6.0(@date-fns/tz@1.5.0)(@types/react@19.2.17)(date-fns@4.4.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) '@react-spring/web': 9.7.5(react-dom@19.2.8(react@19.2.8))(react@19.2.8) diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index e4eb84858..162125ee7 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -11,6 +11,4 @@ allowBuilds: prisma: true sharp: false minimumReleaseAgeExclude: - - '@umami/react-zen@0.247.0' -patchedDependencies: - '@umami/react-zen@0.247.0': patches/@umami__react-zen@0.247.0.patch + - '@umami/react-zen' diff --git a/src/app/(main)/websites/[websiteId]/(reports)/attribution/AttributionPage.tsx b/src/app/(main)/websites/[websiteId]/(reports)/attribution/AttributionPage.tsx index fb61610d7..358bb1879 100644 --- a/src/app/(main)/websites/[websiteId]/(reports)/attribution/AttributionPage.tsx +++ b/src/app/(main)/websites/[websiteId]/(reports)/attribution/AttributionPage.tsx @@ -1,12 +1,13 @@ 'use client'; -import { Column, Grid, Label, ListItem, Loading, Select } from '@umami/react-zen'; +import { Column, Grid, ListItem, Select } from '@umami/react-zen'; import { useState } from 'react'; import { WebsiteControls } from '@/app/(main)/websites/[websiteId]/WebsiteControls'; import { Empty } from '@/components/common/Empty'; -import { MultiSelect, MultiSelectItem } from '@/components/common/MultiSelect'; import { useDateRange, useMessages, useWebsiteValuesQuery } from '@/components/hooks'; import { Attribution } from './Attribution'; +const stepPlaceholder = 'Select an item'; + export function AttributionPage({ websiteId }: { websiteId: string }) { const [model, setModel] = useState('first-click'); const [type, setType] = useState('path'); @@ -31,10 +32,6 @@ export function AttributionPage({ websiteId }: { websiteId: string }) { setSearch(''); }; - const handleStepChange = (values: string[]) => { - setStep(values.filter(value => value !== step).pop() ?? ''); - }; - return ( @@ -62,21 +59,24 @@ export function AttributionPage({ websiteId }: { websiteId: string }) { - - setStep(value?.toString() ?? '')} + placeholder={stepPlaceholder} + renderValue={({ defaultChildren }) => (step ? defaultChildren : stepPlaceholder)} + isLoading={isLoading} searchValue={search} onSearch={setSearch} - renderEmptyState={() => (isLoading ? : )} + maxHeight={320} allowSearch > {items.map(({ value }) => ( - + {value} - + ))} - + {step ? ( diff --git a/src/components/common/ControlledDialog.tsx b/src/components/common/ControlledDialog.tsx index 2030bd273..808253761 100644 --- a/src/components/common/ControlledDialog.tsx +++ b/src/components/common/ControlledDialog.tsx @@ -5,7 +5,7 @@ import type { ReactElement } from 'react'; export function ControlledDialog({ children }: { children: ReactElement }) { return ( -