authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-09-22 21:33:01-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-09-22 21:33:01-07:00
log866fc907592c9746b407484087d66c409e8034fa
tree5c2f1f7ff106515694e5b2e1449721cd322284b7
parent361b047f5f559abccacc802cd5ab9992b01473ea
signature Signed by PGP key B5690EEEBB952194

refactor(web): menu triggers and items stop restyling ui/menu (#13205)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

12 files changed, 78 insertions(+), 96 deletions(-)

apps/web/src/components/BranchToolbar.tsx+3-3
...@@ -41,7 +41,7 @@ import {...@@ -41,7 +41,7 @@ import {
41} from "./BranchToolbarBranchSelector";41} from "./BranchToolbarBranchSelector";
42import { BranchToolbarEnvironmentSelector } from "./BranchToolbarEnvironmentSelector";42import { BranchToolbarEnvironmentSelector } from "./BranchToolbarEnvironmentSelector";
43import { BranchToolbarEnvModeSelector } from "./BranchToolbarEnvModeSelector";43import { BranchToolbarEnvModeSelector } from "./BranchToolbarEnvModeSelector";
44import { Button } from "./ui/button";44import { ComposerControl } from "./chat/ComposerControl";
45import {45import {
46 Menu,46 Menu,
47 MenuGroup,47 MenuGroup,
...@@ -206,8 +206,8 @@ const MobileRunContextSelector = memo(function MobileRunContextSelector({...@@ -206,8 +206,8 @@ const MobileRunContextSelector = memo(function MobileRunContextSelector({
206 return (206 return (
207 <Menu>207 <Menu>
208 <MenuTrigger208 <MenuTrigger
209 render={<Button variant="ghost" size="xs" />}209 render={<ComposerControl size="xs" />}
210 className="min-w-0 max-w-[48%] flex-initial justify-start font-normal text-muted-foreground/70 text-xs! hover:text-foreground/80"210 className="min-w-0 max-w-[48%] flex-initial justify-start"
211 data-composer-context-control211 data-composer-context-control
212 data-composer-shortcut={[212 data-composer-shortcut={[
213 showEnvironmentPicker && !envLocked ? "composer.host" : "",213 showEnvironmentPicker && !envLocked ? "composer.host" : "",
apps/web/src/components/LegacySidebar.tsx+1-3
...@@ -2732,9 +2732,7 @@ function ProjectSortMenu({...@@ -2732,9 +2732,7 @@ function ProjectSortMenu({
2732 <Menu>2732 <Menu>
2733 <Tooltip>2733 <Tooltip>
2734 <TooltipTrigger2734 <TooltipTrigger
2735 render={2735 render={<MenuTrigger render={<Button size="icon-xs" variant="ghost-muted" />} />}
2736 <MenuTrigger className="inline-flex h-6 min-w-6 cursor-pointer items-center justify-center rounded-md px-[calc(--spacing(1)-1px)] text-icon-muted transition-colors hover:bg-accent hover:text-foreground" />
2737 }
2738 >2736 >
2739 <ArrowUpDownIcon className="size-3.5" />2737 <ArrowUpDownIcon className="size-3.5" />
2740 </TooltipTrigger>2738 </TooltipTrigger>
apps/web/src/components/ProjectScriptsControl.tsx+12-23
...@@ -101,8 +101,6 @@ export default function ProjectScriptsControl({...@@ -101,8 +101,6 @@ export default function ProjectScriptsControl({
101 ),101 ),
102 [fileScripts, scripts],102 [fileScripts, scripts],
103 );103 );
104 const dropdownItemClassName =
105 "data-highlighted:bg-transparent data-highlighted:text-foreground hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground data-highlighted:hover:bg-accent data-highlighted:hover:text-accent-foreground data-highlighted:focus-visible:bg-accent data-highlighted:focus-visible:text-accent-foreground";
106104
107 const openAddDialog = () => {105 const openAddDialog = () => {
108 setEditorRequest({ scriptId: null, initial: EMPTY_PROJECT_SCRIPT_INPUT });106 setEditorRequest({ scriptId: null, initial: EMPTY_PROJECT_SCRIPT_INPUT });
...@@ -153,7 +151,6 @@ export default function ProjectScriptsControl({...@@ -153,7 +151,6 @@ export default function ProjectScriptsControl({
153 <MenuItem151 <MenuItem
154 density={presentation === "menu" ? "touch" : "default"}152 density={presentation === "menu" ? "touch" : "default"}
155 key={`${fileScript.name} ${fileScript.command}`}153 key={`${fileScript.name} ${fileScript.command}`}
156 className={dropdownItemClassName}
157 onClick={() => void importFileScript(fileScript)}154 onClick={() => void importFileScript(fileScript)}
158 >155 >
159 <ScriptIcon icon={fileScript.icon ?? "play"} className="size-4" />156 <ScriptIcon icon={fileScript.icon ?? "play"} className="size-4" />
...@@ -178,7 +175,7 @@ export default function ProjectScriptsControl({...@@ -178,7 +175,7 @@ export default function ProjectScriptsControl({
178 <MenuItem175 <MenuItem
179 density={presentation === "menu" ? "touch" : "default"}176 density={presentation === "menu" ? "touch" : "default"}
180 key={script.id}177 key={script.id}
181 className={`group ${dropdownItemClassName}`}178 className="group"
182 onClick={() => onRunScript(script)}179 onClick={() => onRunScript(script)}
183 >180 >
184 <ScriptIcon icon={script.icon} className="size-4" />181 <ScriptIcon icon={script.icon} className="size-4" />
...@@ -186,17 +183,15 @@ export default function ProjectScriptsControl({...@@ -186,17 +183,15 @@ export default function ProjectScriptsControl({
186 {script.runOnWorktreeCreate ? `${script.name} (setup)` : script.name}183 {script.runOnWorktreeCreate ? `${script.name} (setup)` : script.name}
187 </MenuItemLabel>184 </MenuItemLabel>
188 <span className="relative ms-auto flex h-6 min-w-6 items-center justify-end">185 <span className="relative ms-auto flex h-6 min-w-6 items-center justify-end">
189 {shortcutLabel && (186 {shortcutLabel &&
190 <MenuShortcut187 (presentation === "menu" ? (
191 className={188 <MenuShortcut className="ms-0 mr-7">{shortcutLabel}</MenuShortcut>
192 presentation === "menu"189 ) : (
193 ? "ms-0 mr-7"190 // The shortcut yields its slot to the edit button on hover.
194 : "ms-0 transition-opacity group-hover:opacity-0 group-focus-visible:opacity-0"191 <span className="transition-opacity group-hover:opacity-0 group-focus-visible:opacity-0">
195 }192 <MenuShortcut className="ms-0">{shortcutLabel}</MenuShortcut>
196 >193 </span>
197 {shortcutLabel}194 ))}
198 </MenuShortcut>
199 )}
200 <Button195 <Button
201 type="button"196 type="button"
202 variant="ghost"197 variant="ghost"
...@@ -220,11 +215,7 @@ export default function ProjectScriptsControl({...@@ -220,11 +215,7 @@ export default function ProjectScriptsControl({
220 );215 );
221 })}216 })}
222 {importMenuItems}217 {importMenuItems}
223 <MenuItem218 <MenuItem density={presentation === "menu" ? "touch" : "default"} onClick={openAddDialog}>
224 density={presentation === "menu" ? "touch" : "default"}
225 className={dropdownItemClassName}
226 onClick={openAddDialog}
227 >
228 <PlusIcon className="size-4" />219 <PlusIcon className="size-4" />
229 <MenuItemLabel>Add action</MenuItemLabel>220 <MenuItemLabel>Add action</MenuItemLabel>
230 </MenuItem>221 </MenuItem>
...@@ -296,7 +287,6 @@ export default function ProjectScriptsControl({...@@ -296,7 +287,6 @@ export default function ProjectScriptsControl({
296 </Tooltip>287 </Tooltip>
297 <GroupSeparator className="hidden @3xl/header-actions:block" />288 <GroupSeparator className="hidden @3xl/header-actions:block" />
298 <Menu289 <Menu
299 highlightItemOnHover={false}
300 open={actionsMenuOpen.scripts}290 open={actionsMenuOpen.scripts}
301 onOpenChange={(open) =>291 onOpenChange={(open) =>
302 setActionsMenuOpen({ presentation, scripts: open, imports: false })292 setActionsMenuOpen({ presentation, scripts: open, imports: false })
...@@ -312,7 +302,6 @@ export default function ProjectScriptsControl({...@@ -312,7 +302,6 @@ export default function ProjectScriptsControl({
312 </Group>302 </Group>
313 ) : importableScripts.length > 0 ? (303 ) : importableScripts.length > 0 ? (
314 <Menu304 <Menu
315 highlightItemOnHover={false}
316 open={actionsMenuOpen.imports}305 open={actionsMenuOpen.imports}
317 onOpenChange={(open) =>306 onOpenChange={(open) =>
318 setActionsMenuOpen({ presentation, scripts: false, imports: open })307 setActionsMenuOpen({ presentation, scripts: false, imports: open })
...@@ -327,7 +316,7 @@ export default function ProjectScriptsControl({...@@ -327,7 +316,7 @@ export default function ProjectScriptsControl({
327 </MenuTrigger>316 </MenuTrigger>
328 <MenuPopup align="end">317 <MenuPopup align="end">
329 {importMenuItems}318 {importMenuItems}
330 <MenuItem className={dropdownItemClassName} onClick={openAddDialog}>319 <MenuItem onClick={openAddDialog}>
331 <PlusIcon className="size-4" />320 <PlusIcon className="size-4" />
332 Add action321 Add action
333 </MenuItem>322 </MenuItem>
apps/web/src/components/chat/DraftHeroHeadline.tsx+23-22
...@@ -29,6 +29,7 @@ import {...@@ -29,6 +29,7 @@ import {
29 MenuTrigger,29 MenuTrigger,
30} from "../ui/menu";30} from "../ui/menu";
31import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip";31import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip";
32import { InlineButton } from "../ui/button";
32import { resolveProjectSettings } from "@t3tools/shared/projectSettings";33import { resolveProjectSettings } from "@t3tools/shared/projectSettings";
3334
34interface DraftHeroHeadlineProps {35interface DraftHeroHeadlineProps {
...@@ -140,10 +141,13 @@ export function DraftHeroHeadline({...@@ -140,10 +141,13 @@ export function DraftHeroHeadline({
140 // project title) so the hero sentence reads naturally: an141 // project title) so the hero sentence reads naturally: an
141 // aria-label here would replace the title with an action phrase142 // aria-label here would replace the title with an action phrase
142 // mid-sentence and baffle screen-reader users.143 // mid-sentence and baffle screen-reader users.
143 <MenuTrigger className="pointer-events-auto inline-block max-w-64 truncate border-foreground/60 border-b border-dotted align-baseline text-foreground transition-colors hover:border-foreground/80 focus-visible:rounded-sm focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring" />144 <MenuTrigger
145 render={<InlineButton tone="picker" />}
146 className="pointer-events-auto max-w-64 align-baseline"
147 />
144 }148 }
145 >149 >
146 {activeProjectDisplayName ?? "Choose a project"}150 <span className="min-w-0 truncate">{activeProjectDisplayName ?? "Choose a project"}</span>
147 </TooltipTrigger>151 </TooltipTrigger>
148 {activeProjectDisplayName ? (152 {activeProjectDisplayName ? (
149 <TooltipPopup side="top">{activeProjectDisplayName}</TooltipPopup>153 <TooltipPopup side="top">{activeProjectDisplayName}</TooltipPopup>
...@@ -189,26 +193,23 @@ export function DraftHeroHeadline({...@@ -189,26 +193,23 @@ export function DraftHeroHeadline({
189 >193 >
190 {projectPickerEntries.map(({ group }) => {194 {projectPickerEntries.map(({ group }) => {
191 return (195 return (
192 <MenuRadioItem196 <MenuRadioItem key={group.projectKey} value={group.projectKey} closeOnClick>
193 key={group.projectKey}197 <span className="flex min-w-0 items-center gap-2">
194 value={group.projectKey}198 <ProjectFavicon project={group} className="size-4 shrink-0" />
195 closeOnClick199 <Tooltip>
196 className="[&>span:last-child]:flex [&>span:last-child]:min-w-0 [&>span:last-child]:items-center [&>span:last-child]:gap-2"200 <TooltipTrigger render={<span className="block min-w-0 truncate" />}>
197 >201 {group.displayName}
198 <ProjectFavicon project={group} className="size-4 shrink-0" />202 </TooltipTrigger>
199 <Tooltip>203 <TooltipPopup side="top">{group.displayName}</TooltipPopup>
200 <TooltipTrigger render={<span className="block min-w-0 truncate" />}>204 </Tooltip>
201 {group.displayName}205 {showProjectEnvironments ? (
202 </TooltipTrigger>206 <ProjectEnvironmentBadge
203 <TooltipPopup side="top">{group.displayName}</TooltipPopup>207 group={group}
204 </Tooltip>208 primaryEnvironmentId={primaryEnvironmentId}
205 {showProjectEnvironments ? (209 machineByEnvironmentId={environmentMachineById}
206 <ProjectEnvironmentBadge210 />
207 group={group}211 ) : null}
208 primaryEnvironmentId={primaryEnvironmentId}212 </span>
209 machineByEnvironmentId={environmentMachineById}
210 />
211 ) : null}
212 </MenuRadioItem>213 </MenuRadioItem>
213 );214 );
214 })}215 })}
apps/web/src/components/files/FileBreadcrumbs.tsx+10-3
...@@ -155,7 +155,16 @@ function BreadcrumbMenuContent(props: {...@@ -155,7 +155,16 @@ function BreadcrumbMenuContent(props: {
155 <>155 <>
156 <PierreEntryIcon pathValue={entry.path} kind={entry.kind} theme={resolvedTheme} />156 <PierreEntryIcon pathValue={entry.path} kind={entry.kind} theme={resolvedTheme} />
157 <Tooltip>157 <Tooltip>
158 <TooltipTrigger render={<span className="min-w-0 flex-1 truncate" />}>158 <TooltipTrigger
159 render={
160 <span
161 className={cn(
162 "min-w-0 flex-1 truncate",
163 entry.ignored && "text-muted-foreground",
164 )}
165 />
166 }
167 >
159 {entry.label}168 {entry.label}
160 </TooltipTrigger>169 </TooltipTrigger>
161 <TooltipPopup side="right">{entry.path}</TooltipPopup>170 <TooltipPopup side="right">{entry.path}</TooltipPopup>
...@@ -166,7 +175,6 @@ function BreadcrumbMenuContent(props: {...@@ -166,7 +175,6 @@ function BreadcrumbMenuContent(props: {
166 <MenuItem175 <MenuItem
167 key={entry.path}176 key={entry.path}
168 closeOnClick={false}177 closeOnClick={false}
169 className={entry.ignored ? "text-muted-foreground" : undefined}
170 onClick={() => props.onDirectoryChange(entry.path)}178 onClick={() => props.onDirectoryChange(entry.path)}
171 >179 >
172 {row}180 {row}
...@@ -178,7 +186,6 @@ function BreadcrumbMenuContent(props: {...@@ -178,7 +186,6 @@ function BreadcrumbMenuContent(props: {
178 value={entry.path}186 value={entry.path}
179 closeOnClick187 closeOnClick
180 aria-current={isCurrentFile ? "page" : undefined}188 aria-current={isCurrentFile ? "page" : undefined}
181 className={entry.ignored ? "text-muted-foreground" : undefined}
182 >189 >
183 <span className="flex min-w-0 items-center gap-2">{row}</span>190 <span className="flex min-w-0 items-center gap-2">{row}</span>
184 </MenuRadioItem>191 </MenuRadioItem>
apps/web/src/components/preview/PreviewMoreMenu.tsx+5-4
...@@ -206,10 +206,11 @@ export function PreviewMoreMenu({...@@ -206,10 +206,11 @@ export function PreviewMoreMenu({
206 each one drove the popup far past its width.206 each one drove the popup far past its width.
207 */}207 */}
208 {profileName ? (208 {profileName ? (
209 // Truncation sits on the label itself: it renders a block box, so209 // Truncation needs a block box: `text-overflow` on an inline child
210 // `text-overflow` on an inline child inside it never applies and a210 // never applies and a long name would push the popup past its width.
211 // long name would push the popup past its width instead.211 <MenuGroupLabel className="max-w-64">
212 <MenuGroupLabel className="max-w-64 truncate">Profile: {profileName}</MenuGroupLabel>212 <span className="block truncate">Profile: {profileName}</span>
213 </MenuGroupLabel>
213 ) : null}214 ) : null}
214 <MenuItem215 <MenuItem
215 onClick={() =>216 onClick={() =>
apps/web/src/components/pullRequest/PullRequestStackHeader.tsx+12-10
...@@ -11,16 +11,18 @@ export function PullRequestStackHeader({...@@ -11,16 +11,18 @@ export function PullRequestStackHeader({
11 stale?: boolean;11 stale?: boolean;
12}) {12}) {
13 return (13 return (
14 <MenuGroupLabel className="flex items-center justify-between gap-2">14 <MenuGroupLabel>
15 <span>Stack #{number}</span>15 <div className="flex items-center justify-between gap-2">
16 {notice ? (16 <span>Stack #{number}</span>
17 <Tooltip>17 {notice ? (
18 <TooltipTrigger render={<span role="status" className="text-xs font-normal" />}>18 <Tooltip>
19 {stale ? "May be stale" : "Refreshing…"}19 <TooltipTrigger render={<span role="status" className="text-xs font-normal" />}>
20 </TooltipTrigger>20 {stale ? "May be stale" : "Refreshing…"}
21 <TooltipPopup>{notice}</TooltipPopup>21 </TooltipTrigger>
22 </Tooltip>22 <TooltipPopup>{notice}</TooltipPopup>
23 ) : null}23 </Tooltip>
24 ) : null}
25 </div>
24 </MenuGroupLabel>26 </MenuGroupLabel>
25 );27 );
26}28}
apps/web/src/components/settings/EnvironmentIconPicker.tsx+1-1
...@@ -102,7 +102,7 @@ export function EnvironmentIconMenu({...@@ -102,7 +102,7 @@ export function EnvironmentIconMenu({
102 <MenuSubPopup>102 <MenuSubPopup>
103 {lock !== null ? (103 {lock !== null ? (
104 <>104 <>
105 <MenuItem disabled className="whitespace-normal text-xs">105 <MenuItem disabled className="whitespace-normal">
106 {lock}106 {lock}
107 </MenuItem>107 </MenuItem>
108 <MenuSeparator />108 <MenuSeparator />
apps/web/src/components/settings/SnapShotSettings.tsx+3-16
...@@ -54,10 +54,7 @@ import {...@@ -54,10 +54,7 @@ import {
54 type CaptureSetupStep,54 type CaptureSetupStep,
55} from "./SnapShotSetupDialog.logic";55} from "./SnapShotSetupDialog.logic";
5656
57const soundOptionRowClassName =57const soundOptionRowClassName = "grid grid-cols-[1fr_auto]";
58 "grid grid-cols-[1fr_auto] rounded-sm has-data-checked:bg-foreground/[0.08]";
59const soundOptionItemClassName = "data-checked:bg-transparent";
60const soundPreviewClassName = "min-h-7 w-7 justify-center px-0";
6158
62function captureSettingsError(title: string, error: unknown) {59function captureSettingsError(title: string, error: unknown) {
63 return { title, message: error instanceof Error ? error.message : "Try again." };60 return { title, message: error instanceof Error ? error.message : "Try again." };
...@@ -520,16 +517,11 @@ export function SnapShotSettings() {...@@ -520,16 +517,11 @@ export function SnapShotSettings() {
520 Off517 Off
521 </MenuRadioItem>518 </MenuRadioItem>
522 <div className={soundOptionRowClassName}>519 <div className={soundOptionRowClassName}>
523 <MenuRadioItem520 <MenuRadioItem closeOnClick value="soft-pop">
524 className={soundOptionItemClassName}
525 closeOnClick
526 value="soft-pop"
527 >
528 Whoosh <span className="text-muted-foreground">(Default)</span>521 Whoosh <span className="text-muted-foreground">(Default)</span>
529 </MenuRadioItem>522 </MenuRadioItem>
530 <MenuItem523 <MenuItem
531 aria-label="Play Whoosh"524 aria-label="Play Whoosh"
532 className={soundPreviewClassName}
533 closeOnClick={false}525 closeOnClick={false}
534 onClick={() => playSnapShotSound("soft-pop")}526 onClick={() => playSnapShotSound("soft-pop")}
535 >527 >
...@@ -537,16 +529,11 @@ export function SnapShotSettings() {...@@ -537,16 +529,11 @@ export function SnapShotSettings() {
537 </MenuItem>529 </MenuItem>
538 </div>530 </div>
539 <div className={soundOptionRowClassName}>531 <div className={soundOptionRowClassName}>
540 <MenuRadioItem532 <MenuRadioItem closeOnClick value="camera-shutter">
541 className={soundOptionItemClassName}
542 closeOnClick
543 value="camera-shutter"
544 >
545 Click533 Click
546 </MenuRadioItem>534 </MenuRadioItem>
547 <MenuItem535 <MenuItem
548 aria-label="Play Click"536 aria-label="Play Click"
549 className={soundPreviewClassName}
550 closeOnClick={false}537 closeOnClick={false}
551 onClick={() => playSnapShotSound("camera-shutter")}538 onClick={() => playSnapShotSound("camera-shutter")}
552 >539 >
apps/web/src/components/usage/UsagePage.tsx+1-1
...@@ -738,7 +738,7 @@ function UsageEnvironmentFilter({...@@ -738,7 +738,7 @@ function UsageEnvironmentFilter({
738 <Menu>738 <Menu>
739 <MenuTrigger739 <MenuTrigger
740 render={<InlineButton />}740 render={<InlineButton />}
741 className="group/usage-environment min-w-0 max-w-full gap-1"741 className="group/usage-environment min-w-0 max-w-full"
742 >742 >
743 <span className="min-w-0 truncate">{label}</span>743 <span className="min-w-0 truncate">{label}</span>
744 <span className="flex size-3.5 shrink-0 items-center justify-center text-muted-foreground">744 <span className="flex size-3.5 shrink-0 items-center justify-center text-muted-foreground">
apps/web/src/routes/_chat.pull-requests.tsx+6-9
...@@ -2234,16 +2234,13 @@ function CompactFilterMenu<Value extends string>({...@@ -2234,16 +2234,13 @@ function CompactFilterMenu<Value extends string>({
2234 aria-label={triggerLabel || iconOnly ? `${label}: ${current.label}` : label}2234 aria-label={triggerLabel || iconOnly ? `${label}: ${current.label}` : label}
2235 title={iconOnly ? `${label}: ${current.label}` : undefined}2235 title={iconOnly ? `${label}: ${current.label}` : undefined}
2236 render={2236 render={
2237 outlined ? <Button variant="outline" size={iconOnly ? "icon" : "default"} /> : undefined2237 outlined ? (
2238 }2238 <Button variant="outline" size={iconOnly ? "icon" : "default"} />
2239 className={2239 ) : (
2240 outlined2240 <Button variant="ghost-muted" size="sm" />
2241 ? className2241 )
2242 : cn(
2243 "inline-flex h-7 min-w-0 items-center gap-1 rounded-md px-1.5 text-sm font-medium text-muted-foreground hover:bg-accent hover:text-foreground",
2244 className,
2245 )
2246 }2242 }
2243 className={cn("min-w-0", className)}
2247 >2244 >
2248 {iconOnly ? (2245 {iconOnly ? (
2249 <current.Icon aria-hidden className="size-4" />2246 <current.Icon aria-hidden className="size-4" />
scripts/lint-restyle-ceiling.ts+1-1
...@@ -8,7 +8,7 @@ import * as NodeURL from "node:url";...@@ -8,7 +8,7 @@ import * as NodeURL from "node:url";
8// components/ui exports are migrated to variants (see vite.config.ts). This gate keeps the8// components/ui exports are migrated to variants (see vite.config.ts). This gate keeps the
9// count from growing: CI fails when findings exceed the ceiling. Lower the ceiling when you9// count from growing: CI fails when findings exceed the ceiling. Lower the ceiling when you
10// migrate a file, and delete this script when the rule becomes an error.10// migrate a file, and delete this script when the rule becomes an error.
11export const RESTYLE_CEILING = 582;11export const RESTYLE_CEILING = 499;
1212
13const RULE = "shadcn(no-restyle)";13const RULE = "shadcn(no-restyle)";
1414