From 92775a363982925d6521729564d44443e41bdd97 Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Wed, 2 Sep 2026 14:57:58 -0700 Subject: [PATCH 1/3] chore(tailwind): upgrade to v4 and swap clsx/tailwind-merge for cn Migrates apps/sim from Tailwind v3.4 to v4.3 (CSS-first config) and replaces clsx + tailwind-merge with the cn package in @sim/emcn and apps/docs. The upgrade is intended to be visually inert. Parity was verified by building the stylesheet both ways and diffing computed styles in a real browser: - Preflight: 112/112 bare elements identical, after restoring seven v3 behaviours v4 dropped (button cursor, form-control background, placeholder colour, table/option padding, search-field normalisation, dialog centring) - Utilities: every class the app uses renders pixel-identically - Border widths: 10/10 combinations identical - Class strings: 699 changed strings run through both merge engines, 0 diffs Pinned against v4 defaults that would otherwise shift rendering: --font-sans (v4 changed its own default stack), --text-xs--line-height, and the 24 stock palette colours the app uses (v4 re-authored the palette in oklch, which is visibly more saturated on P3 displays). borderWidth.DEFAULT has no v4 theme key, so a PostCSS pass rewrites Tailwind's own border-width output through --border-width. Re-declaring the utilities in a trailing @layer instead would make `border` beat `border-2` and `border-t-0`. rounded-sm and rounded-md are deliberately NOT renamed: this app overrides that radius scale, so the standard v3->v4 rename would change their values. cn is compiled ahead of time (cn build --full) so the config compiler stays out of the browser bundle; check:cn-tables fails CI if the tables drift. --- .agents/skills/design-taste-frontend/SKILL.md | 2 +- .claude/rules/sim-settings-pages.md | 2 +- .claude/rules/sim-styling.md | 2 +- .cursor/rules/sim-styling.mdc | 2 +- .gitignore | 4 + apps/docs/app/global.css | 6 +- apps/docs/lib/utils.ts | 17 +- apps/docs/package.json | 2 - .../chat/components/input/input.tsx | 6 +- .../message-container/message-container.tsx | 2 +- .../message/components/file-download.tsx | 4 +- .../chat/components/message/message.tsx | 2 +- apps/sim/app/(landing)/CLAUDE.md | 2 +- .../content-post-loading.tsx | 2 +- .../content-post-page/content-post-page.tsx | 2 +- .../hero-chat-loop/hero-chat-loop.tsx | 2 +- .../hero-platform-loop/stage-block-card.tsx | 2 +- .../components/hero-visual/stage-home.tsx | 2 +- .../hero/components/hero-visual/stage-kb.tsx | 4 +- .../hero-visual/workflow-block-content.tsx | 8 +- .../components/hero-visual/workflow-block.tsx | 2 +- .../components/lightbox/lightbox.tsx | 2 +- .../nav-menu-item/nav-menu-item.tsx | 4 +- .../enterprise-home-stage.tsx | 2 +- .../enterprise-sidebar.tsx | 20 +- .../access-control-graphic.tsx | 2 +- .../feature-graphics/audit-trail-graphic.tsx | 6 +- .../build-methods-graphic.tsx | 4 +- .../feature-graphics/deploy-graphic.tsx | 2 +- .../feature-platform-panel.tsx | 2 +- .../it-platform-teams-graphic.tsx | 6 +- .../feature-graphics/lifecycle-graphic.tsx | 2 +- .../feature-graphics/rollback-graphic.tsx | 4 +- .../run-monitoring-graphic.tsx | 4 +- .../feature-graphics/staging-graphic.tsx | 4 +- .../feature-graphics/standards-graphic.tsx | 2 +- .../technical-teams-graphic.tsx | 6 +- .../feature-graphics/file-library-graphic.tsx | 4 +- .../files/components/files-hero-loop.tsx | 17 +- .../connector-sync-graphic.tsx | 4 +- .../components/knowledge-hero-loop.tsx | 10 +- .../feature-graphics/filter-runs-graphic.tsx | 4 +- .../logs/components/logs-hero-loop.tsx | 10 +- .../components/pricing-card/pricing-card.tsx | 4 +- .../document-draft-graphic.tsx | 4 +- .../knowledge-answer-graphic.tsx | 4 +- .../feature-graphics/reconcile-graphic.tsx | 4 +- .../feature-graphics/table-grid-graphic.tsx | 4 +- .../workflow-canvas-graphic.tsx | 8 +- apps/sim/app/_styles/globals.css | 440 +++++++++++++++++- apps/sim/app/_styles/tailwind.css | 9 + .../conversation-list-item.tsx | 4 +- .../[workspaceId]/components/error/error.tsx | 2 +- .../inline-rename-input.tsx | 2 +- .../message-actions/message-actions.tsx | 2 +- .../components/presence/presence-avatars.tsx | 2 +- .../resource-tile/resource-tile.tsx | 2 +- .../components/action-bar/action-bar.tsx | 4 +- .../resource-header/resource-header.tsx | 2 +- .../resource-options/resource-options.tsx | 4 +- .../components/file-viewer/data-table.tsx | 4 +- .../components/file-viewer/pdf-viewer.tsx | 2 +- .../rich-markdown-editor/code-block.tsx | 2 +- .../menus/bubble-menu-chrome.ts | 2 +- .../menus/link-editing.tsx | 2 +- .../menus/link-hover-card.tsx | 2 +- .../menus/suggestion-menu-chrome.ts | 4 +- .../menus/toolbar-button.tsx | 2 +- .../rich-markdown-field.tsx | 2 +- .../components/agent-group/agent-group.tsx | 10 +- .../components/agent-group/tool-call-item.tsx | 2 +- .../components/chat-content/chat-content.tsx | 2 +- .../components/interaction-card.tsx | 2 +- .../components/question/question.tsx | 8 +- .../components/special-tags/special-tags.tsx | 4 +- .../message-content/message-content.tsx | 2 +- .../mothership-chat/mothership-chat.tsx | 4 +- .../browser-session/browser-downloads.tsx | 2 +- .../browser-session/browser-find-bar.tsx | 14 +- .../browser-session/browser-page-issue.tsx | 2 +- .../browser-session/browser-session.tsx | 12 +- .../generic-resource-content.tsx | 5 +- .../resource-content/resource-content.tsx | 2 +- .../resource-registry/resource-registry.tsx | 14 +- .../suggested-actions/suggested-actions.tsx | 6 +- .../user-input/components/constants.ts | 2 +- .../prompt-editor/prompt-editor.test.tsx | 2 +- .../prompt-editor/prompt-editor.tsx | 2 +- .../user-message-content.tsx | 2 +- .../app/workspace/[workspaceId]/home/home.tsx | 2 +- .../integrations-showcase.tsx | 2 +- .../components/chunk-editor/chunk-editor.tsx | 2 +- .../document-tags-modal.tsx | 4 +- .../knowledge/[id]/[documentId]/document.tsx | 2 +- .../[workspaceId]/knowledge/[id]/base.tsx | 6 +- .../[id]/components/action-bar/action-bar.tsx | 7 +- .../add-connector-modal.tsx | 6 +- .../add-documents-modal.tsx | 4 +- .../base-tags-modal/base-tags-modal.tsx | 8 +- .../connectors-section/connectors-section.tsx | 10 +- .../edit-connector-modal.tsx | 4 +- .../create-base-modal/create-base-modal.tsx | 4 +- .../[workspaceId]/knowledge/knowledge.tsx | 4 +- .../components/status-bar/status-bar.tsx | 2 +- .../workflows-list/workflows-list.tsx | 12 +- .../logs/components/dashboard/dashboard.tsx | 8 +- .../file-download/file-download.tsx | 4 +- .../components/trace-view/trace-view.tsx | 44 +- .../components/log-details/log-details.tsx | 34 +- .../app/workspace/[workspaceId]/logs/logs.tsx | 10 +- .../credit-usage/credit-usage-view.tsx | 4 +- .../components/activity-log/activity-log.tsx | 25 +- .../settings/components/api-keys/api-keys.tsx | 2 +- .../components/appearance-theme-select.tsx | 2 +- .../settings/components/billing/billing.tsx | 8 +- .../byok/byok-provider-keys-modal.tsx | 2 +- .../components/default-zoom-select.tsx | 2 +- .../settings/components/general/general.tsx | 10 +- .../inbox-settings-tab/inbox-settings-tab.tsx | 2 +- .../inbox-task-list/inbox-task-list.tsx | 4 +- .../settings/components/mcp/mcp.tsx | 2 +- .../components/member-list/member-list.tsx | 6 +- .../row-actions-menu/row-actions-menu.tsx | 2 +- .../settings-resource-row.tsx | 10 +- .../terminal/terminal-theme-picker.tsx | 2 +- .../workflow-mcp-servers.tsx | 6 +- .../secret-usage-panel/secret-usage-panel.tsx | 2 +- .../column-config-sidebar.tsx | 2 +- .../column-dropdown/column-dropdown.tsx | 2 +- .../enrichment-details/enrichment-details.tsx | 12 +- .../enrichments-sidebar/enrichment-config.tsx | 4 +- .../enrichments-sidebar.tsx | 4 +- .../select-field/select-options-editor.tsx | 2 +- .../table-action-bar/table-action-bar.tsx | 4 +- .../components/table-filter/table-filter.tsx | 2 +- .../cells/expanded-cell-popover.tsx | 2 +- .../table-grid/cells/inline-editors.tsx | 8 +- .../table-grid/headers/column-header-menu.tsx | 4 +- .../components/table-grid/table-grid.tsx | 2 +- .../components/views-menu/views-menu.tsx | 2 +- .../workflow-sidebar/workflow-sidebar.tsx | 6 +- .../comparison-table/comparison-table.tsx | 4 +- .../components/plan-card/plan-card.tsx | 6 +- .../components/action-bar/action-bar.tsx | 28 +- .../w/[workflowId]/components/chat/chat.tsx | 18 +- .../output-select/output-select.tsx | 2 +- .../connection-block-selector.tsx | 6 +- .../note-block/note-markdown-editor.tsx | 2 +- .../deploy-modal/components/api/api.tsx | 14 +- .../deploy-modal/components/chat/chat.tsx | 2 +- .../general/components/versions.tsx | 8 +- .../components/general/general.tsx | 4 +- .../components/field-item/field-item.tsx | 6 +- .../connection-blocks/connection-blocks.tsx | 2 +- .../sub-block/components/code/code.tsx | 2 +- .../components/combobox/combobox.tsx | 2 +- .../credential-selector.tsx | 4 +- .../grouped-checkbox-list.tsx | 4 +- .../knowledge-tag-filters.tsx | 2 +- .../components/long-input/long-input.tsx | 2 +- .../messages-input/messages-input.tsx | 4 +- .../components/short-input/short-input.tsx | 2 +- .../components/skill-input/skill-input.tsx | 4 +- .../components/starter/input-format.tsx | 4 +- .../sub-block/components/table/table.tsx | 2 +- .../sub-block/components/text/text.tsx | 4 +- .../components/code-editor/code-editor.tsx | 2 +- .../components/tool-input/tool-input.tsx | 8 +- .../variables-input/variables-input.tsx | 4 +- .../editor/components/sub-block/sub-block.tsx | 12 +- .../subflow-editor/subflow-editor.tsx | 4 +- .../panel/components/editor/editor.tsx | 10 +- .../panel/components/toolbar/toolbar.tsx | 10 +- .../w/[workflowId]/components/panel/panel.tsx | 10 +- .../workflow-search-replace.tsx | 2 +- .../components/output-panel/output-panel.tsx | 30 +- .../toggle-button/toggle-button.tsx | 4 +- .../components/terminal/terminal.tsx | 12 +- .../[workflowId]/components/terminal/types.ts | 4 +- .../components/variables/variables.tsx | 8 +- .../wand-prompt-bar/wand-prompt-bar.tsx | 2 +- .../workflow-block/workflow-block.tsx | 2 +- .../w/[workflowId]/workflow-constants.ts | 8 +- .../preview-editor/preview-editor.tsx | 50 +- .../components/block/block.tsx | 6 +- .../w/components/preview/preview.tsx | 6 +- .../collapsed-sidebar-menu.tsx | 4 +- .../command-chrome/command-chrome.tsx | 4 +- .../command-items/command-items.tsx | 32 +- .../components/search-modal/search-modal.tsx | 2 +- .../settings-sidebar/settings-sidebar.tsx | 4 +- .../sidebar-footer/sidebar-footer.tsx | 12 +- .../sidebar-section/sidebar-section.tsx | 6 +- .../status-notice/status-notice.tsx | 2 +- .../components/folder-item/folder-item.tsx | 4 +- .../workflow-item/workflow-item.tsx | 4 +- .../view-invitations-modal.tsx | 4 +- .../workspace-header/workspace-header.tsx | 26 +- .../w/components/sidebar/constants.ts | 2 +- .../w/components/sidebar/sidebar.tsx | 20 +- apps/sim/blocks/icon-color.test.ts | 4 +- apps/sim/blocks/icon-color.ts | 6 +- apps/sim/components.json | 4 +- .../agent-stream/agent-stream-chrome.tsx | 2 +- .../emails/_styles/base.tokens.test.ts | 18 +- apps/sim/components/emails/_styles/base.ts | 2 +- apps/sim/components/page-header-bar.ts | 2 +- .../sim/components/permissions/member-row.tsx | 2 +- .../components/pii/custom-patterns-editor.tsx | 2 +- .../components/settings/settings-sidebar.tsx | 11 +- .../settings/standalone-settings-shell.tsx | 2 +- apps/sim/components/ui/button.tsx | 2 +- .../ui/generated-password-input.tsx | 6 +- apps/sim/components/ui/select.tsx | 4 +- .../components/group-detail.tsx | 40 +- .../ee/audit-logs/components/audit-logs.tsx | 10 +- .../components/data-drain-detail.tsx | 4 +- .../components/data-retention-settings.tsx | 2 +- .../components/usage-consumers.tsx | 14 +- .../components/usage-events-view.tsx | 6 +- .../components/usage-monitoring.tsx | 2 +- .../components/whitelabeling-settings.tsx | 2 +- .../fork-activity-panel.tsx | 2 +- .../fork-excluded-workflows.tsx | 2 +- .../fork-file-tree/fork-file-tree.tsx | 2 +- .../fork-resource-picker.tsx | 4 +- .../components/fork-sync/fork-sync-view.tsx | 4 +- .../ee/workspace-forking/components/forks.tsx | 2 +- .../sim/lib/postcss/hairline-border-width.mjs | 79 ++++ apps/sim/package.json | 5 +- apps/sim/postcss.config.mjs | 15 +- apps/sim/tailwind.config.ts | 334 ------------- biome.json | 6 + bun.lock | 130 ++---- bunfig.toml | 6 + package.json | 1 + packages/emcn/cn.config.mjs | 16 + packages/emcn/package.json | 4 +- packages/emcn/src/components/badge/badge.tsx | 2 +- .../components/button-group/button-group.tsx | 2 +- .../emcn/src/components/button/button.tsx | 2 +- .../emcn/src/components/checkbox/checkbox.tsx | 2 +- .../chip-date-picker/chip-date-picker.tsx | 2 +- .../chip-dropdown/chip-dropdown.tsx | 10 +- .../src/components/chip-input/chip-input.tsx | 2 +- .../src/components/chip-modal/chip-modal.tsx | 6 +- .../components/chip-switch/chip-switch.tsx | 2 +- .../emcn/src/components/chip-tag/chip-tag.tsx | 4 +- .../emcn/src/components/chip/chip-chrome.ts | 10 +- packages/emcn/src/components/code/code.tsx | 12 +- .../emcn/src/components/combobox/combobox.tsx | 20 +- .../dropdown-menu/dropdown-menu.tsx | 14 +- .../src/components/info-card/info-card.tsx | 2 +- packages/emcn/src/components/info/info.tsx | 2 +- packages/emcn/src/components/input/input.tsx | 2 +- packages/emcn/src/components/modal/modal.tsx | 2 +- .../emcn/src/components/popover/popover.tsx | 10 +- .../secret-reveal/secret-reveal.tsx | 2 +- .../emcn/src/components/slider/slider.tsx | 2 +- .../emcn/src/components/switch/switch.tsx | 4 +- .../src/components/tab-strip/tab-strip.tsx | 4 +- .../src/components/tag-input/tag-input.tsx | 8 +- .../emcn/src/components/textarea/textarea.tsx | 2 +- .../components/time-picker/time-picker.tsx | 8 +- packages/emcn/src/components/toast/toast.tsx | 2 +- .../src/components/tooltip/tooltip-styles.ts | 2 +- packages/emcn/src/lib/cn-tables.ts | 110 +++++ packages/emcn/src/lib/cn.ts | 32 +- .../src/lib/overflow-span-mount.test.tsx | 2 +- .../src/note/note-block-view.tsx | 2 +- .../src/subflow/subflow-node-view.tsx | 20 +- .../src/workflow-block/sub-block-row-view.tsx | 2 +- .../workflow-block/workflow-block-view.tsx | 30 +- scripts/check-cn-tables.ts | 49 ++ 274 files changed, 1525 insertions(+), 1227 deletions(-) create mode 100644 apps/sim/app/_styles/tailwind.css create mode 100644 apps/sim/lib/postcss/hairline-border-width.mjs delete mode 100644 apps/sim/tailwind.config.ts create mode 100644 packages/emcn/cn.config.mjs create mode 100644 packages/emcn/src/lib/cn-tables.ts create mode 100644 scripts/check-cn-tables.ts diff --git a/.agents/skills/design-taste-frontend/SKILL.md b/.agents/skills/design-taste-frontend/SKILL.md index f7f472a74e9..11ad6fa3e86 100644 --- a/.agents/skills/design-taste-frontend/SKILL.md +++ b/.agents/skills/design-taste-frontend/SKILL.md @@ -4,7 +4,7 @@ source: https://github.com/leonxlnx/taste-skill — skills/taste-skill/SKILL.md description: Anti-slop frontend skill for landing pages, portfolios, and redesigns. The agent reads the brief, infers the right design direction, and ships interfaces that do not look templated. Real design systems when applicable, audit-first on redesigns, strict pre-flight check. --- -> **In this repo:** Tailwind 3.4 (`apps/sim/tailwind.config.ts`); animation via `import { motion } from 'framer-motion'` (not `motion/react` — rewrite every `motion/react` import in the samples below); icons from `@sim/emcn/icons`; colors through the CSS-variable tokens in `.claude/rules/sim-styling.md` (no hardcoded `text-gray-*`/hex/`zinc` utilities, no paired `dark:` utilities). This note overrides any conflicting guidance or code sample anywhere in this file. +> **In this repo:** Tailwind 4 (CSS-first config in `apps/sim/app/_styles/globals.css`); animation via `import { motion } from 'framer-motion'` (not `motion/react` — rewrite every `motion/react` import in the samples below); icons from `@sim/emcn/icons`; colors through the CSS-variable tokens in `.claude/rules/sim-styling.md` (no hardcoded `text-gray-*`/hex/`zinc` utilities, no paired `dark:` utilities). This note overrides any conflicting guidance or code sample anywhere in this file. # tasteskill: Anti-Slop Frontend Skill diff --git a/.claude/rules/sim-settings-pages.md b/.claude/rules/sim-settings-pages.md index 763803ed7db..9893028c352 100644 --- a/.claude/rules/sim-settings-pages.md +++ b/.claude/rules/sim-settings-pages.md @@ -113,7 +113,7 @@ Adding a new settings page: ## Text-scale tokens (no literal pixel sizes) Settings pages never use a literal `text-[Npx]` class — always the named Tailwind -scale token from `apps/sim/tailwind.config.ts`'s `fontSize` extension (`text-micro` +scale token from the `@theme` block in `apps/sim/app/_styles/globals.css` (`text-micro` 10px, `text-xs` 11px, `text-caption` 12px, `text-small` 13px, `text-sm` 14px [Tailwind default, unmodified], `text-base` 15px, `text-md` 16px, `text-lg` 18px [Tailwind default]). A literal size is either a straight rename to the equivalent diff --git a/.claude/rules/sim-styling.md b/.claude/rules/sim-styling.md index 3fd18753f46..51a882f8607 100644 --- a/.claude/rules/sim-styling.md +++ b/.claude/rules/sim-styling.md @@ -46,7 +46,7 @@ setWidth: (width) => { ## Text Scale -Custom font sizes (`apps/sim/tailwind.config.ts`): `text-micro`=10px, `text-xs`=11px, `text-caption`=12px, `text-small`=13px, `text-base`=15px. `text-sm` is Tailwind default 14px. Field titles use `text-small` (13px); hints/errors use `text-caption` (12px). +Custom font sizes (the `@theme` block in `apps/sim/app/_styles/globals.css`): `text-micro`=10px, `text-xs`=11px, `text-caption`=12px, `text-small`=13px, `text-base`=15px. `text-sm` is Tailwind default 14px. Field titles use `text-small` (13px); hints/errors use `text-caption` (12px). Icons default `size-[14px]`. Equal h/w → `size-*` (`size-[14px]`, `size-4`), never `h-N w-N`. diff --git a/.cursor/rules/sim-styling.mdc b/.cursor/rules/sim-styling.mdc index 8b407a204b7..e4688808503 100644 --- a/.cursor/rules/sim-styling.mdc +++ b/.cursor/rules/sim-styling.mdc @@ -40,7 +40,7 @@ setWidth: (width) => { ## Text Scale -Custom font sizes (`apps/sim/tailwind.config.ts`): `text-micro`=10px, `text-xs`=11px, `text-caption`=12px, `text-small`=13px, `text-base`=15px. `text-sm` is Tailwind default 14px. Field titles use `text-small` (13px); hints/errors use `text-caption` (12px). +Custom font sizes (the `@theme` block in `apps/sim/app/_styles/globals.css`): `text-micro`=10px, `text-xs`=11px, `text-caption`=12px, `text-small`=13px, `text-base`=15px. `text-sm` is Tailwind default 14px. Field titles use `text-small` (13px); hints/errors use `text-caption` (12px). Icons default `size-[14px]`. Equal h/w → `size-*` (`size-[14px]`, `size-4`), never `h-N w-N`. diff --git a/.gitignore b/.gitignore index 6bbecf8f295..5b64adb92ac 100644 --- a/.gitignore +++ b/.gitignore @@ -107,3 +107,7 @@ __pycache__/ # `apps/sim/lib/uploads/` — 61 files of tracked source — and silently ignore # anything added there later. /uploads + +# Scratch dir for `bun run cn:check` in packages/emcn (regenerates the cn +# lookup tables to a throwaway path and diffs them against the committed copy). +.cn-check/ diff --git a/apps/docs/app/global.css b/apps/docs/app/global.css index aa2e6f740c8..b0f169b33fb 100644 --- a/apps/docs/app/global.css +++ b/apps/docs/app/global.css @@ -7,7 +7,7 @@ /* Every @sim/emcn component expresses hover through `hover-hover:` so touch devices never latch a sticky hover state. The app registers it as a plugin - variant in apps/sim/tailwind.config.ts; docs is CSS-first Tailwind v4 with no + variant in apps/sim/app/_styles/globals.css; docs is CSS-first Tailwind v4 with no config, so without this declaration the variant compiles to nothing and every emcn hover state silently no-ops here. */ @custom-variant hover-hover { @@ -35,7 +35,7 @@ body { --color-fd-primary: var(--color-fd-foreground); /* Sim's custom type scale — emcn components (Label, Badge, the shared block views) use these names, so they must resolve here or text falls back to the - inherited size. Mirrors apps/sim/tailwind.config.ts. */ + inherited size. Mirrors apps/sim/app/_styles/globals.css. */ --text-micro: 10px; --text-xs: 11px; --text-caption: 12px; @@ -47,7 +47,7 @@ body { --text-caption and --text-small, because the mono face reads small at 12px. */ --text-code: 0.78125rem; - /* The platform's code face. `apps/sim/tailwind.config.ts` lists `var(--font-martian-mono)` + /* The platform's code face. `apps/sim/app/_styles/globals.css` lists `var(--font-martian-mono)` first, but nothing in the app ever defines that variable — `apps/sim/app/layout.tsx` applies only `season.variable` — so every code surface in the product resolves to the system stack below. Docs match what the app actually renders rather than the token it diff --git a/apps/docs/lib/utils.ts b/apps/docs/lib/utils.ts index 2a18386f2dc..a7b128a8254 100644 --- a/apps/docs/lib/utils.ts +++ b/apps/docs/lib/utils.ts @@ -1,12 +1,15 @@ -import { type ClassValue, clsx } from 'clsx' -import { twMerge } from 'tailwind-merge' - /** - * Combines multiple class names into a single string, merging Tailwind classes properly + * Re-exported from the design system rather than built here, so docs runs one + * merge engine instead of two: its own components already import `cn` from + * `@sim/emcn` indirectly, and a second `cn` entry point would ship a duplicate + * engine and lookup tables. + * + * It also carries emcn's `font-size` class group, which docs needs — its + * `global.css` defines the same `--text-micro/caption/small/md` scale, and the + * stock merger does not treat those as font sizes, so `cn('text-small', + * 'text-sm')` emitted both and let CSS source order pick the winner. */ -export function cn(...inputs: ClassValue[]) { - return twMerge(clsx(inputs)) -} +export { cn } from '@sim/emcn' /** * Get the full URL for an asset stored in Vercel Blob diff --git a/apps/docs/package.json b/apps/docs/package.json index 66ba9567c52..67b822703ae 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -23,7 +23,6 @@ "@sim/workflow-renderer": "workspace:*", "@xyflow/react": "12.11.3", "class-variance-authority": "^0.7.1", - "clsx": "^2.1.1", "drizzle-orm": "^0.45.2", "fumadocs-core": "16.8.5", "fumadocs-mdx": "14.3.2", @@ -35,7 +34,6 @@ "react-dom": "19.2.4", "remark-breaks": "^4.0.0", "shiki": "4.3.1", - "tailwind-merge": "^3.0.2", "framer-motion": "^12.5.0", "zod": "4.3.6" }, diff --git a/apps/sim/app/(interfaces)/chat/components/input/input.tsx b/apps/sim/app/(interfaces)/chat/components/input/input.tsx index abb1460c955..e488f8a8ea9 100644 --- a/apps/sim/app/(interfaces)/chat/components/input/input.tsx +++ b/apps/sim/app/(interfaces)/chat/components/input/input.tsx @@ -124,7 +124,7 @@ export const ChatInput: React.FC<{ const canSubmit = (inputValue.trim().length > 0 || attachedFiles.length > 0) && !isStreaming return ( -
+
{uploadErrors.length > 0 && (
@@ -171,7 +171,7 @@ export const ChatInput: React.FC<{ {attachedFiles.map((file) => ( -
+
{file.dataUrl ? (
diff --git a/apps/sim/app/(interfaces)/chat/components/message-container/message-container.tsx b/apps/sim/app/(interfaces)/chat/components/message-container/message-container.tsx index ff52f4c60ea..b508e99ec58 100644 --- a/apps/sim/app/(interfaces)/chat/components/message-container/message-container.tsx +++ b/apps/sim/app/(interfaces)/chat/components/message-container/message-container.tsx @@ -68,7 +68,7 @@ export function ChatMessageContainer({
{showScrollButton && ( -
+
) : (
-
+
{isWorking ? ( @@ -407,8 +407,8 @@ function BoundedViewport({ children, isStreaming, unbounded = false }: BoundedVi
{!unbounded && hasOverflow && ( <> -
-
+
+
)}
diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/tool-call-item.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/tool-call-item.tsx index 908990eea5d..f76c5e4bf03 100644 --- a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/tool-call-item.tsx +++ b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/tool-call-item.tsx @@ -239,7 +239,7 @@ export function ToolCallItem({ return (
- {BlockIcon && } + {BlockIcon && } {isExecuting ? ( {title} diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/chat-content/chat-content.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/chat-content/chat-content.tsx index c143c72bb4a..ad0b2c55bb2 100644 --- a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/chat-content/chat-content.tsx +++ b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/chat-content/chat-content.tsx @@ -298,7 +298,7 @@ const MARKDOWN_COMPONENTS = { {kind && ref && ( )} {children} diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/interaction-card.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/interaction-card.tsx index 3ad8133f722..31ac390e5bf 100644 --- a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/interaction-card.tsx +++ b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/interaction-card.tsx @@ -5,7 +5,7 @@ export const INTERACTION_CARD_ROW_CLASSES = 'flex items-center gap-2 border-[var(--border)] px-2 py-2 text-left transition-colors' export const INTERACTION_CARD_TEXT_INPUT_CLASSES = - 'min-w-0 flex-1 border-0 bg-transparent p-0 text-[var(--text-body)] text-sm outline-none placeholder:text-[var(--text-muted)] disabled:cursor-not-allowed' + 'min-w-0 flex-1 border-0 bg-transparent p-0 text-[var(--text-body)] text-sm outline-hidden placeholder:text-[var(--text-muted)] disabled:cursor-not-allowed' export interface InteractionCardRecapItem { label: string diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/question/question.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/question/question.tsx index 49dc7d9f4c4..4ab09fcf173 100644 --- a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/question/question.tsx +++ b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/question/question.tsx @@ -54,7 +54,7 @@ export function parseQuestionAnswerMessage( } /** Ghost icon-button chrome shared by the stepper chevrons and the dismiss X. */ -const ICON_BUTTON_CLASSES = 'relative size-[14px] flex-shrink-0 p-0' +const ICON_BUTTON_CLASSES = 'relative size-[14px] shrink-0 p-0' /** * Leading checkbox slot for multi_select rows. Purely presentational — it @@ -64,7 +64,7 @@ const ICON_BUTTON_CLASSES = 'relative size-[14px] flex-shrink-0 p-0' */ function RowCheckbox({ checked, disabled }: { checked: boolean; disabled?: boolean }) { return ( -
+
0} leading={ isMulti ? ( -
+
@@ -1525,9 +1525,9 @@ export function BrowserSession({ type='button' aria-label='Browser menu' title='Browser menu' - className={cn(chipVariants(), 'flex-shrink-0')} + className={cn(chipVariants(), 'shrink-0')} > - +
{entry.status === 'executing' && ( - + )} {getToolStatusDisplayTitle(entry.displayTitle, entry.status, entry.toolName)} diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-content/resource-content.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-content/resource-content.tsx index 82fcd1814e0..57e17b324e7 100644 --- a/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-content/resource-content.tsx +++ b/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-content/resource-content.tsx @@ -782,7 +782,7 @@ function EmbeddedFolder({ workspaceId, folderId }: EmbeddedFolderProps) { onClick={() => openInternalLink(`/workspace/${workspaceId}/w/${w.id}`)} className='flex items-center gap-2 rounded-[6px] px-3 py-2 text-left transition-colors hover:bg-[var(--surface-4)]' > - + ))} diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-registry/resource-registry.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-registry/resource-registry.tsx index 527c6d4cf3a..8d39213854f 100644 --- a/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-registry/resource-registry.tsx +++ b/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-registry/resource-registry.tsx @@ -53,7 +53,7 @@ export interface ResourceTypeConfig { function WorkflowDropdownItem({ item }: DropdownItemRenderProps) { return ( <> - + ) @@ -67,7 +67,7 @@ function FileDropdownItem({ item }: DropdownItemRenderProps) { const DocIcon = getDocumentIcon('', item.name) return ( <> - + ) @@ -76,7 +76,7 @@ function FileDropdownItem({ item }: DropdownItemRenderProps) { function IconDropdownItem({ item, icon: Icon }: DropdownItemRenderProps & { icon: ElementType }) { return ( <> - + ) @@ -93,7 +93,7 @@ function IntegrationDropdownItem({ item }: DropdownItemRenderProps) { if (!Icon) return return ( <> - + ) @@ -114,19 +114,19 @@ function LogDropdownItem({ item }: DropdownItemRenderProps) { const statusColor = status === 'info' ? null : STATUS_CONFIG[status].color return ( <> - + {statusColor && (
)} {time && ( diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/suggested-actions/suggested-actions.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/suggested-actions/suggested-actions.tsx index 32f878c1a27..7651b33d0d4 100644 --- a/apps/sim/app/workspace/[workspaceId]/home/components/suggested-actions/suggested-actions.tsx +++ b/apps/sim/app/workspace/[workspaceId]/home/components/suggested-actions/suggested-actions.tsx @@ -362,14 +362,14 @@ export function SuggestedActions({ onSelectPrompt }: SuggestedActionsProps) { */} - + {/* 6px, matching a sidebar section header to its first item — both headers are an 18px box around 12px text, so equal padding reads as equal distance. Padding an inner wrapper rather than the animated element: @@ -389,7 +389,7 @@ export function SuggestedActions({ onSelectPrompt }: SuggestedActionsProps) { i > 0 && 'border-t' )} > - + {action.label} diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/user-input/components/constants.ts b/apps/sim/app/workspace/[workspaceId]/home/components/user-input/components/constants.ts index 6d1658abfc3..e002eed8602 100644 --- a/apps/sim/app/workspace/[workspaceId]/home/components/user-input/components/constants.ts +++ b/apps/sim/app/workspace/[workspaceId]/home/components/user-input/components/constants.ts @@ -74,7 +74,7 @@ const FIELD_MIRROR_CLASSES = cn( export const TEXTAREA_BASE_CLASSES = cn( FIELD_MIRROR_CLASSES, 'block h-auto resize-none overflow-hidden', - 'text-transparent caret-[var(--text-primary)] outline-none', + 'text-transparent caret-[var(--text-primary)] outline-hidden', 'placeholder:text-[var(--text-muted)]', 'focus-visible:ring-0 focus-visible:ring-offset-0' ) diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/user-input/components/prompt-editor/prompt-editor.test.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/user-input/components/prompt-editor/prompt-editor.test.tsx index cc8c6431457..30a4a7d0ea2 100644 --- a/apps/sim/app/workspace/[workspaceId]/home/components/user-input/components/prompt-editor/prompt-editor.test.tsx +++ b/apps/sim/app/workspace/[workspaceId]/home/components/user-input/components/prompt-editor/prompt-editor.test.tsx @@ -258,7 +258,7 @@ describe('PromptEditor autosize', () => { const initialValue = `${'x'.repeat(PASTE_RENDER_THRESHOLDS.ENHANCED_TEXT_CHARACTERS)} ${SKILL_CHIP_TRIGGER}summarize` const { textarea, unmount } = mountEditor({ initialValue, initialContexts: [context] }) - expect(textarea.className).not.toContain('!text-[var(--text-primary)]') + expect(textarea.className).not.toContain('text-[var(--text-primary)]!') expect(textarea.parentElement?.querySelector('[aria-hidden="true"]')).not.toBeNull() unmount() diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/user-input/components/prompt-editor/prompt-editor.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/user-input/components/prompt-editor/prompt-editor.tsx index 1d1b084917a..4f4c0b55587 100644 --- a/apps/sim/app/workspace/[workspaceId]/home/components/user-input/components/prompt-editor/prompt-editor.tsx +++ b/apps/sim/app/workspace/[workspaceId]/home/components/user-input/components/prompt-editor/prompt-editor.tsx @@ -263,7 +263,7 @@ export function PromptEditor({ rows={1} className={cn( TEXTAREA_BASE_CLASSES, - usePlainTextMode && '!text-[var(--text-primary)]', + usePlainTextMode && 'text-[var(--text-primary)]!', readOnly && 'cursor-default caret-transparent' )} /> diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/user-message-content/user-message-content.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/user-message-content/user-message-content.tsx index f7ed8d201b2..adb3db4a40a 100644 --- a/apps/sim/app/workspace/[workspaceId]/home/components/user-message-content/user-message-content.tsx +++ b/apps/sim/app/workspace/[workspaceId]/home/components/user-message-content/user-message-content.tsx @@ -111,7 +111,7 @@ function MentionHighlight({ context }: { context: ChatMessageContext }) { {context.label} diff --git a/apps/sim/app/workspace/[workspaceId]/home/home.tsx b/apps/sim/app/workspace/[workspaceId]/home/home.tsx index 0cff110666d..0f75d4d254d 100644 --- a/apps/sim/app/workspace/[workspaceId]/home/home.tsx +++ b/apps/sim/app/workspace/[workspaceId]/home/home.tsx @@ -738,7 +738,7 @@ export function Home({ chatId, userName, userId }: HomeProps) { isAgentResponding={isSending} genericResourceData={genericResourceData ?? undefined} onUserInteraction={handleResourceInteraction} - className={skipResourceTransition ? '!transition-none' : undefined} + className={skipResourceTransition ? 'transition-none!' : undefined} /> diff --git a/apps/sim/app/workspace/[workspaceId]/integrations/components/integrations-showcase/integrations-showcase.tsx b/apps/sim/app/workspace/[workspaceId]/integrations/components/integrations-showcase/integrations-showcase.tsx index 43a25c08ba1..0e539ce18ec 100644 --- a/apps/sim/app/workspace/[workspaceId]/integrations/components/integrations-showcase/integrations-showcase.tsx +++ b/apps/sim/app/workspace/[workspaceId]/integrations/components/integrations-showcase/integrations-showcase.tsx @@ -83,7 +83,7 @@ export function IntegrationTile({ blockType, icon: Icon, framed = false }: Integ } return ( -
+
{FIELD_TYPE_LABELS[tag.fieldType] || tag.fieldType} -
+
{formatValueForDisplay(tag.value, tag.fieldType)} -
+
) } diff --git a/apps/sim/app/workspace/[workspaceId]/knowledge/[id]/components/add-documents-modal/add-documents-modal.tsx b/apps/sim/app/workspace/[workspaceId]/knowledge/[id]/components/add-documents-modal/add-documents-modal.tsx index 90862127cb8..56144f8dee7 100644 --- a/apps/sim/app/workspace/[workspaceId]/knowledge/[id]/components/add-documents-modal/add-documents-modal.tsx +++ b/apps/sim/app/workspace/[workspaceId]/knowledge/[id]/components/add-documents-modal/add-documents-modal.tsx @@ -193,10 +193,10 @@ export function AddDocumentsModal({ > {file.name} - + {formatFileSize(file.size)} -
+
{isProcessing ? ( ) : ( diff --git a/apps/sim/app/workspace/[workspaceId]/knowledge/[id]/components/base-tags-modal/base-tags-modal.tsx b/apps/sim/app/workspace/[workspaceId]/knowledge/[id]/components/base-tags-modal/base-tags-modal.tsx index ec640af722a..aa2d370e492 100644 --- a/apps/sim/app/workspace/[workspaceId]/knowledge/[id]/components/base-tags-modal/base-tags-modal.tsx +++ b/apps/sim/app/workspace/[workspaceId]/knowledge/[id]/components/base-tags-modal/base-tags-modal.tsx @@ -52,13 +52,13 @@ function DocumentList({ documents, totalCount }: DocumentListProps) { const DocumentIcon = getDocumentIcon('', doc.name) return (
- + {doc.name} {doc.tagValue && ( <> -
+
{doc.tagValue} @@ -287,11 +287,11 @@ export function BaseTagsModal({ open, onOpenChange, knowledgeBaseId }: BaseTagsM {FIELD_TYPE_LABELS[tag.fieldType] || tag.fieldType} -
+
{usage.documentCount} document{usage.documentCount !== 1 ? 's' : ''} -
+
-
+
{canEdit && ( <> {canFullResync ? ( @@ -522,7 +522,7 @@ function ConnectorCard({
- + Connector disabled after repeated sync failures

@@ -725,7 +725,7 @@ export function SyncHistory({ logs, isLoading }: SyncHistoryProps) { return (

-
+
{state === 'running' ? ( ) : state === 'interrupted' ? ( diff --git a/apps/sim/app/workspace/[workspaceId]/knowledge/[id]/components/edit-connector-modal/edit-connector-modal.tsx b/apps/sim/app/workspace/[workspaceId]/knowledge/[id]/components/edit-connector-modal/edit-connector-modal.tsx index c2e13149394..dd552f97dd1 100644 --- a/apps/sim/app/workspace/[workspaceId]/knowledge/[id]/components/edit-connector-modal/edit-connector-modal.tsx +++ b/apps/sim/app/workspace/[workspaceId]/knowledge/[id]/components/edit-connector-modal/edit-connector-modal.tsx @@ -466,7 +466,7 @@ function DocumentsTab({ knowledgeBaseId, connectorId }: DocumentsTabProps) { href={doc.sourceUrl} target='_blank' rel='noopener noreferrer' - className='flex size-5 flex-shrink-0 items-center justify-center rounded-md text-[var(--text-icon)] transition-colors hover-hover:bg-[var(--surface-5)] hover-hover:text-[var(--text-primary)]' + className='flex size-5 shrink-0 items-center justify-center rounded-md text-[var(--text-icon)] transition-colors hover-hover:bg-[var(--surface-5)] hover-hover:text-[var(--text-primary)]' > @@ -478,7 +478,7 @@ function DocumentsTab({ knowledgeBaseId, connectorId }: DocumentsTabProps) { ) : ( -
+
)} {!isIterationType(span.type) && ( - + {formatDuration(duration, { precision: 2 })}
@@ -494,7 +494,7 @@ function DetailCodeSection({ {copied ? ( @@ -531,7 +531,7 @@ function DetailCodeSection({ e.stopPropagation() activateSearch() }} - className='size-[20px] cursor-pointer border border-[var(--border-1)] bg-transparent p-0 backdrop-blur-sm hover-hover:bg-[var(--surface-3)]' + className='size-[20px] cursor-pointer border border-[var(--border-1)] bg-transparent p-0 backdrop-blur-xs hover-hover:bg-[var(--surface-3)]' > @@ -544,7 +544,7 @@ function DetailCodeSection({ {isSearchActive && (
e.stopPropagation()} > )} - + {formatDuration(totalDuration, { precision: 2 }) || '—'} - + {blockCount} {blockCount === 1 ? 'span' : 'spans'} {(() => { const rootCost = formatCostAmount(runCostDollars ?? normalizedSpans[0]?.cost?.total) return rootCost ? ( - + {rootCost} ) : null @@ -1047,7 +1043,7 @@ export const TraceView = memo(function TraceView({ traceSpans, runCostDollars }: @@ -210,7 +210,7 @@ export const WorkflowOutputSection = memo( {isSearchActive && (
e.stopPropagation()} > -
diff --git a/apps/sim/app/workspace/[workspaceId]/logs/logs.tsx b/apps/sim/app/workspace/[workspaceId]/logs/logs.tsx index 7cdc892da44..a1dd5a25dfe 100644 --- a/apps/sim/app/workspace/[workspaceId]/logs/logs.tsx +++ b/apps/sim/app/workspace/[workspaceId]/logs/logs.tsx @@ -195,7 +195,7 @@ function getColorIcon(color: string): React.ComponentType<{ className?: string } const ColorIcon = ({ className }: { className?: string }) => (
+ return } function getTriggerIcon( @@ -220,7 +220,7 @@ function getTriggerIcon( if (!block?.icon) return undefined const BlockIcon = block.icon const TriggerIcon = ({ className }: { className?: string }) => ( - + ) TriggerIcon.displayName = `TriggerIcon(${triggerType})` return TriggerIcon @@ -1469,7 +1469,7 @@ function LogsFilterPanel({ searchQuery, onSearchQueryChange }: LogsFilterPanelPr {selectedStatusColor && (
)} @@ -1494,7 +1494,7 @@ function LogsFilterPanel({ searchQuery, onSearchQueryChange }: LogsFilterPanelPr overlayContent={ {selectedWorkflow && ( - + )} {workflowDisplayLabel} diff --git a/apps/sim/app/workspace/[workspaceId]/settings/billing/credit-usage/credit-usage-view.tsx b/apps/sim/app/workspace/[workspaceId]/settings/billing/credit-usage/credit-usage-view.tsx index f476317d649..011aed2ce38 100644 --- a/apps/sim/app/workspace/[workspaceId]/settings/billing/credit-usage/credit-usage-view.tsx +++ b/apps/sim/app/workspace/[workspaceId]/settings/billing/credit-usage/credit-usage-view.tsx @@ -49,13 +49,13 @@ interface UsageLogRowProps { function UsageLogRow({ log }: UsageLogRowProps) { return (
- + {formatDateTime(new Date(log.createdAt))} {rowLabel(log)} - + {formatApportionedCreditCost(log.creditCost, log.hasCost)}
diff --git a/apps/sim/app/workspace/[workspaceId]/settings/components/activity-log/activity-log.tsx b/apps/sim/app/workspace/[workspaceId]/settings/components/activity-log/activity-log.tsx index 860cbb3c53f..dcaf990fa70 100644 --- a/apps/sim/app/workspace/[workspaceId]/settings/components/activity-log/activity-log.tsx +++ b/apps/sim/app/workspace/[workspaceId]/settings/components/activity-log/activity-log.tsx @@ -57,12 +57,10 @@ function ActivityLogRow({ const cells = ( <> - + {entry.timestamp} - - {entry.event} - + {entry.event} {typeof entry.description === 'string' ? ( @@ -70,7 +68,7 @@ function ActivityLogRow({ entry.description )} - + {typeof entry.actor === 'string' ? ( ) : ( @@ -79,7 +77,7 @@ function ActivityLogRow({ {expandable && ( @@ -121,10 +119,7 @@ function ActivityLogRow({ )} {hasTrailingColumn && ( {entry.trailing} @@ -175,16 +170,14 @@ export function ActivityLog({ return (
- Timestamp - - {eventLabel} - + Timestamp + {eventLabel} {descriptionLabel} - Actor + Actor {/* Row actions carry no header, but the column must still be reserved here or every label above would sit left of the data below it. */} {hasTrailingColumn && ( - + )}
diff --git a/apps/sim/app/workspace/[workspaceId]/settings/components/api-keys/api-keys.tsx b/apps/sim/app/workspace/[workspaceId]/settings/components/api-keys/api-keys.tsx index c1e97c0355e..05adc77f7e9 100644 --- a/apps/sim/app/workspace/[workspaceId]/settings/components/api-keys/api-keys.tsx +++ b/apps/sim/app/workspace/[workspaceId]/settings/components/api-keys/api-keys.tsx @@ -62,7 +62,7 @@ interface ApiKeyRowMenuProps { */ function ApiKeyRowMenu({ keyName, onDelete, canDelete = true }: ApiKeyRowMenuProps) { return ( -
+
+
-
+
@@ -668,13 +668,11 @@ export function Billing({ scope, organizationId, creditUsageHref }: BillingProps 'flex items-center gap-2.5 rounded-lg p-2 text-left transition-colors' const rowContent = ( <> - - {invoice.date} - + {invoice.date} {invoice.badge.label} - + {invoice.amount} diff --git a/apps/sim/app/workspace/[workspaceId]/settings/components/byok/byok-provider-keys-modal.tsx b/apps/sim/app/workspace/[workspaceId]/settings/components/byok/byok-provider-keys-modal.tsx index e29cee913d8..fdc4e76b879 100644 --- a/apps/sim/app/workspace/[workspaceId]/settings/components/byok/byok-provider-keys-modal.tsx +++ b/apps/sim/app/workspace/[workspaceId]/settings/components/byok/byok-provider-keys-modal.tsx @@ -70,7 +70,7 @@ export function BYOKProviderKeysModal({ />
{(capabilities.update || capabilities.delete) && ( -
+
{capabilities.update && onUpdateKey(key)}>Update} {capabilities.delete && onDeleteKey(key)}>Delete}
diff --git a/apps/sim/app/workspace/[workspaceId]/settings/components/default-zoom-select.tsx b/apps/sim/app/workspace/[workspaceId]/settings/components/default-zoom-select.tsx index dc0cf8c90f9..a111048067d 100644 --- a/apps/sim/app/workspace/[workspaceId]/settings/components/default-zoom-select.tsx +++ b/apps/sim/app/workspace/[workspaceId]/settings/components/default-zoom-select.tsx @@ -27,7 +27,7 @@ export function DefaultZoomSelect({ ariaLabel = 'Default zoom', }: DefaultZoomSelectProps) { return ( -
+
setName(e.target.value)} onKeyDown={handleKeyDown} onBlur={handleInputBlur} - className='absolute top-0 left-0 h-full w-full border-0 bg-transparent p-0 text-base outline-none focus:outline-none focus:ring-0 focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-offset-0' + className='absolute top-0 left-0 h-full w-full border-0 bg-transparent p-0 text-base outline-hidden focus:outline-hidden focus:ring-0 focus-visible:outline-hidden focus-visible:ring-0 focus-visible:ring-offset-0' maxLength={100} disabled={updateProfile.isPending} autoComplete='off' @@ -396,7 +396,7 @@ export function General() {
@@ -168,7 +168,7 @@ export function InboxTaskList() { )}
-
+
{formatRelativeTime(task.createdAt)} diff --git a/apps/sim/app/workspace/[workspaceId]/settings/components/mcp/mcp.tsx b/apps/sim/app/workspace/[workspaceId]/settings/components/mcp/mcp.tsx index 29aff5fb184..dd96fd4efc5 100644 --- a/apps/sim/app/workspace/[workspaceId]/settings/components/mcp/mcp.tsx +++ b/apps/sim/app/workspace/[workspaceId]/settings/components/mcp/mcp.tsx @@ -591,7 +591,7 @@ export function MCP() { {hasParams && ( diff --git a/apps/sim/app/workspace/[workspaceId]/settings/components/member-list/member-list.tsx b/apps/sim/app/workspace/[workspaceId]/settings/components/member-list/member-list.tsx index 718e3342866..72ada4c1ef1 100644 --- a/apps/sim/app/workspace/[workspaceId]/settings/components/member-list/member-list.tsx +++ b/apps/sim/app/workspace/[workspaceId]/settings/components/member-list/member-list.tsx @@ -6,7 +6,7 @@ import { SettingsEmptyState } from '@/app/workspace/[workspaceId]/settings/compo import { SettingsSection } from '@/app/workspace/[workspaceId]/settings/components/settings-section/settings-section' const ROW_CLASSES = 'flex items-center gap-2.5 p-2' -const ROW_STATUS_CLASSES = 'flex-shrink-0 text-[var(--text-muted)] text-caption' +const ROW_STATUS_CLASSES = 'shrink-0 text-[var(--text-muted)] text-caption' interface MemberAvatarProps { name: string @@ -24,13 +24,13 @@ export function MemberAvatar({ name, image }: MemberAvatarProps) { src={image} alt={name} referrerPolicy='no-referrer' - className='size-[14px] flex-shrink-0 rounded-full border border-[var(--border)] object-cover' + className='size-[14px] shrink-0 rounded-full border border-[var(--border)] object-cover' /> ) } return ( - + {name.charAt(0).toUpperCase()} ) diff --git a/apps/sim/app/workspace/[workspaceId]/settings/components/row-actions-menu/row-actions-menu.tsx b/apps/sim/app/workspace/[workspaceId]/settings/components/row-actions-menu/row-actions-menu.tsx index 645e0b9a7d4..06820b613a7 100644 --- a/apps/sim/app/workspace/[workspaceId]/settings/components/row-actions-menu/row-actions-menu.tsx +++ b/apps/sim/app/workspace/[workspaceId]/settings/components/row-actions-menu/row-actions-menu.tsx @@ -45,7 +45,7 @@ export function RowActionsMenu({ label, actions, triggerClassName }: RowActionsM diff --git a/apps/sim/app/workspace/[workspaceId]/settings/components/settings-resource-row/settings-resource-row.tsx b/apps/sim/app/workspace/[workspaceId]/settings/components/settings-resource-row/settings-resource-row.tsx index 3753caed70f..e0c7ddbc74b 100644 --- a/apps/sim/app/workspace/[workspaceId]/settings/components/settings-resource-row/settings-resource-row.tsx +++ b/apps/sim/app/workspace/[workspaceId]/settings/components/settings-resource-row/settings-resource-row.tsx @@ -51,7 +51,7 @@ interface SettingsResourceRowProps { /** * Interactive controls pinned to the row's end (chips, actions menu). These sit * ABOVE the row's own hit area, so their clicks are theirs. The row keeps them at - * their natural size — callers never need their own `flex-shrink-0`. + * their natural size — callers never need their own `shrink-0`. * * Decorative trailing content (a status badge, a tag) belongs in {@link badge}: * anything placed here swallows clicks meant for the row. @@ -95,7 +95,7 @@ interface SettingsResourceRowProps { } /** The one navigation chevron for every settings resource row. */ -export const RESOURCE_ROW_ARROW_CLASSES = 'size-4 flex-shrink-0 text-[var(--text-icon)]' +export const RESOURCE_ROW_ARROW_CLASSES = 'size-4 shrink-0 text-[var(--text-icon)]' /** * Single-column list of {@link SettingsResourceRow}s. The rows carry their own @@ -117,7 +117,7 @@ export const RESOURCE_LIST_GRID = 'grid grid-cols-[repeat(auto-fit,minmax(264px,1fr))] gap-x-6 gap-y-0.5' const PLAIN_BASE = - 'flex size-[14px] flex-shrink-0 items-center justify-center text-[var(--text-icon)] [&_svg]:size-[14px] [&_img]:size-[14px]' + 'flex size-[14px] shrink-0 items-center justify-center text-[var(--text-icon)] [&_svg]:size-[14px] [&_img]:size-[14px]' export function SettingsResourceRow({ icon, @@ -191,7 +191,7 @@ export function SettingsResourceRow({ // Decoration and the chevron stay click-through so the row's right edge never // becomes a dead zone; only `trailing` takes pointer events back. const end = hasEnd ? ( -
+
{badge} {trailing != null &&
{trailing}
} {navigable && } @@ -217,7 +217,7 @@ export function SettingsResourceRow({ const controlClass = cn( clusterClass, - 'min-w-0 flex-1 cursor-pointer focus-visible:outline-none', + 'min-w-0 flex-1 cursor-pointer focus-visible:outline-hidden', 'after:absolute after:inset-0 after:rounded-lg after:content-[""]', 'focus-visible:after:ring-2 focus-visible:after:ring-[color-mix(in_srgb,var(--text-muted)_30%,transparent)]' ) diff --git a/apps/sim/app/workspace/[workspaceId]/settings/components/terminal/terminal-theme-picker.tsx b/apps/sim/app/workspace/[workspaceId]/settings/components/terminal/terminal-theme-picker.tsx index c6f9f55aa93..d2c58881a70 100644 --- a/apps/sim/app/workspace/[workspaceId]/settings/components/terminal/terminal-theme-picker.tsx +++ b/apps/sim/app/workspace/[workspaceId]/settings/components/terminal/terminal-theme-picker.tsx @@ -34,7 +34,7 @@ export function TerminalThemePicker({ const selectedValue = typeof value === 'string' ? value : value.id return ( -
+
handleCopyConfig(server.isPublic, server.name)} - className='!p-1.5 -my-1.5' + className='-my-1.5 p-1.5!' > {copiedConfig ? ( @@ -606,12 +606,12 @@ function ServerDetailView({ : 'json' } wrapText - className='!min-h-0 rounded-sm border border-[var(--border-1)]' + className='min-h-0! rounded-sm border border-[var(--border-1)]' /> {activeConfigTab === 'cursor' && ( {entry.useCount > 1 && ( - {entry.useCount} runs + {entry.useCount} runs )} ), diff --git a/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/column-config-sidebar/column-config-sidebar.tsx b/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/column-config-sidebar/column-config-sidebar.tsx index 303742fdd2b..87b813c62ba 100644 --- a/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/column-config-sidebar/column-config-sidebar.tsx +++ b/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/column-config-sidebar/column-config-sidebar.tsx @@ -246,7 +246,7 @@ function ColumnConfigBody({ variant='ghost' size='sm' onClick={onClose} - className='!p-1 size-7' + className='size-7 p-1!' aria-label='Close' > diff --git a/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/column-dropdown/column-dropdown.tsx b/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/column-dropdown/column-dropdown.tsx index 2cb10c8af94..1f4ab32cef4 100644 --- a/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/column-dropdown/column-dropdown.tsx +++ b/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/column-dropdown/column-dropdown.tsx @@ -105,7 +105,7 @@ export function ColumnDropdown({ ) : (
diff --git a/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/enrichments-sidebar/enrichment-config.tsx b/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/enrichments-sidebar/enrichment-config.tsx index b142da251b4..9b7d34e3e11 100644 --- a/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/enrichments-sidebar/enrichment-config.tsx +++ b/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/enrichments-sidebar/enrichment-config.tsx @@ -238,7 +238,7 @@ export function EnrichmentConfig({ variant='ghost' size='sm' onClick={onBack} - className='!p-1 size-7 flex-none' + className='size-7 flex-none p-1!' aria-label='Back to enrichments' > @@ -249,7 +249,7 @@ export function EnrichmentConfig({ variant='ghost' size='sm' onClick={onClose} - className='!p-1 size-7 flex-none' + className='size-7 flex-none p-1!' aria-label='Close' > diff --git a/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/enrichments-sidebar/enrichments-sidebar.tsx b/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/enrichments-sidebar/enrichments-sidebar.tsx index 2ecf49936da..64cd19f1134 100644 --- a/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/enrichments-sidebar/enrichments-sidebar.tsx +++ b/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/enrichments-sidebar/enrichments-sidebar.tsx @@ -77,7 +77,7 @@ function EnrichmentsSidebarBody({ variant='ghost' size='sm' onClick={onClose} - className='!p-1 size-7 flex-none' + className='size-7 flex-none p-1!' aria-label='Close' > @@ -123,7 +123,7 @@ function EnrichmentsSidebarBody({ variant='ghost' size='sm' onClick={onClose} - className='!p-1 size-7 flex-none' + className='size-7 flex-none p-1!' aria-label='Close' > diff --git a/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/select-field/select-options-editor.tsx b/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/select-field/select-options-editor.tsx index 848a0c86921..31b308b7309 100644 --- a/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/select-field/select-options-editor.tsx +++ b/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/select-field/select-options-editor.tsx @@ -78,7 +78,7 @@ export function SelectOptionsEditor({ options, onChange }: SelectOptionsEditorPr variant='ghost' size='sm' onClick={() => remove(option.id)} - className='!p-1 size-7 shrink-0' + className='size-7 shrink-0 p-1!' aria-label={`Remove ${option.name || 'option'}`} > diff --git a/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-action-bar/table-action-bar.tsx b/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-action-bar/table-action-bar.tsx index 301658acb1e..dc8edbd07a1 100644 --- a/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-action-bar/table-action-bar.tsx +++ b/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-action-bar/table-action-bar.tsx @@ -85,7 +85,7 @@ export function TableActionBar({ exit={{ opacity: 0, y: 10 }} transition={{ duration: 0.2 }} className={cn( - '-translate-x-1/2 pointer-events-none absolute bottom-6 left-1/2 z-50 transform', + '-translate-x-1/2 pointer-events-none absolute bottom-6 left-1/2 z-50', className )} > @@ -157,7 +157,7 @@ function ActionIconButton({ label, onClick, disabled, children }: ActionIconButt variant='ghost' onClick={onClick} disabled={disabled} - className='hover-hover:!text-[var(--text-inverse)] size-[28px] rounded-lg bg-[var(--surface-5)] p-0 text-[var(--text-secondary)] hover-hover:bg-[var(--brand-secondary)]' + className='size-[28px] rounded-lg bg-[var(--surface-5)] p-0 text-[var(--text-secondary)] hover-hover:bg-[var(--brand-secondary)] hover-hover:text-[var(--text-inverse)]!' aria-label={label} > {children} diff --git a/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-filter/table-filter.tsx b/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-filter/table-filter.tsx index 3f7430c6e7c..1b3a17006b1 100644 --- a/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-filter/table-filter.tsx +++ b/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-filter/table-filter.tsx @@ -392,7 +392,7 @@ const FilterRuleRow = memo(function FilterRuleRow({ variant='ghost' size='sm' onClick={() => onRemove(rule.id)} - className='!p-1 size-7 shrink-0' + className='size-7 shrink-0 p-1!' aria-label='Remove filter' > diff --git a/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-grid/cells/expanded-cell-popover.tsx b/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-grid/cells/expanded-cell-popover.tsx index 9d1d1208e1d..81586ff5cd3 100644 --- a/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-grid/cells/expanded-cell-popover.tsx +++ b/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-grid/cells/expanded-cell-popover.tsx @@ -263,7 +263,7 @@ function ExpandedCellEditor({ setParseError(null) }} onKeyDown={handleTextareaKeyDown} - className='min-h-0 flex-1 resize-none bg-transparent px-2.5 py-2 font-sans text-[var(--text-primary)] text-small outline-none placeholder:text-[var(--text-muted)]' + className='min-h-0 flex-1 resize-none bg-transparent px-2.5 py-2 font-sans text-[var(--text-primary)] text-small outline-hidden placeholder:text-[var(--text-muted)]' spellCheck={false} autoCorrect='off' /> diff --git a/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-grid/cells/inline-editors.tsx b/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-grid/cells/inline-editors.tsx index ab5d4b4f912..fc5779089b8 100644 --- a/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-grid/cells/inline-editors.tsx +++ b/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-grid/cells/inline-editors.tsx @@ -286,7 +286,7 @@ function ReadyInlineDateEditor({ onBlur={scheduleBlurSave} placeholder='mm/dd/yyyy' className={cn( - 'w-full min-w-0 select-text border-none bg-transparent p-0 text-[var(--text-primary)] text-small outline-none', + 'w-full min-w-0 select-text border-none bg-transparent p-0 text-[var(--text-primary)] text-small outline-hidden', invalid && 'text-[var(--text-error)]' )} /> @@ -402,7 +402,7 @@ function InlineTextEditor({ onWheel={handleEditorWheel} onBlur={() => doSave('blur')} className={cn( - 'w-full min-w-0 select-text border-none bg-transparent p-0 text-[var(--text-primary)] text-small outline-none', + 'w-full min-w-0 select-text border-none bg-transparent p-0 text-[var(--text-primary)] text-small outline-hidden', invalid && 'text-[var(--text-error)]' )} /> @@ -484,13 +484,13 @@ function InlineSelectEditor({ value, column, onSave, onCancel }: InlineEditorPro {!isMulti && !column.required && ( setDraftAnd([])}> None - {draft.length === 0 && } + {draft.length === 0 && } )} {allOptions.map((option) => ( handleSelectOption(e, option.id)}> - {draft.includes(option.id) && } + {draft.includes(option.id) && } ))} diff --git a/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-grid/headers/column-header-menu.tsx b/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-grid/headers/column-header-menu.tsx index 04025f40920..e2667e8434b 100644 --- a/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-grid/headers/column-header-menu.tsx +++ b/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-grid/headers/column-header-menu.tsx @@ -295,7 +295,7 @@ export const ColumnHeaderMenu = React.memo(function ColumnHeaderMenu({ if (e.key === 'Escape') onRenameCancel() }} onBlur={onRenameSubmit} - className='ml-1.5 min-w-0 flex-1 border-0 bg-transparent p-0 text-[var(--text-primary)] text-small outline-none focus:outline-none focus:ring-0' + className='ml-1.5 min-w-0 flex-1 border-0 bg-transparent p-0 text-[var(--text-primary)] text-small outline-hidden focus:outline-hidden focus:ring-0' />
) : readOnly ? ( @@ -315,7 +315,7 @@ export const ColumnHeaderMenu = React.memo(function ColumnHeaderMenu({
) : workflowState.data ? ( <> -
+