Skip to content
Merged
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
10 changes: 9 additions & 1 deletion apps/web/app/(app)/ai-settings/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -354,12 +354,20 @@
{!factsQuery.isLoading && facts.length > 0 && (
<div className="space-y-2">
{pagedFacts.map((fact) => (
<div
key={fact.id}
role={selectMode ? 'button' : undefined}
tabIndex={selectMode ? 0 : undefined}

Check warning on line 360 in apps/web/app/(app)/ai-settings/page.tsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

`tabIndex` should only be declared on interactive elements.

See more on https://sonarcloud.io/project/issues?id=thomasluizon_orbit-ui-mobile&issues=AZ1bH7QXQBrRbJAptMmH&open=AZ1bH7QXQBrRbJAptMmH&pullRequest=2
className={`flex items-start gap-3 rounded-2xl bg-background p-3 transition-colors ${
selectMode && selectedFactIds.has(fact.id) ? 'ring-1 ring-primary/40' : ''
}`}
} ${selectMode ? 'cursor-pointer' : ''}`}
onClick={selectMode ? () => toggleFactSelection(fact.id) : undefined}
onKeyDown={selectMode ? (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault()
toggleFactSelection(fact.id)
}
} : undefined}
>

Check warning on line 371 in apps/web/app/(app)/ai-settings/page.tsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use <input type="button">, <input type="image">, <input type="reset">, <input type="submit">, or <button> instead of the "button" role to ensure accessibility across all devices.

See more on https://sonarcloud.io/project/issues?id=thomasluizon_orbit-ui-mobile&issues=AZ1bH7QXQBrRbJAptMmG&open=AZ1bH7QXQBrRbJAptMmG&pullRequest=2
{selectMode && (
<button
Expand Down
4 changes: 3 additions & 1 deletion apps/web/app/(app)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ export default function TodayPage() {
const rect = controlsMenuRef.current?.getBoundingClientRect()
if (rect) {
const preferredLeft = rect.right - CONTROLS_MENU_WIDTH_PX
const maxLeft = window.innerWidth - CONTROLS_MENU_WIDTH_PX - CONTROLS_MENU_MARGIN_PX
const maxLeft = globalThis.innerWidth - CONTROLS_MENU_WIDTH_PX - CONTROLS_MENU_MARGIN_PX
setControlsMenuPosition({
top: rect.bottom + CONTROLS_MENU_MARGIN_PX,
left: Math.min(Math.max(preferredLeft, CONTROLS_MENU_MARGIN_PX), Math.max(CONTROLS_MENU_MARGIN_PX, maxLeft)),
Expand Down Expand Up @@ -454,6 +454,7 @@ export default function TodayPage() {
<div className="pt-4">
<div
role="tablist"
tabIndex={0}
aria-label={t('habits.viewsLabel')}
className="flex bg-surface-ground rounded-[var(--radius-lg)] p-1 gap-1"
onKeyDown={handleTabKeydown}
Expand Down Expand Up @@ -661,6 +662,7 @@ export default function TodayPage() {
createPortal(
<div
ref={controlsMenuPanelRef}
role="menu"
className="fixed z-[70] min-w-[12.5rem] rounded-[var(--radius-lg)] border border-border-muted bg-surface-overlay shadow-[var(--shadow-lg)] p-1"
style={{
left: `${controlsMenuPosition.left}px`,
Expand Down
2 changes: 1 addition & 1 deletion apps/web/components/chat/breakdown-suggestion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -286,8 +286,8 @@ export function BreakdownSuggestion({
className="hidden"
/>
<div
aria-hidden="true"
className={`size-4 rounded border-2 flex items-center justify-center transition-colors shrink-0 ${createAsParent ? 'bg-primary border-primary' : 'border-border'}`}
onClick={() => setCreateAsParent(!createAsParent)}
>
{createAsParent && <Check className="size-2.5 text-white" />}
</div>
Expand Down
23 changes: 13 additions & 10 deletions apps/web/components/gamification/all-done-celebration.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,17 @@ export function AllDoneCelebration() {
if (!mounted || !shouldRender) return null

return createPortal(
<output
aria-live="polite"
className="fixed inset-0 z-[10003] flex items-center justify-center cursor-pointer"
style={{
transition: 'opacity 0.3s ease-out',
opacity: isVisible ? 1 : 0,
}}
onClick={dismiss}
>
<div role="status" aria-live="polite">
<button
type="button"
aria-label={t('habits.allDoneCelebrationTitle')}
className="fixed inset-0 z-[10003] flex items-center justify-center cursor-pointer appearance-none bg-transparent border-none p-0 w-full"
style={{
transition: 'opacity 0.3s ease-out',
opacity: isVisible ? 1 : 0,
}}
onClick={dismiss}
>
{/* Backdrop */}
<div className="absolute inset-0 bg-black/80" />

Expand Down Expand Up @@ -106,7 +108,8 @@ export function AllDoneCelebration() {
{t('habits.allDoneCelebrationSubtitle')}
</p>
</div>
</output>,
</button>
</div>,
document.body
)
}
20 changes: 12 additions & 8 deletions apps/web/components/gamification/goal-completed-celebration.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,17 @@ export function GoalCompletedCelebration() {
if (!mounted || !shouldRender) return null

return createPortal(
<div
className="fixed inset-0 z-[10003] flex items-center justify-center cursor-pointer"
style={{
transition: 'opacity 0.3s ease-out',
opacity: isVisible ? 1 : 0,
}}
onClick={dismiss}
>
<div role="status" aria-live="polite">
<button
type="button"
aria-label={t('goals.completedCelebrationTitle')}
className="fixed inset-0 z-[10003] flex items-center justify-center cursor-pointer appearance-none bg-transparent border-none p-0 w-full"
style={{
transition: 'opacity 0.3s ease-out',
opacity: isVisible ? 1 : 0,
}}
onClick={dismiss}
>
{/* Backdrop */}
<div className="absolute inset-0 bg-black/80" />

Expand Down Expand Up @@ -99,6 +102,7 @@ export function GoalCompletedCelebration() {
{t('goals.completedCelebrationSubtitle', { name: goalName })}
</p>
</div>
</button>
</div>,
document.body
)
Expand Down
23 changes: 13 additions & 10 deletions apps/web/components/gamification/streak-celebration.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,17 @@ export function StreakCelebration() {
if (!mounted || !shouldRender) return null

return createPortal(
<output
aria-live="polite"
className="fixed inset-0 z-[10002] flex items-center justify-center cursor-pointer"
style={{
transition: 'opacity 0.3s ease-out',
opacity: isVisible ? 1 : 0,
}}
onClick={dismiss}
>
<div role="status" aria-live="polite">
<button
type="button"
aria-label={t('streakDisplay.celebration.subtitle', { count: streakCount })}
className="fixed inset-0 z-[10002] flex items-center justify-center cursor-pointer appearance-none bg-transparent border-none p-0 w-full"
style={{
transition: 'opacity 0.3s ease-out',
opacity: isVisible ? 1 : 0,
}}
onClick={dismiss}
>
{/* Backdrop */}
<div className="absolute inset-0 bg-black/75" />

Expand Down Expand Up @@ -129,7 +131,8 @@ export function StreakCelebration() {
{encouragement}
</p>
</div>
</output>,
</button>
</div>,
document.body
)
}
20 changes: 12 additions & 8 deletions apps/web/components/gamification/streak-freeze-celebration.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,17 @@ export const StreakFreezeCelebration = forwardRef<StreakFreezeCelebrationHandle>
if (!mounted || !shouldRender) return null

return createPortal(
<div
className="fixed inset-0 z-[10003] flex items-center justify-center cursor-pointer"
style={{
transition: 'opacity 0.3s ease-out',
opacity: isVisible ? 1 : 0,
}}
onClick={dismiss}
>
<div role="status" aria-live="polite">
<button
type="button"
aria-label={t('streakDisplay.freeze.celebrationTitle')}
className="fixed inset-0 z-[10003] flex items-center justify-center cursor-pointer appearance-none bg-transparent border-none p-0 w-full"
style={{
transition: 'opacity 0.3s ease-out',
opacity: isVisible ? 1 : 0,
}}
onClick={dismiss}
>
{/* Backdrop */}
<div className="absolute inset-0 bg-black/80" />

Expand Down Expand Up @@ -95,6 +98,7 @@ export const StreakFreezeCelebration = forwardRef<StreakFreezeCelebrationHandle>
{t('streakDisplay.freeze.celebrationSubtitle')}
</p>
</div>
</button>
</div>,
document.body
)
Expand Down
8 changes: 5 additions & 3 deletions apps/web/components/gamification/welcome-back-toast.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,10 @@ export function WelcomeBackToast() {
if (!mounted || !shouldRender) return null

return createPortal(
<div
className="fixed top-4 left-1/2 z-[10000] max-w-sm w-[calc(100%-2rem)] bg-surface-overlay border border-border-muted rounded-2xl shadow-[var(--shadow-lg)] backdrop-blur-xl px-5 py-4 cursor-pointer"
<button
type="button"
aria-label={toastMessage}
className="fixed top-4 left-1/2 z-[10000] max-w-sm w-[calc(100%-2rem)] bg-surface-overlay border border-border-muted rounded-2xl shadow-[var(--shadow-lg)] backdrop-blur-xl px-5 py-4 cursor-pointer text-left"
style={{
transition: 'opacity 0.4s var(--ease-spring), transform 0.4s var(--ease-spring)',
opacity: isVisible ? 1 : 0,
Expand All @@ -91,7 +93,7 @@ export function WelcomeBackToast() {
{toastMessage}
</p>
</div>
</div>,
</button>,
document.body
)
}
2 changes: 2 additions & 0 deletions apps/web/components/goals/goal-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -201,18 +201,20 @@
return (
<div ref={listRef} className="space-y-3">
{goals.map((goal, index) => (
<div
key={goal.id}
role="group"
aria-roledescription="draggable item"
draggable
className={getDragClasses(index)}
onDragStart={() => handleDragStart(index)}
onDragEnter={() => handleDragEnter(index)}
onDragEnd={handleDragEnd}
onDragOver={(e) => e.preventDefault()}
onTouchStart={(e) => handleTouchStart(index, e)}
onTouchMove={handleTouchMove}
onTouchEnd={handleTouchEnd}
>

Check warning on line 217 in apps/web/components/goals/goal-list.tsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use <details>, <fieldset>, <optgroup>, or <address> instead of the "group" role to ensure accessibility across all devices.

See more on https://sonarcloud.io/project/issues?id=thomasluizon_orbit-ui-mobile&issues=AZ1bH7USQBrRbJAptMmY&open=AZ1bH7USQBrRbJAptMmY&pullRequest=2
<GoalCard goal={goal} />
</div>
))}
Expand Down
28 changes: 16 additions & 12 deletions apps/web/components/habits/checklist-templates.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,22 +107,26 @@ export function ChecklistTemplates({ items, onLoad }: ChecklistTemplatesProps) {
{t('habits.form.templates')}:
</span>
{templates.map((tmpl) => (
<button
<span
key={tmpl.id}
type="button"
className="inline-flex items-center gap-1 px-2 py-0.5 rounded-lg text-xs bg-surface border border-border-muted text-text-secondary hover:text-text-primary hover:border-primary/30 transition-all duration-150"
className="inline-flex items-center gap-1 rounded-lg text-xs bg-surface border border-border-muted"
>
<span onClick={() => handleLoad(tmpl.id)}>{tmpl.name}</span>
<span
className="text-text-muted hover:text-red-500 transition-colors"
onClick={(e) => {
e.stopPropagation()
handleDelete(tmpl.id)
}}
<button
type="button"
className="px-2 py-0.5 text-text-secondary hover:text-text-primary transition-all duration-150"
onClick={() => handleLoad(tmpl.id)}
>
{tmpl.name}
</button>
<button
type="button"
aria-label={t('common.delete')}
className="px-1 py-0.5 text-text-muted hover:text-red-500 transition-colors"
onClick={() => handleDelete(tmpl.id)}
>
<X className="size-3" />
</span>
</button>
</button>
</span>
))}
</div>
</>
Expand Down
Loading
Loading