@agilant/toga-blox 1.0.8 → 1.0.10
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/assets/cable.jpg +0 -0
- package/assets/card-1.jpg +0 -0
- package/assets/cat-logo.png +0 -0
- package/assets/item.jpg +0 -0
- package/assets/map.png +0 -0
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/clover.xml +953 -0
- package/coverage/coverage-final.json +74 -0
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +551 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +196 -0
- package/coverage/toga-blox-npm/index.html +131 -0
- package/coverage/toga-blox-npm/postcss.config.js.html +103 -0
- package/coverage/toga-blox-npm/src/components/Badge/Badge.stories.tsx.html +793 -0
- package/coverage/toga-blox-npm/src/components/Badge/Badge.tsx.html +247 -0
- package/coverage/toga-blox-npm/src/components/Badge/index.html +131 -0
- package/coverage/toga-blox-npm/src/components/Card/Card.stories.tsx.html +787 -0
- package/coverage/toga-blox-npm/src/components/Card/Card.tsx.html +163 -0
- package/coverage/toga-blox-npm/src/components/Card/index.html +131 -0
- package/coverage/toga-blox-npm/src/components/Card/templates/CategoryCardTemplate.tsx.html +343 -0
- package/coverage/toga-blox-npm/src/components/Card/templates/CompassCardTemplate.tsx.html +259 -0
- package/coverage/toga-blox-npm/src/components/Card/templates/CounterContentCardTemplate.tsx.html +685 -0
- package/coverage/toga-blox-npm/src/components/Card/templates/HorizontalCardTemplate.tsx.html +637 -0
- package/coverage/toga-blox-npm/src/components/Card/templates/ItemCardTemplate.tsx.html +550 -0
- package/coverage/toga-blox-npm/src/components/Card/templates/KitContentCardTemplate.tsx.html +469 -0
- package/coverage/toga-blox-npm/src/components/Card/templates/ShippingAddressCardTemplate.tsx.html +418 -0
- package/coverage/toga-blox-npm/src/components/Card/templates/VerticalCardTemplate.tsx.html +592 -0
- package/coverage/toga-blox-npm/src/components/Card/templates/index.html +221 -0
- package/coverage/toga-blox-npm/src/components/CounterButton/CounterButton.stories.tsx.html +358 -0
- package/coverage/toga-blox-npm/src/components/CounterButton/CounterButton.tsx.html +385 -0
- package/coverage/toga-blox-npm/src/components/CounterButton/index.html +131 -0
- package/coverage/toga-blox-npm/src/components/Description/Description.stories.tsx.html +286 -0
- package/coverage/toga-blox-npm/src/components/Description/Description.tsx.html +124 -0
- package/coverage/toga-blox-npm/src/components/Description/index.html +131 -0
- package/coverage/toga-blox-npm/src/components/DropDownIconButton/DropDownIconButton.stories.tsx.html +676 -0
- package/coverage/toga-blox-npm/src/components/DropDownIconButton/DropDownIconButton.tsx.html +346 -0
- package/coverage/toga-blox-npm/src/components/DropDownIconButton/index.html +131 -0
- package/coverage/toga-blox-npm/src/components/Footer/ContactInfoItem.tsx.html +139 -0
- package/coverage/toga-blox-npm/src/components/Footer/Footer.stories.tsx.html +934 -0
- package/coverage/toga-blox-npm/src/components/Footer/Footer.tsx.html +373 -0
- package/coverage/toga-blox-npm/src/components/Footer/index.html +146 -0
- package/coverage/toga-blox-npm/src/components/FormButton/FormButton.stories.tsx.html +952 -0
- package/coverage/toga-blox-npm/src/components/FormButton/FormButton.tsx.html +343 -0
- package/coverage/toga-blox-npm/src/components/FormButton/index.html +131 -0
- package/coverage/toga-blox-npm/src/components/GenericList/GenericList.stories.tsx.html +376 -0
- package/coverage/toga-blox-npm/src/components/GenericList/GenericList.tsx.html +520 -0
- package/coverage/toga-blox-npm/src/components/GenericList/index.html +131 -0
- package/coverage/toga-blox-npm/src/components/GenericList/templates/DummyDataList.tsx.html +154 -0
- package/coverage/toga-blox-npm/src/components/GenericList/templates/DynamicIconList.tsx.html +250 -0
- package/coverage/toga-blox-npm/src/components/GenericList/templates/index.html +131 -0
- package/coverage/toga-blox-npm/src/components/GetSupport/GetSupport.stories.tsx.html +325 -0
- package/coverage/toga-blox-npm/src/components/GetSupport/GetSupport.tsx.html +262 -0
- package/coverage/toga-blox-npm/src/components/GetSupport/index.html +131 -0
- package/coverage/toga-blox-npm/src/components/HamburgerButton/Hamburger.stories.tsx.html +760 -0
- package/coverage/toga-blox-npm/src/components/HamburgerButton/HamburgerButton.tsx.html +232 -0
- package/coverage/toga-blox-npm/src/components/HamburgerButton/index.html +131 -0
- package/coverage/toga-blox-npm/src/components/Header/Header.stories.tsx.html +1633 -0
- package/coverage/toga-blox-npm/src/components/Header/Header.tsx.html +814 -0
- package/coverage/toga-blox-npm/src/components/Header/headerContext.tsx.html +460 -0
- package/coverage/toga-blox-npm/src/components/Header/index.html +146 -0
- package/coverage/toga-blox-npm/src/components/Hero/Hero.stories.tsx.html +289 -0
- package/coverage/toga-blox-npm/src/components/Hero/Hero.tsx.html +259 -0
- package/coverage/toga-blox-npm/src/components/Hero/index.html +131 -0
- package/coverage/toga-blox-npm/src/components/IconButton/IconButton.stories.tsx.html +673 -0
- package/coverage/toga-blox-npm/src/components/IconButton/IconButton.tsx.html +313 -0
- package/coverage/toga-blox-npm/src/components/IconButton/index.html +131 -0
- package/coverage/toga-blox-npm/src/components/Image/Image.stories.tsx.html +322 -0
- package/coverage/toga-blox-npm/src/components/Image/Image.tsx.html +226 -0
- package/coverage/toga-blox-npm/src/components/Image/index.html +131 -0
- package/coverage/toga-blox-npm/src/components/Input/Input.stories.tsx.html +1621 -0
- package/coverage/toga-blox-npm/src/components/Input/Input.tsx.html +568 -0
- package/coverage/toga-blox-npm/src/components/Input/InputMemoTypes.tsx.html +181 -0
- package/coverage/toga-blox-npm/src/components/Input/index.html +146 -0
- package/coverage/toga-blox-npm/src/components/MobileMenu/MobileMenu.tsx.html +208 -0
- package/coverage/toga-blox-npm/src/components/MobileMenu/index.html +116 -0
- package/coverage/toga-blox-npm/src/components/Nav/Nav.stories.tsx.html +628 -0
- package/coverage/toga-blox-npm/src/components/Nav/Nav.tsx.html +622 -0
- package/coverage/toga-blox-npm/src/components/Nav/index.html +131 -0
- package/coverage/toga-blox-npm/src/components/Page/TableDataDummy.tsx.html +733 -0
- package/coverage/toga-blox-npm/src/components/Page/ViewPageTemplate.stories.tsx.html +1714 -0
- package/coverage/toga-blox-npm/src/components/Page/ViewPageTemplate.tsx.html +115 -0
- package/coverage/toga-blox-npm/src/components/Page/index.html +146 -0
- package/coverage/toga-blox-npm/src/components/PageSection/PageSection.stories.tsx.html +433 -0
- package/coverage/toga-blox-npm/src/components/PageSection/PageSection.tsx.html +121 -0
- package/coverage/toga-blox-npm/src/components/PageSection/index.html +131 -0
- package/coverage/toga-blox-npm/src/components/SearchInput/SearchInput.stories.tsx.html +517 -0
- package/coverage/toga-blox-npm/src/components/SearchInput/SearchInput.tsx.html +325 -0
- package/coverage/toga-blox-npm/src/components/SearchInput/index.html +131 -0
- package/coverage/toga-blox-npm/src/components/Slider/Slider.stories.tsx.html +349 -0
- package/coverage/toga-blox-npm/src/components/Slider/Slider.tsx.html +502 -0
- package/coverage/toga-blox-npm/src/components/Slider/index.html +131 -0
- package/coverage/toga-blox-npm/src/components/Submenus/AdminSubmenu.tsx.html +136 -0
- package/coverage/toga-blox-npm/src/components/Submenus/AlertSubmenu.tsx.html +253 -0
- package/coverage/toga-blox-npm/src/components/Submenus/AlertSubmenuItem.tsx.html +202 -0
- package/coverage/toga-blox-npm/src/components/Submenus/index.html +146 -0
- package/coverage/toga-blox-npm/src/components/Text/Text.stories.tsx.html +235 -0
- package/coverage/toga-blox-npm/src/components/Text/Text.tsx.html +172 -0
- package/coverage/toga-blox-npm/src/components/Text/index.html +131 -0
- package/coverage/toga-blox-npm/src/components/Toaster/Toaster.stories.tsx.html +445 -0
- package/coverage/toga-blox-npm/src/components/Toaster/Toaster.tsx.html +301 -0
- package/coverage/toga-blox-npm/src/components/Toaster/index.html +131 -0
- package/coverage/toga-blox-npm/src/hoc/styling/index.html +116 -0
- package/coverage/toga-blox-npm/src/hoc/styling/withStoryBook.tsx.html +142 -0
- package/coverage/toga-blox-npm/src/userHoc/index.html +116 -0
- package/coverage/toga-blox-npm/src/userHoc/withMemo.tsx.html +145 -0
- package/coverage/toga-blox-npm/src/utils/assertTagName.tsx.html +106 -0
- package/coverage/toga-blox-npm/src/utils/generateAccordionItem.tsx.html +373 -0
- package/coverage/toga-blox-npm/src/utils/generateFooterContacts.tsx.html +295 -0
- package/coverage/toga-blox-npm/src/utils/generateNavMenu.tsx.html +247 -0
- package/coverage/toga-blox-npm/src/utils/generateSocialList.tsx.html +187 -0
- package/coverage/toga-blox-npm/src/utils/getFontAwesomeIcon.tsx.html +145 -0
- package/coverage/toga-blox-npm/src/utils/index.html +206 -0
- package/coverage/toga-blox-npm/src/utils/inputValidation.tsx.html +163 -0
- package/coverage/toga-blox-npm/tailwind.config.js.html +205 -0
- package/declarations.d.ts +1 -1
- package/package.json +5 -6
- package/src/components/Badge/Badge.stories.tsx +110 -207
- package/src/components/Badge/Badge.test.tsx +40 -41
- package/src/components/Badge/Badge.tsx +29 -99
- package/src/components/Badge/Badge.types.tsx +12 -23
- package/src/components/Card/Card.stories.tsx +166 -22
- package/src/components/Card/Card.test.tsx +3 -3
- package/src/components/Card/Card.tsx +12 -16
- package/src/components/Card/DUMMYPRODUCTDATA.json +381 -225
- package/src/components/Card/templates/CategoryCardTemplate.tsx +86 -0
- package/src/components/Card/templates/CompassCardTemplate.tsx +1 -1
- package/src/components/Card/templates/CounterContentCardTemplate.tsx +200 -0
- package/src/components/Card/templates/ItemCardTemplate.tsx +155 -0
- package/src/components/Card/templates/KitContentCardTemplate.tsx +128 -0
- package/src/components/Card/templates/ShippingAddressCardTemplate.tsx +111 -0
- package/src/components/Card/templates/VerticalCardTemplate.tsx +100 -85
- package/src/components/CounterButton/CounterButton.tsx +1 -1
- package/src/components/Description/Description.stories.tsx +67 -0
- package/src/components/Description/Description.tsx +13 -0
- package/src/components/Description/Description.types.ts +9 -0
- package/src/components/DropDownIconButton/DropDownIconButton.stories.tsx +197 -0
- package/src/components/DropDownIconButton/DropDownIconButton.test.tsx +90 -0
- package/src/components/DropDownIconButton/DropDownIconButton.tsx +87 -0
- package/src/components/DropDownIconButton/DropDownIconButton.types.ts +21 -0
- package/src/components/DropDownIconButton/index.ts +2 -0
- package/src/components/Footer/ContactInfoItem.tsx +8 -10
- package/src/components/Footer/Footer.stories.tsx +13 -22
- package/src/components/Footer/Footer.tsx +25 -88
- package/src/components/Footer/Footer.types.tsx +2 -2
- package/src/components/FormButton/FormButton.stories.tsx +101 -226
- package/src/components/FormButton/FormButton.test.tsx +1 -1
- package/src/components/FormButton/FormButton.tsx +34 -42
- package/src/components/FormButton/FormButton.types.ts +7 -13
- package/src/components/GenericList/GenericList.stories.tsx +5 -12
- package/src/components/GenericList/GenericList.tsx +91 -92
- package/src/components/GenericList/templates/DynamicIconList.tsx +45 -64
- package/src/components/GetSupport/GetSupport.stories.tsx +80 -0
- package/src/components/GetSupport/GetSupport.test.tsx +62 -0
- package/src/components/GetSupport/GetSupport.tsx +59 -0
- package/src/components/GetSupport/GetSupport.types.ts +11 -0
- package/src/components/HamburgerButton/Hamburger.stories.tsx +225 -0
- package/src/components/HamburgerButton/HamburgerButton.tsx +37 -56
- package/src/components/HamburgerButton/HamburgerButton.types.tsx +2 -1
- package/src/components/Header/Header.stories.tsx +3 -5
- package/src/components/Header/Header.tsx +37 -83
- package/src/components/Hero/Hero.stories.tsx +1 -2
- package/src/components/IconButton/IconButton.stories.tsx +196 -0
- package/src/components/{Icon/Icon.test.tsx → IconButton/IconButton.test.tsx} +3 -4
- package/src/components/IconButton/IconButton.tsx +76 -0
- package/src/components/IconButton/IconButton.types.ts +28 -0
- package/src/components/IconButton/index.ts +2 -0
- package/src/components/Image/Image.tsx +1 -1
- package/src/components/Input/Input.stories.tsx +10 -12
- package/src/components/Input/Input.test.tsx +2 -3
- package/src/components/Input/Input.tsx +41 -104
- package/src/components/MobileMenu/MobileMenu.types.tsx +0 -2
- package/src/components/Nav/DUMMYNAVDATA.json +4 -4
- package/src/components/Nav/Nav.tsx +49 -112
- package/src/components/Nav/Nav.types.tsx +14 -2
- package/src/components/Page/ViewPageTemplate.stories.tsx +2 -2
- package/src/components/Page/ViewPageTemplate.test.tsx +1 -1
- package/src/components/Page/ViewPageTemplate.types.ts +1 -1
- package/src/components/PageSection/PageSection.stories.tsx +3 -1
- package/src/components/PageSection/PageSections.test.tsx +2 -1
- package/src/components/SearchInput/SearchInput.stories.tsx +144 -0
- package/src/components/SearchInput/SearchInput.tsx +81 -0
- package/src/components/SearchInput/SearchInput.types.ts +28 -0
- package/src/components/Slider/Slider.stories.tsx +88 -0
- package/src/components/Slider/Slider.tsx +139 -0
- package/src/components/Slider/Slider.types.ts +21 -0
- package/src/components/Submenus/AdminSubmenu.tsx +17 -0
- package/src/components/Submenus/AlertSubmenu.tsx +56 -0
- package/src/components/Submenus/AlertSubmenuItem.tsx +39 -0
- package/src/components/Submenus/types.tsx +32 -0
- package/src/components/Text/Text.stories.tsx +47 -10
- package/src/components/Text/Text.test.tsx +10 -17
- package/src/components/Toaster/Toaster.stories.tsx +69 -78
- package/src/components/Toaster/Toaster.test.tsx +49 -43
- package/src/components/Toaster/Toaster.tsx +43 -56
- package/src/components/Toaster/Toaster.types.ts +9 -8
- package/src/utils/assertTagName.tsx +1 -1
- package/src/utils/generateAccordionItem.tsx +7 -13
- package/src/utils/generateFooterContacts.tsx +4 -9
- package/src/utils/getFontAwesomeIcon.tsx +8 -13
- package/tailwind.config.js +17 -2
- package/src/components/Badge/badgeClassNames.tsx +0 -173
- package/src/components/Card/cardClassNames.ts +0 -49
- package/src/components/Footer/footerClassNames.tsx +0 -57
- package/src/components/FormButton/formButtonClassNames.tsx +0 -153
- package/src/components/GenericList/genericListClassNames.tsx +0 -8
- package/src/components/Header/headerClassNames.tsx +0 -50
- package/src/components/Icon/Icon.stories.tsx +0 -227
- package/src/components/Icon/Icon.tsx +0 -208
- package/src/components/Icon/Icon.types.ts +0 -24
- package/src/components/Icon/iconClassNames.ts +0 -79
- package/src/components/Icon/index.ts +0 -2
- package/src/components/Input/inputClassNames.tsx +0 -169
- package/src/components/Nav/navClassNames.tsx +0 -192
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { Meta, StoryFn } from "@storybook/react";
|
|
2
|
+
import Slider from "./Slider";
|
|
3
|
+
import { SliderProps } from "./Slider.types";
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
title: 'Components/Slider',
|
|
7
|
+
component: Slider,
|
|
8
|
+
argTypes: {
|
|
9
|
+
min: {
|
|
10
|
+
control: 'none',
|
|
11
|
+
description: 'The minimum value of the range. Example: `0`',
|
|
12
|
+
},
|
|
13
|
+
title: {
|
|
14
|
+
control: 'none',
|
|
15
|
+
description: 'The title of the range. Example: `Temperature Range`',
|
|
16
|
+
},
|
|
17
|
+
max: {
|
|
18
|
+
control: 'none',
|
|
19
|
+
description: 'The maximum value of the range. Example: `100`',
|
|
20
|
+
},
|
|
21
|
+
step: {
|
|
22
|
+
control: 'none',
|
|
23
|
+
description: 'The step value for the range. Example: `1`',
|
|
24
|
+
},
|
|
25
|
+
minValue: {
|
|
26
|
+
control: 'none',
|
|
27
|
+
description: 'The initial minimum value. Example: `10`',
|
|
28
|
+
},
|
|
29
|
+
maxValue: {
|
|
30
|
+
control: 'none',
|
|
31
|
+
description: 'The initial maximum value. Example: `90`',
|
|
32
|
+
},
|
|
33
|
+
onMinChange: {
|
|
34
|
+
control: 'none',
|
|
35
|
+
description: 'Callback function when the minimum value changes. Example: `(value: number) => console.log(value)`',
|
|
36
|
+
},
|
|
37
|
+
onMaxChange: {
|
|
38
|
+
control: 'none',
|
|
39
|
+
description: 'Callback function when the maximum value changes. Example: `(value: number) => console.log(value)`',
|
|
40
|
+
},
|
|
41
|
+
additionalClasses: {
|
|
42
|
+
control: 'none',
|
|
43
|
+
description: 'Additional CSS classes for the component. Example: `my-custom-slider`',
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
tags: ['autodocs'],
|
|
47
|
+
parameters: {
|
|
48
|
+
layout: 'centered',
|
|
49
|
+
},
|
|
50
|
+
} as Meta;
|
|
51
|
+
|
|
52
|
+
const Template: StoryFn<SliderProps> = (args) => <Slider {...args} />;
|
|
53
|
+
|
|
54
|
+
export const Default = Template.bind({});
|
|
55
|
+
Default.args = {
|
|
56
|
+
min: 0,
|
|
57
|
+
max: 100,
|
|
58
|
+
step: 1,
|
|
59
|
+
minValue: 20,
|
|
60
|
+
maxValue: 80,
|
|
61
|
+
onMinChange: (value: number) => console.log('Min value changed:', value),
|
|
62
|
+
onMaxChange: (value: number) => console.log('Max value changed:', value),
|
|
63
|
+
title: 'Range',
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export const TemperatureRange = Template.bind({});
|
|
67
|
+
TemperatureRange.args = {
|
|
68
|
+
min: -50,
|
|
69
|
+
max: 50,
|
|
70
|
+
step: 0.5,
|
|
71
|
+
minValue: -10,
|
|
72
|
+
maxValue: 30,
|
|
73
|
+
onMinChange: (value: number) => console.log('Min value changed:', value),
|
|
74
|
+
onMaxChange: (value: number) => console.log('Max value changed:', value),
|
|
75
|
+
title: 'Temperature Range',
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export const PriceRange = Template.bind({});
|
|
79
|
+
PriceRange.args = {
|
|
80
|
+
min: 0,
|
|
81
|
+
max: 2000,
|
|
82
|
+
step: 1,
|
|
83
|
+
minValue: 900,
|
|
84
|
+
maxValue: 1578,
|
|
85
|
+
onMinChange: (value: number) => console.log('Min value changed:', value),
|
|
86
|
+
onMaxChange: (value: number) => console.log('Max value changed:', value),
|
|
87
|
+
title: 'Price Range',
|
|
88
|
+
};
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import React, { useRef, useState } from "react";
|
|
2
|
+
import { SliderProps } from "./Slider.types";
|
|
3
|
+
|
|
4
|
+
const Slider: React.FC<SliderProps> = ({
|
|
5
|
+
min,
|
|
6
|
+
max,
|
|
7
|
+
step,
|
|
8
|
+
minValue,
|
|
9
|
+
maxValue,
|
|
10
|
+
onMinChange,
|
|
11
|
+
onMaxChange,
|
|
12
|
+
additionalClasses = "",
|
|
13
|
+
containerClasses = "p-8 border rounded-lg shadow-md bg-white max-w-lg",
|
|
14
|
+
title = "Range",
|
|
15
|
+
titleClasses = "text-xl text-black mb-4 font-bold",
|
|
16
|
+
minLabel = "Min Value",
|
|
17
|
+
maxLabel = "Max Value",
|
|
18
|
+
labelClasses = "text-sm text-gray-500",
|
|
19
|
+
inputClasses = "mt-2 text-lg font-semibold text-gray-900 border border-gray-300 rounded px-2 py-1 text-center w-20",
|
|
20
|
+
sliderClasses = "relative w-full h-2 bg-gray-300 rounded",
|
|
21
|
+
rangeClasses = "absolute h-2 bg-teal-500 rounded",
|
|
22
|
+
thumbClasses = "absolute w-6 h-6 bg-white border-2 border-teal-500 rounded-full cursor-pointer",
|
|
23
|
+
onAddSection,
|
|
24
|
+
}) => {
|
|
25
|
+
const [minThumbValue, setMinThumbValue] = useState(minValue);
|
|
26
|
+
const [maxThumbValue, setMaxThumbValue] = useState(maxValue);
|
|
27
|
+
const sliderRef = useRef<HTMLDivElement>(null);
|
|
28
|
+
const isDragging = useRef<"min" | "max" | null>(null);
|
|
29
|
+
|
|
30
|
+
const getPercentage = (value: number) =>
|
|
31
|
+
((value - min) / (max - min)) * 100;
|
|
32
|
+
|
|
33
|
+
const handleMinChange = (value: number) => {
|
|
34
|
+
if (value <= maxThumbValue && value >= min) {
|
|
35
|
+
setMinThumbValue(value);
|
|
36
|
+
onMinChange(value);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const handleMaxChange = (value: number) => {
|
|
41
|
+
if (value >= minThumbValue && value <= max) {
|
|
42
|
+
setMaxThumbValue(value);
|
|
43
|
+
onMaxChange(value);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const handlePointerMove = (event: React.PointerEvent) => {
|
|
48
|
+
if (sliderRef.current && isDragging.current) {
|
|
49
|
+
const sliderRect = sliderRef.current.getBoundingClientRect();
|
|
50
|
+
const sliderWidth = sliderRect.width;
|
|
51
|
+
const clickX = event.clientX - sliderRect.left;
|
|
52
|
+
const newValue = min + (clickX / sliderWidth) * (max - min);
|
|
53
|
+
|
|
54
|
+
if (isDragging.current === "min") {
|
|
55
|
+
handleMinChange(Math.round(newValue / step) * step);
|
|
56
|
+
} else if (isDragging.current === "max") {
|
|
57
|
+
handleMaxChange(Math.round(newValue / step) * step);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const handlePointerUp = () => {
|
|
63
|
+
isDragging.current = null;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const handlePointerDown = (thumb: "min" | "max") => {
|
|
67
|
+
isDragging.current = thumb;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
return (
|
|
71
|
+
<div className={`${containerClasses} ${additionalClasses}`}>
|
|
72
|
+
<h3 className={titleClasses}>{title}</h3>
|
|
73
|
+
<hr className="border-gray-300 mb-6" />
|
|
74
|
+
<div className="flex justify-between gap-4 mb-6">
|
|
75
|
+
<div className="flex flex-col items-center">
|
|
76
|
+
<span className={labelClasses}>{minLabel}</span>
|
|
77
|
+
<input
|
|
78
|
+
type="number"
|
|
79
|
+
value={minThumbValue}
|
|
80
|
+
onChange={(e) => handleMinChange(Number(e.target.value))}
|
|
81
|
+
className={inputClasses}
|
|
82
|
+
/>
|
|
83
|
+
</div>
|
|
84
|
+
<div className="flex flex-col items-center">
|
|
85
|
+
<span className={labelClasses}>{maxLabel}</span>
|
|
86
|
+
<input
|
|
87
|
+
type="number"
|
|
88
|
+
value={maxThumbValue}
|
|
89
|
+
onChange={(e) => handleMaxChange(Number(e.target.value))}
|
|
90
|
+
className={inputClasses}
|
|
91
|
+
/>
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
<div
|
|
95
|
+
className={sliderClasses}
|
|
96
|
+
ref={sliderRef}
|
|
97
|
+
onPointerMove={handlePointerMove}
|
|
98
|
+
onPointerUp={handlePointerUp}
|
|
99
|
+
onPointerCancel={handlePointerUp}
|
|
100
|
+
onPointerLeave={handlePointerUp}
|
|
101
|
+
>
|
|
102
|
+
<div
|
|
103
|
+
className={rangeClasses}
|
|
104
|
+
style={{
|
|
105
|
+
left: `${getPercentage(minThumbValue)}%`,
|
|
106
|
+
right: `${100 - getPercentage(maxThumbValue)}%`,
|
|
107
|
+
}}
|
|
108
|
+
/>
|
|
109
|
+
<div
|
|
110
|
+
className={thumbClasses}
|
|
111
|
+
style={{
|
|
112
|
+
left: `${getPercentage(minThumbValue)}%`,
|
|
113
|
+
transform: "translate(-50%, -50%)",
|
|
114
|
+
top: "50%",
|
|
115
|
+
zIndex: 5,
|
|
116
|
+
}}
|
|
117
|
+
onPointerDown={() => handlePointerDown("min")}
|
|
118
|
+
/>
|
|
119
|
+
<div
|
|
120
|
+
className={thumbClasses}
|
|
121
|
+
style={{
|
|
122
|
+
left: `${getPercentage(maxThumbValue)}%`,
|
|
123
|
+
transform: "translate(-50%, -50%)",
|
|
124
|
+
top: "50%",
|
|
125
|
+
zIndex: 4,
|
|
126
|
+
}}
|
|
127
|
+
onPointerDown={() => handlePointerDown("max")}
|
|
128
|
+
/>
|
|
129
|
+
</div>
|
|
130
|
+
{onAddSection && (
|
|
131
|
+
<button onClick={onAddSection} className="mt-4 text-blue-500">
|
|
132
|
+
Add Section
|
|
133
|
+
</button>
|
|
134
|
+
)}
|
|
135
|
+
</div>
|
|
136
|
+
);
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
export default Slider;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface SliderProps {
|
|
2
|
+
min: number;
|
|
3
|
+
max: number;
|
|
4
|
+
step: number;
|
|
5
|
+
minValue: number;
|
|
6
|
+
maxValue: number;
|
|
7
|
+
onMinChange: (value: number) => void;
|
|
8
|
+
onMaxChange: (value: number) => void;
|
|
9
|
+
additionalClasses?: string;
|
|
10
|
+
containerClasses?: string;
|
|
11
|
+
title?: string;
|
|
12
|
+
titleClasses?: string;
|
|
13
|
+
minLabel?: string;
|
|
14
|
+
maxLabel?: string;
|
|
15
|
+
labelClasses?: string;
|
|
16
|
+
inputClasses?: string;
|
|
17
|
+
sliderClasses?: string;
|
|
18
|
+
rangeClasses?: string;
|
|
19
|
+
thumbClasses?: string;
|
|
20
|
+
onAddSection?: () => void;
|
|
21
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { AdminSubmenuProps } from "./types";
|
|
3
|
+
|
|
4
|
+
const AdminSubmenu: React.FC<AdminSubmenuProps> = ({
|
|
5
|
+
callToActionChildren,
|
|
6
|
+
secondCallToActionChildren,
|
|
7
|
+
menuClasses = "p-4 bg-white rounded-lg shadow-lg",
|
|
8
|
+
}) => {
|
|
9
|
+
return (
|
|
10
|
+
<div className={menuClasses}>
|
|
11
|
+
<div>{callToActionChildren}</div>
|
|
12
|
+
<div>{secondCallToActionChildren}</div>
|
|
13
|
+
</div>
|
|
14
|
+
);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export default AdminSubmenu;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import AlertSubmenuItem from "./AlertSubmenuItem";
|
|
3
|
+
import { AlertSubmenuProps } from "./types";
|
|
4
|
+
|
|
5
|
+
const AlertSubmenu: React.FC<AlertSubmenuProps> = ({
|
|
6
|
+
data,
|
|
7
|
+
newAlertCount,
|
|
8
|
+
newAlertColor,
|
|
9
|
+
onClearAlerts,
|
|
10
|
+
newAlertCountClasses = "text-gray-900 font-semibold",
|
|
11
|
+
clearAlertsTextClasses = "text-blue-600 hover:underline",
|
|
12
|
+
clearAlertsText = "Mark all as Read",
|
|
13
|
+
menuContainerClasses = "rounded-lg border border-stroke bg-white shadow-lg",
|
|
14
|
+
menuHeaderContainerClasses = "flex justify-between items-center p-4 border-b border-gray-200",
|
|
15
|
+
alertListContainerClasses = "overflow-y-auto max-h-[300px] divide-y divide-gray-200",
|
|
16
|
+
}) => {
|
|
17
|
+
const alertList = data.map((alert, index) => (
|
|
18
|
+
<AlertSubmenuItem
|
|
19
|
+
key={index}
|
|
20
|
+
link={alert.link}
|
|
21
|
+
title={alert.title}
|
|
22
|
+
subtitle={alert.subtitle}
|
|
23
|
+
status={alert.status}
|
|
24
|
+
statusColor={newAlertColor}
|
|
25
|
+
externalLink={alert.externalLink}
|
|
26
|
+
titleClasses="font-medium text-gray-900"
|
|
27
|
+
externalLinkClasses="text-sm text-blue-600"
|
|
28
|
+
subtitleClasses="text-sm text-gray-500"
|
|
29
|
+
itemContainerClasses="p-4 hover:bg-gray-50"
|
|
30
|
+
/>
|
|
31
|
+
));
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<div className={menuContainerClasses}>
|
|
35
|
+
<div className={menuHeaderContainerClasses}>
|
|
36
|
+
<span className={newAlertCountClasses}>
|
|
37
|
+
{newAlertCount} alerts
|
|
38
|
+
</span>
|
|
39
|
+
<button
|
|
40
|
+
className={clearAlertsTextClasses}
|
|
41
|
+
onClick={onClearAlerts}
|
|
42
|
+
>
|
|
43
|
+
{clearAlertsText}
|
|
44
|
+
</button>
|
|
45
|
+
</div>
|
|
46
|
+
<div className={alertListContainerClasses}>
|
|
47
|
+
<ul>{alertList}</ul>
|
|
48
|
+
<div className="text-center p-4 text-gray-500">
|
|
49
|
+
All up to date!
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export default AlertSubmenu;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { AlertSubmenuItemProps } from "./types";
|
|
3
|
+
|
|
4
|
+
const AlertSubmenuItem: React.FC<AlertSubmenuItemProps> = ({
|
|
5
|
+
link = "#",
|
|
6
|
+
title,
|
|
7
|
+
externalLink,
|
|
8
|
+
subtitle,
|
|
9
|
+
status,
|
|
10
|
+
statusColor = "bg-blue-500",
|
|
11
|
+
itemContainerClasses = "flex justify-between items-center p-4",
|
|
12
|
+
titleClasses = "font-medium text-gray-900",
|
|
13
|
+
externalLinkClasses = "text-sm text-blue-600",
|
|
14
|
+
subtitleClasses = "text-sm text-gray-500",
|
|
15
|
+
}) => {
|
|
16
|
+
return (
|
|
17
|
+
<li className={itemContainerClasses}>
|
|
18
|
+
<a href={link} className="flex items-start gap-4">
|
|
19
|
+
<div className="flex-shrink-0 pt-2">
|
|
20
|
+
{status && (
|
|
21
|
+
<span
|
|
22
|
+
className={`inline-block w-3 h-3 rounded-full ${statusColor}`}
|
|
23
|
+
aria-label="New"
|
|
24
|
+
></span>
|
|
25
|
+
)}
|
|
26
|
+
</div>
|
|
27
|
+
<div>
|
|
28
|
+
<h6 className={titleClasses}>{title}</h6>
|
|
29
|
+
{externalLink && (
|
|
30
|
+
<p className={externalLinkClasses}>{externalLink}</p>
|
|
31
|
+
)}
|
|
32
|
+
<p className={subtitleClasses}>{subtitle}</p>
|
|
33
|
+
</div>
|
|
34
|
+
</a>
|
|
35
|
+
</li>
|
|
36
|
+
);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export default AlertSubmenuItem;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
|
|
2
|
+
export interface AlertSubmenuItemProps {
|
|
3
|
+
link?: string;
|
|
4
|
+
title: string;
|
|
5
|
+
externalLink?: string;
|
|
6
|
+
subtitle?: string;
|
|
7
|
+
status?: string;
|
|
8
|
+
statusColor?: string;
|
|
9
|
+
itemContainerClasses?: string;
|
|
10
|
+
titleClasses?: string;
|
|
11
|
+
externalLinkClasses?: string;
|
|
12
|
+
subtitleClasses?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface AlertSubmenuProps<T = Record<string, any>> {
|
|
16
|
+
data: T[];
|
|
17
|
+
newAlertCount?: number;
|
|
18
|
+
newAlertColor?: string;
|
|
19
|
+
onClearAlerts?: () => void;
|
|
20
|
+
newAlertCountClasses?: string;
|
|
21
|
+
clearAlertsTextClasses?: string;
|
|
22
|
+
clearAlertsText?: string;
|
|
23
|
+
menuContainerClasses?: string;
|
|
24
|
+
menuHeaderContainerClasses?: string;
|
|
25
|
+
alertListContainerClasses?: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface AdminSubmenuProps {
|
|
29
|
+
callToActionChildren?: JSX.Element;
|
|
30
|
+
secondCallToActionChildren?: JSX.Element;
|
|
31
|
+
menuClasses?: string;
|
|
32
|
+
}
|
|
@@ -7,28 +7,65 @@ export default {
|
|
|
7
7
|
component: Text,
|
|
8
8
|
argTypes: {
|
|
9
9
|
size: {
|
|
10
|
-
control:
|
|
11
|
-
|
|
10
|
+
control: {
|
|
11
|
+
type: "select", // Dropdown control
|
|
12
|
+
},
|
|
13
|
+
options: [
|
|
14
|
+
"text-xs",
|
|
15
|
+
"text-sm",
|
|
16
|
+
"text-md",
|
|
17
|
+
"text-lg",
|
|
18
|
+
"text-xl",
|
|
19
|
+
"text-2xl",
|
|
20
|
+
"text-3xl",
|
|
21
|
+
"text-base",
|
|
22
|
+
], // Define options explicitly
|
|
23
|
+
description:
|
|
24
|
+
"The font size for the text. Use Tailwind CSS classes like 'text-xs', 'text-sm', 'text-md', etc. Default is 'text-base'.",
|
|
12
25
|
},
|
|
13
26
|
color: {
|
|
14
|
-
control:
|
|
15
|
-
|
|
27
|
+
control: {
|
|
28
|
+
type: "select", // Dropdown control
|
|
29
|
+
},
|
|
30
|
+
options: [
|
|
31
|
+
"text-red-800",
|
|
32
|
+
"text-blue-800",
|
|
33
|
+
"text-green-800",
|
|
34
|
+
"text-slate-950",
|
|
35
|
+
"text-black",
|
|
36
|
+
],
|
|
37
|
+
description:
|
|
38
|
+
"The color of the text. Use Tailwind CSS classes like 'text-red-800', 'text-blue-800', 'text-black', etc. Default is 'text-black'.",
|
|
16
39
|
},
|
|
17
40
|
tag: {
|
|
18
|
-
control:
|
|
19
|
-
|
|
41
|
+
control: {
|
|
42
|
+
type: "select", // Dropdown control
|
|
43
|
+
},
|
|
44
|
+
options: ["h1", "h2", "h3", "h4", "h5", "p", "span"], // Ensure valid HTML tags are listed
|
|
45
|
+
description:
|
|
46
|
+
"The type of HTML element the text should be. Options include 'h1', 'h2', 'p', etc. Default is 'span'.",
|
|
20
47
|
},
|
|
21
48
|
fontFamily: {
|
|
22
|
-
control:
|
|
23
|
-
|
|
49
|
+
control: {
|
|
50
|
+
type: "select", // Dropdown control
|
|
51
|
+
},
|
|
52
|
+
options: ["font-sans", "font-mono", "font-serif"], // Define the font-family options
|
|
53
|
+
description:
|
|
54
|
+
"The type of font family. Use Tailwind CSS classes like 'font-sans', 'font-mono', etc. Default is 'font-sans'.",
|
|
24
55
|
},
|
|
25
56
|
text: {
|
|
26
|
-
control:
|
|
57
|
+
control: {
|
|
58
|
+
type: "text", // Text input control
|
|
59
|
+
},
|
|
27
60
|
description: "The main text displayed on the component.",
|
|
61
|
+
defaultValue: "Testing",
|
|
28
62
|
},
|
|
29
63
|
additionalClasses: {
|
|
30
|
-
control:
|
|
64
|
+
control: {
|
|
65
|
+
type: "text", // Text input control
|
|
66
|
+
},
|
|
31
67
|
description: "Additional Tailwind CSS classes to be added.",
|
|
68
|
+
defaultValue: "",
|
|
32
69
|
},
|
|
33
70
|
},
|
|
34
71
|
tags: ["autodocs"],
|
|
@@ -7,10 +7,10 @@ describe("<Text />", () => {
|
|
|
7
7
|
render(
|
|
8
8
|
<Text
|
|
9
9
|
text="Testing"
|
|
10
|
-
size="md"
|
|
11
|
-
color="red"
|
|
10
|
+
size="text-md"
|
|
11
|
+
color="text-red-500"
|
|
12
12
|
tag="h1"
|
|
13
|
-
fontFamily="sans"
|
|
13
|
+
fontFamily="font-sans"
|
|
14
14
|
/>
|
|
15
15
|
);
|
|
16
16
|
});
|
|
@@ -23,30 +23,23 @@ describe("<Text />", () => {
|
|
|
23
23
|
expect(screen.getByTestId("text")).toHaveTextContent("Testing");
|
|
24
24
|
});
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
// // For example, if using Tailwind, check for the relevant class instead
|
|
31
|
-
// const textElement = screen.getByTestId("text");
|
|
32
|
-
// expect(textElement).toHaveClass("text-red-500");
|
|
33
|
-
// });
|
|
26
|
+
test("renders correct font color", () => {
|
|
27
|
+
const textElement = screen.getByTestId("text");
|
|
28
|
+
expect(textElement).toHaveClass("text-red-500");
|
|
29
|
+
});
|
|
34
30
|
|
|
35
|
-
|
|
36
|
-
// Check for class or style attribute
|
|
31
|
+
test("renders correct font size", () => {
|
|
37
32
|
const textElement = screen.getByTestId("text");
|
|
38
|
-
expect(textElement).toHaveClass("text-md");
|
|
33
|
+
expect(textElement).toHaveClass("text-md");
|
|
39
34
|
});
|
|
40
35
|
|
|
41
36
|
test("renders correct font family", () => {
|
|
42
37
|
const textElement = screen.getByTestId("text");
|
|
43
|
-
// Check for the presence of the Tailwind CSS class for 'sans' font family
|
|
44
38
|
expect(textElement).toHaveClass("font-sans");
|
|
45
39
|
});
|
|
46
40
|
|
|
47
41
|
test("renders correct element type", () => {
|
|
48
|
-
// Assuming 'as' prop is set to 'h1' in your test setup
|
|
49
42
|
const textElement = screen.getByTestId("text");
|
|
50
|
-
expect(textElement.tagName).toBe("H1");
|
|
43
|
+
expect(textElement.tagName).toBe("H1");
|
|
51
44
|
});
|
|
52
45
|
});
|