chore(deps): upgrade frappe-ui to 1.0.0-beta.45 - #747
Closed
NagariaHussain wants to merge 15 commits into
Closed
Conversation
Inventory of the 696-commit delta, restricted to what touches wiki: four loud breaks, thirteen silent ones, two non-idempotent codemods, and a phased order that puts the useFileUpload privacy audit first. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Clears every break in the delta that fails the build. - tiptap moves to 3.29.2 as a set. @tiptap/markdown declares exact peers on @tiptap/core and @tiptap/pm at its own version, so a partial bump leaves two cores in the tree. yarn v1 ignores a "@tiptap/**" glob resolution, so all 43 packages are pinned explicitly. - frappe-ui/editor-style.css and frappe-ui/list-style.css are gone. The editor and list barrels self-import their CSS and are marked side-effectful, so the stylesheets ship with the subpath imports. The built output still carries 119 ProseMirror and 36 list-slot rules. - pageMetaPlugin is removed. Nothing declares the pageMeta() option; Spaces.vue already uses usePageMeta. - Alert is redesigned and stateless. It was registered globally with no call sites, so the registration goes rather than the migration. - Autocomplete is removed. AssignDialog used it with `multiple`, so it becomes MultiSelect, whose model is a value array rather than option objects. - tailwind.config.js spreads the preset's own `content` export. The hand-written globs it replaces covered src/components and src/molecules only, dropping every class the editor and list molecules emit. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The named radius aliases are removed in frappe-ui 1.0.0 (ADR-0006). The preset replaces Tailwind's borderRadius scale, so an unmigrated rounded-md emits no CSS at all — square corners, no build error. Applied with `tokens-v2 --radius-only` across the editor SPA and the public reader's Jinja templates: 113 renames over 29 files. --radius-only rather than the full codemod because the color and typography passes already ran during the beta.25 upgrade and neither is idempotent. The three var(--radius-sm|lg) reads are hand-migrated — the codemod only rewrites rounded-* classes, and the alias CSS variables go away with the aliases. Pixel values are identical throughout; this changes vocabulary, not rendering. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The updated espresso v2 export shifts every chromatic ink scale down one level — the new ink-red-1 is the old ink-red-2 — and the scales now end at -9. ink-gray keeps its own 9-step scale and does not shift. Nothing warns: every ink-<family>-N site renders one shade off after the token update, so this lands with the upgrade rather than after it. Applied with `tokens-v2 --ink-shift` over frontend/src and wiki/templates (33 renames, 11 files). The mode has no sentinel it can read back from file content, so it writes a .tokens-v2-ink-shift marker in each target and refuses to run again; the markers are committed so a fresh clone keeps the guard. The six var(--ink-<family>-N) reads in the reader's hand-written CSS are migrated by hand — they sit beside generated files the codemod would rewrite for nothing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
None of these fail the build. Each one renders wrong instead. - Tabs is a composed family now and models the trigger value, not an index, so the index round-trip through the tab query goes away. Composed rather than the `:tabs` shorthand because v1 ships no layout defaults: the panel has to be a constrained flex column for ContributionsPanel to scroll, and generated panels take no classes. - Dropdown ignores `placement` and falls back to align="start", so both right-aligned menus quietly moved left. - PageHeaderMobile's #left/#right are #prefix/#suffix. Vue drops content passed to an unknown slot, so the tree toggle and the two menus just stopped rendering. - Combobox's template ref exposes clear(), not reset(). Audited and unchanged: all three useFileUpload calls already pass `private: false`, so the default flip to private cannot 403 an editor image or a space logo; Select's trigger slot is unused. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The change-card locator matched on `rounded-lg`, which the radius codemod renamed to `rounded-6` in the source. The class is gone from the markup, so the locator resolved to nothing and the Reordered label assertion timed out. The only e2e locator in the suite that matched on a token class. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Records the two corrections the work forced on the plan — the radius codemod needs --radius-only because the color and typography passes already ran and are not idempotent, and the tiptap resolutions have to name all 43 packages because yarn v1 ignores a glob — plus the four breaks that turned out to need no change, and the e2e baseline that separates the upgrade's one real test break from local flake. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
frappe-ui 1.0.0-beta.41 switched sync-tokens to oklch, so colors.json
holds oklch() where it used to hold hex. The OG card template declares
those six values inline, and the drift test compares the two directly:
AssertionError: '#0f0f0f' != 'oklch(0.168 0 0)'
The card renders through headless Chromium, which reads oklch, so the
template carries the new notation rather than a hex approximation of it.
The test's scraper accepts either notation, so it keeps comparing what
colors.json actually holds instead of assuming one form.
TEMPLATE_VERSION is part of the cache fingerprint, so bumping it drops
every cached card.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A callout's markdown never reached a fixed point under tiptap 3.29.2:
every parse/serialize pass appended two more newlines, so repeated saves
inflated the stored content without bound.
:::note[Test]\nhello\n:::\n\n\n\n
:::note[Test]\nhello\n:::\n\n\n\n\n\n
:::note[Test]\nhello\n:::\n\n\n\n\n\n\n\n
renderMarkdown appended its own `\n\n` after the closing fence. The
serializer already separates blocks and the doc's trailing empty
paragraph serialises to another blank line, which put four newlines after
the fence. Four is one past where PreserveBlankLines turns marked's
`space` token into a real empty paragraph, and that paragraph then
serialised to two more newlines on the next pass. Paragraphs, headings
and lists were stable throughout because they leave the separator to the
serializer; the callout is now the same.
The markdown hooks move to callout-markdown.js so they can be tested:
callout-block.js imports a .vue node view at the top level, which
`node --test` cannot load. Verified by reverting the one-line change with
the tests in place — six round-trip cases and both direct assertions fail
without it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
FeatherIcon and its bare-name back-compat are removed in frappe-ui 1.0.0 (ADR-0008). A string that does not start with `lucide-` now resolves to nothing — renderIcon returns null and dev logs one warning per component and prop — so every `icon="settings"` and `icon: 'trash-2'` in the app silently stopped drawing: dropdown rows, tree actions, review actions, the space chrome bar. All 41 sites take the `lucide-` prefix. Every name survives the move except `github`, which lucide dropped along with the rest of its brand icons; the two GitHub affordances use `lucide-git-branch`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
SidebarHeader is a fixed 48px region that owns its own gutter, so it is meant to go straight into Sidebar. Our wrapping `p-2` div added a second one, pushing the logo and title in past every row below them. Padding moves to the scroll region and the footer, which is what v1's composition contract asks for now that Sidebar no longer applies any of its own. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
useColorScheme owns everything the local composable was doing by hand: the `data-theme` attribute, persistence, following the OS, and muting transitions across a swap so the page doesn't flash. Its version also cancels a pending unmute, so back-to-back swaps can't uncover a repaint — which the two-rAF dance here could. The `.no-transition` rule goes too; frappe-ui/style.css ships it. What stays local, and why: - The toggle flips the *painted* scheme rather than delegating to toggleColorScheme, which branches on the preference: starting from `system` on a dark OS it picks `dark`, and the first click looks dead. - `resolvedTheme` tracks the `data-theme` attribute through a MutationObserver. DiffViewer and MermaidBlockView need the painted scheme, and it isn't derivable from the preference — `system` resolves against the OS, and an OS flip repaints without changing the preference, so there is nothing reactive to watch. The storage key moves from `wiki-theme` to frappe-ui's `theme`. A saved value under the old key is copied over once, and the public reader — which keeps its own Alpine implementation, having no frappe-ui to import — reads the new key with the old one as a fallback and writes the new one, so a toggle on either surface still reaches the other. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
All three tab panels rendered at once, splitting the height three ways and clipping the list after about three rows. reka keeps an inactive TabsContent's wrapper in the DOM and drops only its slot content, marking the wrapper with `hidden`. Tailwind's preflight turns that into `display: none` via `[hidden]`, which is a single attribute selector — exactly as specific as a `.flex` utility, and utilities are emitted after preflight. So the `flex` this call site put on TabPanel won the cascade, and every panel stayed a visible flex child claiming `flex-1`. Moving `display` behind `data-[state=active]:` leaves `hidden` to win on the inactive ones. `min-h-0` and `flex-1` are inert while hidden, so they can stay unconditional. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The underline variant's indicator is a 1px rail line. It measured and positioned correctly, but against the dark theme it reads as part of the track border rather than as a selection, so the active tab looked unmarked. TabList has full variant parity with TabButtons, so the button-style track is a prop rather than a different component — and the composed family keeps owning the panels, which TabButtons does not do. Page padding moves to a wrapper: the pill track hugs its content, so padding on TabList itself would sit inside the pill. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`icon: node.is_published ? 'eye-off' : 'eye'` kept bare Feather names, so the publish toggle in the tree's three-dot menu drew no icon. The upgrade sweep that prefixed the other 41 call sites matched `icon: '...'` and `icon="..."` only — a ternary's branches were invisible to it, and it ran over .vue files alone. Rather than grep harder next time, this adds a test that walks every source file, isolates each icon key or prop's own expression, and fails on any string literal in it that is not a `lucide-` class. It reads ternaries, template props and bindings, and .js as well as .vue. The break is silent by design — v1 renders null for an unsupported icon string and only warns in dev — so a build and a passing e2e run both stay green while the icon is missing. Verified by restoring the bare names with the test in place. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Member
Author
|
Superseded by #752, which carries this branch plus the upgrade to |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why?
We are on
frappe-ui@1.0.0-beta.25(20 July). Upstream is atbeta.45— 696 commits, ~76 changelog entries, and the delta only grows the longer we wait.What?
Upgrades to
1.0.0-beta.45, and moves tiptap to3.29.2as a set.Breaking changes that reached us:
frappe-ui/editor-style.cssandfrappe-ui/list-style.cssexports removed — the barrels self-import their CSS nowAutocompleteremoved →MultiSelectinAssignDialogpageMetaPluginremovedrounded-mdemits no CSS at all — 113 renames over 29 filesink-graydoes not shift — 33 renames over 11 filesTabsis a composed family and models the trigger value, not an indexDropdownignoresplacement; menus quietly left-alignPageHeaderMobile#left/#right→#prefix/#suffix— Vue drops unknown slots without a wordComboboxtemplate ref exposesclear(), notreset()Alertwas registered globally with no call sites, so the registration goes rather than the redesign migration.Audited and left alone: all three
useFileUpload()calls already passprivate: false, so the default flip to private cannot 403 an editor image or a space logo.Select's trigger slot is unused,Sidebaralready owns its padding and scroll container, and the editor's caption change cannot reachWikiImage— it is ours.How?
Two codemod passes, both non-idempotent, both landed with the version bump because either half alone renders wrong:
tokens-v2 --radius-only— not the plain codemod, whose color and typography passes already ran during the beta.25 upgradetokens-v2 --ink-shift, with its.tokens-v2-ink-shiftmarkers committed so a fresh clone keeps the re-run guardThe six
var(--ink-*)and threevar(--radius-*)reads in hand-written CSS are migrated by hand — the codemods only rewrite classes.All 43 tiptap packages are pinned by name in
resolutions. Bumping only our ten direct deps left frappe-ui's transitive@tiptap/extension-*at3.27.1, each declaring an exact@tiptap/corepeer, which produced 19 nested copies of core; yarn v1 ignores a"@tiptap/**"glob resolution.tailwind.config.jsnow spreads the preset's owncontentexport. The hand-written globs it replaces coveredsrc/componentsandsrc/moleculesonly, silently dropping every class the editor and list molecules emit.Testing
yarn buildclean. Verified the editor and list stylesheets still ship after dropping the explicit CSS imports: 119 ProseMirror and 36 list-slot rules in the built output.node --testfromfrontend/).change-request-flow.spec.tslocated a change card byrounded-lg, which the codemod renamed torounded-6. It was the only token-class locator in the suite.callout-rich-text+local-first-storein isolation give 7 failed / 9 passed on this branch and 7 failed / 9 passed ondevelop, with the two differing tests going in both directions.Spec and reconciliation:
specs/frappe_ui_beta45_upgrade.md.🤖 Generated with Claude Code