Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/raystack/components/button/button.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@

@media (prefers-reduced-motion: no-preference) {
.button {
transition: all 0.2s ease;
transition: var(--rs-transition-interactive);
}
}

Expand Down
21 changes: 21 additions & 0 deletions packages/raystack/components/checkbox/checkbox.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
border: 1px solid var(--rs-color-border-base-secondary);
cursor: pointer;
flex-shrink: 0;
transition: background-color 150ms ease, border-color 150ms ease;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Use shared motion tokens instead of hardcoded values.

The base .checkbox transition uses 150ms ease while the .indicator (line 111) correctly uses var(--rs-duration-fast) var(--rs-ease-out). The ease keyword (cubic-bezier(0.25, 0.1, 0.25, 1)) is also a different curve from --rs-ease-out, so even if durations match, the easing will feel inconsistent between background/border and the indicator. This contradicts the PR objective of consolidating easing and duration into shared tokens.

♻️ Proposed fix
-.checkbox {
+.checkbox {
   /* ... */
-  transition: background-color 150ms ease, border-color 150ms ease;
+  transition:
+    background-color var(--rs-duration-fast) var(--rs-ease-out),
+    border-color var(--rs-duration-fast) var(--rs-ease-out);
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
transition: background-color 150ms ease, border-color 150ms ease;
transition:
background-color var(--rs-duration-fast) var(--rs-ease-out),
border-color var(--rs-duration-fast) var(--rs-ease-out);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/raystack/components/checkbox/checkbox.module.css` at line 23, Update
the base .checkbox transition to use the shared --rs-duration-fast and
--rs-ease-out tokens, matching the existing .indicator transition instead of
hardcoded 150ms ease. Preserve the transitioned background-color and
border-color properties.

}

/* Size variants */
Expand Down Expand Up @@ -107,6 +108,26 @@
width: 100%;
height: 100%;
color: var(--rs-color-foreground-accent-emphasis);
transition: opacity var(--rs-duration-fast) var(--rs-ease-out);
}

.indicator[data-starting-style],
.indicator[data-ending-style],
.indicator[data-unchecked] {
opacity: 0;
}

@media (prefers-reduced-motion: no-preference) {
.indicator {
transition:
opacity var(--rs-duration-fast) var(--rs-ease-out),
transform var(--rs-duration-fast) var(--rs-ease-out);
}

.indicator[data-starting-style],
.indicator[data-ending-style] {
transform: scale(0.8);
}
}

.icon {
Expand Down
10 changes: 9 additions & 1 deletion packages/raystack/components/checkbox/checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,19 @@ function CheckboxItem({
>
<CheckboxPrimitive.Indicator
className={styles.indicator}
keepMounted
render={
render ??
((props, state) => (
<span {...props}>
{state.indeterminate ? <IndeterminateIcon /> : <CheckMarkIcon />}
{(state.checked ||
state.indeterminate ||
state.transitionStatus === 'ending') &&
(state.indeterminate ? (
<IndeterminateIcon />
) : (
<CheckMarkIcon />
))}
</span>
))
}
Expand Down
20 changes: 20 additions & 0 deletions packages/raystack/components/combobox/combobox.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,26 @@
max-height: 320px;
min-width: var(--anchor-width);
overflow: auto;
transform-origin: var(--transform-origin);
transition: opacity var(--rs-duration-fast) var(--rs-ease-out);
}

.content[data-starting-style],
.content[data-ending-style] {
opacity: 0;
}

@media (prefers-reduced-motion: no-preference) {
.content {
transition:
opacity var(--rs-duration-fast) var(--rs-ease-out),
transform var(--rs-duration-fast) var(--rs-ease-out);
}

.content[data-starting-style],
.content[data-ending-style] {
transform: scale(0.97);
}
}

.list {
Expand Down
17 changes: 0 additions & 17 deletions packages/raystack/components/command/command.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -162,20 +162,12 @@
inset: 0;
z-index: var(--rs-z-index-portal);
background-color: var(--rs-color-overlay-black-a5);
transition:
opacity 200ms ease-out,
backdrop-filter 200ms ease-out;
}

.backdropBlur {
backdrop-filter: var(--rs-blur-lg);
}

.backdrop[data-starting-style],
.backdrop[data-ending-style] {
opacity: 0;
}

.viewport {
position: fixed;
inset: 0;
Expand All @@ -202,13 +194,4 @@
overflow: hidden;
outline: none;
isolation: isolate;
transition:
opacity 200ms ease-out,
transform 200ms ease-out;
}

.dialogPopup[data-starting-style],
.dialogPopup[data-ending-style] {
opacity: 0;
transform: scale(0.98);
}
13 changes: 9 additions & 4 deletions packages/raystack/components/dialog/dialog.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
background-color: var(--rs-color-overlay-black-a5);
position: fixed;
inset: 0;
transition: opacity 150ms cubic-bezier(0.45, 1.005, 0, 1.005);
transition: opacity var(--rs-duration-normal) var(--rs-ease-out);
z-index: var(--rs-z-index-portal);
}

Expand All @@ -24,7 +24,7 @@
position: fixed;
top: 0;
left: 50%;
transition: opacity 150ms;
transition: opacity var(--rs-duration-normal) var(--rs-ease-out);
/* translateY is the smaller of 160px (desired top offset) and
calc(50vh - 50%) (the y-coord that vertically centers the dialog,
where the inner 50% resolves to the element's own height). On tall
Expand All @@ -50,6 +50,11 @@
background-color: var(--rs-color-overlay-black-a1);
}

.dialogContent[data-starting-style],
.dialogContent[data-ending-style] {
opacity: 0;
}

.dialogContent.showNestedAnimation[data-starting-style],
.dialogContent.showNestedAnimation[data-ending-style] {
opacity: 0;
Expand Down Expand Up @@ -78,8 +83,8 @@
@media (prefers-reduced-motion: no-preference) {
.dialogContent {
transition:
opacity 150ms,
transform 150ms ease;
opacity var(--rs-duration-normal) var(--rs-ease-out),
transform var(--rs-duration-normal) var(--rs-ease-out);
}
}

Expand Down
4 changes: 2 additions & 2 deletions packages/raystack/components/drawer/drawer.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
z-index: var(--rs-z-index-portal);
background-color: var(--rs-color-overlay-black-a5);
opacity: calc(1 - var(--drawer-swipe-progress, 0));
transition: opacity 450ms cubic-bezier(0.32, 0.72, 0, 1);
transition: opacity var(--rs-duration-drawer) var(--rs-ease-drawer);
}

.backdrop[data-starting-style],
Expand Down Expand Up @@ -202,6 +202,6 @@
.drawerPopup-left,
.drawerPopup-top,
.drawerPopup-bottom {
transition: transform 450ms cubic-bezier(0.32, 0.72, 0, 1);
transition: transform var(--rs-duration-drawer) var(--rs-ease-drawer);
}
}
25 changes: 25 additions & 0 deletions packages/raystack/components/empty-state/empty-state.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,28 @@
height: 100%;
padding: var(--rs-space-9) var(--rs-space-5);
}

@keyframes empty-state-enter {
from {
opacity: 0;
}
}

@keyframes empty-state-enter-rise {
from {
opacity: 0;
translate: 0 var(--rs-space-2);
}
}

.emptyState,
.emptyStateContent {
animation: empty-state-enter var(--rs-duration-moderate) var(--rs-ease-out);
}

@media (prefers-reduced-motion: no-preference) {
.emptyState,
.emptyStateContent {
animation-name: empty-state-enter-rise;
}
}
2 changes: 1 addition & 1 deletion packages/raystack/components/field/field.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
letter-spacing: var(--rs-letter-spacing-small);
outline: none;
box-sizing: border-box;
transition: all 0.2s ease;
transition: var(--rs-transition-interactive);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Gate the .input transition behind prefers-reduced-motion: no-preference.

The transition is declared directly in .input without a reduced-motion guard, while button.module.css (line 211) and text-area.module.css (line 17) both wrap the same --rs-transition-interactive token inside @media (prefers-reduced-motion: no-preference). Users with reduced-motion preference will still see transitions on field inputs, breaking the standardization this PR aims to achieve.

♿ Proposed fix to wrap transition in reduced-motion media query
 .input {
   width: 100%;
   padding: 0 var(--rs-space-3);
   border-radius: var(--rs-radius-2);
   border: 1px solid var(--rs-color-border-base-tertiary);
   background: var(--rs-color-background-base-primary);
   font-weight: var(--rs-font-weight-regular);
   font-size: var(--rs-font-size-small);
   line-height: var(--rs-line-height-small);
   letter-spacing: var(--rs-letter-spacing-small);
   outline: none;
   box-sizing: border-box;
-  transition: var(--rs-transition-interactive);
   height: var(--rs-space-9);
 }
+
+@media (prefers-reduced-motion: no-preference) {
+  .input {
+    transition: var(--rs-transition-interactive);
+  }
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
transition: var(--rs-transition-interactive);
width: 100%;
padding: 0 var(--rs-space-3);
border-radius: var(--rs-radius-2);
border: 1px solid var(--rs-color-border-base-tertiary);
background: var(--rs-color-background-base-primary);
font-weight: var(--rs-font-weight-regular);
font-size: var(--rs-font-size-small);
line-height: var(--rs-line-height-small);
letter-spacing: var(--rs-letter-spacing-small);
outline: none;
box-sizing: border-box;
height: var(--rs-space-9);
}
`@media` (prefers-reduced-motion: no-preference) {
.input {
transition: var(--rs-transition-interactive);
}
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/raystack/components/field/field.module.css` at line 43, Move the
--rs-transition-interactive declaration from the .input base rule into an `@media`
(prefers-reduced-motion: no-preference) block, matching the existing pattern in
button.module.css and text-area.module.css.

height: var(--rs-space-9);
}

Expand Down
21 changes: 21 additions & 0 deletions packages/raystack/components/menu/menu.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,28 @@
border: 0.5px solid var(--rs-color-border-base-primary);
color: var(--rs-color-foreground-base-primary);
min-width: var(--anchor-width);
transform-origin: var(--transform-origin);
transition: opacity var(--rs-duration-fast) var(--rs-ease-out);
}

.content[data-starting-style],
.content[data-ending-style] {
opacity: 0;
}

@media (prefers-reduced-motion: no-preference) {
.content {
transition:
opacity var(--rs-duration-fast) var(--rs-ease-out),
transform var(--rs-duration-fast) var(--rs-ease-out);
}

.content[data-starting-style],
.content[data-ending-style] {
transform: scale(0.97);
}
}

.content:focus,
.content:focus-visible {
outline: none;
Expand Down
4 changes: 2 additions & 2 deletions packages/raystack/components/meter/meter.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,11 @@

@media (prefers-reduced-motion: no-preference) {
.indicator {
transition: width 500ms;
transition: width var(--rs-duration-moderate) linear;
}

.circularIndicatorCircle {
transition: stroke-dashoffset 500ms;
transition: stroke-dashoffset var(--rs-duration-moderate) linear;
Comment on lines +89 to +93

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Verify the 500ms → 250ms duration reduction is intentional.

The previous hardcoded 500ms is replaced with var(--rs-duration-moderate) (250ms), halving the animation duration. This is a significant user-visible behavior change for meter indicators. Additionally, the token's documented scope in effects.css lists "tabs indicator, preview card, tour steps" but not meter/progress — consider updating that comment or introducing a dedicated token if 250ms feels too fast for data-viz indicators.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/raystack/components/meter/meter.module.css` around lines 89 - 93,
Verify whether the meter animation should intentionally change from 500ms to the
250ms var(--rs-duration-moderate) value. If 250ms is not appropriate for meter
indicators, preserve the prior duration or introduce a dedicated token; if it is
intentional, update the token documentation in effects.css to include
meter/progress indicators.

}
}

Expand Down
23 changes: 13 additions & 10 deletions packages/raystack/components/popover/popover.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,24 @@
box-shadow: var(--rs-shadow-soft);
border: 1px solid var(--rs-color-border-base-primary);
color: var(--rs-color-foreground-base-primary);
transform-origin: var(--transform-origin);
transition: opacity var(--rs-duration-normal) var(--rs-ease-out);
}

@keyframes slideUpAndFade {
from {
opacity: 0;
transform: translateY(var(--rs-space-1));
}
to {
opacity: 1;
transform: translateY(0);
}
.popover[data-starting-style],
.popover[data-ending-style] {
opacity: 0;
}

@media (prefers-reduced-motion: no-preference) {
.popover {
animation: slideUpAndFade 400ms cubic-bezier(0.16, 1, 0.3, 1);
transition:
opacity var(--rs-duration-normal) var(--rs-ease-out),
transform var(--rs-duration-normal) var(--rs-ease-out);
}

.popover[data-starting-style],
.popover[data-ending-style] {
transform: scale(0.97);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.positioner {
--easing: cubic-bezier(0.22, 1, 0.36, 1);
--animation-duration: 0.35s;
--easing: var(--rs-ease-out);
--animation-duration: var(--rs-duration-moderate);

z-index: var(--rs-z-index-portal);
height: var(--positioner-height);
Expand Down
4 changes: 2 additions & 2 deletions packages/raystack/components/progress/progress.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,11 @@

@media (prefers-reduced-motion: no-preference) {
.indicator {
transition: width 500ms;
transition: width var(--rs-duration-moderate) linear;
}

.circularIndicatorCircle {
transition: stroke-dashoffset 500ms;
transition: stroke-dashoffset var(--rs-duration-moderate) linear;
Comment on lines +89 to +93

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Same 500ms → 250ms duration reduction as meter — verify intentional.

This file mirrors the meter changes exactly. The same concern about halving the animation duration applies here. Keeping meter and progress on the same token is good for consistency, but confirm the faster fill rate is the desired UX.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/raystack/components/progress/progress.module.css` around lines 89 -
93, Verify whether the duration reduction in the .circularIndicatorCircle
transition is intentional and matches the desired progress UX. If not, restore
the prior duration token; otherwise keep it aligned with the meter transition
token for consistency.

}
}

Expand Down
21 changes: 21 additions & 0 deletions packages/raystack/components/radio/radio.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
justify-content: center;
cursor: pointer;
box-sizing: border-box;
transition: background-color 150ms ease, border-color 150ms ease;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Use shared motion tokens instead of hardcoded values.

Same issue as checkbox.module.css line 23 — the base .radioitem uses 150ms ease while .indicator (line 78) uses var(--rs-duration-fast) var(--rs-ease-out). Different easing curves (ease vs --rs-ease-out) will produce visually inconsistent transitions.

♻️ Proposed fix
 .radioitem {
   /* ... */
-  transition: background-color 150ms ease, border-color 150ms ease;
+  transition:
+    background-color var(--rs-duration-fast) var(--rs-ease-out),
+    border-color var(--rs-duration-fast) var(--rs-ease-out);
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
transition: background-color 150ms ease, border-color 150ms ease;
transition:
background-color var(--rs-duration-fast) var(--rs-ease-out),
border-color var(--rs-duration-fast) var(--rs-ease-out);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/raystack/components/radio/radio.module.css` at line 23, Update the
base .radioitem transition to use the shared --rs-duration-fast and
--rs-ease-out motion tokens, matching the .indicator transition instead of
hardcoded 150ms ease values. Preserve the existing background-color and
border-color transition properties.

}

/* Group-level size — low specificity via :where() so item-level size wins */
Expand Down Expand Up @@ -74,6 +75,26 @@
width: 100%;
height: 100%;
position: relative;
transition: opacity var(--rs-duration-fast) var(--rs-ease-out);
}

.indicator[data-starting-style],
.indicator[data-ending-style],
.indicator[data-unchecked] {
opacity: 0;
}

@media (prefers-reduced-motion: no-preference) {
.indicator {
transition:
opacity var(--rs-duration-fast) var(--rs-ease-out),
transform var(--rs-duration-fast) var(--rs-ease-out);
}

.indicator[data-starting-style],
.indicator[data-ending-style] {
transform: scale(0.8);
}
}

.indicator::after {
Expand Down
2 changes: 1 addition & 1 deletion packages/raystack/components/radio/radio.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ function RadioItem({ className, size, ...props }: RadioItemProps) {
{...props}
className={radioVariants({ size, className })}
>
<RadioPrimitive.Indicator className={styles.indicator} />
<RadioPrimitive.Indicator className={styles.indicator} keepMounted />
</RadioPrimitive.Root>
);
}
Expand Down
Loading
Loading