Skip to content
Draft
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
1 change: 0 additions & 1 deletion app/component/IndexPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,6 @@ function IndexPage({ fromMap, ...props }, context) {

return config.showNearYouButtons ? (
<CtrlPanel.NearStopsAndRoutes
appElement="#app"
modeArray={modeArray}
loading={favouriteStatus === STATUS_FETCHING_OR_UPDATING}
modeSet={iconModeSet}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,45 @@

<!-- Generated by documentation.js. Update this documentation by updating the source code. -->

## validNearYouModes
## CtrlPanel

CtrlPanel gathers multiple components to same area (desktop-size: left or mobile-size: bottom)

### Parameters

* `props` **[Object][1]**

* `props.children` **[node][2]** panel content (optional, default `DEFAULT_CHILDREN`)
* `props.position` **[string][3]** 'left' or 'bottom'
* `props.fontWeights` **[Object][1]** font weights, e.g. { medium: 500 } (optional, default `DEFAULT_FONT_WEIGHTS`)

### Examples

```javascript
<CtrlPanel language="fi" position="left">
<CtrlPanel.SeparatorLine />
<CtrlPanel.NearStopsAndRoutes
modearray={['bus', 'tram', 'subway', 'rail', 'ferry', 'citybike']}
language="fi"
/>
</CtrlPanel>
```

Show button links to near you page for different travel modes
## CtrlPanel.NearStopsAndRoutes

### Parameters

* `props` **[Object][1]**

* `props.modeArray` **[Array][2]<[string][3]>** Names of transport modes to show buttons for. Should be in lower case. Also defines button order
* `props.modeArray` **[Array][4]<[string][3]>** Names of transport modes to show buttons for. Should be in lower case. Also defines button order
* `props.language` **[string][3]** Language used for accessible labels
* `props.title` **[boolean][4]** Custom titles per language
* `props.title` **[Object][1]** Custom titles per language
* `props.alertsContext` **[Object][1]**

* `props.alertsContext.getModesWithAlerts` **[function][5]** Function which should return an array of transport modes that have active alerts (e.g. \[BUS, SUBWAY])
* `props.alertsContext.currentTime` **[Number][6]** Time stamp with which the returned alerts are validated with
* `props.alertsContext.feedIds` **[Number][6]** feedIds for which the alerts are fetched for
* `props.colors` **[element][7]** theme color configuration
* `props.colors` **[Object][1]** theme color configuration
* `props.urlPrefix` **[string][3]** URL prefix for links

### Examples
Expand All @@ -36,37 +58,17 @@ const alertsContext = {
/>
```

## CtrlPanel

**Extends React.Component**

CtrlPanel gathers multiple components to same area (desktop-size: left or mobile-size: bottom)

### Examples

```javascript
<CtrlPanel language="fi" position="left">
<CtrlPanel.SeparatorLine />
<CtrlPanel.NearStopsAndRoutes
modearray={['bus', 'tram', 'subway', 'rail', 'ferry', 'citybike']}
language="fi"
/>
</CtrlPanel>
```

[1]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object

[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array
[2]: https://developer.mozilla.org/docs/Web/API/Node/nextSibling

[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String

[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean
[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array

[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function

[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number

[7]: https://developer.mozilla.org/docs/Web/API/Element
---

This module is part of the Digitransit-ui project. It is maintained in the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@
},
"peerDependencies": {
"@digitransit-component/digitransit-component-icon": "workspace:^",
"@hsl-fi/modal": "^0.3.2",
"@hsl-fi/dialog": "^3.1.3",
"@hsl-fi/layout-primitives": "^4.9.0",
"@hsl-fi/sass": "1.0.0",
"@hsl-fi/shimmer": "0.1.2",
"classnames": "2.5.1",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,74 +1,66 @@
import PropTypes from 'prop-types';
import React from 'react';
import { useTranslation } from 'react-i18next';
import Modal from '@hsl-fi/modal';
import { Modal, ModalContent } from '@hsl-fi/dialog';
import { Text } from '@hsl-fi/layout-primitives';
import styles from './styles.scss';

export default function AllModesModal({
appElement,
modalOpen,
closeModal,
isMobile,
language,
isMobile,
fontWeights,
colors,
children,
}) {
const [t] = useTranslation();

return (
<Modal
appElement={appElement}
closeButtonLabel={(t('close'), { lng: language })}
variant={isMobile ? 'large' : 'small'}
isOpen={modalOpen}
onCrossClick={closeModal}
lang={language}
open={modalOpen}
onOpenChange={open => {
if (!open) {
closeModal();
}
}}
>
<div
className={styles['near-you-container']}
style={{ '--font-weight': fontWeights.medium }}
<ModalContent
lang={language}
title={t('title', { lng: language })}
description={
isMobile ? undefined : (
<Text variant="paragraph-small" fixedSize="desktop" color="default">
{t('description', { lng: language })}
</Text>
)
}
buttons={[
{
children: t('close', { lng: language }),
variant: 'secondary',
onClick: closeModal,
},
]}
>
<h2 className={styles['near-you-title']}>
{t('title', { lng: language })}
</h2>
{!isMobile && (
<div className={styles['modal-desc']}>
{t('description', { lng: language })}
<div
className={`${styles['near-you-container']} ${styles['modal-rows']}`}
style={{ '--font-weight': fontWeights.medium }}
>
<div className={styles['near-you-buttons-container-wide']}>
{children}
</div>
)}
<div style={{ height: '20px' }} />
<div className={styles['near-you-buttons-container-wide']}>
{children}
</div>
{!isMobile && (
<div
key=""
className={styles.separator}
style={{ '--margin': '-12%', '--width': '124%' }}
/>
)}
<div className={styles['close-container']}>
<button
type="button"
onClick={closeModal}
className={isMobile ? styles['close-mobile'] : styles.close}
style={{ '--color': colors.primary }}
>
{t('close', { lng: language })}
</button>
</div>
</div>
</ModalContent>
</Modal>
);
}

AllModesModal.propTypes = {
appElement: PropTypes.string.isRequired,
language: PropTypes.string.isRequired,
isMobile: PropTypes.bool.isRequired,
modalOpen: PropTypes.bool.isRequired,
closeModal: PropTypes.func.isRequired,
isMobile: PropTypes.bool.isRequired,
fontWeights: PropTypes.shape({ medium: PropTypes.number }).isRequired,
colors: PropTypes.objectOf(PropTypes.string).isRequired,
children: PropTypes.arrayOf(PropTypes.node).isRequired,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import PropTypes from 'prop-types';
import React from 'react';
import { useTranslation } from 'react-i18next';
import Shimmer from '@hsl-fi/shimmer';
import NearYouButton from './NearYouButton';
import { isKeyboardSelectionEvent } from './utils';

const MODAL_FONT_WEIGHT = 325;

/** Keyboard and pointer accessible link-like button for one transport mode */
export default function ModeButton({
mode,
language,
modeSet,
colors,
fontWeights,
withAlert,
loading,
horizontal,
inModal,
onActivate,
}) {
const [t] = useTranslation();

const buttonProps = {
mode,
modeSet,
colors,
withAlert,
boxed: inModal || horizontal, // squared icon or interior only
};

if (inModal) {
const titleKey =
modeSet === 'hsl' && mode === 'rail' ? 'rail_local' : `${mode}_short`;
buttonProps.title = t(titleKey, { lng: language });
buttonProps.titleWeight = MODAL_FONT_WEIGHT;
buttonProps.withArrow = true;
buttonProps.margin = '0';
buttonProps.iconSize = '35px';
buttonProps.padding = '6px';
} else {
buttonProps.withBorder = true;
if (!horizontal) {
buttonProps.title = t(mode, { lng: language });
buttonProps.titleWeight = fontWeights.medium;
}
}

return (
<div
aria-label={t(mode, { lng: language })}
role="link"
tabIndex="0"
onClick={() => onActivate()}
onKeyDown={e => {
if (isKeyboardSelectionEvent(e)) {
onActivate(e);
}
}}
>
<Shimmer active={loading}>
<NearYouButton {...buttonProps} />
</Shimmer>
</div>
);
}

ModeButton.propTypes = {
mode: PropTypes.string.isRequired,
language: PropTypes.string.isRequired,
modeSet: PropTypes.string.isRequired,
colors: PropTypes.objectOf(PropTypes.string).isRequired,
fontWeights: PropTypes.shape({ medium: PropTypes.number }).isRequired,
withAlert: PropTypes.bool.isRequired,
loading: PropTypes.bool.isRequired,
horizontal: PropTypes.bool.isRequired,
inModal: PropTypes.bool.isRequired,
onActivate: PropTypes.func.isRequired,
};
Loading
Loading