Commit Graph

11 Commits

Author SHA1 Message Date
Thomas des Francs 59c16ef46f Polish settings billing and MCP UI (#22554)
## Summary

- Polish Billing credits progress rounding and secondary action styling.
- Update MCP setup logos, card spacing, grouping, and badge color.

## Before/After

MCP & APIs

<img width="2258" height="2010" alt="MCP & APIs settings visual"
src="https://github.com/user-attachments/assets/915c8b50-5b98-4ba9-8e5c-a33f36440f6e"
/>

Billing

<img width="2240" height="1644" alt="Billing settings visual"
src="https://github.com/user-attachments/assets/9e3eb332-5792-4a4a-80b0-1b984e574008"
/>
2026-07-04 23:27:40 +02:00
Thomas des Francs e609320666 Squirclesssss 🟦🔵 (#22535) 2026-07-04 07:07:29 +02:00
Raphaël Bosi 566c3b6629 Remove v1 onboarding and rely only on v2 (#22398)
https://github.com/user-attachments/assets/a6bfaac3-6c79-4fd5-999a-e6a70cff8ac8


Removes the old (v1) signup and onboarding flow now that v2 is the only
path, and drops the `isOnboardingV2` flag entirely. The surviving
(formerly-v2) pages reclaim the canonical `AppPath` members and clean
URLs (`/welcome`, `/verify`, `/workspace-activation`, `/create/profile`,
`/sync/emails`, `/install-apps`, `/invite-team`, `/plan-required`).

- Deletes the v1 pages, the v1 workspace-creation form, the
`isOnboardingV2State` flag + `onboardingV2` URL-param plumbing, and
`InstallAppsAutoSkipEffect`.
- Collapses the router and page-change navigation matrix to a single set
of paths, and renames the v2 components/stories to drop the `V2` suffix.

Follow-up fixes so the single flow behaves correctly on every
deployment:

- Restore the captcha-token, query-param and pageview effects on the
default (root) domain, and serve `/authorize` there so OAuth login keeps
working.
- Gate the invite-team → `/plan-required` interception on billing so
billing-disabled instances aren't trapped on the upgrade page.
- On a cold boot to an auth/onboarding path, show the onboarding loader
instead of the CRM skeleton, and add `/verify-email` and
`/plan-required/payment-success` to that loader path list.
- Add a retry to PaymentSuccess after the confirmation timeout, fix the
InstallApps icon crossfade, restyle the book-call pages for the
full-page layout, and delete code orphaned by the v1 removal.
- Extract the pageview/captcha/query-param logic out of
`PageChangeEffect` into standalone Effect components shared by the root
and workspace app trees.

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22398?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2026-07-03 16:12:34 +00:00
Thomas des Francs d8cc81cb91 Improve billing settings UI (#22377)
## Summary

- Refresh the settings billing subscription and credits cards with
clearer status, usage, and action states.
- Add the credit-package picker flow and route past-due/cancellation
actions to billing management instead of credit modals.
- Clean up related billing UI helpers and formatting.

## Screens

### regular
<img width="1007" height="781" alt="image"
src="https://github.com/user-attachments/assets/dc9c0c59-8cda-422a-a0d3-56292421a744"
/>

### downgrading
<img width="1049" height="818" alt="image"
src="https://github.com/user-attachments/assets/0dc3dea8-5b55-4cf2-bc92-997cf6e9bebc"
/>
<img width="1048" height="901" alt="image"
src="https://github.com/user-attachments/assets/fba805ad-f523-444b-93a0-2011b6b43443"
/>

### Trialing

without card
<img width="1008" height="903" alt="image"
src="https://github.com/user-attachments/assets/d5dd11b6-4c92-4102-ac22-ad1ad4e9fbfb"
/>

with card
<img width="1008" height="806" alt="image"
src="https://github.com/user-attachments/assets/0dbeb00e-890e-4448-94fe-0cc0ef411e8d"
/>


### Past due & Unpaid

<img width="1052" height="860" alt="Past due"
src="https://github.com/user-attachments/assets/25ba53ef-6e74-4b4c-bfe1-d6c74e165917"
/>
<img width="1138" height="860" alt="Unpaid"
src="https://github.com/user-attachments/assets/bb16fe65-84e4-40a7-8951-90b01030aded"
/>

---------

Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com>
2026-07-01 17:02:54 +00:00
Raphaël Bosi 766d90af7e Remove framer-motion from twenty-ui (#22021)
## What

Removes the `framer-motion` dependency from `twenty-ui` and replaces
every usage with pure CSS animations, reaching for Base UI primitives
where one fits:

- **Collapse/expand** (`AnimatedEaseInOut`,
`AnimatedExpandableContainer`): rebuilt on Base UI `Collapsible`
(CSS-animated `--collapsible-panel-height/width` + transition states).
Public props unchanged, so the ~28 call sites are untouched.
- **ProgressBar**: rebuilt on Base UI `Progress` (proper
`role`/`aria-valuenow`). The snackbar auto-dismiss countdown now uses a
CSS keyframe + `animation-play-state` (pause on hover), removing a
per-frame React re-render; `useProgressAnimation` is deleted.
- The remaining `Animated*` components, the circular spinner, checkmark,
and the placeholder pointer parallax move to plain CSS (SCSS modules +
the `duration()` helper + theme tokens).
- Deletes 3 unused components (`AnimatedTranslation`,
`AnimatedTextWord`, `AnimatedFadeOut`).

## Why

`twenty-ui` is a publicly published library with a size budget, so
dropping framer-motion shrinks what consumers ship. `twenty-front` keeps
its own framer-motion; that is out of scope here.

## Notes for reviewers

- A few `twenty-ui` components received framer props from `twenty-front`
call sites; those were migrated (e.g. `AnimatedLightIconButton` gained a
CSS `rotate` prop, and the `EMPTY_PLACEHOLDER_TRANSITION_PROPS` spreads
were removed).
- Behavior change: Base UI `Collapsible` animates only on open/close
transitions, so the old "animate in on first mount while already open"
case no longer plays (the `initial` prop is kept for API compatibility).

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22021?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-23 17:43:08 +02:00
Raphaël Bosi 0f451897cf Make twenty-ui theming a consumer-facing API (#22007)
**What**
- Add `useTheme()` and `useThemeColorScheme()` as the public theme
accessors, and migrate the 88 internal `useContext(ThemeContext)` call
sites to them. `ThemeContext` stays exported.
- Make `ThemeProvider` overridable and scopeable: new `applyToRoot`
(default `true`), `overrides` (a `--t-*` map), and `className` props.
When scoping is requested it renders a `display: contents` wrapper that
also serves as the themed portal container, exposed via
`ThemeScopeContext` / `useThemeContainer()`. `AppTooltip` and `Modal`
portal into that container, falling back to `document.body`.
- Document the `--t-*` override contract in the README; barrels
regenerated.

**Why**
Consumers had no stable theme accessor (they reached into the raw
context) and no supported way to re-theme. This adds both without
behavior change.

**Reviewer notes**
- The default path is unchanged: `applyToRoot` defaults to `true`, so
the colorScheme class still lands on `<html>` and portaled overlays
(tooltips, dropdowns, modals) stay themed. The global class is
load-bearing for body portals; scoping is opt-in.
- `twenty-front` is untouched (migrating its consumers is a separate
follow-up).

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22007?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-23 14:16:09 +02:00
Raphaël Bosi 5f22908588 Decouple twenty-ui Avatar from app server-URL config (#21968)
Makes `twenty-ui`'s `Avatar` render the `avatarUrl` it receives instead
of building it from `window._env_`/`window.location` at module load, so
the library no longer depends on the app environment. URL resolution
moves to `twenty-front` via a `getAbsoluteImageUrl` helper applied at
the call sites.

Part of making twenty-ui a standalone library.
2026-06-22 18:38:00 +02:00
Raphaël Bosi e0fadfee7c Remove jotai from twenty-ui (#21937)
twenty-ui no longer depends on jotai, so its components work without a
consumer-provided jotai store (better practice for a shared UI library).
twenty-front keeps jotai; this is scoped to the library.

- **Avatar**: tracks image-load failure in local `useState` instead of a
global atom.
- **Icons**: the icon registry moved from a jotai atom to a React
Context. `IconsProvider` and `useIcons` keep identical signatures; the
context itself stays internal.
- Removed the unused `createState` helper, the `invalidAvatarUrlsAtomV2`
/ `iconsState` atoms, and `JotaiRootDecorator`; regenerated barrels and
dropped the `jotai` dependency.

No other package needs changes: nothing imports the removed symbols, and
`twenty-sdk` (which re-exports twenty-ui via `export *`) simply stops
surfacing the two leaked atoms on its next publish.

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21937?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-22 13:33:32 +02:00
Raphaël Bosi 1f6c2b89fd Accessibility guardrails and component hardening for twenty-ui (#21848)
Builds on twenty-ui's existing runtime axe gate by adding a static
enforcement layer and fixing accessibility gaps in shared components.
Color contrast is intentionally out of scope (still deferred via
`A11Y_DEFER_COLOR_CONTRAST`).

## What changed
- **Static guardrails:** enabled oxlint's `jsx-a11y` plugin
(keyboard-operability rules at `error`), and added a custom
`twenty/no-storybook-a11y-disable` rule that blocks `a11y: { test: 'off'
| 'todo' }` so the axe gate can't be silently disabled again.
- **Focus visibility:** wired the existing `focus-ring` mixin into all
buttons for real `:focus-visible` rings (was `outline: none`).
- **Decorative icons:** `aria-hidden` on icons inside labeled buttons
(added to `IconComponentProps` + render sites).
- **Inputs:** accessible-name support on `SearchInput` and `Checkbox`.
- **Interactive components:** `Tag` renders a real `<button>` when
clickable; the non-semantic clickable `div`s (`Avatar`, `Status`,
`ColorSchemeCard`, `NavigationBarItem`, etc.) are now keyboard-operable
via a shared `handleClickableElementKeyDown` helper, role and accessible
name.

## Notes for reviewers
- Two `oxlint-disable` lines remain on genuine non-interactive capture
wrappers (`CodeEditor`, `OverflowingTextWithTooltip`).
- 8 lint warnings remain by design: conditional-interactivity
`no-static-element-interactions` and legitimate `autoFocus` on
`SearchInput`.
- `NavigationBarItem` gained a required `ariaLabel`; its only consumer
(`MobileNavigationBar`) is updated with translated labels.

## Follow-ups (separate PRs)
- Enforced accessible names on icon-only buttons
(`IconButton`/`LightIconButton`) — breaking, ~128 call sites.
- `aria-activedescendant` wiring for the dropdown/listbox keyboard
layer.

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21848?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-19 15:57:23 +02:00
Raphaël Bosi 86a4066997 Accessibility fix pass for remaining twenty-ui domains (#21790)
Completes the twenty-ui accessibility fix pass for the remaining 32
`a11y: { test: 'todo' }` story files (navigation, feedback,
data-display, typography, surfaces, layout, json-visualizer), following
the input pilot (#21776, merged). The package now has **zero** `test:
'todo'` overrides left.

**What changed (gate-driven)**
- Bulk color-contrast deferred via the shared
`A11Y_DEFER_COLOR_CONTRAST` (greppable, tracked for the later
design-token pass).
- Real violations the axe gate surfaced and fixed: accessible names on
`ProgressBar` (progressbar), `Modal` (dialog), and the
MultiSelect/Toggle inner Checkbox/Switch; `role="listbox"` parents for
`MenuItemSelect`/`SelectAvatar`; `ariaLabel` on
`MenuItem`/`MenuItemDraggable` icon-buttons; a `version` for
`GithubVersionLink`; and `JsonTree`'s empty array/object now renders a
proper `<li>` (`list` rule).

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21790?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-18 16:11:38 +02:00
Raphaël Bosi 8034c7725f Reorganize twenty-ui into best-practice component domains and per-component folders (#21745)
Reorganizes `twenty-ui`'s component organization to follow how the best
UI libraries (MUI, Mantine, Base UI, Polaris) structure their source,
now that the package has stabilized.

**Taxonomy** — dissolves the meaningless `components/` junk-drawer and
the 107-file `display/` mega-category. New domains/subpaths:
`data-display`, `typography`, `icon`, `surfaces`; `feedback` and
`layout` absorb the rest (banners/callout/info + placeholders →
feedback; modal/card → surfaces; motion + separators → layout).

**Per-component layout** — every component is now
`<domain>/<ComponentName>/<ComponentName>.tsx` with colocated
styles/stories/types, `internal/` for private helpers and `parts/` for
re-exported compound sub-parts. The redundant inner `/components/` is
gone. `icon` and `json-visualizer` are kept as cohesive subsystems.

**Also:** adds a tree-shakeable root barrel (`import { Button } from
'twenty-ui'`), the generator now owns `individual-entry.ts`, and a real
barrel-leak bug is fixed (private `internals/` parts were leaking into
the public API).

Consumer imports (~1.2k files) and the `twenty-sdk` UI aggregator were
updated by codemod. The change is **export-neutral** except 16
intentionally-removed private internals symbols (all verified
unconsumed). Gates green: typecheck, lint, build, size-limit, storybook.


<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21745?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-18 10:31:29 +02:00