@tmf_ciclica/ciclicastorybook 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.storybook/main.js +21 -0
- package/.storybook/preview.jsx +31 -0
- package/README.md +8 -0
- package/eslint.config.js +38 -0
- package/index.html +13 -0
- package/package.json +67 -0
- package/public/vite.svg +1 -0
- package/src/App.css +0 -0
- package/src/App.jsx +36 -0
- package/src/_variables.scss +56 -0
- package/src/assets/img/arrowDown.svg +3 -0
- package/src/assets/img/closeIcon.svg +4 -0
- package/src/assets/img/copyIcon.svg +17 -0
- package/src/assets/img/deleteIcon.svg +6 -0
- package/src/assets/img/eyeActiveIcon.svg +6 -0
- package/src/assets/img/eyeNotActiveIcon.svg +8 -0
- package/src/assets/img/filtersIcon.svg +6 -0
- package/src/assets/img/langarrow.png +0 -0
- package/src/assets/img/pause.svg +5 -0
- package/src/assets/img/play.svg +4 -0
- package/src/assets/img/processingIcon.svg +20 -0
- package/src/assets/img/sample-image.png +0 -0
- package/src/assets/img/sample2.png +0 -0
- package/src/assets/img/world.svg +3 -0
- package/src/assets/mapStyles/mapStyle.js +781 -0
- package/src/components/AmbitSelector/AmbitItem/AmbitItem.jsx +74 -0
- package/src/components/AmbitSelector/AmbitItem/AmbitItem.module.scss +27 -0
- package/src/components/AmbitSelector/AmbitSelector.jsx +68 -0
- package/src/components/AmbitSelector/AmbitSelector.module.scss +29 -0
- package/src/components/AmbitSelector/AmbitSelector.stories.jsx +21 -0
- package/src/components/ButtonsList/ButtonsList.jsx +92 -0
- package/src/components/ButtonsList/ButtonsList.module.scss +37 -0
- package/src/components/ButtonsList/ButtonsList.stories.jsx +55 -0
- package/src/components/DropdownList/DropdownList.jsx +69 -0
- package/src/components/DropdownList/DropdownList.module.scss +20 -0
- package/src/components/DropdownList/DropdownList.stories.jsx +22 -0
- package/src/components/DropdownList/DropdownListExample/DropDownListExample.jsx +33 -0
- package/src/components/DropdownList/DropdownListExample/DropdownListExample.stories.jsx +11 -0
- package/src/components/EditAmbit/EditAmbit.jsx +7 -0
- package/src/components/FiltersAmbit/AppliedFilters/AppliedFilters.jsx +57 -0
- package/src/components/FiltersAmbit/AppliedFilters/AppliedFilters.module.scss +13 -0
- package/src/components/FiltersAmbit/AppliedFilters/AppliedFilters.stories.jsx +47 -0
- package/src/components/FiltersAmbit/FiltersAmbit.jsx +58 -0
- package/src/components/FiltersAmbit/FiltersAmbit.module.scss +28 -0
- package/src/components/FiltersAmbit/FiltersAmbit.stories.jsx +36 -0
- package/src/components/FiltersAmbit/GeographicFilters/GeographicalFilters.jsx +33 -0
- package/src/components/FiltersAmbit/GeographicFilters/GeographicalFilters.module.scss +13 -0
- package/src/components/FiltersAmbit/GeographicFilters/GeographicalFilters.stories.jsx +47 -0
- package/src/components/FiltersAmbit/TematicalFilters/TematicalFilters.jsx +83 -0
- package/src/components/FiltersAmbit/TematicalFilters/TematicalFilters.module.scss +8 -0
- package/src/components/FiltersAmbit/TematicalFilters/TematicalFilters.stories.jsx +17 -0
- package/src/components/FiltersAmbit/TematicalFilters/TematicalFiltersCategory/TematicalFiltersCategory.jsx +60 -0
- package/src/components/FiltersAmbit/TematicalFilters/TematicalFiltersInput/AbsoluteSlider/AbsoluteSlider.jsx +61 -0
- package/src/components/FiltersAmbit/TematicalFilters/TematicalFiltersInput/AbsoluteSlider/AbsoluteSlider.module.scss +45 -0
- package/src/components/FiltersAmbit/TematicalFilters/TematicalFiltersInput/CategoryCheckbox/CategoryChackbox.module.scss +18 -0
- package/src/components/FiltersAmbit/TematicalFilters/TematicalFiltersInput/CategoryCheckbox/CategoryCheckbox.jsx +47 -0
- package/src/components/FiltersAmbit/TematicalFilters/TematicalFiltersInput/TematicalFiltersInput.jsx +267 -0
- package/src/components/FiltersAmbit/TematicalFilters/TematicalFiltersInput/TematicalFiltersInput.module.scss +31 -0
- package/src/components/FiltersAmbit/TematicalFilters/TematicalFiltersSubcat/TematicalFiltersSubcat.jsx +58 -0
- package/src/components/FiltersAmbit/useAmbitStore.jsx +10 -0
- package/src/components/Graphic/BarChart/BarChart.jsx +146 -0
- package/src/components/Graphic/BarChart/BarChart.module.scss +5 -0
- package/src/components/Graphic/BarChart/BarChart.stories.jsx +18 -0
- package/src/components/Graphic/Graphic.jsx +55 -0
- package/src/components/Graphic/Graphic.module.scss +12 -0
- package/src/components/Graphic/Graphic.stories.jsx +25 -0
- package/src/components/IndicatorsList/Indicator/Indicator.jsx +180 -0
- package/src/components/IndicatorsList/Indicator/Indicator.module.scss +46 -0
- package/src/components/IndicatorsList/IndicatorSubCategory/IndicatorSubCategory.jsx +76 -0
- package/src/components/IndicatorsList/IndicatorSubCategory/IndicatorSubCategory.module.scss +12 -0
- package/src/components/IndicatorsList/IndicatorsCategory/IndicatorsCategory.jsx +122 -0
- package/src/components/IndicatorsList/IndicatorsCategory/IndicatorsCategory.module.scss +20 -0
- package/src/components/IndicatorsList/IndicatorsList.jsx +173 -0
- package/src/components/IndicatorsList/IndicatorsList.module.scss +10 -0
- package/src/components/IndicatorsList/IndicatorsList.stories.jsx +263 -0
- package/src/components/LangSelector/LangSelector.jsx +70 -0
- package/src/components/LangSelector/LangSelector.module.scss +41 -0
- package/src/components/LangSelector/LangSelector.stories.jsx +27 -0
- package/src/components/Legend/Legend.jsx +132 -0
- package/src/components/Legend/Legend.module.scss +121 -0
- package/src/components/Legend/Legend.stories.jsx +53 -0
- package/src/components/LogoApp/LogoApp.jsx +33 -0
- package/src/components/LogoApp/LogoApp.module.scss +7 -0
- package/src/components/LogoApp/LogoApp.stories.jsx +27 -0
- package/src/components/MapboxMap/MapboxMap.jsx +160 -0
- package/src/components/MapboxMap/MapboxMap.module.scss +4 -0
- package/src/components/MapboxMap/MapboxMap.stories.jsx +57 -0
- package/src/components/MaplibreMap/MaplibreMap.jsx +166 -0
- package/src/components/MaplibreMap/MaplibreMap.module.scss +5 -0
- package/src/components/MaplibreMap/MaplibreMap.stories.jsx +55 -0
- package/src/components/SectionBar/SectionBar.jsx +41 -0
- package/src/components/SectionBar/SectionBar.module.scss +40 -0
- package/src/components/SectionBar/SectionBar.stories.jsx +35 -0
- package/src/components/TimeSlider/TimeSlider.jsx +147 -0
- package/src/components/TimeSlider/TimeSlider.module.scss +63 -0
- package/src/components/TimeSlider/TimeSlider.stories.jsx +9 -0
- package/src/components/Tooltip/Tooltip.jsx +40 -0
- package/src/components/Tooltip/Tooltip.module.scss +141 -0
- package/src/components/Tooltip/Tooltip.stories.jsx +51 -0
- package/src/components/TopNavMenu/TopNavMenu.jsx +62 -0
- package/src/components/TopNavMenu/TopNavMenu.module.scss +21 -0
- package/src/components/TopNavMenu/TopNavMenu.stories.jsx +20 -0
- package/src/components/UserMenuTrigger/UserMenuTrigger.jsx +47 -0
- package/src/components/UserMenuTrigger/UserMenuTrigger.module.scss +5 -0
- package/src/components/UserMenuTrigger/UserMenuTrigger.stories.jsx +33 -0
- package/src/components/index.jsx +17 -0
- package/src/constants/indicators.js +1371 -0
- package/src/constants/mapTexts.js +161 -0
- package/src/constants/textLayers.js +639 -0
- package/src/constants/topNavMenuOptions.js +14 -0
- package/src/i18n.js +19 -0
- package/src/index.js +2 -0
- package/src/index.scss +87 -0
- package/src/locales/ca.json +8 -0
- package/src/locales/es.json +15 -0
- package/src/main.jsx +10 -0
- package/src/sections/HeaderSection/HeaderSection.jsx +51 -0
- package/src/sections/HeaderSection/HeaderSection.module.scss +33 -0
- package/src/sections/HeaderSection/HeaderSection.stories.jsx +61 -0
- package/src/sections/RightSidebar/RightSidebar.jsx +35 -0
- package/src/sections/RightSidebar/RightSidebar.module.scss +39 -0
- package/src/sections/RightSidebar/RightSidebar.stories.jsx +21 -0
- package/src/sections/index.js +2 -0
- package/src/store/index.js +1 -0
- package/src/store/mapSlice/index.js +1 -0
- package/src/store/mapSlice/mapSlice.js +30 -0
- package/src/store/rightBarSlice/index.js +1 -0
- package/src/store/rightBarSlice/rightBarSlice.js +28 -0
- package/src/store/routerSlice/index.js +1 -0
- package/src/store/routerSlice/routerSlice.js +14 -0
- package/src/store/store.js +14 -0
- package/src/store/userSlice/index.js +1 -0
- package/src/store/userSlice/userSlice.js +22 -0
- package/vite.config.js +36 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import React from "react"
|
|
2
|
+
import style from "./AmbitItem.module.scss"
|
|
3
|
+
import deleteIcon from "../../../assets/img/deleteIcon.svg"
|
|
4
|
+
import copyIcon from "../../../assets/img/copyIcon.svg"
|
|
5
|
+
import filtersIcon from "../../../assets/img/filtersIcon.svg"
|
|
6
|
+
import processingIcon from "../../../assets/img/processingIcon.svg"
|
|
7
|
+
import eyeActiveIcon from "../../../assets/img/eyeActiveIcon.svg"
|
|
8
|
+
import eyeNotActiveIcon from "../../../assets/img/eyeNotActiveIcon.svg"
|
|
9
|
+
import PropTypes from "prop-types"
|
|
10
|
+
export const AmbitItem = ({
|
|
11
|
+
ambit,
|
|
12
|
+
onClickCopy,
|
|
13
|
+
onClickDelete,
|
|
14
|
+
onClickFilters,
|
|
15
|
+
onClickAmbit,
|
|
16
|
+
isBeingProcessed,
|
|
17
|
+
isActive,
|
|
18
|
+
activeColor,
|
|
19
|
+
fontColor,
|
|
20
|
+
moreInfo,
|
|
21
|
+
}) => {
|
|
22
|
+
const { name, date, id } = ambit
|
|
23
|
+
return (
|
|
24
|
+
<div
|
|
25
|
+
className={style.ambitItem}
|
|
26
|
+
style={{ borderBottom: `1px solid ${fontColor}` }}
|
|
27
|
+
>
|
|
28
|
+
<div className={style.ambitNameDate} onClick={() => onClickAmbit(id)}>
|
|
29
|
+
<div className={style.ambitName}>
|
|
30
|
+
{
|
|
31
|
+
<img
|
|
32
|
+
|
|
33
|
+
src={isActive ? eyeActiveIcon : eyeNotActiveIcon}
|
|
34
|
+
/>
|
|
35
|
+
}
|
|
36
|
+
<span style={{ color: isActive ? activeColor : fontColor }}>
|
|
37
|
+
{name}
|
|
38
|
+
</span>
|
|
39
|
+
</div>
|
|
40
|
+
<div className={style.ambitDate}>
|
|
41
|
+
{new Date(date).toLocaleDateString()}
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
<div className={style.ambitButtons}>
|
|
45
|
+
{isBeingProcessed && <img src={filtersIcon} />}
|
|
46
|
+
<button onClick={() => onClickFilters(id)}>
|
|
47
|
+
<img src={filtersIcon} />
|
|
48
|
+
</button>
|
|
49
|
+
<button onClick={() => onClickCopy(id)}>
|
|
50
|
+
<img src={copyIcon} />
|
|
51
|
+
</button>
|
|
52
|
+
<button onClick={() => onClickDelete(id)}>
|
|
53
|
+
<img src={deleteIcon} />
|
|
54
|
+
</button>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
AmbitItem.propTypes = {
|
|
60
|
+
ambit: PropTypes.shape({
|
|
61
|
+
name: PropTypes.string.isRequired,
|
|
62
|
+
date: PropTypes.string.isRequired,
|
|
63
|
+
id: PropTypes.string.isRequired,
|
|
64
|
+
}).isRequired,
|
|
65
|
+
onClickCopy: PropTypes.func.isRequired,
|
|
66
|
+
onClickDelete: PropTypes.func.isRequired,
|
|
67
|
+
onClickFilters: PropTypes.func.isRequired,
|
|
68
|
+
onClickAmbit: PropTypes.func.isRequired,
|
|
69
|
+
isBeingProcessed: PropTypes.bool,
|
|
70
|
+
isActive: PropTypes.bool,
|
|
71
|
+
activeColor: PropTypes.string,
|
|
72
|
+
fontColor: PropTypes.string,
|
|
73
|
+
moreInfo: PropTypes.object, // Optional, can be used for additional info
|
|
74
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
.ambitItem {
|
|
2
|
+
@include flex($direction: row, $align: center, $justify: space-between);
|
|
3
|
+
padding-top: 10px;
|
|
4
|
+
padding-bottom: 10px;
|
|
5
|
+
gap: 10px;
|
|
6
|
+
width: 100%;
|
|
7
|
+
padding-bottom: 30px;
|
|
8
|
+
padding-top: 30px;
|
|
9
|
+
|
|
10
|
+
.ambitNameDate {
|
|
11
|
+
flex: 1;
|
|
12
|
+
@include flex($align: center);
|
|
13
|
+
cursor: pointer;
|
|
14
|
+
.ambitName {
|
|
15
|
+
@include flex($justify: flex-start, $align: center);
|
|
16
|
+
flex: 1;
|
|
17
|
+
}
|
|
18
|
+
.ambitDate {
|
|
19
|
+
flex: 0.5;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
.ambitButtons {
|
|
23
|
+
flex: 0.3;
|
|
24
|
+
@include flex($direction: row, $align: center, $justify: flex-end);
|
|
25
|
+
gap: 8px;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import style from "./AmbitSelector.module.scss"
|
|
2
|
+
import { AmbitItem } from "./AmbitItem/AmbitItem"
|
|
3
|
+
import PropTypes from "prop-types"
|
|
4
|
+
import { useTranslation } from "react-i18next"
|
|
5
|
+
import CloseICon from "../../assets/img/closeIcon.svg"
|
|
6
|
+
export const AmbitSelector = ({
|
|
7
|
+
ambitList,
|
|
8
|
+
activeAmbitId,
|
|
9
|
+
fontColor = "#605B56",
|
|
10
|
+
activeColor,
|
|
11
|
+
nameLabel,
|
|
12
|
+
dateLabel,
|
|
13
|
+
onClickCopy = (id) => console.log(`Copy ambit: ${id}`),
|
|
14
|
+
onCLickDelete = (id) => console.log(`Delete ambit: ${id}`),
|
|
15
|
+
onClickFilters = (id) => console.log(`Filters clicked: ${id}`),
|
|
16
|
+
onClickAmbit = (id) => console.log(`OnCLickAmbit: ${id}`),
|
|
17
|
+
}) => {
|
|
18
|
+
const { t } = useTranslation()
|
|
19
|
+
return (
|
|
20
|
+
<div className={style.ambitSelector} style={{ color: fontColor }}>
|
|
21
|
+
<div
|
|
22
|
+
className={style.header}
|
|
23
|
+
style={{ borderBottom: `1px solid ${fontColor}` }}
|
|
24
|
+
>
|
|
25
|
+
<div className={style.nameDateContainer}>
|
|
26
|
+
<div className={style.ambitName}>
|
|
27
|
+
<span>{t(nameLabel)}</span>
|
|
28
|
+
</div>
|
|
29
|
+
<div className={style.ambitDate}>
|
|
30
|
+
<span>{t(dateLabel)}</span>
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
<div className={style.buttonsContainer} />
|
|
34
|
+
</div>
|
|
35
|
+
{ambitList &&
|
|
36
|
+
ambitList.length > 0 &&
|
|
37
|
+
ambitList.map((ambit) => (
|
|
38
|
+
<AmbitItem
|
|
39
|
+
key={`ambitKey${ambit.id}`}
|
|
40
|
+
isActive={activeAmbitId == ambit.id}
|
|
41
|
+
ambit={ambit}
|
|
42
|
+
fontColor={fontColor}
|
|
43
|
+
activeColor={activeColor}
|
|
44
|
+
onClickCopy={onClickCopy}
|
|
45
|
+
onClickDelete={onCLickDelete}
|
|
46
|
+
onClickFilters={onClickFilters}
|
|
47
|
+
onClickAmbit={onClickAmbit}
|
|
48
|
+
/>
|
|
49
|
+
))}
|
|
50
|
+
</div>
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
AmbitSelector.propTypes = {
|
|
54
|
+
ambitList: PropTypes.arrayOf(
|
|
55
|
+
PropTypes.shape({
|
|
56
|
+
name: PropTypes.string.isRequired,
|
|
57
|
+
date: PropTypes.string.isRequired,
|
|
58
|
+
id: PropTypes.string.isRequired,
|
|
59
|
+
})
|
|
60
|
+
).isRequired,
|
|
61
|
+
activeAmbitId: PropTypes.string,
|
|
62
|
+
fontColor: PropTypes.string,
|
|
63
|
+
activeColor: PropTypes.string,
|
|
64
|
+
onClickCopy: PropTypes.func.isRequired,
|
|
65
|
+
onCLickDelete: PropTypes.func.isRequired,
|
|
66
|
+
onClickFilters: PropTypes.func.isRequired,
|
|
67
|
+
onClickAmbit: PropTypes.func.isRequired,
|
|
68
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
.ambitSelector {
|
|
2
|
+
@include flex($direction: column, $align: flex-start, $justify: center);
|
|
3
|
+
width: 100%;
|
|
4
|
+
padding-right: 25px;
|
|
5
|
+
padding-left: 25px;
|
|
6
|
+
.header {
|
|
7
|
+
width: 100%;
|
|
8
|
+
@include flex($direction: row, $align: center, $justify: space-between);
|
|
9
|
+
padding-bottom: 26px;
|
|
10
|
+
.nameDateContainer {
|
|
11
|
+
@include flex($direction: row, $align: center, $justify: flex-start);
|
|
12
|
+
width: 100%;
|
|
13
|
+
flex: 1;
|
|
14
|
+
@include flex($align: center);
|
|
15
|
+
|
|
16
|
+
.ambitName {
|
|
17
|
+
@include flex($justify: flex-start, $align: center);
|
|
18
|
+
flex: 1;
|
|
19
|
+
}
|
|
20
|
+
.ambitDate {
|
|
21
|
+
flex: 0.5;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
.buttonsContainer {
|
|
25
|
+
flex: 0.3;
|
|
26
|
+
@include flex($direction: row, $align: center, $justify: flex-end);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { useState } from "react"
|
|
2
|
+
import { AmbitSelector } from "./AmbitSelector"
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: "Components/AmbitSelector",
|
|
6
|
+
component: AmbitSelector,
|
|
7
|
+
}
|
|
8
|
+
export const Default = {
|
|
9
|
+
args: {
|
|
10
|
+
ambitList: [
|
|
11
|
+
{ name: "Ambit 1", date: "2023-01-01", id: "ambit1" },
|
|
12
|
+
{ name: "Ambit 2", date: "2023-02-01", id: "ambit2" },
|
|
13
|
+
{ name: "Ambit 3", date: "2023-03-01", id: "ambit3" },
|
|
14
|
+
],
|
|
15
|
+
activeAmbitId: "ambit1",
|
|
16
|
+
activeColor: "#B32F5D",
|
|
17
|
+
fontColor: "#605B56",
|
|
18
|
+
nameLabel: "Name",
|
|
19
|
+
dateLabel: "Date",
|
|
20
|
+
},
|
|
21
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
|
|
2
|
+
/*
|
|
3
|
+
Componente para un listado de botones con su función on click. El listado puede ser vertical y horizontal, pueden ser botones con o sin nombre y con o sin tooltip. Ejemplos: los botones flotantes en los mapas (indicadores, filtros) o el menú inferior "Mapa/Gráficos"
|
|
4
|
+
Recibe:
|
|
5
|
+
buttons-> array de objetos -> {
|
|
6
|
+
icon: src de la img del botón,
|
|
7
|
+
activeIcon: src de la img del botón activo (si necesaria),
|
|
8
|
+
isActive: isActive,
|
|
9
|
+
name: nombre del botón para ponerlo al lado, para el tooltip y/o para el alt de la img
|
|
10
|
+
onClick: función onclick
|
|
11
|
+
},
|
|
12
|
+
orientation: 'horizontal' o 'vertical',
|
|
13
|
+
showName: boolean si se muestra o no el nombre,
|
|
14
|
+
namePosition: posición del nombre al lado del nombre ('right', 'left'),
|
|
15
|
+
useTooltip: boolean si hay o no tooltip,
|
|
16
|
+
tooltipPosition: ('right', 'left', 'bottom', 'top')
|
|
17
|
+
*/
|
|
18
|
+
import PropTypes from 'prop-types';
|
|
19
|
+
import styles from './ButtonsList.module.scss';
|
|
20
|
+
import { useTranslation } from 'react-i18next';
|
|
21
|
+
import { Tooltip } from '../Tooltip/Tooltip';
|
|
22
|
+
|
|
23
|
+
export const ButtonsList = ({
|
|
24
|
+
buttons = [],
|
|
25
|
+
orientation = 'horizontal',
|
|
26
|
+
showName = true,
|
|
27
|
+
namePosition = 'right',
|
|
28
|
+
useTooltip = false,
|
|
29
|
+
tooltipPosition = 'top',
|
|
30
|
+
}) => {
|
|
31
|
+
const {t} = useTranslation()
|
|
32
|
+
return (
|
|
33
|
+
<div
|
|
34
|
+
className={`${styles.buttonsContainer} ${
|
|
35
|
+
orientation === 'vertical' && styles.vertical}
|
|
36
|
+
${orientation === 'horizontal' && styles.horizontal}`}
|
|
37
|
+
>
|
|
38
|
+
{buttons.map((btn, index) => {
|
|
39
|
+
const {
|
|
40
|
+
icon,
|
|
41
|
+
activeIcon,
|
|
42
|
+
isActive,
|
|
43
|
+
name,
|
|
44
|
+
onClick,
|
|
45
|
+
} = btn;
|
|
46
|
+
|
|
47
|
+
const buttonContent = (
|
|
48
|
+
<>
|
|
49
|
+
{(showName && namePosition === 'left') && (
|
|
50
|
+
<span className={styles.buttonName}>{t(name)}</span>
|
|
51
|
+
)}
|
|
52
|
+
<img src={isActive ? activeIcon : icon} alt={t(name)}/>
|
|
53
|
+
{(showName && namePosition === 'right') && (
|
|
54
|
+
<span className={styles.buttonName}>{t(name)}</span>
|
|
55
|
+
)}
|
|
56
|
+
</>
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<div className='tooltip-parent' key={index}>
|
|
61
|
+
<button
|
|
62
|
+
onClick={onClick}
|
|
63
|
+
className={`${styles.button}
|
|
64
|
+
${isActive&&styles.active}`}
|
|
65
|
+
>
|
|
66
|
+
{buttonContent}
|
|
67
|
+
</button>
|
|
68
|
+
{useTooltip && <Tooltip text={name} position={tooltipPosition} /> }
|
|
69
|
+
</div>
|
|
70
|
+
);
|
|
71
|
+
})}
|
|
72
|
+
</div>
|
|
73
|
+
);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
ButtonsList.propTypes = {
|
|
77
|
+
buttons: PropTypes.arrayOf(
|
|
78
|
+
PropTypes.shape({
|
|
79
|
+
icon: PropTypes.node.isRequired,
|
|
80
|
+
activeIcon: PropTypes.node,
|
|
81
|
+
isActive: PropTypes.bool,
|
|
82
|
+
name: PropTypes.string, // key de i18n
|
|
83
|
+
onClick: PropTypes.func,
|
|
84
|
+
})
|
|
85
|
+
).isRequired,
|
|
86
|
+
orientation: PropTypes.oneOf(['horizontal', 'vertical']),
|
|
87
|
+
showName: PropTypes.bool,
|
|
88
|
+
namePosition: PropTypes.oneOf(['left', 'right']),
|
|
89
|
+
useTooltip: PropTypes.bool,
|
|
90
|
+
tooltipPosition: PropTypes.oneOf(['top', 'bottom', 'left', 'right']),
|
|
91
|
+
};
|
|
92
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
.buttonsContainer {
|
|
2
|
+
display: flex;
|
|
3
|
+
gap: 8px;
|
|
4
|
+
|
|
5
|
+
&.vertical {
|
|
6
|
+
flex-direction: column;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
&.horizontal {
|
|
10
|
+
flex-direction: row;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.button {
|
|
15
|
+
background: transparent;
|
|
16
|
+
border: none;
|
|
17
|
+
display: flex;
|
|
18
|
+
align-items: center;
|
|
19
|
+
cursor: pointer;
|
|
20
|
+
padding: 4px;
|
|
21
|
+
position: relative;
|
|
22
|
+
|
|
23
|
+
&:hover {
|
|
24
|
+
opacity: 0.8;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
&.active {
|
|
28
|
+
font-weight: bold;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.buttonName {
|
|
32
|
+
margin: 0 4px;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
|
|
2
|
+
import { ButtonsList } from './ButtonsList';
|
|
3
|
+
import Icon from '../../assets/img/pause.svg'
|
|
4
|
+
import IconActive from '../../assets/img/play.svg'
|
|
5
|
+
|
|
6
|
+
export default {
|
|
7
|
+
title: 'Components/ButtonsList',
|
|
8
|
+
component: ButtonsList
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const mockButtons = [
|
|
12
|
+
{
|
|
13
|
+
icon: Icon,
|
|
14
|
+
activeIcon: IconActive,
|
|
15
|
+
isActive: true,
|
|
16
|
+
name: 'home',
|
|
17
|
+
onClick: () => alert('Home clicked'),
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
icon: Icon,
|
|
21
|
+
activeIcon: IconActive,
|
|
22
|
+
isActive: false,
|
|
23
|
+
name: 'settings',
|
|
24
|
+
onClick: () => alert('Settings clicked'),
|
|
25
|
+
},
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
export const HorizontalWithNames = () => (
|
|
29
|
+
<ButtonsList
|
|
30
|
+
buttons={mockButtons}
|
|
31
|
+
orientation="horizontal"
|
|
32
|
+
showName={true}
|
|
33
|
+
namePosition="right"
|
|
34
|
+
useTooltip={false}
|
|
35
|
+
/>
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
export const VerticalWithTooltips = () => (
|
|
39
|
+
<ButtonsList
|
|
40
|
+
buttons={mockButtons}
|
|
41
|
+
orientation="vertical"
|
|
42
|
+
showName={false}
|
|
43
|
+
useTooltip={true}
|
|
44
|
+
tooltipPosition="right"
|
|
45
|
+
/>
|
|
46
|
+
);
|
|
47
|
+
export const HorizontalWithNamesLeft = () => (
|
|
48
|
+
<ButtonsList
|
|
49
|
+
buttons={mockButtons}
|
|
50
|
+
orientation="horizontal"
|
|
51
|
+
showName={true}
|
|
52
|
+
namePosition="left"
|
|
53
|
+
useTooltip={false}
|
|
54
|
+
/>
|
|
55
|
+
);
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import React, { useEffect, useState } from "react"
|
|
2
|
+
import { motion } from "framer-motion"
|
|
3
|
+
import style from "./DropdownList.module.scss"
|
|
4
|
+
import { useTranslation } from "react-i18next"
|
|
5
|
+
import PropTypes from "prop-types"
|
|
6
|
+
|
|
7
|
+
//DropdownList component to use in various contexts, such as filters or indicators.
|
|
8
|
+
//IsOpen should be the state of the dropdown and should be toggled in the onClickFunction.
|
|
9
|
+
//This is for able to have only one dropdown open at a time, if needed.
|
|
10
|
+
//The content of the dropdown is passed as children.
|
|
11
|
+
//Theres an example of use in the dropdownListExample component with his own .stories.
|
|
12
|
+
export const DropdownList = ({
|
|
13
|
+
isOpen: open,
|
|
14
|
+
onClick,
|
|
15
|
+
children,
|
|
16
|
+
color,
|
|
17
|
+
activeColor = "#F8A925",
|
|
18
|
+
title = "Title",
|
|
19
|
+
//Change the height only if the title is more than one line or you change title fontSize, otherwise should be 53px
|
|
20
|
+
height = 53,
|
|
21
|
+
//Adjust height if you change fontSize
|
|
22
|
+
titleFontStyles,
|
|
23
|
+
showBottomBar = true,
|
|
24
|
+
titleMarginChildren = 25,
|
|
25
|
+
}) => {
|
|
26
|
+
const { t } = useTranslation()
|
|
27
|
+
return (
|
|
28
|
+
<motion.div
|
|
29
|
+
className={style.indicatorsCategory}
|
|
30
|
+
initial={{ height: `${height}px` }}
|
|
31
|
+
animate={{ height: open ? "auto" : `${height}px` }}
|
|
32
|
+
transition={{ duration: 0.4 }}
|
|
33
|
+
style={{
|
|
34
|
+
backgroundColor: "white",
|
|
35
|
+
borderBottom:
|
|
36
|
+
open && showBottomBar ? `1px solid ${activeColor}` : "0px",
|
|
37
|
+
marginBottom: open ? "20px" : "0px",
|
|
38
|
+
}}
|
|
39
|
+
>
|
|
40
|
+
<h2
|
|
41
|
+
style={{
|
|
42
|
+
...titleFontStyles,
|
|
43
|
+
marginBottom: titleMarginChildren ? titleMarginChildren : "auto",
|
|
44
|
+
}}
|
|
45
|
+
className={`${style.title}`}
|
|
46
|
+
onClick={onClick}
|
|
47
|
+
>
|
|
48
|
+
<span style={{ color: open ? activeColor : color }}>
|
|
49
|
+
{open ? "-" : "+"}
|
|
50
|
+
</span>
|
|
51
|
+
<span style={{ marginLeft: 12, color: open ? activeColor : color }}>
|
|
52
|
+
{t(title)}
|
|
53
|
+
</span>
|
|
54
|
+
</h2>
|
|
55
|
+
{<div className={style.content}>{children}</div>}
|
|
56
|
+
</motion.div>
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
DropdownList.propTypes = {
|
|
60
|
+
isOpen: PropTypes.bool,
|
|
61
|
+
onClick: PropTypes.func,
|
|
62
|
+
children: PropTypes.node,
|
|
63
|
+
color: PropTypes.string,
|
|
64
|
+
activeColor: PropTypes.string,
|
|
65
|
+
title: PropTypes.string,
|
|
66
|
+
height: PropTypes.number,
|
|
67
|
+
showBottomBar: PropTypes.bool,
|
|
68
|
+
titleFontStyles: PropTypes.object,
|
|
69
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
.indicatorsCategory {
|
|
2
|
+
overflow: hidden;
|
|
3
|
+
|
|
4
|
+
.title {
|
|
5
|
+
align-items: center;
|
|
6
|
+
gap: 10px;
|
|
7
|
+
cursor: pointer;
|
|
8
|
+
margin-bottom: 25px;
|
|
9
|
+
}
|
|
10
|
+
.list {
|
|
11
|
+
display: flex;
|
|
12
|
+
flex-wrap: nowrap;
|
|
13
|
+
justify-content: start;
|
|
14
|
+
flex-direction: column;
|
|
15
|
+
align-items: start;
|
|
16
|
+
width: 100%;
|
|
17
|
+
gap: 20px;
|
|
18
|
+
padding-bottom: 20px;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { useState } from "react"
|
|
2
|
+
import { DropdownList } from "./DropdownList"
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: "Components/DropdownList",
|
|
6
|
+
component: DropdownList,
|
|
7
|
+
}
|
|
8
|
+
let open = false
|
|
9
|
+
export const Default = {
|
|
10
|
+
args: {
|
|
11
|
+
children: (
|
|
12
|
+
<div>
|
|
13
|
+
<h3>Test</h3>
|
|
14
|
+
</div>
|
|
15
|
+
),
|
|
16
|
+
isOpen: open,
|
|
17
|
+
//setIsOpen: () => {open = !open },
|
|
18
|
+
color: "#605B56",
|
|
19
|
+
activeColor: "#F8A925",
|
|
20
|
+
showBottomBar: true,
|
|
21
|
+
},
|
|
22
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React, { useState } from "react"
|
|
2
|
+
import { DropdownList } from "../DropdownList"
|
|
3
|
+
|
|
4
|
+
export const DropDownListExample = () => {
|
|
5
|
+
const [activeDropdown, setActiveDropdown] = useState(0)
|
|
6
|
+
const categoriesList = [
|
|
7
|
+
{ title: "Example0", id: 0 },
|
|
8
|
+
{ title: "Example1", id: 1 },
|
|
9
|
+
{ title: "Example2", id: 2 },
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<div>
|
|
14
|
+
{categoriesList?.map(({ id, title }) => {
|
|
15
|
+
return (
|
|
16
|
+
<DropdownList
|
|
17
|
+
id={id}
|
|
18
|
+
title={title}
|
|
19
|
+
isOpen={activeDropdown == id}
|
|
20
|
+
onClick={() => {
|
|
21
|
+
setActiveDropdown((actual) => (actual == id ? undefined : id))
|
|
22
|
+
}}
|
|
23
|
+
color="#605B56"
|
|
24
|
+
activeColor="#F8A925"
|
|
25
|
+
>
|
|
26
|
+
<h3>{title} </h3>
|
|
27
|
+
<p>This is a test content inside the dropdown list.</p>
|
|
28
|
+
</DropdownList>
|
|
29
|
+
)
|
|
30
|
+
})}
|
|
31
|
+
</div>
|
|
32
|
+
)
|
|
33
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { useState } from "react"
|
|
2
|
+
import { DropDownListExample } from "./DropDownListExample"
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: "Components/DropDownListExample",
|
|
6
|
+
component: DropDownListExample,
|
|
7
|
+
}
|
|
8
|
+
let open = false
|
|
9
|
+
export const Default = {
|
|
10
|
+
args: {},
|
|
11
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { useEffect, useState } from "react"
|
|
2
|
+
|
|
3
|
+
import CloseIcon from '../../../assets/img/closeIcon.svg';
|
|
4
|
+
import { DropdownList } from "../../DropdownList/DropdownList"
|
|
5
|
+
import PropTypes from "prop-types"
|
|
6
|
+
import { div } from "framer-motion/client"
|
|
7
|
+
import styles from "./AppliedFilters.module.scss"
|
|
8
|
+
import { useAmbitStore } from "../useAmbitStore"
|
|
9
|
+
import { useTranslation } from "react-i18next"
|
|
10
|
+
|
|
11
|
+
export const AppliedFilters = ({ title, onClick, isOpen = true, textColor = "#ffffff", backgroundColor = "#605B5680" }) => {
|
|
12
|
+
const { t } = useTranslation()
|
|
13
|
+
const { tematicalFiltersSelected } = useAmbitStore((s) => s)
|
|
14
|
+
|
|
15
|
+
const deleteFilter = (codename) => {
|
|
16
|
+
// Takes the filter code to remove and updates the store accordingly
|
|
17
|
+
useAmbitStore.setState(state => ({
|
|
18
|
+
tematicalFiltersSelected: state.tematicalFiltersSelected.filter(
|
|
19
|
+
f => f.code !== codename
|
|
20
|
+
)
|
|
21
|
+
}));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<DropdownList
|
|
26
|
+
isOpen={isOpen}
|
|
27
|
+
onClick={onClick}
|
|
28
|
+
title={title ? t(title) : "Applied Filters"}
|
|
29
|
+
>
|
|
30
|
+
<div className={styles.AppliedFiltersContainer}>
|
|
31
|
+
{tematicalFiltersSelected?.map((filter, key) => {
|
|
32
|
+
return (
|
|
33
|
+
|
|
34
|
+
<div key={key} className={styles.AppliedFilterContent} style={{ color: textColor, background: backgroundColor }}>
|
|
35
|
+
{filter.code}
|
|
36
|
+
|
|
37
|
+
<img src={CloseIcon} alt="CloseIcon" onClick={() => deleteFilter(filter.code)} style={{ cursor: 'pointer' }} />
|
|
38
|
+
</div>
|
|
39
|
+
)
|
|
40
|
+
})}
|
|
41
|
+
</div>
|
|
42
|
+
</DropdownList>
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
AppliedFilters.propTypes = {
|
|
46
|
+
isOpen: PropTypes.bool,
|
|
47
|
+
onClick: PropTypes.func,
|
|
48
|
+
title: PropTypes.string,
|
|
49
|
+
textColor: PropTypes.string,
|
|
50
|
+
backgroundColor: PropTypes.string,
|
|
51
|
+
indicators: PropTypes.arrayOf(
|
|
52
|
+
PropTypes.shape({
|
|
53
|
+
title: PropTypes.string.isRequired,
|
|
54
|
+
Codename: PropTypes.string.isRequired,
|
|
55
|
+
})
|
|
56
|
+
),
|
|
57
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
.AppliedFiltersContainer {
|
|
2
|
+
@include flex(row, start, start, $gap: 10px);
|
|
3
|
+
|
|
4
|
+
.AppliedFilterContent {
|
|
5
|
+
@include flex($gap: 10px);
|
|
6
|
+
@include fontBase;
|
|
7
|
+
height: 35px;
|
|
8
|
+
width: fit-content;
|
|
9
|
+
padding: 0px 20px;
|
|
10
|
+
border-radius: 100px;
|
|
11
|
+
// background-color: red;
|
|
12
|
+
}
|
|
13
|
+
}
|