Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
524409d
initial updates and tests
sharhio Jan 28, 2026
fe06017
restructuring
sharhio Jan 28, 2026
3f101ab
tests for new components
sharhio Jan 28, 2026
be7722f
separated query fragments
sharhio Jan 28, 2026
45420a9
dropdown context update
sharhio Jan 28, 2026
54fbaf1
refactoring
sharhio Jan 29, 2026
719a710
refactoring
sharhio Jan 30, 2026
5b7e38e
refactoring
sharhio Feb 2, 2026
f50d925
refactoring & bug fixes
sharhio Feb 2, 2026
a77a25a
minor improvements
sharhio Feb 3, 2026
4364de3
new data structure
sharhio Feb 3, 2026
9bf143b
simplification
sharhio Feb 3, 2026
d29c79f
select date instead of range
sharhio Feb 4, 2026
ed45dda
delete redundant files
sharhio Feb 4, 2026
6c805f7
redirections in one place
sharhio Feb 4, 2026
8efa74e
remove duplicate date
sharhio Feb 4, 2026
9f11c02
simplified date logic
sharhio Feb 5, 2026
a006c64
stop memos and useEffects from running on every render
sharhio Feb 5, 2026
9e10371
refactor data population
sharhio Feb 5, 2026
1d89824
fix constant operation render, validation tests
sharhio Feb 9, 2026
8914724
better tests
sharhio Feb 9, 2026
6a7aa55
update jsdocs and comments
sharhio Feb 9, 2026
235a926
all canceled styles updated to black text with red strikethrough
sharhio Feb 9, 2026
fb0a280
minor improvements and better test coverage
sharhio Feb 10, 2026
e9d7278
new schedule datepicker
sharhio Feb 13, 2026
8e3eb94
test fixes
sharhio Feb 13, 2026
2e625e7
selector details and styles
sharhio Feb 17, 2026
fc9bdf6
remove fluxible connection
sharhio Feb 17, 2026
c5ebeaf
refactor date select
sharhio Feb 17, 2026
d4d5bcf
refactoring, tests
sharhio Feb 17, 2026
750e08f
show no trips message
sharhio Feb 23, 2026
17fa82c
redirect and tests
sharhio Feb 23, 2026
ba3bcc6
Merge branch 'v3' into AB#411-timetable-refactor
sharhio Feb 23, 2026
ce6851f
remove unnecessary
sharhio Feb 23, 2026
74eff1f
separate datepicker styles
sharhio Feb 23, 2026
f747602
refactoring & tests
sharhio Feb 23, 2026
1f6cabc
dateselect refactor
sharhio Feb 24, 2026
962086f
dateselect optimization
sharhio Feb 24, 2026
164bbaf
data selection improvement
sharhio Feb 24, 2026
53992ae
redirect refactor
sharhio Feb 24, 2026
3303b10
refactoring and test updates
sharhio Feb 25, 2026
3f1f957
refactoring
sharhio Feb 25, 2026
35bda06
jsdocs fix
sharhio Feb 25, 2026
e15d00c
test refactor
sharhio Feb 25, 2026
f6d9e52
minor cleanup
sharhio Feb 26, 2026
155f8c8
scheduledropdown fixes
sharhio Feb 26, 2026
1fa41ed
better tests
sharhio Feb 27, 2026
36427af
clarify comment
sharhio Feb 27, 2026
b77342d
fix test
sharhio Feb 27, 2026
e3b603e
Merge branch 'next' into AB#411-timetable-refactor
sharhio Feb 27, 2026
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
272 changes: 272 additions & 0 deletions app/component/date-select-grouped.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,272 @@
.route-schedule-grouped-date-select .date-select {
@media print {
display: none;
}

margin-right: 0;
background-color: $white;
border: 1px solid $control-border-color;
display: flex;
align-items: center;
border-radius: var(--space-xs);
height: auto;
min-height: 44px;
justify-content: space-between;
max-width: none;
flex-basis: auto;
width: 100%;

.route-schedule-grouped__control {
width: 100%;
height: 100%;
background: none !important;
border-color: transparent !important;
padding: 13px 16px;

.route-schedule-grouped__value-container {
overflow: visible;
padding: 0;

.route-schedule-grouped__placeholder {
width: 100%;
display: flex;
margin: 0;
padding: 0 3px 0 0;

.left-column {
color: $black;
font-size: 0.92rem;
font-weight: $font-weight-book;
text-align: left;
overflow: visible;
text-overflow: ellipsis;
white-space: nowrap;
display: flex;
flex-direction: column;
border-right: 1px solid $gray;

.combobox-label {
font-size: $font-size-xsmall;
white-space: nowrap;
color: $gray;
letter-spacing: -0.48px;
font-weight: $font-weight-book;
}

.selected-value {
line-height: normal;
letter-spacing: normal;
}

& select {
cursor: pointer;
border-bottom: 2px none !important;
transition: all 0.2s ease-out;
height: 1.27em;
line-height: 1.3em;

&:hover {
color: $secondary-color;
}
}
}
}
}
}

.route-schedule-grouped__control--menu-is-open {
outline: none;
border-color: $primary-color;
background: $white;
border: 1px solid $primary-color;
box-shadow: 0 0 3px 0 $secondary-color;
border-radius: var(--space-xs);
}

.route-schedule-grouped__control--is-focused:not(
.route-schedule-grouped__control--menu-is-open
),
.route-schedule-grouped__control--is-focused:not(
.route-schedule-grouped__control--menu-is-open
)
.route-schedule-grouped__input,
.route-schedule-grouped__control
:focus:not(.route-schedule-grouped__control--menu-is-open) {
border-radius: var(--space-xs);
box-shadow: 0 0 3px 0 $secondary-color;
}

.date-select-arrow {
display: flex;
align-items: center;
justify-content: center;
padding: 0;

svg {
transition: transform 150ms ease-in-out;
transform-origin: center;
}

.inverted {
transform: rotate(180deg);
}
}

.route-schedule-grouped__dropdown-indicator {
padding: 0;
width: 16px;
min-width: 16px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 0; // control padding provides the gap
}

.route-schedule-grouped__dropdown-indicator .date-select-arrow {
width: 16px;
height: 16px;
}
}

.route-schedule-grouped__menu {
width: 100%;
min-width: 100%;
z-index: 9999;
border-radius: var(--space-xs);
overflow: hidden;
background: $white;
border: 1px solid $light-gray;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
max-height: unquote('min(400px, 60vh)');
}

.route-schedule-grouped__menu-list {
margin: 0;
padding: 0;
border-radius: inherit;
position: relative;
max-height: inherit;
overflow-y: auto;
}

.route-schedule-grouped__group-heading {
color: $gray;
font-size: $font-size-xsmall;
font-weight: $font-weight-book;
text-transform: none !important;
border-bottom: 1px solid $light-gray;
padding: 0.5rem 1rem 0.25rem;
border-top: 1px solid $light-gray;
position: relative;

&::before {
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
width: 1px;
background: $light-gray;
pointer-events: none;
}
}

// Remove extra spacing introduced by react-select's group wrapper
.route-schedule-grouped__group {
padding: 0 !important;
margin: 0 !important;
}

// Ensure the first group does not receive top padding from menu-list wrappers
.route-schedule-grouped__menu-list .route-schedule-grouped__group:first-child {
padding-top: 0;

.route-schedule-grouped__group-heading {
border-top: none;
}
}

.route-schedule-grouped__option {
display: flex;
justify-content: space-between;
font-weight: $font-weight-book;
position: relative;
padding: 0.5rem 1rem;
cursor: pointer;
background: $white;

&::after {
content: '';
position: absolute;
left: 8px;
right: 0;
bottom: 0;
height: 1px;
background: $light-gray;
}

&::before {
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
width: 1px;
background: $light-gray;
pointer-events: none;
}

svg {
position: relative;
}
}

.route-schedule-grouped__option:last-child::after {
display: none;
}

.route-schedule-grouped__option--is-selected {
background-color: transparent !important;
color: inherit !important;
}

.route-schedule-grouped__option,
.route-schedule-grouped-date-select .date-select {
.date-select-option {
display: flex;
align-items: center;
width: 100%;
}

.date-select-check {
width: 24px;
padding-left: $padding-xsmall;
padding-right: $padding-xsmall;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
color: $primary-color;

svg {
width: 16px;
height: 16px;
display: block;
}
}

.check-placeholder {
display: inline-block;
width: 16px;
height: 16px;
}

.date-select-label {
flex: 1 1 auto;
padding-left: 0;
display: flex;
align-items: center;
height: 100%;
font-weight: $font-weight-book;
}
}
20 changes: 10 additions & 10 deletions app/component/routepage/RouteControlPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -447,16 +447,6 @@ class RouteControlPanel extends React.Component {
{routeNotifications}
{showStandardControls(route) && (
<>
{patternId && (
<RoutePatternSelectContainer
params={match.params}
route={route}
onSelectChange={this.onPatternChange}
gtfsId={route.gtfsId}
className={cx({ 'bp-large': breakpoint === 'large' })}
useCurrentTime={useCurrentTime}
/>
)}
{/* eslint-disable jsx-a11y/interactive-supports-focus */}
<div
className="route-tabs"
Expand Down Expand Up @@ -560,6 +550,16 @@ class RouteControlPanel extends React.Component {
</div>
</button>
</div>
{patternId && (
<RoutePatternSelectContainer
params={match.params}
route={route}
onSelectChange={this.onPatternChange}
gtfsId={route.gtfsId}
className={cx({ 'bp-large': breakpoint === 'large' })}
useCurrentTime={useCurrentTime}
/>
)}
</>
)}
</div>
Expand Down
34 changes: 27 additions & 7 deletions app/component/routepage/RoutePatternSelectContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,13 @@ class RoutePatternSelectContainer extends Component {

const noSpecialRoutes = !specialRoutes.length;
const noFutureRoutes = !futureRoutes.length;
const noSimilarRoutes = !this.state.similarRoutes?.length;

// If similar-route loading is enabled, avoid treating "no similar routes" as true
// until loading finishes. This prevents an initial button-only render that jumps
// to a dropdown once similar routes load.
const noSimilarRoutes = this.context.config.showSimilarRoutesOnRouteDropDown
? !this.state.similarRoutes?.length && !this.state.loadingSimilar
: true;

const renderButtonOnly =
mainRoutes.length &&
Expand All @@ -170,6 +176,12 @@ class RoutePatternSelectContainer extends Component {
className={cx('route-pattern-select', this.props.className)}
aria-atomic="true"
>
<h3 className="route-pattern-select-title">
<FormattedMessage
id="route-page.choose-direction"
defaultMessage="Choose direction"
/>
</h3>
<label htmlFor="route-pattern-toggle-button">
{directionSwap && (
<span className="sr-only">
Expand Down Expand Up @@ -231,12 +243,20 @@ class RoutePatternSelectContainer extends Component {
}

return (
<RoutePatternSelect
currentPattern={currentPattern}
optionArray={optionArray}
onSelectChange={this.props.onSelectChange}
className={this.props.className}
/>
<div className={cx('route-pattern-select', this.props.className)}>
<h3 className="route-pattern-select-title">
<FormattedMessage
id="route-page.choose-direction"
defaultMessage="Choose direction"
/>
</h3>
<RoutePatternSelect
currentPattern={currentPattern}
optionArray={optionArray}
onSelectChange={this.props.onSelectChange}
className={this.props.className}
/>
</div>
);
}
}
Expand Down
Loading
Loading