diff --git a/packages/storybook/src/stories/Filters/atoms/ToggleButton.stories.tsx b/packages/storybook/src/stories/Filters/atoms/ToggleButton.stories.tsx
new file mode 100644
index 000000000..1673b42fd
--- /dev/null
+++ b/packages/storybook/src/stories/Filters/atoms/ToggleButton.stories.tsx
@@ -0,0 +1,125 @@
+import React, { useCallback, useState } from "react";
+import { ToggleButton } from "scorer-ui-kit";
+import { boolean, object, select, text } from "@storybook/addon-knobs";
+import { action } from "@storybook/addon-actions";
+import styled from "styled-components";
+
+export default {
+ title: 'Filters/atoms',
+ component: ToggleButton,
+ decorators: []
+};
+
+const layoutOptions = [
+ { text: 'Grid', value: 'grid', icon: 'LayoutGrid' },
+ { text: 'List', value: 'list', icon: 'LayoutList' }
+]
+
+const CameraData = styled.div``;
+const Camera = styled.li``;
+
+const Container = styled.div``;
+const DataGroup = styled.ol<{ layout: string }>`
+ margin-top: 20px;
+ display: grid;
+ ${({ layout }) => layout === 'grid' &&
+ `
+ list-style-type: none;
+ grid-template-columns: repeat(3, 300px);
+ gap: 16px;
+ ${Camera} {
+ padding: 100px 20px;
+ border: 1px solid var(--grey-9);
+ text-align: center;
+ }
+ `
+ };
+`;
+
+const StatusSpan = styled.span<{ isOnline?: boolean }>`
+ ${({ isOnline }) => isOnline ?
+ `
+ color: var(--success);
+ `
+ :
+ `
+ color: var(--warning);
+ `}
+ `;
+
+export const _ToggleButton = () => {
+ const [selectedLayout, setSelectedLayout] = useState(0)
+
+ const disabled = boolean('Disabled', false);
+ const design = select('Design type', { Default: 'default', Basic: 'basic' }, 'basic');
+ const categoryLabel = text('Category Label', 'Layout:');
+ const options = object('Options', layoutOptions);
+ const showToggleValue = action('Button Value: ');
+
+ const onToggle = useCallback((index: number, value: string | number) => {
+ setSelectedLayout(index);
+ showToggleValue(value);
+ }, [showToggleValue])
+
+ return (
+
+
+
+
+
+
+ Camera01 - Online
+
+
+
+
+ Camera02 - Online
+
+
+
+
+ Camera03 - OffLine
+
+
+
+
+ Camera04 - OffLine
+
+
+
+
+ Camera05 - OffLine
+
+
+
+
+ Camera06 - OffLine
+
+
+
+
+ Camera07 - Online
+
+
+
+
+ Camera08 - Online
+
+
+
+
+ Camera09 - Online
+
+
+
+
+ )
+}
\ No newline at end of file
diff --git a/packages/ui-lib/src/Filters/FilterTypes.ts b/packages/ui-lib/src/Filters/FilterTypes.ts
index cb9c48c17..373c11466 100644
--- a/packages/ui-lib/src/Filters/FilterTypes.ts
+++ b/packages/ui-lib/src/Filters/FilterTypes.ts
@@ -7,6 +7,7 @@ import { IFilterDropdown } from './molecules/FilterDropdown';
type IFilterItem = { text: string; value: string | number; }
type IFilterValue = IFilterItem | IFilterItem[] | null;
type IFilterType = 'search' | 'dropdown' | 'datepicker';
+type IToggleOption = { text: string; value: string | number; icon: string }
// Type checking for IFilterItem
// https://stackoverflow.com/questions/14425568/interface-type-check-with-typescript
@@ -78,5 +79,6 @@ export type {
ISearchFilter,
IFilterDropdownExt,
IFilterDatePicker,
- IFilterDropdownConfig
+ IFilterDropdownConfig,
+ IToggleOption,
};
\ No newline at end of file
diff --git a/packages/ui-lib/src/Filters/atoms/FilterButton.tsx b/packages/ui-lib/src/Filters/atoms/FilterButton.tsx
index 36c888a0d..23381482d 100644
--- a/packages/ui-lib/src/Filters/atoms/FilterButton.tsx
+++ b/packages/ui-lib/src/Filters/atoms/FilterButton.tsx
@@ -5,10 +5,11 @@ import Icon, { IconWrapper } from '../../Icons/Icon';
import { animation } from '../../theme/common';
import { FilterButtonDesign } from '..';
-const FlipWrapper = styled.div<{ isSortAscending: boolean }>`
+const LeftIconWrapper = styled.div<{ isSortAscending: boolean }>`
${({ isSortAscending }) => isSortAscending && css`
transform: scaleY(-1);
`};
+ padding: 0 6px;
`;
const fadeInAnimation = keyframes`
@@ -20,17 +21,29 @@ const fadeInAnimation = keyframes`
}
`;
-const FlipArrowContainer = styled.div``;
+const FlipArrowContainer = styled.div<{ design?: FilterButtonDesign }>`
+ ${({ design }) => design === 'default' ?
+ `padding: 0px 12px 0px 8px;`
+ :
+ `padding: 0px 8px;`
+ };
+`;
const StyledButton = styled.button<{ isOpen?: boolean, hasFlipArrow?: boolean, design?: FilterButtonDesign }>`
${resetButtonStyles};
border-radius: 3px;
height: var(--common-height);
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ flex-shrink: 0;
+ padding: 4px 10px 4px 4px;
- ${({design}) => design === 'basic'?
+ ${({ design }) => design === 'basic' ?
`
background-color: transparent;
border: 1px solid transparent;
+ padding: 4px;
`
:
`
@@ -40,6 +53,8 @@ const StyledButton = styled.button<{ isOpen?: boolean, hasFlipArrow?: boolean, d
`
};
+ ${({ hasFlipArrow }) => hasFlipArrow && `padding: 4px 0px 4px 4px;`};
+
text-align: left;
font-size: 12px;
font-weight: 500;
@@ -56,7 +71,6 @@ const StyledButton = styled.button<{ isOpen?: boolean, hasFlipArrow?: boolean, d
animation: ${fadeInAnimation} ${animation.speed.slower} ${animation.easing.primary.out};
${IconWrapper} {
- padding: 0 9px;
display: flex;
align-items: center;
[stroke]{
@@ -66,18 +80,18 @@ const StyledButton = styled.button<{ isOpen?: boolean, hasFlipArrow?: boolean, d
&:hover:enabled, &:active:enabled {
color: var(--grey-12);
-
+
${({design}) => design === 'basic'? '' : css`
box-shadow: 0px 4px 9px 0px var(--primary-a2);
border-color: var(--primary-7);
`};
-
+
${IconWrapper} {
[stroke]{
stroke: var(--primary-9);
}
}
-
+
${({isOpen}) => !isOpen && css`
${FlipArrowContainer} ${IconWrapper} {
[stroke]{
@@ -85,7 +99,7 @@ const StyledButton = styled.button<{ isOpen?: boolean, hasFlipArrow?: boolean, d
}
};
`};
-
+
}
&:disabled {
@@ -106,7 +120,7 @@ const StyledButton = styled.button<{ isOpen?: boolean, hasFlipArrow?: boolean, d
}
}
}
-
+
${FlipArrowContainer} ${IconWrapper} {
[stroke]{
stroke: var(--white-1);
@@ -119,13 +133,12 @@ const StyledButton = styled.button<{ isOpen?: boolean, hasFlipArrow?: boolean, d
const InnerContainer = styled.div`
- display: flex;
- align-items: center;
+ display: flex;
+ align-items: center;
+ gap: 4px;
`;
-const ButtonText = styled.div<{ hasFlipArrow: boolean }>`
- padding-right: ${({ hasFlipArrow }) => hasFlipArrow ? '3px' : '20px'};
-`;
+const ButtonText = styled.div<{ hasFlipArrow: boolean }>``;
interface OwnProps {
icon: string
@@ -150,18 +163,18 @@ const FilterButton: React.FC = ({
return (
-
+
-
+
{children}
-
- {hasFlipArrow && }
-
+
+ {hasFlipArrow && }
+
);
diff --git a/packages/ui-lib/src/Filters/atoms/ToggleButton.tsx b/packages/ui-lib/src/Filters/atoms/ToggleButton.tsx
new file mode 100644
index 000000000..d3eeac0e1
--- /dev/null
+++ b/packages/ui-lib/src/Filters/atoms/ToggleButton.tsx
@@ -0,0 +1,31 @@
+import React, { useCallback } from 'react';
+import { IToggleOption } from '../FilterTypes';
+import FilterButton from './FilterButton';
+import { FilterButtonDesign } from '..';
+
+type IToggleButton = {
+ options: IToggleOption[]
+ categoryLabel: String
+ selectedIndex: number
+ design?: FilterButtonDesign
+ onToggle: (index: number, value: string | number) => void
+}
+
+const ToggleButton: React.FC = ({ options, categoryLabel, selectedIndex, design = 'basic', onToggle, ...props }) => {
+
+ const onToggleCallback = useCallback((currentIndex: number) => {
+ const selected = currentIndex === 1 ? 0 : 1;
+ onToggle(selected, options[selected].value);
+
+ }, [onToggle, options]);
+
+ if (selectedIndex !== 0 && selectedIndex !== 1) return null;
+
+ return (
+ onToggleCallback(selectedIndex)} {...{design}} {...props}>
+ {`${categoryLabel} : ${options[selectedIndex].text}`}
+
+ );
+};
+
+export default ToggleButton;
\ No newline at end of file
diff --git a/packages/ui-lib/src/Filters/index.ts b/packages/ui-lib/src/Filters/index.ts
index 7de7333ce..e99343341 100644
--- a/packages/ui-lib/src/Filters/index.ts
+++ b/packages/ui-lib/src/Filters/index.ts
@@ -7,6 +7,8 @@ import FilterLayout from './molecules/FilterLayout';
import FilterInputs, { IFilterInputs } from './molecules/FilterInputs';
import FiltersResults, { IFilterLabel } from './molecules/FiltersResults';
import FilterBar from './organisms/FilterBar';
+import ToggleButton from './atoms/ToggleButton';
+
import {
IFilterType,
IFilterItem,
@@ -17,6 +19,7 @@ import {
IFilterDropdownConfig,
IFilterDatePicker,
isFilterItem,
+ IToggleOption,
} from './FilterTypes';
export {
@@ -31,6 +34,7 @@ export {
FilterBar,
isFilterItem,
isDateInterval,
+ ToggleButton
};
type FilterButtonDesign = 'default' | 'basic'
@@ -48,5 +52,6 @@ export type {
DateInterval,
IFilterDatePicker,
FilterButtonDesign,
+ IToggleOption,
DateRange
};
diff --git a/packages/ui-lib/src/index.tsx b/packages/ui-lib/src/index.tsx
index ec5c8fe72..582ff4a3e 100644
--- a/packages/ui-lib/src/index.tsx
+++ b/packages/ui-lib/src/index.tsx
@@ -76,7 +76,9 @@ import {
IFilterValue,
IFilterResult,
isFilterItem,
- FilterButtonDesign
+ FilterButtonDesign,
+ ToggleButton,
+ IToggleOption
} from './Filters';
import Icon, { IconSVGs } from './Icons/Icon';
@@ -279,6 +281,7 @@ export {
FilterInputs,
FiltersResults,
FilterBar,
+ ToggleButton,
isFilterItem,
isDateInterval,
@@ -419,5 +422,6 @@ export type {
AlertType,
ITooltipType,
FilterButtonDesign,
+ IToggleOption,
DateRange
};