Component build stabilization
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -41,3 +41,4 @@ stats.html
|
||||
|
||||
analyticsrc.json
|
||||
|
||||
Date
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@armco/armory-react-components",
|
||||
"version": "0.0.23",
|
||||
"version": "0.0.24",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@armco/armory-react-components",
|
||||
"version": "0.0.23",
|
||||
"version": "0.0.24",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@armco/analytics": "^0.2.5",
|
||||
|
||||
10
package.json
10
package.json
@@ -1,16 +1,15 @@
|
||||
{
|
||||
"name": "@armco/armory-react-components",
|
||||
"description": "React Component Library for Armco's stack of products and services",
|
||||
"version": "0.0.23",
|
||||
"version": "0.0.24",
|
||||
"type": "module",
|
||||
"author": "Armco (@restruct-corporate-advantage)",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"start": "NODE_ENV=production vite",
|
||||
"build": "tsc && vite build",
|
||||
"build:publish": "tsc --p ./tsconfig-build.json && vite build --config vite-publish.config.ts",
|
||||
"build:clean": "rm -rf ./build",
|
||||
"build:sh": "./scripts/publish-build.sh",
|
||||
"build:publish": "./scripts/build.sh",
|
||||
"build:publish:compile": "tsc --p ./tsconfig-build.json && vite build --config vite-publish.config.ts",
|
||||
"generate": "plop",
|
||||
"atom": "plop atom",
|
||||
"molecule": "plop molecule",
|
||||
@@ -23,8 +22,7 @@
|
||||
"type-check": "tsc",
|
||||
"publish:dry": "npm publish --dry-run",
|
||||
"publish:local": "./scripts/publish-local.sh",
|
||||
"publish:public": "npm publish --access public",
|
||||
"shpublish": "./scripts/publish.sh",
|
||||
"publish:public": "./scripts/publish.sh",
|
||||
"storybook": "storybook dev -p 6006",
|
||||
"build-storybook": "storybook build"
|
||||
},
|
||||
|
||||
120
scripts/build.sh
Executable file
120
scripts/build.sh
Executable file
@@ -0,0 +1,120 @@
|
||||
#!/bin/sh
|
||||
|
||||
copy_files() {
|
||||
local source_dir="$1"
|
||||
local destination_dir="$2"
|
||||
local files_to_copy=(".tsx" ".component.scss")
|
||||
|
||||
echo "Copying file from $source_dir to $destination_dir"
|
||||
find "$source_dir" -type d -mindepth 1 -maxdepth 1 | while read -r directory; do
|
||||
echo "Found directory: $directory"
|
||||
for file in "${files_to_copy[@]}"; do
|
||||
source_file="$directory/$(basename "$directory")$file"
|
||||
destination_file="$destination_dir/$(basename "$directory")$file"
|
||||
# echo "Copying $source_file to $destination_file"
|
||||
cp "$source_file" "$destination_file"
|
||||
# echo "Copied $source_file to $destination_file"
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
search_replace_in_files() {
|
||||
local directory_or_file="$1"
|
||||
local search_string="$2"
|
||||
local replace_string="$3"
|
||||
local -a dir_names=("${@:4}") # Accept array of directory names as arguments
|
||||
|
||||
echo "Initiate search and replace in files $search_string $replace_string"
|
||||
|
||||
# Step 1: Check if the argument is a file
|
||||
if [ -f "$directory_or_file" ]; then
|
||||
# Process the single file
|
||||
perl -pi -e "s|$search_string|$replace_string|g" "$directory_or_file"
|
||||
else
|
||||
# Step 2: Get all files recursively matching the condition (only .tsx and .scss)
|
||||
files=$(find "$directory_or_file" -type f \( -name "*.tsx" -o -name "*.scss" -o -name "*.ts" \))
|
||||
# Step 3: Iterate over each file and perform search and replace
|
||||
for file in $files; do
|
||||
# Step 4: Iterate over each directory name in the array
|
||||
for dir_name in "${dir_names[@]}"; do
|
||||
# Step 5: Check if the file name starts with any of the specified directories
|
||||
if [[ "$file" == *"/$dir_name/"* ]]; then
|
||||
echo "Skipping file $file as it starts with '$dir_name/'"
|
||||
continue 2 # Continue to the next iteration of the outer loop
|
||||
fi
|
||||
done
|
||||
# Step 6: Perform search and replace in each file using perl
|
||||
perl -pi -e "s|$search_string|$replace_string|g" "$file"
|
||||
done
|
||||
fi
|
||||
|
||||
echo "Search and replace in TypeScript and SCSS files completed."
|
||||
}
|
||||
|
||||
# Function to split the string into an array based on a delimiter
|
||||
split_string() {
|
||||
local string="$1"
|
||||
local delimiter="$2"
|
||||
IFS="$delimiter" read -r -a array <<< "$string"
|
||||
echo "${array[@]}"
|
||||
}
|
||||
|
||||
rm -rf ./lib
|
||||
mkdir -p "./lib"
|
||||
|
||||
file_types=("types" "utils" "config" "static" "store" "hooks")
|
||||
ignore_dirs=("utils config static" "types" "utils" "utils" "" "")
|
||||
|
||||
copy_files "src/app/components/atoms" "lib"
|
||||
copy_files "src/app/components/molecules" "lib"
|
||||
cp src/app/components/atoms/index.tsx lib/atoms.ts
|
||||
cp src/app/components/molecules/index.tsx lib/molecules.ts
|
||||
cp src/app/components/components.ts lib/index.ts
|
||||
cp -r src/app/types lib
|
||||
cp -r src/app/utils lib
|
||||
cp -r src/app/config lib
|
||||
cp -r src/app/static lib
|
||||
cp src/app/hooks.ts "lib"
|
||||
cp -r src/app/hooks "lib"
|
||||
cp src/react-app-env.d.ts lib
|
||||
cp src/vite-env.d.ts lib
|
||||
cp package.json lib
|
||||
cp src/app/components/atoms/Calendar/JustCalendar.tsx "lib"
|
||||
cp src/app/components/atoms/Calendar/MonthSelector.tsx "lib"
|
||||
cp src/app/components/atoms/Calendar/MonthSelector.component.scss "lib"
|
||||
cp src/app/components/atoms/Calendar/JustCalendar.component.scss "lib"
|
||||
cp src/app/components/atoms/Calendar/EventForm.tsx "lib"
|
||||
cp src/app/components/atoms/Calendar/MonthNavigator.tsx "lib"
|
||||
cp src/app/components/atoms/Calendar/MonthNavigator.component.scss "lib"
|
||||
cp src/app/components/atoms/Calendar/helper.ts "lib"
|
||||
cp src/app/components/molecules/Carousel/Thumbs.tsx "lib"
|
||||
cp src/app/components/molecules/Carousel/cssClasses.ts "lib"
|
||||
cp src/app/components/molecules/Carousel/animations.ts "lib"
|
||||
cp src/app/store.ts "lib"
|
||||
|
||||
for i in $(seq 0 $((${#file_types[@]} - 1))); do
|
||||
echo ${file_types[i]} ${ignore_dirs[i]}
|
||||
ignore_dirs_array=($(split_string "${ignore_dirs[i]}" " "))
|
||||
search_replace_in_files "lib" "\.\./\.\./\.\./${file_types[i]}" "./${file_types[i]}" "${ignore_dirs_array[@]}"
|
||||
search_replace_in_files "lib" "\.\./\.\./${file_types[i]}" "./${file_types[i]}" "${ignore_dirs_array[@]}"
|
||||
search_replace_in_files "lib" "\.\./${file_types[i]}" "./${file_types[i]}" "${ignore_dirs_array[@]}"
|
||||
done
|
||||
|
||||
search_replace_in_files "lib" "\.\./components/molecules" ".."
|
||||
search_replace_in_files "lib" "\.\./components/atoms" ".."
|
||||
search_replace_in_files "lib/types/types.ts" "Carousel/Carousel" "Carousel"
|
||||
search_replace_in_files "lib/DatePicker.tsx" "\.\./Calendar/helper" "./helper" "types"
|
||||
search_replace_in_files "lib/DateRangePicker.tsx" "\.\./Calendar/helper" "./helper" "types"
|
||||
search_replace_in_files "lib/package.json" "\./build/index" "index"
|
||||
search_replace_in_files "lib/types/components.interface.ts" "\.\./Calendar/helper" "../helper"
|
||||
search_replace_in_files "lib" "\"\.\./\.\.\"" "\"..\""
|
||||
|
||||
sed '/componentsViewerPage/d' lib/store.ts > temp_file && mv temp_file lib/store.ts
|
||||
sed '/iconsPage/d' lib/store.ts > temp_file && mv temp_file lib/store.ts
|
||||
sed '/iconPage/d' lib/store.ts > temp_file && mv temp_file lib/store.ts
|
||||
sed '/tasksPage/d' lib/store.ts > temp_file && mv temp_file lib/store.ts
|
||||
|
||||
search_replace_in_files "lib" "\"\.\.\"" "\"\.\""
|
||||
|
||||
rm -rf build
|
||||
npm run build:publish:compile
|
||||
@@ -1,67 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
copy_files() {
|
||||
local source_dir="$1"
|
||||
local destination_dir="$2"
|
||||
local files_to_copy=(".tsx" ".component.scss")
|
||||
|
||||
find "$source_dir" -type d -mindepth 1 -maxdepth 1 | while read -r directory; do
|
||||
echo "Found directory: $directory"
|
||||
for file in "${files_to_copy[@]}"; do
|
||||
source_file="$directory/$(basename "$directory")$file"
|
||||
destination_file="$destination_dir/$(basename "$directory")$file"
|
||||
echo "Copying $source_file to $destination_file"
|
||||
cp "$source_file" "$destination_file"
|
||||
echo "Copied $source_file to $destination_file"
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
search_replace_in_files() {
|
||||
local directory="$1"
|
||||
local search_string="$2"
|
||||
local replace_string="$3"
|
||||
|
||||
# Use find to locate TypeScript and SCSS files in the directory
|
||||
find "$directory" -type f \( -name "*.tsx" -o -name "*.scss" \) -exec sh -c '
|
||||
for file do
|
||||
echo "Processed: $file"
|
||||
perl -pi -e "s|$search_string|$replace_string|g" "$file"
|
||||
done
|
||||
' sh {} +
|
||||
|
||||
echo "Search and replace in TypeScript and SCSS files completed."
|
||||
}
|
||||
|
||||
|
||||
# copy_files "../src/app/components/atoms" "../lib"
|
||||
# copy_files "../src/app/components/molecules" "../lib"
|
||||
# cp ../src/app/components/atoms/index.tsx ../lib/atoms.ts
|
||||
# cp ../src/app/components/molecules/index.tsx ../lib/molecules.ts
|
||||
# cp ../src/app/components/components.ts ../lib/index.ts
|
||||
# cp -r ../src/app/types ../lib
|
||||
# cp -r ../src/app/utils ../lib
|
||||
# cp -r ../src/app/config ../lib
|
||||
# cp -r ../src/app/static ../lib
|
||||
# cp ../src/app/hooks.ts "../lib"
|
||||
# cp -r ../src/app/pages "../lib"
|
||||
# cp ../src/react-app-env.d.ts ../lib
|
||||
# cp ../src/vite-env.d.ts ../lib
|
||||
# cp ../tsconfig.json ../lib
|
||||
# cp ../package.json ../lib
|
||||
# cp ../src/app/components/atoms/Calendar/JustCalendar.tsx "../lib"
|
||||
# cp ../src/app/components/atoms/Calendar/MonthSelector.tsx "../lib"
|
||||
# cp ../src/app/components/atoms/Calendar/EventForm.tsx "../lib"
|
||||
# cp ../src/app/components/atoms/Calendar/MonthNavigator.tsx "../lib"
|
||||
# cp ../src/app/components/atoms/Calendar/helper.ts "../lib"
|
||||
# cp ../src/app/store.ts "../lib"
|
||||
# search_replace_in_files "../lib" "../../../types" "./types"
|
||||
# search_replace_in_files "../lib" "\.\./\.\." "\."
|
||||
# search_replace_in_files "../lib" "\.\./utils" "utils"
|
||||
# search_replace_in_files "../lib" "\.\./config" "config"
|
||||
# search_replace_in_files "../lib" "\.\./static" "static"
|
||||
# search_replace_in_files "../lib" "\.\." "\."
|
||||
# search_replace_in_files "../lib" "\(\.args" "\(\.\.\.args"
|
||||
npm run build:publish
|
||||
@@ -1,7 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
semver=${1:-patch}
|
||||
|
||||
set -e
|
||||
npm run build:sh
|
||||
npm pack --pack-destination ~/__Projects__/Common
|
||||
source ./scripts/build.sh
|
||||
npm pack --pack-destination ~/__Projects__/Common
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
source ./scripts/publish-build.sh
|
||||
npm --no-git-tag-version version patch
|
||||
npm publish --access public
|
||||
semver=${1:-patch}
|
||||
|
||||
set -e
|
||||
# source ./scripts/build.sh
|
||||
npm --no-git-tag-version version ${semver}
|
||||
npm publish --access public
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import { useEffect, useState } from "react"
|
||||
import Icon from "../Icon"
|
||||
import { AlertProps } from ".."
|
||||
import { AlertProps, Icon, LoadableIcon } from ".."
|
||||
import { ICON_ROOT } from "../../../config/constants"
|
||||
import "./Alert.component.scss"
|
||||
import LoadableIcon from "../LoadableIcon"
|
||||
|
||||
let timeoutRef: any
|
||||
const Alert = (props: AlertProps): JSX.Element => {
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { useEffect, useRef } from "react"
|
||||
import * as d3 from "d3"
|
||||
import { ArVizProps } from ".."
|
||||
import { ArVizProps, BubbleChart } from ".."
|
||||
import { ArVisualizationTypes } from "../../../types/enums"
|
||||
import { generateBubbleChart } from "../../../utils/chartGenerators"
|
||||
import BubbleChart from "../BubbleChart"
|
||||
import { ObjectType } from "../../../types/types"
|
||||
import "./ArViz.component.scss"
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import LoadableIcon from "../LoadableIcon"
|
||||
import { MonthNavigatorProps } from ".."
|
||||
import { LoadableIcon, MonthNavigatorProps } from ".."
|
||||
import {
|
||||
ArCalViews,
|
||||
ArMonthSelectorViews,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { useState } from "react"
|
||||
import { ColorSelectorProps } from ".."
|
||||
import { ColorSelectorProps, TextInput } from ".."
|
||||
import "./ColorSelector.component.scss"
|
||||
import TextInput from "../TextInput"
|
||||
|
||||
const ColorSelector = (props: ColorSelectorProps): JSX.Element => {
|
||||
const { classes, label, onChange, withSample } = props
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import { ChangeEvent, useEffect, useState } from "react"
|
||||
import { CronTabProps } from ".."
|
||||
import TextInput from "../TextInput"
|
||||
import LoadableIcon from "../LoadableIcon"
|
||||
import { CronTabProps, LoadableIcon, TextInput } from ".."
|
||||
import "./CronTab.component.scss"
|
||||
|
||||
const cronFields = ["min", "hour", "day", "week", "month"]
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
import React from "react"
|
||||
import Calendar from "./Calendar" // Import your Calendar component
|
||||
import TimePicker from "./TimePicker" // Import your TimePicker component
|
||||
|
||||
interface CalTimeProps {
|
||||
month: number
|
||||
showTimePicker?: boolean
|
||||
year: number
|
||||
// Add other props as needed
|
||||
}
|
||||
|
||||
const CalTime: React.FC<CalTimeProps> = ({ showTimePicker, ...otherProps }) => {
|
||||
return (
|
||||
<div className="ar-CalTime">
|
||||
{/* Render the Calendar component */}
|
||||
<Calendar {...otherProps} />
|
||||
|
||||
{/* Render the TimePicker component if showTimePicker is true */}
|
||||
{showTimePicker && <TimePicker />}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default CalTime
|
||||
@@ -1,103 +0,0 @@
|
||||
import React from "react"
|
||||
import moment from "moment"
|
||||
|
||||
interface CalendarProps {
|
||||
year: number
|
||||
month: number
|
||||
}
|
||||
|
||||
const Calendar: React.FC<CalendarProps> = ({ year, month }) => {
|
||||
const firstDayOfMonth = moment(`${year}-${month}-01`)
|
||||
const lastDayOfMonth = firstDayOfMonth.clone().endOf("month")
|
||||
const firstDayOfWeek = firstDayOfMonth.day()
|
||||
const numberOfDays = lastDayOfMonth.date()
|
||||
|
||||
interface Weekday {
|
||||
abbr: string
|
||||
ariaLabel: string
|
||||
value: string
|
||||
}
|
||||
|
||||
const getWeekdayNames = (): Weekday[] => {
|
||||
const weekdays = moment.weekdaysShort()
|
||||
return weekdays.map((weekday) => ({
|
||||
abbr: weekday,
|
||||
ariaLabel: `Select ${weekday}`,
|
||||
value: weekday.substr(0, 2),
|
||||
}))
|
||||
}
|
||||
|
||||
const renderCalendarGrid = () => {
|
||||
const daysArray = Array.from(
|
||||
{ length: numberOfDays },
|
||||
(_, index) => index + 1,
|
||||
)
|
||||
const weekdays = getWeekdayNames()
|
||||
|
||||
return (
|
||||
<table
|
||||
className="ar-Calendar w-100 h-100"
|
||||
role="grid"
|
||||
aria-labelledby="calendar-heading"
|
||||
>
|
||||
<caption id="calendar-heading">
|
||||
{firstDayOfMonth.format("MMMM YYYY")}
|
||||
</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
{weekdays.map((weekday) => (
|
||||
<th
|
||||
key={weekday.abbr}
|
||||
abbr={weekday.abbr}
|
||||
role="columnheader"
|
||||
aria-label={weekday.ariaLabel}
|
||||
>
|
||||
{weekday.value}
|
||||
</th>
|
||||
))}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{Array.from(
|
||||
{ length: Math.ceil((numberOfDays + firstDayOfWeek) / 7) },
|
||||
(_, row) => (
|
||||
<tr key={row}>
|
||||
{Array.from({ length: 7 }, (_, col) => {
|
||||
const day = row * 7 + col + 1 - firstDayOfWeek
|
||||
return day > 0 && day <= numberOfDays ? (
|
||||
<td
|
||||
key={day}
|
||||
role="gridcell"
|
||||
className="calendar-day cursor-pointer"
|
||||
aria-label={firstDayOfMonth
|
||||
.date(day)
|
||||
.format("D MMMM YYYY")}
|
||||
onClick={() => handleDayClick(day)}
|
||||
>
|
||||
{day}
|
||||
</td>
|
||||
) : (
|
||||
<td
|
||||
key={`empty-${col}`}
|
||||
role="gridcell"
|
||||
aria-hidden="true"
|
||||
></td>
|
||||
)
|
||||
})}
|
||||
</tr>
|
||||
),
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
)
|
||||
}
|
||||
|
||||
const handleDayClick = (day: number) => {
|
||||
// Handle day click event here
|
||||
console.log(`Selected day: ${day}`)
|
||||
}
|
||||
|
||||
return renderCalendarGrid()
|
||||
}
|
||||
|
||||
export default Calendar
|
||||
@@ -1,531 +0,0 @@
|
||||
$color_1: inherit;
|
||||
$color_2: #fff;
|
||||
$color_3: #ccc;
|
||||
$color_4: #999;
|
||||
$color_5: #000;
|
||||
$font-family_1: arial;
|
||||
$background-color_1: #fff;
|
||||
$background-color_2: #eee;
|
||||
$background-color_3: #ebf4f8;
|
||||
$background-color_4: #357ebd;
|
||||
$background-color_5: #08c;
|
||||
$border-color_1: transparent;
|
||||
$border-bottom-color_1: rgba(0, 0, 0, 0.2);
|
||||
|
||||
/* Larger Screen Styling */
|
||||
// .ar-DateRange {
|
||||
// // position: absolute;
|
||||
// color: $color_1;
|
||||
// background-color: $background-color_1;
|
||||
// border-radius: 4px;
|
||||
// border: 1px solid #ddd;
|
||||
// width: 278px;
|
||||
// max-width: none;
|
||||
// padding: 0;
|
||||
// margin-top: 7px;
|
||||
// top: 100px;
|
||||
// left: 20px;
|
||||
// z-index: 3001;
|
||||
// // display: none;
|
||||
// font-family: $font-family_1;
|
||||
// font-size: 15px;
|
||||
// line-height: 1em;
|
||||
// &:before {
|
||||
// position: absolute;
|
||||
// display: inline-block;
|
||||
// border-bottom-color: $border-bottom-color_1;
|
||||
// content: '';
|
||||
// top: -7px;
|
||||
// border-right: 7px solid transparent;
|
||||
// border-left: 7px solid transparent;
|
||||
// border-bottom: 7px solid #ccc;
|
||||
// }
|
||||
// &:after {
|
||||
// position: absolute;
|
||||
// display: inline-block;
|
||||
// border-bottom-color: $border-bottom-color_1;
|
||||
// content: '';
|
||||
// top: -6px;
|
||||
// border-right: 6px solid transparent;
|
||||
// border-bottom: 6px solid #fff;
|
||||
// border-left: 6px solid transparent;
|
||||
// }
|
||||
// .drp-calendar {
|
||||
// // display: none;
|
||||
// max-width: 270px;
|
||||
// }
|
||||
// .drp-calendar.left {
|
||||
// padding: 8px 0 8px 8px;
|
||||
// }
|
||||
// .drp-calendar.right {
|
||||
// padding: 8px;
|
||||
// }
|
||||
// .drp-calendar.single {
|
||||
// .calendar-table {
|
||||
// border: none;
|
||||
// }
|
||||
// }
|
||||
// .calendar-table {
|
||||
// .next {
|
||||
// span {
|
||||
// color: $color_2;
|
||||
// border: solid black;
|
||||
// border-width: 0 2px 2px 0;
|
||||
// border-radius: 0;
|
||||
// display: inline-block;
|
||||
// padding: 3px;
|
||||
// -webkit-transform: rotate(-45deg);
|
||||
// transform: rotate(-45deg);
|
||||
// }
|
||||
// }
|
||||
// .prev {
|
||||
// span {
|
||||
// color: $color_2;
|
||||
// border: solid black;
|
||||
// border-width: 0 2px 2px 0;
|
||||
// border-radius: 0;
|
||||
// display: inline-block;
|
||||
// padding: 3px;
|
||||
// -webkit-transform: rotate(135deg);
|
||||
// transform: rotate(135deg);
|
||||
// }
|
||||
// }
|
||||
// th {
|
||||
// white-space: nowrap;
|
||||
// text-align: center;
|
||||
// vertical-align: middle;
|
||||
// min-width: 32px;
|
||||
// width: 32px;
|
||||
// height: 24px;
|
||||
// line-height: 24px;
|
||||
// font-size: 12px;
|
||||
// border-radius: 4px;
|
||||
// border: 1px solid transparent;
|
||||
// white-space: nowrap;
|
||||
// cursor: pointer;
|
||||
// }
|
||||
// td {
|
||||
// white-space: nowrap;
|
||||
// text-align: center;
|
||||
// vertical-align: middle;
|
||||
// min-width: 32px;
|
||||
// width: 32px;
|
||||
// height: 24px;
|
||||
// line-height: 24px;
|
||||
// font-size: 12px;
|
||||
// border-radius: 4px;
|
||||
// border: 1px solid transparent;
|
||||
// white-space: nowrap;
|
||||
// cursor: pointer;
|
||||
// }
|
||||
// border: 1px solid #fff;
|
||||
// border-radius: 4px;
|
||||
// background-color: $background-color_1;
|
||||
// table {
|
||||
// width: 100%;
|
||||
// margin: 0;
|
||||
// border-spacing: 0;
|
||||
// border-collapse: collapse;
|
||||
// }
|
||||
// }
|
||||
// td.available {
|
||||
// &:hover {
|
||||
// background-color: $background-color_2;
|
||||
// border-color: $border-color_1;
|
||||
// color: $color_1;
|
||||
// }
|
||||
// }
|
||||
// th.available {
|
||||
// &:hover {
|
||||
// background-color: $background-color_2;
|
||||
// border-color: $border-color_1;
|
||||
// color: $color_1;
|
||||
// }
|
||||
// }
|
||||
// td.week {
|
||||
// font-size: 80%;
|
||||
// color: $color_3;
|
||||
// }
|
||||
// th.week {
|
||||
// font-size: 80%;
|
||||
// color: $color_3;
|
||||
// }
|
||||
// td.off {
|
||||
// background-color: $background-color_1;
|
||||
// border-color: $border-color_1;
|
||||
// color: $color_4;
|
||||
// }
|
||||
// td.off.in-range {
|
||||
// background-color: $background-color_1;
|
||||
// border-color: $border-color_1;
|
||||
// color: $color_4;
|
||||
// }
|
||||
// td.off.start-date {
|
||||
// background-color: $background-color_1;
|
||||
// border-color: $border-color_1;
|
||||
// color: $color_4;
|
||||
// }
|
||||
// td.off.end-date {
|
||||
// background-color: $background-color_1;
|
||||
// border-color: $border-color_1;
|
||||
// color: $color_4;
|
||||
// }
|
||||
// td.in-range {
|
||||
// background-color: $background-color_3;
|
||||
// border-color: $border-color_1;
|
||||
// color: $color_5;
|
||||
// border-radius: 0;
|
||||
// }
|
||||
// td.start-date {
|
||||
// border-radius: 4px 0 0 4px;
|
||||
// }
|
||||
// td.end-date {
|
||||
// border-radius: 0 4px 4px 0;
|
||||
// }
|
||||
// td.start-date.end-date {
|
||||
// border-radius: 4px;
|
||||
// }
|
||||
// td.active {
|
||||
// background-color: $background-color_4;
|
||||
// border-color: $border-color_1;
|
||||
// color: $color_2;
|
||||
// &:hover {
|
||||
// background-color: $background-color_4;
|
||||
// border-color: $border-color_1;
|
||||
// color: $color_2;
|
||||
// }
|
||||
// }
|
||||
// th.month {
|
||||
// width: auto;
|
||||
// }
|
||||
// td.disabled {
|
||||
// color: $color_4;
|
||||
// cursor: not-allowed;
|
||||
// text-decoration: line-through;
|
||||
// }
|
||||
// option.disabled {
|
||||
// color: $color_4;
|
||||
// cursor: not-allowed;
|
||||
// text-decoration: line-through;
|
||||
// }
|
||||
// select.monthselect {
|
||||
// font-size: 12px;
|
||||
// padding: 1px;
|
||||
// height: auto;
|
||||
// margin: 0;
|
||||
// cursor: default;
|
||||
// margin-right: 2%;
|
||||
// width: 56%;
|
||||
// }
|
||||
// select.yearselect {
|
||||
// font-size: 12px;
|
||||
// padding: 1px;
|
||||
// height: auto;
|
||||
// margin: 0;
|
||||
// cursor: default;
|
||||
// width: 40%;
|
||||
// }
|
||||
// select.hourselect {
|
||||
// width: 50px;
|
||||
// margin: 0 auto;
|
||||
// background: #eee;
|
||||
// border: 1px solid #eee;
|
||||
// padding: 2px;
|
||||
// outline: 0;
|
||||
// font-size: 12px;
|
||||
// }
|
||||
// select.minuteselect {
|
||||
// width: 50px;
|
||||
// margin: 0 auto;
|
||||
// background: #eee;
|
||||
// border: 1px solid #eee;
|
||||
// padding: 2px;
|
||||
// outline: 0;
|
||||
// font-size: 12px;
|
||||
// }
|
||||
// select.secondselect {
|
||||
// width: 50px;
|
||||
// margin: 0 auto;
|
||||
// background: #eee;
|
||||
// border: 1px solid #eee;
|
||||
// padding: 2px;
|
||||
// outline: 0;
|
||||
// font-size: 12px;
|
||||
// }
|
||||
// select.ampmselect {
|
||||
// width: 50px;
|
||||
// margin: 0 auto;
|
||||
// background: #eee;
|
||||
// border: 1px solid #eee;
|
||||
// padding: 2px;
|
||||
// outline: 0;
|
||||
// font-size: 12px;
|
||||
// }
|
||||
// .calendar-time {
|
||||
// text-align: center;
|
||||
// margin: 4px auto 0 auto;
|
||||
// line-height: 30px;
|
||||
// position: relative;
|
||||
// select.disabled {
|
||||
// color: $color_3;
|
||||
// cursor: not-allowed;
|
||||
// }
|
||||
// }
|
||||
// .drp-buttons {
|
||||
// clear: both;
|
||||
// text-align: right;
|
||||
// padding: 8px;
|
||||
// border-top: 1px solid #ddd;
|
||||
// // display: none;
|
||||
// line-height: 12px;
|
||||
// vertical-align: middle;
|
||||
// .btn {
|
||||
// margin-left: 8px;
|
||||
// font-size: 12px;
|
||||
// font-weight: bold;
|
||||
// padding: 4px 8px;
|
||||
// }
|
||||
// }
|
||||
// .drp-selected {
|
||||
// display: inline-block;
|
||||
// font-size: 12px;
|
||||
// padding-right: 8px;
|
||||
// }
|
||||
// .ranges {
|
||||
// float: none;
|
||||
// text-align: left;
|
||||
// margin: 0;
|
||||
// ul {
|
||||
// list-style: none;
|
||||
// margin: 0 auto;
|
||||
// padding: 0;
|
||||
// width: 100%;
|
||||
// }
|
||||
// li {
|
||||
// font-size: 12px;
|
||||
// padding: 8px 12px;
|
||||
// cursor: pointer;
|
||||
// &:hover {
|
||||
// background-color: $background-color_2;
|
||||
// }
|
||||
// }
|
||||
// li.active {
|
||||
// background-color: $background-color_5;
|
||||
// color: $color_2;
|
||||
// }
|
||||
// }
|
||||
// &.opensleft {
|
||||
// &:before {
|
||||
// right: 9px;
|
||||
// }
|
||||
// &:after {
|
||||
// right: 10px;
|
||||
// }
|
||||
// }
|
||||
// &.openscenter {
|
||||
// &:before {
|
||||
// left: 0;
|
||||
// right: 0;
|
||||
// width: 0;
|
||||
// margin-left: auto;
|
||||
// margin-right: auto;
|
||||
// }
|
||||
// &:after {
|
||||
// left: 0;
|
||||
// right: 0;
|
||||
// width: 0;
|
||||
// margin-left: auto;
|
||||
// margin-right: auto;
|
||||
// }
|
||||
// }
|
||||
// &.opensright {
|
||||
// &:before {
|
||||
// left: 9px;
|
||||
// }
|
||||
// &:after {
|
||||
// left: 10px;
|
||||
// }
|
||||
// }
|
||||
// &.drop-up {
|
||||
// margin-top: -7px;
|
||||
// &:before {
|
||||
// top: initial;
|
||||
// bottom: -7px;
|
||||
// border-bottom: initial;
|
||||
// border-top: 7px solid #ccc;
|
||||
// }
|
||||
// &:after {
|
||||
// top: initial;
|
||||
// bottom: -6px;
|
||||
// border-bottom: initial;
|
||||
// border-top: 6px solid #fff;
|
||||
// }
|
||||
// }
|
||||
// &.single {
|
||||
// .ar-DateRange {
|
||||
// .ranges {
|
||||
// float: none;
|
||||
// }
|
||||
// }
|
||||
// .drp-calendar {
|
||||
// float: none;
|
||||
// }
|
||||
// .drp-selected {
|
||||
// // display: none;
|
||||
// }
|
||||
// }
|
||||
// &.show-calendar {
|
||||
// .drp-calendar {
|
||||
// display: block;
|
||||
// }
|
||||
// .drp-buttons {
|
||||
// display: block;
|
||||
// }
|
||||
// .ranges {
|
||||
// margin-top: 8px;
|
||||
// }
|
||||
// }
|
||||
// &.auto-apply {
|
||||
// .drp-buttons {
|
||||
// // display: none;
|
||||
// }
|
||||
// }
|
||||
// &.show-ranges.single.rtl {
|
||||
// .drp-calendar.left {
|
||||
// border-right: 1px solid #ddd;
|
||||
// }
|
||||
// }
|
||||
// &.show-ranges.single.ltr {
|
||||
// .drp-calendar.left {
|
||||
// border-left: 1px solid #ddd;
|
||||
// }
|
||||
// }
|
||||
// &.show-ranges.rtl {
|
||||
// .drp-calendar.right {
|
||||
// border-right: 1px solid #ddd;
|
||||
// }
|
||||
// }
|
||||
// &.show-ranges.ltr {
|
||||
// .drp-calendar.left {
|
||||
// border-left: 1px solid #ddd;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// @media (min-width: 564px) {
|
||||
// .ar-DateRange {
|
||||
// width: auto;
|
||||
// direction: ltr;
|
||||
// text-align: left;
|
||||
// .ranges {
|
||||
// ul {
|
||||
// width: 140px;
|
||||
// }
|
||||
// float: left;
|
||||
// }
|
||||
// .drp-calendar.left {
|
||||
// clear: left;
|
||||
// margin-right: 0;
|
||||
// .calendar-table {
|
||||
// border-right: none;
|
||||
// border-top-right-radius: 0;
|
||||
// border-bottom-right-radius: 0;
|
||||
// padding-right: 8px;
|
||||
// }
|
||||
// }
|
||||
// .drp-calendar.right {
|
||||
// margin-left: 0;
|
||||
// .calendar-table {
|
||||
// border-left: none;
|
||||
// border-top-left-radius: 0;
|
||||
// border-bottom-left-radius: 0;
|
||||
// }
|
||||
// }
|
||||
// .drp-calendar {
|
||||
// float: left;
|
||||
// }
|
||||
// &.single {
|
||||
// .ranges {
|
||||
// ul {
|
||||
// width: 100%;
|
||||
// }
|
||||
// float: left;
|
||||
// }
|
||||
// .drp-calendar.left {
|
||||
// clear: none;
|
||||
// }
|
||||
// .drp-calendar {
|
||||
// float: left;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// @media (min-width: 730px) {
|
||||
// .ar-DateRange {
|
||||
// .ranges {
|
||||
// width: auto;
|
||||
// float: left;
|
||||
// }
|
||||
// .drp-calendar.left {
|
||||
// clear: none !important;
|
||||
// }
|
||||
// &.rtl {
|
||||
// .ranges {
|
||||
// float: right;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
.ar-Date {
|
||||
/* Styles for the Date component */
|
||||
background-color: #fff; /* Background color for the Date component */
|
||||
padding: 16px; /* Padding for the Date component */
|
||||
border: 1px solid #ddd; /* Border for the Date component */
|
||||
font-size: 0.75rem;
|
||||
|
||||
&__header {
|
||||
/* Styles for the header section of the Date component */
|
||||
font-size: 1.25rem; /* Font size for the header */
|
||||
font-weight: bold; /* Bold font for the header */
|
||||
margin-bottom: 16px; /* Margin at the bottom of the header */
|
||||
}
|
||||
|
||||
/* Add more styles for child elements of Date component */
|
||||
}
|
||||
|
||||
/* RangeSelector component styles */
|
||||
.ar-RangeSelector {
|
||||
/* Styles for the RangeSelector component */
|
||||
/* Add RangeSelector-specific styles here */
|
||||
}
|
||||
|
||||
.ar-Calendar {
|
||||
|
||||
}
|
||||
|
||||
.ar-TimePicker {
|
||||
|
||||
}
|
||||
|
||||
.ar-Slider {
|
||||
|
||||
.ar-Slider__items-container {
|
||||
scroll-snap-type: x mandatory;
|
||||
overflow-x: auto;
|
||||
white-space: nowrap;
|
||||
|
||||
.ar-Slider__item {
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.ar-CalTime {
|
||||
width: 12rem;
|
||||
height: 10rem;
|
||||
/* Styles for the CalTime component within CalView */
|
||||
/* Add CalTime-specific styles here */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Add more styles for other classes as needed */
|
||||
@@ -1,6 +0,0 @@
|
||||
import React from "react"
|
||||
import Date from "./Date"
|
||||
|
||||
describe("Date", () => {
|
||||
it("renders without error", () => {})
|
||||
})
|
||||
@@ -1,114 +0,0 @@
|
||||
import { useState } from "react"
|
||||
import { DateProps } from ".."
|
||||
import { ArButtonVariants, ArSizes } from "../../../types/enums"
|
||||
import RangeSelector from "./RangeSelector"
|
||||
import Slider from "./Slider"
|
||||
import Button from "../Button"
|
||||
import CalTime from "./CalTime"
|
||||
import "./Date.component.scss"
|
||||
|
||||
const Date: React.FC<DateProps> = (props) => {
|
||||
const {
|
||||
minDate,
|
||||
maxDate,
|
||||
startDate,
|
||||
endDate,
|
||||
isRangeSelector,
|
||||
showTimePicker,
|
||||
timePickerSeconds,
|
||||
is12HourFormat,
|
||||
showQuickSelectors,
|
||||
customSelectors,
|
||||
showTodayInFooter,
|
||||
showDropdowns,
|
||||
} = props
|
||||
// State for current month and year
|
||||
const [currentMonth, setCurrentMonth] = useState<number>(
|
||||
(startDate?.getMonth() || 0) + 1,
|
||||
)
|
||||
const [currentYear, setCurrentYear] = useState<number>(
|
||||
startDate?.getFullYear() as number,
|
||||
)
|
||||
|
||||
// Function to handle month change
|
||||
const handleMonthChange = (newMonth: number) => {
|
||||
// Update the current month state
|
||||
setCurrentMonth(newMonth)
|
||||
}
|
||||
|
||||
// Function to handle year change
|
||||
const handleYearChange = (newYear: number) => {
|
||||
// Update the current year state
|
||||
setCurrentYear(newYear)
|
||||
}
|
||||
|
||||
const numberOfViews = isRangeSelector ? 4 : 3
|
||||
|
||||
const items = Array.from({ length: numberOfViews }).map((_, index) => (
|
||||
<div key={index} className="ar-CalView__instance">
|
||||
<CalTime month={currentMonth} year={currentYear} {...props} />
|
||||
</div>
|
||||
))
|
||||
|
||||
return (
|
||||
<div className="ar-Date container">
|
||||
{/* Add responsive classes for mobile */}
|
||||
<div className="row">
|
||||
{showQuickSelectors && (
|
||||
<div className="col-lg-3">
|
||||
<RangeSelector customSelectors={customSelectors} />
|
||||
</div>
|
||||
)}
|
||||
{/* Second Column */}
|
||||
<div className="col-lg-9">
|
||||
{/* Use Slider component */}
|
||||
<Slider month={currentMonth} year={currentYear}>
|
||||
{/* Render your calendar instances and time pickers here */}
|
||||
{/* Example for rendering calendar instances */}
|
||||
{items}
|
||||
</Slider>
|
||||
</div>
|
||||
</div>
|
||||
{/* Second Row */}
|
||||
<div className="row d-sm-block">
|
||||
<div className="col-lg-12">
|
||||
<div className="date-picker-footer">
|
||||
{showTodayInFooter && (
|
||||
<Button
|
||||
size={ArSizes.XSMALL}
|
||||
variant={ArButtonVariants.SECONDARY}
|
||||
content="Today"
|
||||
onClick={() => {
|
||||
/* Handle "Today" button click */
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<div className="date-picker-selected">
|
||||
{/* Display selected date/time */}
|
||||
{/* ... */}
|
||||
</div>
|
||||
<div className="date-picker-buttons">
|
||||
<Button
|
||||
size={ArSizes.XSMALL}
|
||||
variant={ArButtonVariants.SECONDARY}
|
||||
content="Cancel"
|
||||
onClick={() => {
|
||||
/* Handle "Today" button click */
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
size={ArSizes.XSMALL}
|
||||
content="Apply"
|
||||
onClick={() => {
|
||||
/* Handle "Today" button click */
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Date
|
||||
@@ -1,43 +0,0 @@
|
||||
import React from "react"
|
||||
import { List } from "../.." // Import your pre-existing List component
|
||||
import { ListItemProps } from ".."
|
||||
|
||||
interface RangeSelectorProps {
|
||||
customSelectors?: Array<ListItemProps>
|
||||
isSingle?: boolean
|
||||
}
|
||||
|
||||
const RangeSelector: React.FC<RangeSelectorProps> = ({
|
||||
isSingle,
|
||||
customSelectors,
|
||||
}) => {
|
||||
const defaultSingleDatePickerRanges: Array<ListItemProps> = [
|
||||
{ label: "Today", onClick: () => {} },
|
||||
{ label: "Yesterday", onClick: () => {} },
|
||||
{ label: "Tomorrow", onClick: () => {} },
|
||||
{ label: "Minus 7 Days", onClick: () => {} },
|
||||
{ label: "Minus 30 Days", onClick: () => {} },
|
||||
{ label: "Minus 365 Days", onClick: () => {} },
|
||||
]
|
||||
|
||||
const defaultDateRangeRanges: Array<ListItemProps> = [
|
||||
{ label: "Last 3 Days", onClick: () => {} },
|
||||
{ label: "Last Week", onClick: () => {} },
|
||||
{ label: "Last Month", onClick: () => {} },
|
||||
{ label: "Last 6 Months", onClick: () => {} },
|
||||
{ label: "Custom", onClick: () => {} },
|
||||
]
|
||||
|
||||
const ranges = customSelectors
|
||||
? customSelectors
|
||||
: isSingle
|
||||
? defaultSingleDatePickerRanges
|
||||
: defaultDateRangeRanges
|
||||
return (
|
||||
<div className="ar-RangeSelector">
|
||||
<List data={ranges} itemClasses="cursor-pointer" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default RangeSelector
|
||||
@@ -1,43 +0,0 @@
|
||||
.slider-container {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
width: 300px; /* Adjust container width as needed */
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.slide {
|
||||
flex: 0 0 100%;
|
||||
height: 100px; /* Adjust slide height as needed */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 24px;
|
||||
background-color: #e0e0e0;
|
||||
transition: transform 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.slide.active {
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.prev-button,
|
||||
.next-button {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
padding: 5px 10px;
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.prev-button {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.next-button {
|
||||
right: 0;
|
||||
}
|
||||
@@ -1,160 +0,0 @@
|
||||
import React, { useState, ReactNode, useRef, MutableRefObject } from "react"
|
||||
import LoadableIcon from "../LoadableIcon"
|
||||
import { formatDate } from "./dateRangeFunctions"
|
||||
import { Helper } from "../../../utils"
|
||||
import Carousel from "../../molecules/Carousel"
|
||||
|
||||
interface SliderProps {
|
||||
children: ReactNode[]
|
||||
swipeThreshold?: number
|
||||
month: number
|
||||
year: number
|
||||
}
|
||||
|
||||
// function scrollToNext(
|
||||
// currentIndex: number,
|
||||
// items: Array<ReactNode>,
|
||||
// container: MutableRefObject<null>,
|
||||
// ) {
|
||||
// if (currentIndex < items.length - 1) {
|
||||
// currentIndex++
|
||||
// const nextItem = items[currentIndex]
|
||||
// ;(container.current as unknown as JSX.Element)?.scroll({
|
||||
// left: nextItem?.offsetLeft,
|
||||
// behavior: "smooth", // Use smooth behavior for smooth scrolling
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
||||
function scrollToNext(
|
||||
currentIndex: number,
|
||||
container: MutableRefObject<HTMLElement | null>,
|
||||
) {
|
||||
if (
|
||||
container.current?.children &&
|
||||
Array.isArray(container.current?.children) &&
|
||||
currentIndex < container.current?.children.length - 1
|
||||
) {
|
||||
currentIndex++
|
||||
const nextItem = container.current?.children[currentIndex]
|
||||
nextItem?.scrollIntoView({
|
||||
behavior: "smooth",
|
||||
block: "nearest",
|
||||
inline: "start",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const Slider: React.FC<SliderProps> = ({
|
||||
children,
|
||||
month,
|
||||
year,
|
||||
swipeThreshold = 25,
|
||||
}) => {
|
||||
const sliderRef = useRef(null)
|
||||
const itemsContainerRef = useRef(null)
|
||||
const [currentIndex, setCurrentIndex] = useState<number>(0)
|
||||
const [startX, setStartX] = useState<number | null>(null)
|
||||
|
||||
const numberOfViews = children.length
|
||||
|
||||
const slideToNext = () => {
|
||||
const nextIndex = (currentIndex + 1) % children.length
|
||||
setCurrentIndex(nextIndex)
|
||||
}
|
||||
|
||||
const slideToPrevious = () => {
|
||||
const previousIndex = (currentIndex - 1 + children.length) % children.length
|
||||
setCurrentIndex(previousIndex)
|
||||
}
|
||||
|
||||
const handleTouchStart = (e: React.TouchEvent) => {
|
||||
setStartX(e.touches[0].clientX)
|
||||
}
|
||||
|
||||
const handleTouchMove = (e: React.TouchEvent) => {
|
||||
if (startX !== null) {
|
||||
const deltaX = e.touches[0].clientX - startX
|
||||
if (deltaX > swipeThreshold) {
|
||||
// Swipe right, move to the previous slide
|
||||
slideToPrevious()
|
||||
} else if (deltaX < -swipeThreshold) {
|
||||
// Swipe left, move to the next slide
|
||||
slideToNext()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const handleTouchEnd = () => {
|
||||
setStartX(null)
|
||||
}
|
||||
|
||||
// Function to handle changing to the previous calendar view
|
||||
const handlePrev = () => {
|
||||
// Update the currentIndex to navigate to the previous view
|
||||
setCurrentIndex((prevIndex) => Math.max(prevIndex - 1, 0))
|
||||
}
|
||||
|
||||
// Function to handle changing to the next calendar view
|
||||
const handleNext = () => {
|
||||
scrollToNext(
|
||||
Math.min(currentIndex + 1, numberOfViews - 1),
|
||||
itemsContainerRef,
|
||||
)
|
||||
// Update the currentIndex to navigate to the next view
|
||||
// setCurrentIndex((prevIndex) => Math.min(prevIndex + 1, numberOfViews - 1))
|
||||
}
|
||||
|
||||
return (
|
||||
// Inside Slider component's return statement
|
||||
<div className="ar-Slider" ref={sliderRef}>
|
||||
{/* <div className="cal-view-controls d-flex justify-content-between">
|
||||
<LoadableIcon
|
||||
icon="md/MdKeyboardArrowLeft"
|
||||
onClick={handlePrev}
|
||||
classes="prev-button cursor-pointer"
|
||||
aria-label="Previous Calendar"
|
||||
/>
|
||||
<div className="d-inline-block">{formatDate(month, year)}</div>
|
||||
<LoadableIcon
|
||||
icon="md/MdKeyboardArrowRight"
|
||||
onClick={handleNext}
|
||||
classes="next-button cursor-pointer"
|
||||
aria-label="Next Calendar"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="ar-Slider__items-container d-flex"
|
||||
ref={itemsContainerRef}
|
||||
>
|
||||
{children.map((child, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={`ar-Slider__item ${
|
||||
index === currentIndex ? "active" : ""
|
||||
}`}
|
||||
style={{
|
||||
scrollSnapAlign: index === currentIndex ? "start" : "none",
|
||||
}}
|
||||
onTouchStart={handleTouchStart}
|
||||
onTouchMove={handleTouchMove}
|
||||
onTouchEnd={handleTouchEnd}
|
||||
role="tabpanel" // Use role="tabpanel" for each slide
|
||||
tabIndex={index === currentIndex ? 0 : -1} // Allow keyboard focus on active slide
|
||||
>
|
||||
{child}
|
||||
</div>
|
||||
))}
|
||||
</div> */}
|
||||
<Carousel
|
||||
classes="ar-Slider__items-container"
|
||||
infiniteLoop={true}
|
||||
noMarkers
|
||||
>
|
||||
{children}
|
||||
</Carousel>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Slider
|
||||
@@ -1,70 +0,0 @@
|
||||
import React from "react"
|
||||
import { Dropdown } from "../.." // Import your Dropdown component
|
||||
|
||||
interface TimePickerProps {
|
||||
is12HourFormat?: boolean
|
||||
showSeconds?: boolean
|
||||
}
|
||||
|
||||
const TimePicker: React.FC<TimePickerProps> = ({
|
||||
is12HourFormat,
|
||||
showSeconds,
|
||||
}) => {
|
||||
const getOptions = (type: "hour" | "minute" | "second") => {
|
||||
const options = []
|
||||
const max = type === "hour" ? (is12HourFormat ? 12 : 24) : 60
|
||||
const format = type === "hour" ? 1 : 2
|
||||
|
||||
for (let i = 0; i < max; i++) {
|
||||
const label = String(i).padStart(format, "0")
|
||||
options.push({ label, value: i })
|
||||
}
|
||||
|
||||
return options
|
||||
}
|
||||
|
||||
const hourOptions = getOptions("hour")
|
||||
const minuteOptions = getOptions("minute")
|
||||
const secondOptions = showSeconds ? getOptions("second") : []
|
||||
const amPmOptions = is12HourFormat
|
||||
? [
|
||||
{ label: "AM", value: "AM" },
|
||||
{ label: "PM", value: "PM" },
|
||||
]
|
||||
: []
|
||||
|
||||
return (
|
||||
<div className="ar-TimePicker">
|
||||
<Dropdown
|
||||
options={hourOptions}
|
||||
ariaLabel="Hour"
|
||||
onSelectionChanged={() => {}}
|
||||
/>
|
||||
<span>:</span>
|
||||
<Dropdown
|
||||
options={minuteOptions}
|
||||
ariaLabel="Minute"
|
||||
onSelectionChanged={() => {}}
|
||||
/>
|
||||
{showSeconds && (
|
||||
<>
|
||||
<span>:</span>
|
||||
<Dropdown
|
||||
options={secondOptions}
|
||||
ariaLabel="Second"
|
||||
onSelectionChanged={() => {}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{is12HourFormat && (
|
||||
<Dropdown
|
||||
options={amPmOptions}
|
||||
ariaLabel="AM/PM"
|
||||
onSelectionChanged={() => {}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default TimePicker
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,3 +0,0 @@
|
||||
import Date from "./Date"
|
||||
|
||||
export default Date
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useEffect, useState } from "react"
|
||||
// import { getIconByKey, saveIconToFactory } from "../../../store"
|
||||
// import { useAppDispatch, useAppSelector } from "../../../hooks"
|
||||
import { getIconByKey, saveIconToFactory } from "../../../store"
|
||||
import { useAppDispatch, useAppSelector } from "../../../hooks"
|
||||
import { Network, DomHelper } from "../../../utils"
|
||||
import { LoadableIconProps } from ".."
|
||||
import { GenericObject, ObjectType } from "../../../types/types"
|
||||
@@ -21,6 +21,20 @@ const placeholder = parser
|
||||
)
|
||||
.querySelector("svg")
|
||||
|
||||
/**
|
||||
* Component fetches icons from three types of sources:
|
||||
*
|
||||
* 1. Absolute URL: It is for fetching from static paths of icons available in armco's static server
|
||||
* 2. http or https: As obvious, it is to fetch svg from any publicly available URL that doesn't directly return
|
||||
* renderable content but needs to be processed (else we could directly pass such urls to img src)
|
||||
* 3. Primary usage is for fetching react icons that have a category and name in the format gr.GrStatusPlaceholder
|
||||
*
|
||||
* This component takes care of duplicate API calls by caching icons even if multiple instances of same icon are rendered
|
||||
* Futher changes to icon like size and color also don't need API calls and changes are handled by this component
|
||||
*
|
||||
* @param props
|
||||
* @returns JSX: img containing processed svg
|
||||
*/
|
||||
const LoadableIcon = (props: LoadableIconProps) => {
|
||||
const {
|
||||
classes,
|
||||
@@ -45,19 +59,26 @@ const LoadableIcon = (props: LoadableIconProps) => {
|
||||
width,
|
||||
} = props
|
||||
let { icon } = props
|
||||
const [juice, setJuice] = useState<string>()
|
||||
|
||||
const [hovered, setHovered] = useState<boolean>()
|
||||
const [innerToggled, setToggled] = useState<boolean>()
|
||||
// Raw svg content with no styling
|
||||
const [iconContent, setIconContent] = useState<SVGSVGElement | null>(
|
||||
placeholder,
|
||||
)
|
||||
// const dispatch = useAppDispatch()
|
||||
// Processed SVG content with size, color, classes, etc.
|
||||
const [juice, setJuice] = useState<string>()
|
||||
const dispatch = useAppDispatch()
|
||||
|
||||
// 1. Absolute URL is for fetching from static paths in the static server
|
||||
// 2. http or https as obvious is to fetch svg from any URL
|
||||
// 3. Primary usage is for fetching react icons that have a category and name in the format gr.GrStatusPlaceholder
|
||||
const isAbsoluteOrSlashStart =
|
||||
icon &&
|
||||
(icon.startsWith("http://") ||
|
||||
icon.startsWith("https://") ||
|
||||
icon.startsWith("/"))
|
||||
|
||||
icon =
|
||||
icon && !isAbsoluteOrSlashStart && icon.indexOf("/") > -1
|
||||
? icon.replace(/\//g, ".")
|
||||
@@ -75,9 +96,7 @@ const LoadableIcon = (props: LoadableIconProps) => {
|
||||
const iconKey =
|
||||
icon && (iconCategory && iconName ? `${iconCategory}_${iconName}` : icon)
|
||||
|
||||
// const iData = useAppSelector<string>(getIconByKey(iconKey || ""))
|
||||
|
||||
const iData = iconKey && iconsFactory[iconKey]
|
||||
const iData = useAppSelector<string>(getIconByKey(iconKey || ""))
|
||||
|
||||
const getIcon = () => {
|
||||
if (icon && iconKey && !ongoingApiCalls[iconKey]) {
|
||||
@@ -91,7 +110,7 @@ const LoadableIcon = (props: LoadableIconProps) => {
|
||||
.parseFromString(res.body, "image/svg+xml")
|
||||
.querySelector("svg")
|
||||
if (parsedSvg) {
|
||||
// dispatch(saveIconToFactory({ [iconKey]: res.body }))
|
||||
dispatch(saveIconToFactory({ [iconKey]: res.body }))
|
||||
iconsFactory[iconKey] = res.body
|
||||
setIconContent(parsedSvg)
|
||||
}
|
||||
@@ -121,6 +140,8 @@ const LoadableIcon = (props: LoadableIconProps) => {
|
||||
}
|
||||
}, [icon])
|
||||
|
||||
// This effect is most likely to be called only once (unless the icon source itself changes outside conditionally)
|
||||
// Purpose is to apply SVG properties as sent in props to the icon like size, color etc.
|
||||
useEffect(() => {
|
||||
iconContent &&
|
||||
!isLocal &&
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import { useEffect, useRef, useState } from "react"
|
||||
import { ModalProps } from ".."
|
||||
import LoadableIcon from "../LoadableIcon"
|
||||
import { Button, LoadableIcon, ModalProps } from ".."
|
||||
import { ObjectType } from "../../../types/types"
|
||||
import Button from "../Button"
|
||||
import { ArButtonVariants, ArSizes } from "../../../types/enums"
|
||||
import "./Modal.component.scss"
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import Icon from "../Icon"
|
||||
import { PillProps } from ".."
|
||||
import { Icon, PillProps } from ".."
|
||||
import "./Pill.component.scss"
|
||||
|
||||
const Pill = (props: PillProps): JSX.Element => {
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import { useState } from "react"
|
||||
import LoadableIcon from "../LoadableIcon"
|
||||
import Popover from "../Popover"
|
||||
import { LoadableIcon, Popover, SegmentedControlProps } from ".."
|
||||
import { ArPopoverSlots, ArPopoverTriggers } from "../../../types/enums"
|
||||
import { SegmentedControlProps } from ".."
|
||||
import { FunctionType, SegmentType } from "../../../types/types"
|
||||
import "./SegmentedControl.component.scss"
|
||||
|
||||
|
||||
@@ -5,9 +5,7 @@ import {
|
||||
ArVisualizationTypes,
|
||||
} from "../../../types/enums"
|
||||
import { ObjectType } from "../../../types/types"
|
||||
import ArViz from "../ArViz"
|
||||
import LoadableIcon from "../LoadableIcon"
|
||||
import Popover from "../Popover"
|
||||
import { ArViz, LoadableIcon, Popover } from ".."
|
||||
import "./Tags.component.scss"
|
||||
|
||||
const Tags = (props: TagsProps): JSX.Element => {
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
import { ChangeEvent, FocusEvent, useEffect, useState } from "react"
|
||||
import Slider from "../Slider"
|
||||
import Button from "../Button"
|
||||
import { TextInputProps } from ".."
|
||||
import { Button, Slider, TextInputProps, Icon } from ".."
|
||||
import { ArButtonVariants, ArPlacement } from "../../../types/enums"
|
||||
import { FunctionType } from "../../../types/types"
|
||||
import Icon from "../Icon"
|
||||
import "./TextInput.component.scss"
|
||||
|
||||
const TextInput = (props: TextInputProps): JSX.Element => {
|
||||
|
||||
@@ -14,7 +14,6 @@ import ColorPicker from "./ColorPicker"
|
||||
import ColorSelector from "./ColorSelector"
|
||||
import ContextMenu from "./ContextMenu"
|
||||
import CronTab from "./CronTab"
|
||||
import Date from "./Date"
|
||||
import DateInput from "./DateInput"
|
||||
import DatePicker from "./DatePicker"
|
||||
import DateRangePicker from "./DateRangePicker"
|
||||
@@ -88,7 +87,6 @@ import {
|
||||
ColorSelectorProps,
|
||||
ContextMenuProps,
|
||||
CronTabProps,
|
||||
DateProps,
|
||||
DateInputProps,
|
||||
DatePickerProps,
|
||||
DateRangePickerProps,
|
||||
@@ -170,7 +168,6 @@ export {
|
||||
ColorSelector,
|
||||
ContextMenu,
|
||||
CronTab,
|
||||
Date,
|
||||
DateInput,
|
||||
DatePicker,
|
||||
DateRangePicker,
|
||||
@@ -245,7 +242,6 @@ export {
|
||||
type ColorSelectorProps,
|
||||
type ContextMenuProps,
|
||||
type CronTabProps,
|
||||
type DateProps,
|
||||
type DateInputProps,
|
||||
type DatePickerProps,
|
||||
type DateRangePickerProps,
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Component, ErrorInfo, ReactNode } from "react"
|
||||
import { Link } from "react-router-dom"
|
||||
import Icon from "../../atoms/Icon"
|
||||
import { Icon } from "../.."
|
||||
import "./ErrorBoundary.component.scss"
|
||||
|
||||
interface ErrorBoundaryProps {
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import { useState } from "react"
|
||||
import { selectTag } from "../../../pages/IconsPage/IconsPage.slice"
|
||||
import { useAppDispatch } from "../../../hooks"
|
||||
import { AlphabetFilter, CategoryFilter, Dropdown, Pillbox, Tags } from "../.."
|
||||
import { PillProps } from "../.."
|
||||
import {
|
||||
@@ -13,11 +11,17 @@ import Helper from "../../../utils/helper"
|
||||
import "./Filters.component.scss"
|
||||
|
||||
const Filters = (props: FiltersProps): JSX.Element => {
|
||||
const { config, data, filteredData, initialFilters, onFilterChange } = props
|
||||
const {
|
||||
config,
|
||||
clickHandler,
|
||||
data,
|
||||
filteredData,
|
||||
initialFilters,
|
||||
onFilterChange,
|
||||
} = props
|
||||
const [filters, setFilters] = useState<FilterState | undefined>(
|
||||
initialFilters,
|
||||
)
|
||||
const dispatch = useAppDispatch()
|
||||
const useData = filteredData || data
|
||||
const total = useData && useData.length
|
||||
|
||||
@@ -128,10 +132,6 @@ const Filters = (props: FiltersProps): JSX.Element => {
|
||||
}
|
||||
})
|
||||
|
||||
const clickHandler = (e: any) => {
|
||||
dispatch(selectTag(e.point.name))
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="ar-Filters p-3 h-100 overflow-auto w-100">
|
||||
<h5>Filters</h5>
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import { useRef, useState } from "react"
|
||||
import { SuggestionsProps, SuggestionProps } from ".."
|
||||
import { LoadableIconProps } from "../.."
|
||||
import LoadableIcon from "../../atoms/LoadableIcon"
|
||||
import {
|
||||
SuggestionsProps,
|
||||
SuggestionProps,
|
||||
LoadableIcon,
|
||||
LoadableIconProps,
|
||||
} from "../.."
|
||||
import "./Suggestions.component.scss"
|
||||
|
||||
const Suggestion = (props: SuggestionProps) => {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { TilesProps } from ".."
|
||||
import ProductDescriptionTile from "../ProductDescriptionTile"
|
||||
import { ProductDescriptionTile, TilesProps } from ".."
|
||||
import "./Tiles.component.scss"
|
||||
|
||||
const Tiles = (props: TilesProps): JSX.Element => {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { v4 as uuid } from "uuid"
|
||||
import { getLoggedIn, getUser, notify, setLoggedIn } from "../../../store"
|
||||
import { getLoggedIn, getUser, notify, setLoggedIn, setRightPanelContent } from "../../../store"
|
||||
import { useAppDispatch, useAppSelector } from "../../../hooks"
|
||||
import { setRightPanelContent } from "../../../store"
|
||||
import { Button, List, LoadableIcon, Popover } from "../.."
|
||||
import { UserOptionsProps } from ".."
|
||||
import {
|
||||
@@ -15,8 +14,8 @@ import { User } from "../../../types/entity.interface"
|
||||
import { Helper, Network } from "../../../utils"
|
||||
import { ENDPOINTS } from "../../../config/constants"
|
||||
import API_CONFIG from "../../../config/api-config"
|
||||
import "./UserOptions.component.scss"
|
||||
import WEB_CONFIG from "../../../config/web-config"
|
||||
import "./UserOptions.component.scss"
|
||||
|
||||
const isMobile = Helper.isMobile()
|
||||
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import { useEffect, useState } from "react"
|
||||
import { useAppSelector } from "../../hooks"
|
||||
import { useAppDispatch, useAppSelector } from "../../hooks"
|
||||
import { getRightPanelContent } from "../../store"
|
||||
import { selectTag } from "./IconsPage.slice"
|
||||
import { Filters } from "../../components"
|
||||
import Footer from "../../components/Footer"
|
||||
import Main from "../../components/Main"
|
||||
import IconsList from "../../components/IconsList"
|
||||
import { ObjectType } from "../../types/types"
|
||||
import { FilterState } from "../../types/filterconfig.interface"
|
||||
import { IconResponse } from "../../types/iconresponse.interface"
|
||||
import Network from "../../utils/network"
|
||||
import "./IconsPage.page.scss"
|
||||
|
||||
@@ -32,6 +34,7 @@ const IconsPage = (props: IconsPageProps): JSX.Element => {
|
||||
const rightPanelContent = useAppSelector<
|
||||
{ name: string; props?: ObjectType } | undefined
|
||||
>(getRightPanelContent)
|
||||
const dispatch = useAppDispatch()
|
||||
|
||||
// useEffect(() => {
|
||||
// !icons && fetchData("/icon/all", setIcons)
|
||||
@@ -98,6 +101,10 @@ const IconsPage = (props: IconsPageProps): JSX.Element => {
|
||||
// }
|
||||
// }, [filters, icons, searchText])
|
||||
|
||||
const clickHandler = (e: any) => {
|
||||
dispatch(selectTag(e.point.name))
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="ar-IconsPage d-flex flex-column">
|
||||
<Main
|
||||
@@ -112,6 +119,7 @@ const IconsPage = (props: IconsPageProps): JSX.Element => {
|
||||
}}
|
||||
// config={{ tags }}
|
||||
// data={icons}
|
||||
clickHandler={clickHandler}
|
||||
filteredData={filteredIcons}
|
||||
initialFilters={filters}
|
||||
onFilterChange={setFilters}
|
||||
|
||||
BIN
src/app/static/images/Stubble Component Lib Snap Orig.png
Normal file
BIN
src/app/static/images/Stubble Component Lib Snap Orig.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.1 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 3.1 MiB After Width: | Height: | Size: 97 KiB |
@@ -47,6 +47,7 @@ import {
|
||||
TreeListData,
|
||||
} from "./entity.interface"
|
||||
import { User } from "./entity.interface"
|
||||
import { IconResponse, PageItem } from "./iconresponse.interface"
|
||||
import {
|
||||
AnimationHandler,
|
||||
ArrayType,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ObjectType } from "./types"
|
||||
import { FunctionType, ObjectType } from "./types"
|
||||
|
||||
export interface BasicFilterConfig {
|
||||
value: string
|
||||
@@ -13,6 +13,7 @@ export interface FilterConfig {
|
||||
}
|
||||
|
||||
export interface FiltersProps {
|
||||
clickHandler: FunctionType
|
||||
data?: Array<any>
|
||||
filteredData?: Array<any>
|
||||
config: FilterConfig
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
interface PageItem {}
|
||||
export interface PageItem {}
|
||||
|
||||
interface IconResponse extends PageItem {
|
||||
export interface IconResponse extends PageItem {
|
||||
name: string
|
||||
group: string
|
||||
svg: string
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
interface RouteConfig {
|
||||
export interface RouteConfig {
|
||||
path: string
|
||||
class: string
|
||||
element: string | JSX.Element | any
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
ComponentDescription,
|
||||
ComponentList,
|
||||
} from "../types/componentlist.interface"
|
||||
import { RouteConfig } from "../types/route.interface"
|
||||
// import * as COMPONENTS from "@armco/armory-react-components"
|
||||
|
||||
class Helper {
|
||||
|
||||
@@ -3,6 +3,7 @@ import base_lottie from "../static/LottieConfigs/base-lottie.json"
|
||||
import { LoadableIconProps } from "../types/components.interface"
|
||||
import { AnimationInjectConfig } from "../types/entity.interface"
|
||||
import { ArAnimationInjectionTypes, ArAnimationProperty } from "../types/enums"
|
||||
import { IconResponse } from "../types/iconresponse.interface"
|
||||
import { Animation, ImageAsset, OffsetKeyframe } from "../types/lottie"
|
||||
|
||||
class LottieHelper {
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"declaration": true,
|
||||
"emitDeclarationOnly": true,
|
||||
"declarationDir": "./build/es/types",
|
||||
"downlevelIteration": true,
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"importHelpers": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "react-jsx",
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noImplicitReturns": true,
|
||||
"outDir": "./build",
|
||||
"resolveJsonModule": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"target": "esnext",
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": [
|
||||
"build",
|
||||
"plop-templates",
|
||||
"node_modules",
|
||||
"src/**/*.test.*",
|
||||
"src/**/*.spec.*",
|
||||
"**/*.scss"
|
||||
],
|
||||
}
|
||||
@@ -22,6 +22,6 @@
|
||||
],
|
||||
"target": "es5",
|
||||
},
|
||||
"include": ["src"],
|
||||
"include": ["src", "Date"],
|
||||
"exclude": ["build", "plop-templates", "node_modules", "src/**/*.test.*", "src/**/*.spec.*", "src/stories", "scripts"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user