Major refactor, pulled in all types, deleted some components
Some checks failed
armco-org/shared-components/pipeline/head There was a failure building this commit
Some checks failed
armco-org/shared-components/pipeline/head There was a failure building this commit
This commit is contained in:
2
Jenkinsfile
vendored
2
Jenkinsfile
vendored
@@ -1,6 +1,6 @@
|
||||
@Library('jenkins-shared') _
|
||||
kanikoPipeline(
|
||||
repoName: 'layout',
|
||||
repoName: 'shared-components',
|
||||
branch: env.BRANCH_NAME ?: 'main',
|
||||
isNpmLib: true
|
||||
)
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"name": "@armco/components/TreeViz",
|
||||
"main": "../build/cjs/TreeViz.js",
|
||||
"module": "../build/es/TreeViz.js",
|
||||
"types": "../build/types/TreeViz.d.ts"
|
||||
}
|
||||
20903
package-lock.json
generated
20903
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
24
package.json
24
package.json
@@ -20,33 +20,39 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@armco/configs": "^0.0.11",
|
||||
"@armco/utils": "^0.0.29",
|
||||
"@armco/icon": "^0.0.10",
|
||||
"@armco/utils": "^0.0.29",
|
||||
"@tanstack/react-table": "^8.21.2",
|
||||
"bootstrap": "^5.3.0",
|
||||
"react-app-polyfill": "^3.0.0",
|
||||
"react-dev-utils": "^12.0.1",
|
||||
"react": ">=16.8.0",
|
||||
"react-app-polyfill": "^3.0.0",
|
||||
"react-bootstrap": "^2.7.4",
|
||||
"react-dev-utils": "^12.0.1",
|
||||
"react-dnd": ">=16.0.0",
|
||||
"react-dnd-html5-backend": ">=16.0.0",
|
||||
"react-dnd-touch-backend": ">=16.0.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-draggable": "^4.4.6",
|
||||
"resize-observer-polyfill": "^1.5.1",
|
||||
"react-resizable": "^3.0.5",
|
||||
"react-router-dom": "^6.13.0",
|
||||
"resize-observer-polyfill": "^1.5.1",
|
||||
"uuid": "^9.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@armco/types": "^0.0.18"
|
||||
"@armco/types": "^0.0.18",
|
||||
"@types/react-dom": "^19.2.2",
|
||||
"@types/uuid": "^10.0.0",
|
||||
"@vitejs/plugin-react": "^5.1.0",
|
||||
"glob": "^11.0.3",
|
||||
"sass-embedded": "^1.93.3",
|
||||
"vite-plugin-dts": "^4.5.4",
|
||||
"vite-plugin-lib-inject-css": "^2.2.2",
|
||||
"vite-plugin-svgr": "^4.5.0",
|
||||
"vitest": "^4.0.7"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"d3": "^7.9.0",
|
||||
"highcharts": "^12.1.2",
|
||||
"highcharts-react-official": "^3.2.1",
|
||||
"highlight.js": "^11.8.0",
|
||||
"moment": "^2.29.4",
|
||||
"moment": "^2.29.4"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { {{pascalCase name}}Props } from "@armco/types"
|
||||
import { {{pascalCase name}}Props } from "./types"
|
||||
import "./{{pascalCase name}}.component.scss"
|
||||
|
||||
const {{pascalCase name}} = (props: {{pascalCase name}}Props): JSX.Element => {
|
||||
const {{pascalCase name}} = (props: {{pascalCase name}}Props): ReactNode => {
|
||||
return <div className="ar-{{pascalCase name}}">In Component {{pascalCase name}}</div>
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import "./{{pascalCase name}}.page.scss"
|
||||
|
||||
interface {{pascalCase name}}Props {}
|
||||
|
||||
const {{pascalCase name}} = (props: {{pascalCase name}}Props): JSX.Element => {
|
||||
const {{pascalCase name}} = (props: {{pascalCase name}}Props): ReactNode => {
|
||||
return <div className="ar-{{pascalCase name}}">In Page {{pascalCase name}}</div>
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
.ar-AboutUs {
|
||||
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
import { AboutUsProps } from "@armco/types"
|
||||
import "./AboutUs.component.scss"
|
||||
import { ReactNode } from "react"
|
||||
import { BaseProps } from "./types"
|
||||
|
||||
const AboutUs = (props: AboutUsProps): JSX.Element => {
|
||||
export interface AboutUsProps extends BaseProps { }
|
||||
|
||||
const AboutUs = (props: AboutUsProps): ReactNode => {
|
||||
return <div className="ar-AboutUs">In Component AboutUs</div>
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,30 @@
|
||||
import { ReactNode, useEffect, useRef, useState } from "react"
|
||||
import {
|
||||
ArAccordionVariants,
|
||||
ArThemes,
|
||||
AccordionExpansionPanelProps,
|
||||
AccordionProps,
|
||||
} from "@armco/types"
|
||||
import { FunctionType } from "@armco/types"
|
||||
import { ArAccordionStyles, ArAccordionVariants, ArThemes } from "./enums"
|
||||
import { BaseProps } from "./types"
|
||||
import Icon from "@armco/icon"
|
||||
import "./Accordion.component.scss"
|
||||
|
||||
|
||||
export interface AccordionProps extends BaseProps {
|
||||
data: Array<AccordionExpansionPanelProps>
|
||||
firstExpanded?: boolean
|
||||
variant?: ArAccordionVariants
|
||||
appearance?: ArAccordionStyles
|
||||
isRemovable?: boolean
|
||||
}
|
||||
|
||||
export interface AccordionExpansionPanelProps extends BaseProps {
|
||||
id: string
|
||||
title: string
|
||||
expanded?: boolean
|
||||
isRemovable?: boolean
|
||||
setExpandedId?: FunctionType
|
||||
shouldGrow?: boolean
|
||||
content: ReactNode
|
||||
}
|
||||
|
||||
|
||||
const AccordionExpansionPanel = (
|
||||
props: AccordionExpansionPanelProps,
|
||||
): ReactNode => {
|
||||
@@ -41,9 +58,8 @@ const AccordionExpansionPanel = (
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`ar-AccordionExpansionPanel${
|
||||
shouldGrow ? " show-grow d-flex flex-column flex-grow-1" : ""
|
||||
}${classes ? " " + classes : ""}${expanded ? " expanded" : ""}`}
|
||||
className={`ar-AccordionExpansionPanel${shouldGrow ? " show-grow d-flex flex-column flex-grow-1" : ""
|
||||
}${classes ? " " + classes : ""}${expanded ? " expanded" : ""}`}
|
||||
id={id}
|
||||
key={id}
|
||||
>
|
||||
@@ -78,9 +94,8 @@ const AccordionExpansionPanel = (
|
||||
)}
|
||||
</div>
|
||||
<div
|
||||
className={`ar-AccordionExpansionPanel__content${
|
||||
shouldGrow ? " d-flex flex-grow-1" : ""
|
||||
}`}
|
||||
className={`ar-AccordionExpansionPanel__content${shouldGrow ? " d-flex flex-grow-1" : ""
|
||||
}`}
|
||||
ref={contentRef}
|
||||
>
|
||||
{typeof content === "string" ? (
|
||||
@@ -93,7 +108,7 @@ const AccordionExpansionPanel = (
|
||||
)
|
||||
}
|
||||
|
||||
const Accordion = (props: AccordionProps): JSX.Element => {
|
||||
const Accordion = (props: AccordionProps): ReactNode => {
|
||||
const {
|
||||
appearance,
|
||||
classes,
|
||||
@@ -127,9 +142,8 @@ const Accordion = (props: AccordionProps): JSX.Element => {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`ar-Accordion${classes ? " " + classes : ""}${
|
||||
appearance ? " " + appearance : ""
|
||||
}`}
|
||||
className={`ar-Accordion${classes ? " " + classes : ""}${appearance ? " " + appearance : ""
|
||||
}`}
|
||||
>
|
||||
{localData?.map((item, index) => {
|
||||
item.setExpandedId = setExpanded
|
||||
|
||||
@@ -1,11 +1,18 @@
|
||||
import { useEffect, useState } from "react"
|
||||
import { AdvancedColorPickerProps } from "@armco/types"
|
||||
import { ReactNode, useEffect, useState } from "react"
|
||||
import { hslToHex, hexToHsl } from "@armco/utils/domHelper"
|
||||
import { BaseProps } from "./types"
|
||||
import Slider from "./Slider"
|
||||
import COLOR_PICKER_CONFIG from "./ColorPickerConfig"
|
||||
import "./AdvancedColorPicker.component.scss"
|
||||
|
||||
const AdvancedColorPicker = (props: AdvancedColorPickerProps): JSX.Element => {
|
||||
export interface AdvancedColorPickerProps extends BaseProps {
|
||||
displaySample?: boolean;
|
||||
id?: string;
|
||||
onColorSelect?: (arg: string) => void;
|
||||
title?: string;
|
||||
}
|
||||
|
||||
const AdvancedColorPicker = (props: AdvancedColorPickerProps): ReactNode => {
|
||||
const { demo, displaySample, id, onColorSelect, title } = props
|
||||
const [color, setColor] = useState<string>()
|
||||
const [hue, setHue] = useState<number>()
|
||||
@@ -89,7 +96,7 @@ const AdvancedColorPicker = (props: AdvancedColorPickerProps): JSX.Element => {
|
||||
label="Hue"
|
||||
min={0}
|
||||
max={255}
|
||||
onChange={(e) =>
|
||||
onChange={(e: any) =>
|
||||
setHue(parseInt((e.target as HTMLInputElement).value) / 255)
|
||||
}
|
||||
withManual
|
||||
@@ -98,7 +105,7 @@ const AdvancedColorPicker = (props: AdvancedColorPickerProps): JSX.Element => {
|
||||
label="Saturation"
|
||||
min={0}
|
||||
max={100}
|
||||
onChange={(e) =>
|
||||
onChange={(e: any) =>
|
||||
setSaturation(parseInt((e.target as HTMLInputElement).value) / 100)
|
||||
}
|
||||
withManual
|
||||
@@ -107,7 +114,7 @@ const AdvancedColorPicker = (props: AdvancedColorPickerProps): JSX.Element => {
|
||||
label="Lightness"
|
||||
min={0}
|
||||
max={100}
|
||||
onChange={(e) =>
|
||||
onChange={(e: any) =>
|
||||
setLightness(parseInt((e.target as HTMLInputElement).value) / 100)
|
||||
}
|
||||
withManual
|
||||
|
||||
@@ -1,10 +1,21 @@
|
||||
import { useEffect, useState } from "react"
|
||||
import { AlertProps, ArThemes } from "@armco/types"
|
||||
import { ReactNode, useEffect, useState } from "react"
|
||||
import { ArAlertType, ArThemes } from "./enums"
|
||||
import { BaseProps } from "./types"
|
||||
import Icon from "@armco/icon"
|
||||
import "./Alert.component.scss"
|
||||
|
||||
export interface AlertProps extends BaseProps {
|
||||
closeable?: boolean
|
||||
position?: string
|
||||
show?: boolean
|
||||
type?: ArAlertType
|
||||
message: string | ReactNode
|
||||
timeout?: number
|
||||
uid: string
|
||||
}
|
||||
|
||||
let timeoutRef: any
|
||||
const Alert = (props: AlertProps): JSX.Element => {
|
||||
const Alert = (props: AlertProps): ReactNode => {
|
||||
const {
|
||||
classes,
|
||||
closeable,
|
||||
@@ -50,9 +61,8 @@ const Alert = (props: AlertProps): JSX.Element => {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`ar-Alert position-fixed d-flex ${position || "top-center"}${
|
||||
classes ? " " + classes : ""
|
||||
} ${type || "information"}${showClass ? " " + showClass : ""}`}
|
||||
className={`ar-Alert position-fixed d-flex ${position || "top-center"}${classes ? " " + classes : ""
|
||||
} ${type || "information"}${showClass ? " " + showClass : ""}`}
|
||||
>
|
||||
<span className="ar-Alert__icon d-inline-block p-2">
|
||||
<Icon
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { ReactNode } from "react"
|
||||
import "./AlertStackManager.component.scss"
|
||||
|
||||
interface AlertStackManagerProps {
|
||||
export interface AlertStackManagerProps {
|
||||
max?: number
|
||||
}
|
||||
|
||||
const AlertStackManager = (props: AlertStackManagerProps): JSX.Element => {
|
||||
const AlertStackManager = (props: AlertStackManagerProps): ReactNode => {
|
||||
return (
|
||||
<div className="ar-AlertStackManager">In Component AlertStackManager</div>
|
||||
)
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import { ArPillSizes, BasicFilterConfig } from "@armco/types"
|
||||
import { ReactNode } from "react"
|
||||
import { BasicFilterConfig } from "@armco/types"
|
||||
import { ArPillSizes } from "./enums"
|
||||
import SelectionPill from "./SelectionPill"
|
||||
import "./AlphabetFilter.component.scss"
|
||||
|
||||
interface AlphabetFilterProps {
|
||||
export interface AlphabetFilterProps {
|
||||
onSelectionChanged: Function
|
||||
}
|
||||
|
||||
const AlphabetFilter = (props: AlphabetFilterProps): JSX.Element => {
|
||||
const AlphabetFilter = (props: AlphabetFilterProps): ReactNode => {
|
||||
const { onSelectionChanged } = props
|
||||
const alpha = Array.from(Array(26)).map((e, i) => i + 65)
|
||||
const alphabet = alpha.map((x) => String.fromCharCode(x))
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
import { AnchorProps } from "@armco/types"
|
||||
import { ReactNode } from "react"
|
||||
import { FunctionType } from "@armco/types"
|
||||
import { BaseProps } from "./types"
|
||||
import "./Anchor.component.scss"
|
||||
|
||||
const Anchor = (props: AnchorProps): JSX.Element => {
|
||||
export interface AnchorProps extends BaseProps {
|
||||
text: string
|
||||
href?: string
|
||||
onClick?: FunctionType
|
||||
}
|
||||
|
||||
const Anchor = (props: AnchorProps): ReactNode => {
|
||||
const { classes, text, ...rest } = props
|
||||
return (
|
||||
<a className={`ar-Anchor${classes ? " " + classes : ""}`} {...rest}>
|
||||
|
||||
@@ -1,16 +1,29 @@
|
||||
import { ReactNode } from "react"
|
||||
import { useNavigate } from "react-router-dom"
|
||||
import { AppNavigatorDataType, FunctionType } from "@armco/types"
|
||||
import { BaseProps } from "./types"
|
||||
import {
|
||||
ArThemes,
|
||||
ArButtonVariants,
|
||||
ArSizes,
|
||||
AppAndToolsSelectorProps,
|
||||
AppTileProps,
|
||||
} from "@armco/types"
|
||||
} from "./enums"
|
||||
import Icon from "@armco/icon"
|
||||
import { useTheme } from "@armco/utils/hooks"
|
||||
import Button from "./Button"
|
||||
import "./AppAndToolsSelector.component.scss"
|
||||
|
||||
export interface AppAndToolsSelectorProps extends BaseProps {
|
||||
data: Array<AppNavigatorDataType>
|
||||
}
|
||||
|
||||
export interface AppTileProps extends BaseProps {
|
||||
label: string
|
||||
icon: string
|
||||
url?: string
|
||||
onClick?: FunctionType
|
||||
description?: Array<string>
|
||||
}
|
||||
|
||||
const AppTile = (props: AppTileProps) => {
|
||||
const { classes, label, icon, url, theme } = props
|
||||
const navigate = useNavigate()
|
||||
@@ -39,7 +52,7 @@ const AppTile = (props: AppTileProps) => {
|
||||
)
|
||||
}
|
||||
|
||||
const AppAndToolsSelector = (props: AppAndToolsSelectorProps): JSX.Element => {
|
||||
const AppAndToolsSelector = (props: AppAndToolsSelectorProps): ReactNode => {
|
||||
const { data } = props
|
||||
const { theme } = useTheme()
|
||||
return (
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React from "react"
|
||||
import { ReactNode } from "react"
|
||||
import "./Application.component.scss"
|
||||
|
||||
interface ApplicationProps {}
|
||||
export interface ApplicationProps { }
|
||||
|
||||
const Application = (props: any): JSX.Element => {
|
||||
const Application = (props: ApplicationProps): ReactNode => {
|
||||
return (
|
||||
<div className="ar-Application">
|
||||
In Component Application
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
import { ChangeEvent, useEffect, useState } from "react"
|
||||
import { ChangeEvent, ReactNode, useEffect, useState } from "react"
|
||||
import {
|
||||
ArDndItemTypes,
|
||||
ArIconTileTypes,
|
||||
ArIconsViewerProps,
|
||||
ArPopoverSlots,
|
||||
ArThemes,
|
||||
SegmentData,
|
||||
IconResponse,
|
||||
ArIconSourceTypes,
|
||||
} from "@armco/types"
|
||||
} from "./enums"
|
||||
import { SegmentData, IconResponse } from "@armco/types"
|
||||
import { ENDPOINTS, STATIC_HOST } from "@armco/configs/endpoints"
|
||||
import { useTheme } from "@armco/utils/hooks"
|
||||
import { debounce } from "@armco/utils/helper"
|
||||
import Icon from "@armco/icon"
|
||||
import { BaseProps } from "./types"
|
||||
import ScrollPagination from "./ScrollPagination"
|
||||
import SearchField from "./SearchField"
|
||||
import SegmentedControl from "./SegmentedControl"
|
||||
@@ -43,7 +42,14 @@ const compactionStyles = [
|
||||
},
|
||||
]
|
||||
|
||||
const ArIconsViewer = (props: ArIconsViewerProps): JSX.Element => {
|
||||
export interface ArIconsViewerProps extends BaseProps {
|
||||
view?: SegmentData;
|
||||
hasSearch?: boolean;
|
||||
hasViewSelector?: boolean;
|
||||
isDraggable?: boolean;
|
||||
}
|
||||
|
||||
const ArIconsViewer = (props: ArIconsViewerProps): ReactNode => {
|
||||
const {
|
||||
demo,
|
||||
view: externalView,
|
||||
@@ -66,11 +72,10 @@ const ArIconsViewer = (props: ArIconsViewerProps): JSX.Element => {
|
||||
|
||||
const getItem = (icon: IconResponse) => (
|
||||
<span
|
||||
className={`ar-ArIconsViewer__icon-container border-radius-l1 h-100 w-100${
|
||||
view.name !== ArIconTileTypes.LIST
|
||||
? " flex-center"
|
||||
: " border flex-v-center"
|
||||
}`}
|
||||
className={`ar-ArIconsViewer__icon-container border-radius-l1 h-100 w-100${view.name !== ArIconTileTypes.LIST
|
||||
? " flex-center"
|
||||
: " border flex-v-center"
|
||||
}`}
|
||||
slot={ArPopoverSlots.ANCHOR}
|
||||
>
|
||||
<Icon
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
.ar-ArViz {
|
||||
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
import { useEffect, useRef } from "react"
|
||||
import { select } from "d3"
|
||||
import { ArVisualizationTypes, ArVizProps, ObjectType } from "@armco/types"
|
||||
import { generateBubbleChart } from "@armco/utils/chartGenerators"
|
||||
import BubbleChart from "./BubbleChart"
|
||||
import "./ArViz.component.scss"
|
||||
|
||||
// TODO: Replace this with ArViz dummy in dummies.txt
|
||||
const dataDummy = {}
|
||||
|
||||
const ArViz = (props: ArVizProps): JSX.Element => {
|
||||
const { clickHandler, type, data } = props
|
||||
const svgContainerRef = useRef(null)
|
||||
|
||||
useEffect(() => {
|
||||
if (data && svgContainerRef.current) {
|
||||
switch (type) {
|
||||
case ArVisualizationTypes.BUBBLE:
|
||||
generateBubbleChart(dataDummy)
|
||||
}
|
||||
const svg = svgContainerRef.current as SVGSVGElement
|
||||
const boundingBox = svg.getBBox()
|
||||
const svgToUpdate = select("#ar-ArViz__chart-container")
|
||||
svgToUpdate.attr(
|
||||
"viewBox",
|
||||
`${boundingBox.x} ${boundingBox.y} ${boundingBox.width} ${boundingBox.height}`,
|
||||
)
|
||||
}
|
||||
}, [svgContainerRef, data, type])
|
||||
|
||||
return type === ArVisualizationTypes.BUBBLE ? (
|
||||
<BubbleChart data={data as Array<ObjectType>} clickHandler={clickHandler} />
|
||||
) : (
|
||||
<div className="ar-ArViz h-100 w-100 overflow-auto p-3">
|
||||
<svg
|
||||
id="ar-ArViz__chart-container"
|
||||
className="h-100 w-100"
|
||||
ref={svgContainerRef}
|
||||
viewBox=""
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default ArViz
|
||||
@@ -1,9 +1,15 @@
|
||||
import { ArmcoIamProviderProps, ArDefaultLoginPage } from "@armco/types"
|
||||
import { ReactNode } from "react"
|
||||
import { WEB_CONFIG } from "@armco/configs/endpoints"
|
||||
import { BaseProps } from "./types"
|
||||
import { ArDefaultLoginPage } from "./enums"
|
||||
import LoginProvider from "./LoginProvider"
|
||||
import "./ArmcoIamProvider.component.scss"
|
||||
|
||||
const ArmcoIamProvider = (props: ArmcoIamProviderProps): JSX.Element => {
|
||||
export interface ArmcoIamProviderProps extends BaseProps {
|
||||
defaultPage?: ArDefaultLoginPage
|
||||
}
|
||||
|
||||
const ArmcoIamProvider = (props: ArmcoIamProviderProps): ReactNode => {
|
||||
const { defaultPage } = props
|
||||
return (
|
||||
<LoginProvider
|
||||
|
||||
@@ -1,8 +1,18 @@
|
||||
import { BadgeProps } from "@armco/types"
|
||||
import { ReactNode } from "react"
|
||||
import { BaseProps } from "./types";
|
||||
import { ArBadgeType, ArSizes } from "./enums";
|
||||
import Icon from "@armco/icon"
|
||||
import "./Badge.component.scss"
|
||||
|
||||
const Badge = (props: BadgeProps): JSX.Element => {
|
||||
export interface BadgeProps extends BaseProps {
|
||||
icon?: string;
|
||||
size?: ArSizes;
|
||||
shadow?: boolean;
|
||||
text?: string;
|
||||
type?: ArBadgeType;
|
||||
}
|
||||
|
||||
const Badge = (props: BadgeProps): ReactNode => {
|
||||
const { classes, icon, size, shadow, style, text, type } = props
|
||||
if (icon?.indexOf("/") === -1) {
|
||||
console.warn(
|
||||
@@ -11,9 +21,8 @@ const Badge = (props: BadgeProps): JSX.Element => {
|
||||
}
|
||||
return (
|
||||
<span
|
||||
className={`ar-Badge${size ? " " + size : " regular"}${
|
||||
type ? " " + type : " inprogress"
|
||||
}${shadow ? " shadow" : ""}${classes ? " " + classes : ""}`}
|
||||
className={`ar-Badge${size ? " " + size : " regular"}${type ? " " + type : " inprogress"
|
||||
}${shadow ? " shadow" : ""}${classes ? " " + classes : ""}`}
|
||||
style={style}
|
||||
>
|
||||
{icon && size !== "small" && <Icon icon={icon} />}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React from "react"
|
||||
import { ReactNode } from "react"
|
||||
import "./Banner.component.scss"
|
||||
|
||||
interface BannerProps {}
|
||||
export interface BannerProps { }
|
||||
|
||||
const Banner = (props: any): JSX.Element => {
|
||||
const Banner = (props: BannerProps): ReactNode => {
|
||||
return (
|
||||
<div className="ar-Banner">
|
||||
In Component Banner
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React from "react"
|
||||
import React, { ReactNode } from "react"
|
||||
import "./Benefits.component.scss"
|
||||
|
||||
interface BenefitsProps {}
|
||||
export interface BenefitsProps { }
|
||||
|
||||
const Benefits = (props: any): JSX.Element => {
|
||||
const Benefits = (props: BenefitsProps): ReactNode => {
|
||||
return (
|
||||
<div className="ar-Benefits">
|
||||
In Component Benefits
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React from "react"
|
||||
import { ReactNode } from "react"
|
||||
import "./Blog.component.scss"
|
||||
|
||||
interface BlogProps {}
|
||||
export interface BlogProps { }
|
||||
|
||||
const Blog = (props: any): JSX.Element => {
|
||||
const Blog = (props: BlogProps): ReactNode => {
|
||||
return (
|
||||
<div className="ar-Blog">
|
||||
In Component Blog
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React from "react"
|
||||
import { ReactNode } from "react"
|
||||
import "./Brands.component.scss"
|
||||
|
||||
interface BrandsProps {}
|
||||
export interface BrandsProps { }
|
||||
|
||||
const Brands = (props: any): JSX.Element => {
|
||||
const Brands = (props: BrandsProps): ReactNode => {
|
||||
return (
|
||||
<div className="ar-Brands">
|
||||
In Component Brands
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
import { ReactNode } from "react"
|
||||
import { useNavigate } from "react-router-dom"
|
||||
import {
|
||||
ArButtonVariants,
|
||||
ArSizes,
|
||||
BreadCrumbData,
|
||||
BreadcrumbProps,
|
||||
} from "@armco/types"
|
||||
import { BreadCrumbData } from "@armco/types"
|
||||
import { BaseProps } from "./types"
|
||||
import { ArButtonVariants, ArSizes } from "./enums"
|
||||
import Button from "./Button"
|
||||
import "./Breadcrumb.component.scss"
|
||||
|
||||
const Breadcrumb = (props: BreadcrumbProps): JSX.Element => {
|
||||
export interface BreadcrumbProps extends BaseProps {
|
||||
data: Array<BreadCrumbData>
|
||||
separator?: string
|
||||
size?: ArSizes
|
||||
onClick?: Function
|
||||
}
|
||||
|
||||
const Breadcrumb = (props: BreadcrumbProps): ReactNode => {
|
||||
const { classes, data, demo, separator, size, onClick } = props
|
||||
const navigate = useNavigate()
|
||||
|
||||
@@ -41,8 +46,8 @@ const Breadcrumb = (props: BreadcrumbProps): JSX.Element => {
|
||||
"onClick" in node
|
||||
? (e) => node.onClick(e, node.data)
|
||||
: onClick
|
||||
? (e) => onClick(e, node.data)
|
||||
: () => navigate("route" in node ? node.route : "")
|
||||
? (e) => onClick(e, node.data)
|
||||
: () => navigate("route" in node ? node.route : "")
|
||||
}
|
||||
/>
|
||||
{index < nodes.length - 1 && (separator || "/")}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
.ar-Breadcrumbs {
|
||||
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import React from "react"
|
||||
import "./Breadcrumbs.component.scss"
|
||||
|
||||
interface BreadcrumbsProps {}
|
||||
|
||||
const Breadcrumbs = (props: any): JSX.Element => {
|
||||
return (
|
||||
<div className="ar-Breadcrumbs">
|
||||
In Component Breadcrumbs
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Breadcrumbs
|
||||
@@ -1,5 +1,7 @@
|
||||
import { ReactNode } from "react"
|
||||
import { v4 as uuid } from "uuid"
|
||||
import { ArThemes, BrowserIncompatibilityProps } from "@armco/types"
|
||||
import type { BaseProps } from "./types"
|
||||
import { ArThemes } from "./enums"
|
||||
import { copyToClipboard } from "@armco/utils/helper"
|
||||
import { useTheme } from "@armco/utils/hooks"
|
||||
import Icon from "@armco/icon"
|
||||
@@ -7,9 +9,15 @@ import Alert from "./Alert"
|
||||
import Link from "./Link"
|
||||
import "./BrowserIncompatibility.component.scss"
|
||||
|
||||
|
||||
export interface BrowserIncompatibilityProps extends BaseProps {
|
||||
applicationName?: string
|
||||
moreLink?: string
|
||||
}
|
||||
|
||||
const BrowserIncompatibility = (
|
||||
props: BrowserIncompatibilityProps,
|
||||
): JSX.Element => {
|
||||
): ReactNode => {
|
||||
const { applicationName, moreLink } = props
|
||||
const { theme } = useTheme()
|
||||
const demoDummyLink = "https://notabuck.com/armco-design-system/docs/devices"
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
.ar-BubbleChart {
|
||||
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
import { useEffect, useRef } from "react"
|
||||
import Highcharts from "highcharts"
|
||||
import "highcharts/highcharts-more"
|
||||
import { BubbleChartProps, ObjectType } from "@armco/types"
|
||||
import "./BubbleChart.component.scss"
|
||||
|
||||
const BubbleChart = (props: BubbleChartProps): JSX.Element => {
|
||||
const { clickHandler, data } = props
|
||||
const chartRef = useRef(null)
|
||||
|
||||
useEffect(() => {
|
||||
if (!Highcharts) {
|
||||
if (chartRef.current) {
|
||||
;(chartRef.current as HTMLDivElement).innerHTML = `
|
||||
<div style="color: #ff4d4f; font-family: monospace; padding: 10px; border: 1px solid #ff4d4f; border-radius: 4px;">
|
||||
Highcharts is not installed. Please install highcharts to use BubbleChart.
|
||||
</div>
|
||||
`
|
||||
}
|
||||
return
|
||||
}
|
||||
if (chartRef.current && data) {
|
||||
const labels = Object.keys(data)
|
||||
const values = Object.values(data)
|
||||
|
||||
const options = {
|
||||
chart: {
|
||||
type: "packedbubble",
|
||||
},
|
||||
title: {
|
||||
text: null,
|
||||
},
|
||||
tooltip: {
|
||||
formatter: function (): string {
|
||||
return (
|
||||
"Tag: <b>" +
|
||||
("point" in this && (this.point as ObjectType).name) +
|
||||
"</b><br>Count: <b>" +
|
||||
("y" in this && this.y) +
|
||||
"</b>"
|
||||
)
|
||||
},
|
||||
},
|
||||
credits: {
|
||||
enabled: false,
|
||||
},
|
||||
plotOptions: {
|
||||
packedbubble: {
|
||||
minSize: "30%",
|
||||
maxSize: "120%",
|
||||
zMin: 0,
|
||||
zMax: 1000,
|
||||
layoutAlgorithm: {
|
||||
splitSeries: false,
|
||||
gravitationalConstant: 0.02,
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: true,
|
||||
format: "{point.name}",
|
||||
filter: {
|
||||
property: "y",
|
||||
operator: ">",
|
||||
value: 250,
|
||||
},
|
||||
style: {
|
||||
color: "black",
|
||||
textOutline: "none",
|
||||
fontWeight: "normal",
|
||||
},
|
||||
},
|
||||
events: {
|
||||
click: function (e: any) {
|
||||
clickHandler && clickHandler(e)
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
series: [
|
||||
{
|
||||
cursor: "pointer",
|
||||
showInLegend: false,
|
||||
data: labels.map((label, index) => ({
|
||||
// x: index, // X-axis position
|
||||
// y: values[index], // Y-axis value
|
||||
// z: values[index], // Bubble size value
|
||||
value: values[index],
|
||||
name: label, // Label for the bubble
|
||||
})),
|
||||
},
|
||||
],
|
||||
xAxis: {
|
||||
visible: false,
|
||||
},
|
||||
yAxis: {
|
||||
visible: false,
|
||||
},
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
Highcharts.chart(chartRef.current, options)
|
||||
}
|
||||
}, [data]) // Re-render chart when data prop changes
|
||||
|
||||
return <div ref={chartRef} style={{ width: "100%" }}></div>
|
||||
}
|
||||
|
||||
export default BubbleChart
|
||||
@@ -1,3 +0,0 @@
|
||||
.ar-BubbleViz {
|
||||
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
import { BubbleVizProps } from "@armco/types"
|
||||
import "./BubbleViz.component.scss"
|
||||
|
||||
const BubbleViz = (props: BubbleVizProps): JSX.Element => {
|
||||
const { classes } = props
|
||||
|
||||
return <div className={`ar-BubbleViz${classes ? " " + classes : ""}`}></div>
|
||||
}
|
||||
|
||||
export default BubbleViz
|
||||
@@ -1,14 +1,32 @@
|
||||
import { useState } from "react"
|
||||
import { CSSProperties, MouseEventHandler, ReactNode, useState } from "react"
|
||||
import { FunctionType } from "@armco/types"
|
||||
import {
|
||||
ArButtonTypes,
|
||||
ArButtonVariants,
|
||||
ArSizes,
|
||||
ArThemes,
|
||||
ButtonProps,
|
||||
} from "@armco/types"
|
||||
} from "./enums"
|
||||
import { BaseProps } from "./types"
|
||||
import Icon from "@armco/icon"
|
||||
import "./Button.component.scss"
|
||||
|
||||
export interface ButtonProps extends BaseProps {
|
||||
content?: ReactNode | FunctionType
|
||||
color?: string
|
||||
contentClasses?: string
|
||||
contentStyles?: CSSProperties
|
||||
disabled?: boolean
|
||||
preIcon?: string
|
||||
postIcon?: string
|
||||
onClick?: MouseEventHandler<HTMLButtonElement>
|
||||
onMouseEnter?: MouseEventHandler<HTMLButtonElement>
|
||||
onMouseLeave?: MouseEventHandler<HTMLButtonElement>
|
||||
size?: string
|
||||
type?: ArButtonTypes
|
||||
variant?: ArButtonVariants
|
||||
withSplitOptions?: boolean
|
||||
}
|
||||
|
||||
const Button = (props: ButtonProps) => {
|
||||
const {
|
||||
classes,
|
||||
@@ -51,8 +69,8 @@ const Button = (props: ButtonProps) => {
|
||||
? "black"
|
||||
: "white"
|
||||
: theme === ArThemes.DARK1
|
||||
? "white"
|
||||
: "#3232d8"
|
||||
? "white"
|
||||
: "#3232d8"
|
||||
} else {
|
||||
setColor = "white"
|
||||
}
|
||||
@@ -62,11 +80,9 @@ const Button = (props: ButtonProps) => {
|
||||
return (
|
||||
<button
|
||||
type={type}
|
||||
className={`ar-Button d-inline-flex ar-Button__main fw-bold flex-center${
|
||||
classes ? " " + classes : ""
|
||||
}${variant ? " ar-" + variant : ""}${size ? " ar-" + size : ""}${
|
||||
withSplitOptions ? " has-split-button" : ""
|
||||
}`}
|
||||
className={`ar-Button d-inline-flex ar-Button__main fw-bold flex-center${classes ? " " + classes : ""
|
||||
}${variant ? " ar-" + variant : ""}${size ? " ar-" + size : ""}${withSplitOptions ? " has-split-button" : ""
|
||||
}`}
|
||||
onClick={onClick}
|
||||
style={btnStyles}
|
||||
onMouseEnter={(e) => {
|
||||
@@ -95,9 +111,8 @@ const Button = (props: ButtonProps) => {
|
||||
</span>
|
||||
{postIcon && (
|
||||
<span
|
||||
className={`ar-Button__icon flex-center post${
|
||||
content ? " ms-2" : ""
|
||||
}`}
|
||||
className={`ar-Button__icon flex-center post${content ? " ms-2" : ""
|
||||
}`}
|
||||
>
|
||||
<Icon
|
||||
icon={postIcon}
|
||||
|
||||
15
src/Card.tsx
15
src/Card.tsx
@@ -1,13 +1,18 @@
|
||||
import { CardProps } from "@armco/types"
|
||||
import { ReactNode } from "react"
|
||||
import type { BaseProps } from "./types"
|
||||
import "./Card.component.scss"
|
||||
|
||||
const Card = (props: CardProps): JSX.Element => {
|
||||
export interface CardProps extends BaseProps {
|
||||
children?: ReactNode
|
||||
header?: ReactNode
|
||||
}
|
||||
|
||||
const Card = (props: CardProps): ReactNode => {
|
||||
const { children, classes, header } = props
|
||||
return (
|
||||
<div
|
||||
className={`ar-Card border d-flex flex-column${
|
||||
classes ? " " + classes : ""
|
||||
}`}
|
||||
className={`ar-Card border d-flex flex-column${classes ? " " + classes : ""
|
||||
}`}
|
||||
>
|
||||
{header && (
|
||||
<div className="w-100 fw-bold p-2 border-bottom">{header}</div>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React from "react"
|
||||
import { ReactNode } from "react"
|
||||
import "./Careers.component.scss"
|
||||
|
||||
interface CareersProps {}
|
||||
export interface CareersProps { }
|
||||
|
||||
const Careers = (props: any): JSX.Element => {
|
||||
const Careers = (props: CareersProps): ReactNode => {
|
||||
return (
|
||||
<div className="ar-Careers">
|
||||
In Component Careers
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
.ar-Carousel {
|
||||
|
||||
}
|
||||
911
src/Carousel.tsx
911
src/Carousel.tsx
@@ -1,911 +0,0 @@
|
||||
import { Children, Component, ReactNode } from "react"
|
||||
import { AnimationHandler, CarouselProps, SwiperProps } from "@armco/types"
|
||||
import { isKeyboardEvent } from "@armco/utils/domHelper"
|
||||
import klass from "./cssClasses"
|
||||
import Thumbs from "./Thumbs"
|
||||
import {
|
||||
slideAnimationHandler,
|
||||
slideSwipeAnimationHandler,
|
||||
slideStopSwipingHandler,
|
||||
fadeAnimationHandler,
|
||||
} from "./animations"
|
||||
import Swiper from "./Swiper"
|
||||
import "./Carousel.component.scss"
|
||||
|
||||
export interface CarouselState {
|
||||
autoPlay?: boolean
|
||||
cancelClick: boolean
|
||||
hasMount: boolean
|
||||
initialized: boolean
|
||||
isMouseEntered: boolean
|
||||
itemSize: number
|
||||
previousItem: number
|
||||
selectedItem: number
|
||||
swiping?: boolean
|
||||
swipeMovementStarted: boolean
|
||||
itemListStyle?: React.CSSProperties
|
||||
slideStyle?: React.CSSProperties
|
||||
selectedStyle?: React.CSSProperties
|
||||
prevStyle?: React.CSSProperties
|
||||
}
|
||||
|
||||
const noop = () => {}
|
||||
|
||||
const defaultStatusFormatter = (current: number, total: number) =>
|
||||
`${current} of ${total}`
|
||||
|
||||
export default class Carousel extends Component<CarouselProps, CarouselState> {
|
||||
private thumbsRef?: Thumbs
|
||||
private carouselWrapperRef?: HTMLDivElement
|
||||
// @ts-ignore
|
||||
private listRef?: HTMLElement | HTMLUListElement
|
||||
private itemsRef?: HTMLElement[]
|
||||
private timer?: ReturnType<typeof setTimeout>
|
||||
private animationHandler: AnimationHandler
|
||||
|
||||
static displayName = "Carousel"
|
||||
|
||||
static defaultProps: CarouselProps = {
|
||||
ariaLabel: undefined,
|
||||
axis: "horizontal",
|
||||
centerSlidePercentage: 80,
|
||||
interval: 3000,
|
||||
labels: {
|
||||
leftArrow: "previous slide / item",
|
||||
rightArrow: "next slide / item",
|
||||
item: "slide item",
|
||||
},
|
||||
onClickItem: noop,
|
||||
onClickThumb: noop,
|
||||
onChange: noop,
|
||||
onSwipeStart: () => {},
|
||||
onSwipeEnd: () => {},
|
||||
onSwipeMove: () => false,
|
||||
preventMovementUntilSwipeScrollTolerance: false,
|
||||
renderArrowPrev: (
|
||||
onClickHandler: () => void,
|
||||
hasPrev: boolean,
|
||||
label: string,
|
||||
) => (
|
||||
<button
|
||||
type="button"
|
||||
aria-label={label}
|
||||
className={klass.ARROW_PREV(!hasPrev)}
|
||||
onClick={onClickHandler}
|
||||
/>
|
||||
),
|
||||
renderArrowNext: (
|
||||
onClickHandler: () => void,
|
||||
hasNext: boolean,
|
||||
label: string,
|
||||
) => (
|
||||
<button
|
||||
type="button"
|
||||
aria-label={label}
|
||||
className={klass.ARROW_NEXT(!hasNext)}
|
||||
onClick={onClickHandler}
|
||||
/>
|
||||
),
|
||||
renderIndicator: (
|
||||
onClickHandler: (e: React.MouseEvent | React.KeyboardEvent) => void,
|
||||
isSelected: boolean,
|
||||
index: number,
|
||||
label: string,
|
||||
) => {
|
||||
return (
|
||||
<li
|
||||
className={klass.DOT(isSelected)}
|
||||
onClick={onClickHandler}
|
||||
onKeyDown={onClickHandler}
|
||||
value={index}
|
||||
key={index}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
aria-label={`${label} ${index + 1}`}
|
||||
/>
|
||||
)
|
||||
},
|
||||
renderItem: (item: ReactNode) => {
|
||||
return item
|
||||
},
|
||||
renderThumbs: (children: ReactNode | Array<ReactNode>) => {
|
||||
const images = Children.map<ReactNode | undefined, ReactNode>(
|
||||
children,
|
||||
(item) => {
|
||||
let img: ReactNode | undefined = item
|
||||
|
||||
// if the item is not an image, try to find the first image in the item's children.
|
||||
if (
|
||||
(item as React.ReactElement<{ children: ReactNode }>).type !== "img"
|
||||
) {
|
||||
img =
|
||||
item &&
|
||||
(
|
||||
Children.toArray(
|
||||
(
|
||||
(item as React.ReactElement).props as {
|
||||
children: ReactNode
|
||||
}
|
||||
).children,
|
||||
) as ReactNode[]
|
||||
).find(
|
||||
(children) => (children as React.ReactElement).type === "img",
|
||||
)
|
||||
}
|
||||
|
||||
if (!img) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
return img
|
||||
},
|
||||
)
|
||||
|
||||
if (images?.filter((image) => image).length === 0) {
|
||||
console.warn(
|
||||
`No images found! Can't build the thumb list without images. If you don't need thumbs, set showThumbs={false} in the Carousel. Note that it's not possible to get images rendered inside custom components.`,
|
||||
)
|
||||
|
||||
return []
|
||||
}
|
||||
|
||||
return images
|
||||
},
|
||||
statusFormatter: defaultStatusFormatter,
|
||||
selectedItem: 0,
|
||||
showArrows: true,
|
||||
showIndicators: true,
|
||||
showStatus: true,
|
||||
showThumbs: true,
|
||||
stopOnHover: true,
|
||||
swipeScrollTolerance: 5,
|
||||
swipeable: true,
|
||||
transitionTime: 350,
|
||||
verticalSwipe: "standard",
|
||||
width: "100%",
|
||||
animationHandler: "slide",
|
||||
swipeAnimationHandler: slideSwipeAnimationHandler,
|
||||
stopSwipingHandler: slideStopSwipingHandler,
|
||||
}
|
||||
|
||||
constructor(props: CarouselProps) {
|
||||
super(props)
|
||||
|
||||
const initState = {
|
||||
initialized: false,
|
||||
previousItem: props.selectedItem,
|
||||
selectedItem: props.selectedItem,
|
||||
hasMount: false,
|
||||
isMouseEntered: false,
|
||||
autoPlay: props.autoPlay,
|
||||
swiping: false,
|
||||
swipeMovementStarted: false,
|
||||
cancelClick: false,
|
||||
itemSize: 1,
|
||||
itemListStyle: {},
|
||||
slideStyle: {},
|
||||
selectedStyle: {},
|
||||
prevStyle: {},
|
||||
}
|
||||
|
||||
this.animationHandler =
|
||||
(typeof props.animationHandler === "function" &&
|
||||
props.animationHandler) ||
|
||||
(props.animationHandler === "fade" && fadeAnimationHandler) ||
|
||||
slideAnimationHandler
|
||||
|
||||
this.state = {
|
||||
...initState,
|
||||
...this.animationHandler(props, initState),
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (!this.props.children) {
|
||||
return
|
||||
}
|
||||
|
||||
this.setupCarousel()
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps: CarouselProps, prevState: CarouselState) {
|
||||
if (!prevProps.children && this.props.children && !this.state.initialized) {
|
||||
this.setupCarousel()
|
||||
}
|
||||
|
||||
if (!prevProps.autoFocus && this.props.autoFocus) {
|
||||
this.forceFocus()
|
||||
}
|
||||
|
||||
if (prevState.swiping && !this.state.swiping) {
|
||||
// We stopped swiping, ensure we are heading to the new/current slide and not stuck
|
||||
|
||||
this.setState({
|
||||
...this.props.stopSwipingHandler(this.props, this.state),
|
||||
})
|
||||
}
|
||||
|
||||
if (
|
||||
prevProps.selectedItem !== this.props.selectedItem ||
|
||||
prevProps.centerMode !== this.props.centerMode
|
||||
) {
|
||||
this.updateSizes()
|
||||
this.moveTo(this.props.selectedItem)
|
||||
}
|
||||
|
||||
if (prevProps.autoPlay !== this.props.autoPlay) {
|
||||
if (this.props.autoPlay) {
|
||||
this.setupAutoPlay()
|
||||
} else {
|
||||
this.destroyAutoPlay()
|
||||
}
|
||||
|
||||
this.setState({ autoPlay: this.props.autoPlay })
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.destroyCarousel()
|
||||
}
|
||||
|
||||
setThumbsRef = (node: Thumbs) => {
|
||||
this.thumbsRef = node
|
||||
}
|
||||
|
||||
setCarouselWrapperRef = (node: HTMLDivElement) => {
|
||||
this.carouselWrapperRef = node
|
||||
}
|
||||
|
||||
setListRef = (node: HTMLElement | HTMLUListElement) => {
|
||||
this.listRef = node
|
||||
}
|
||||
|
||||
setItemsRef = (node: HTMLElement, index: number) => {
|
||||
if (!this.itemsRef) {
|
||||
this.itemsRef = []
|
||||
}
|
||||
this.itemsRef[index] = node
|
||||
}
|
||||
|
||||
setupCarousel() {
|
||||
this.bindEvents()
|
||||
|
||||
if (this.state.autoPlay && Children.count(this.props.children) > 1) {
|
||||
this.setupAutoPlay()
|
||||
}
|
||||
|
||||
if (this.props.autoFocus) {
|
||||
this.forceFocus()
|
||||
}
|
||||
|
||||
this.setState(
|
||||
{
|
||||
initialized: true,
|
||||
},
|
||||
() => {
|
||||
const initialImage = this.getInitialImage()
|
||||
if (initialImage && !initialImage.complete) {
|
||||
// if it's a carousel of images, we set the mount state after the first image is loaded
|
||||
initialImage.addEventListener("load", this.setMountState)
|
||||
} else {
|
||||
this.setMountState()
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
destroyCarousel() {
|
||||
if (this.state.initialized) {
|
||||
this.unbindEvents()
|
||||
this.destroyAutoPlay()
|
||||
}
|
||||
}
|
||||
|
||||
setupAutoPlay() {
|
||||
this.autoPlay()
|
||||
const carouselWrapper = this.carouselWrapperRef
|
||||
|
||||
if (this.props.stopOnHover && carouselWrapper) {
|
||||
carouselWrapper.addEventListener("mouseenter", this.stopOnHover)
|
||||
carouselWrapper.addEventListener("mouseleave", this.startOnLeave)
|
||||
}
|
||||
}
|
||||
|
||||
destroyAutoPlay() {
|
||||
this.clearAutoPlay()
|
||||
const carouselWrapper = this.carouselWrapperRef
|
||||
|
||||
if (this.props.stopOnHover && carouselWrapper) {
|
||||
carouselWrapper.removeEventListener("mouseenter", this.stopOnHover)
|
||||
carouselWrapper.removeEventListener("mouseleave", this.startOnLeave)
|
||||
}
|
||||
}
|
||||
|
||||
bindEvents() {
|
||||
// as the widths are calculated, we need to resize
|
||||
// the carousel when the window is resized
|
||||
window.addEventListener("resize", this.updateSizes)
|
||||
// issue #2 - image loading smaller
|
||||
window.addEventListener("DOMContentLoaded", this.updateSizes)
|
||||
|
||||
if (this.props.useKeyboardArrows) {
|
||||
document.addEventListener("keydown", this.navigateWithKeyboard)
|
||||
}
|
||||
}
|
||||
|
||||
unbindEvents() {
|
||||
// removing listeners
|
||||
window.removeEventListener("resize", this.updateSizes)
|
||||
window.removeEventListener("DOMContentLoaded", this.updateSizes)
|
||||
|
||||
const initialImage = this.getInitialImage()
|
||||
|
||||
if (initialImage) {
|
||||
initialImage.removeEventListener("load", this.setMountState)
|
||||
}
|
||||
|
||||
if (this.props.useKeyboardArrows) {
|
||||
document.removeEventListener("keydown", this.navigateWithKeyboard)
|
||||
}
|
||||
}
|
||||
|
||||
autoPlay = () => {
|
||||
if (Children.count(this.props.children) <= 1) {
|
||||
return
|
||||
}
|
||||
|
||||
this.clearAutoPlay()
|
||||
|
||||
if (!this.props.autoPlay) {
|
||||
return
|
||||
}
|
||||
|
||||
this.timer = setTimeout(() => {
|
||||
this.increment()
|
||||
}, this.props.interval)
|
||||
}
|
||||
|
||||
clearAutoPlay = () => {
|
||||
if (this.timer) clearTimeout(this.timer)
|
||||
}
|
||||
|
||||
resetAutoPlay = () => {
|
||||
this.clearAutoPlay()
|
||||
this.autoPlay()
|
||||
}
|
||||
|
||||
stopOnHover = () => {
|
||||
this.setState({ isMouseEntered: true }, this.clearAutoPlay)
|
||||
}
|
||||
|
||||
startOnLeave = () => {
|
||||
this.setState({ isMouseEntered: false }, this.autoPlay)
|
||||
}
|
||||
|
||||
forceFocus() {
|
||||
this.carouselWrapperRef?.focus()
|
||||
}
|
||||
|
||||
isFocusWithinTheCarousel = () => {
|
||||
if (!this.carouselWrapperRef) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (
|
||||
document.activeElement === this.carouselWrapperRef ||
|
||||
this.carouselWrapperRef.contains(document.activeElement)
|
||||
) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
navigateWithKeyboard = (e: KeyboardEvent) => {
|
||||
if (!this.isFocusWithinTheCarousel()) {
|
||||
return
|
||||
}
|
||||
|
||||
const { axis } = this.props
|
||||
const isHorizontal = axis === "horizontal"
|
||||
const keyNames = {
|
||||
ArrowUp: 38,
|
||||
ArrowRight: 39,
|
||||
ArrowDown: 40,
|
||||
ArrowLeft: 37,
|
||||
}
|
||||
|
||||
const nextKey = isHorizontal ? keyNames.ArrowRight : keyNames.ArrowDown
|
||||
const prevKey = isHorizontal ? keyNames.ArrowLeft : keyNames.ArrowUp
|
||||
|
||||
if (nextKey === e.keyCode) {
|
||||
this.increment()
|
||||
} else if (prevKey === e.keyCode) {
|
||||
this.decrement()
|
||||
}
|
||||
}
|
||||
|
||||
updateSizes = () => {
|
||||
if (
|
||||
!this.state.initialized ||
|
||||
!this.itemsRef ||
|
||||
this.itemsRef.length === 0
|
||||
) {
|
||||
return
|
||||
}
|
||||
const isHorizontal = this.props.axis === "horizontal"
|
||||
const firstItem = this.itemsRef[0]
|
||||
if (!firstItem) {
|
||||
return
|
||||
}
|
||||
const itemSize = isHorizontal
|
||||
? firstItem.clientWidth
|
||||
: firstItem.clientHeight
|
||||
|
||||
this.setState({
|
||||
itemSize,
|
||||
})
|
||||
|
||||
if (this.thumbsRef) {
|
||||
this.thumbsRef.updateSizes()
|
||||
}
|
||||
}
|
||||
|
||||
setMountState = () => {
|
||||
this.setState({ hasMount: true })
|
||||
this.updateSizes()
|
||||
}
|
||||
|
||||
handleClickItem = (index: number, item: React.ReactNode) => {
|
||||
if (Children.count(this.props.children) === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
if (this.state.cancelClick) {
|
||||
this.setState({
|
||||
cancelClick: false,
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
this.props.onClickItem(index, item)
|
||||
|
||||
if (index !== this.state.selectedItem) {
|
||||
this.setState({
|
||||
selectedItem: index,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On Change handler, Passes the index and React node to the supplied onChange prop
|
||||
* @param index of the carousel item
|
||||
* @param item React node of the item being changed
|
||||
*/
|
||||
handleOnChange = (index: number, item: React.ReactNode) => {
|
||||
if (Children.count(this.props.children) <= 1) {
|
||||
return
|
||||
}
|
||||
|
||||
this.props.onChange(index, item)
|
||||
}
|
||||
|
||||
handleClickThumb = (index: number, item: React.ReactNode) => {
|
||||
this.props.onClickThumb(index, item)
|
||||
|
||||
this.moveTo(index)
|
||||
}
|
||||
|
||||
onSwipeStart = (event: React.TouchEvent) => {
|
||||
this.setState({
|
||||
swiping: true,
|
||||
})
|
||||
this.props.onSwipeStart(event)
|
||||
}
|
||||
|
||||
onSwipeEnd = (event: React.TouchEvent) => {
|
||||
this.setState({
|
||||
swiping: false,
|
||||
cancelClick: false,
|
||||
swipeMovementStarted: false,
|
||||
})
|
||||
this.props.onSwipeEnd(event)
|
||||
|
||||
this.clearAutoPlay()
|
||||
|
||||
if (this.state.autoPlay) {
|
||||
this.autoPlay()
|
||||
}
|
||||
}
|
||||
|
||||
onSwipeMove = (delta: { x: number; y: number }, event: React.TouchEvent) => {
|
||||
this.props.onSwipeMove(event)
|
||||
|
||||
const animationHandlerResponse = this.props.swipeAnimationHandler(
|
||||
delta,
|
||||
this.props,
|
||||
this.state,
|
||||
this.setState.bind(this),
|
||||
)
|
||||
|
||||
this.setState({
|
||||
...animationHandlerResponse,
|
||||
})
|
||||
|
||||
// If we have not moved, we should have an empty object returned
|
||||
// Return false to allow scrolling when not swiping
|
||||
return !!Object.keys(animationHandlerResponse).length
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrements the selectedItem index a number of positions through the children list
|
||||
* @param positions
|
||||
* @param fromSwipe
|
||||
*/
|
||||
decrement = (positions = 1) => {
|
||||
this.moveTo(
|
||||
this.state.selectedItem - (typeof positions === "number" ? positions : 1),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments the selectedItem index a number of positions through the children list
|
||||
* @param positions
|
||||
* @param fromSwipe
|
||||
*/
|
||||
increment = (positions = 1) => {
|
||||
this.moveTo(
|
||||
this.state.selectedItem + (typeof positions === "number" ? positions : 1),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the selected item to the position provided
|
||||
* @param position
|
||||
* @param fromSwipe
|
||||
*/
|
||||
moveTo = (position?: number) => {
|
||||
if (typeof position !== "number") {
|
||||
return
|
||||
}
|
||||
|
||||
const lastPosition = Children.count(this.props.children) - 1
|
||||
|
||||
if (position < 0) {
|
||||
position = this.props.infiniteLoop ? lastPosition : 0
|
||||
}
|
||||
|
||||
if (position > lastPosition) {
|
||||
position = this.props.infiniteLoop ? 0 : lastPosition
|
||||
}
|
||||
|
||||
this.selectItem({
|
||||
// if it's not a slider, we don't need to set position here
|
||||
selectedItem: position,
|
||||
})
|
||||
|
||||
// don't reset auto play when stop on hover is enabled, doing so will trigger a call to auto play more than once
|
||||
// and will result in the interval function not being cleared correctly.
|
||||
if (this.state.autoPlay && this.state.isMouseEntered === false) {
|
||||
this.resetAutoPlay()
|
||||
}
|
||||
}
|
||||
|
||||
onClickNext = () => {
|
||||
this.increment(1)
|
||||
}
|
||||
|
||||
onClickPrev = () => {
|
||||
this.decrement(1)
|
||||
}
|
||||
|
||||
onSwipeForward = () => {
|
||||
this.increment(1)
|
||||
|
||||
if (this.props.emulateTouch) {
|
||||
this.setState({ cancelClick: true })
|
||||
}
|
||||
}
|
||||
|
||||
onSwipeBackwards = () => {
|
||||
this.decrement(1)
|
||||
|
||||
if (this.props.emulateTouch) {
|
||||
this.setState({ cancelClick: true })
|
||||
}
|
||||
}
|
||||
|
||||
changeItem =
|
||||
(newIndex: number) => (e: React.MouseEvent | React.KeyboardEvent) => {
|
||||
if (!isKeyboardEvent(e) || e.key === "Enter") {
|
||||
this.moveTo(newIndex)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called when you want to 'select' a new item, or rather move to a 'selected' item
|
||||
* It also handles the onChange callback wrapper
|
||||
* @param state state object with updated selected item, and swiping bool if relevant
|
||||
*/
|
||||
selectItem = (state: Pick<CarouselState, "selectedItem" | "swiping">) => {
|
||||
// Merge in the new state while updating updating previous item
|
||||
this.setState(
|
||||
{
|
||||
previousItem: this.state.selectedItem,
|
||||
...state,
|
||||
},
|
||||
() => {
|
||||
// Run animation handler and update styles based on it
|
||||
this.setState(this.animationHandler(this.props, this.state))
|
||||
},
|
||||
)
|
||||
this.handleOnChange(
|
||||
state.selectedItem,
|
||||
Children.toArray(this.props.children)[state.selectedItem],
|
||||
)
|
||||
}
|
||||
|
||||
getInitialImage = () => {
|
||||
const selectedItem = this.props.selectedItem
|
||||
const item = this.itemsRef && this.itemsRef[selectedItem]
|
||||
const images = (item && item.getElementsByTagName("img")) || []
|
||||
return images[0]
|
||||
}
|
||||
|
||||
getVariableItemHeight = (position: number) => {
|
||||
const item = this.itemsRef && this.itemsRef[position]
|
||||
|
||||
if (this.state.hasMount && item && item.children.length) {
|
||||
const slideImages = item.children[0].getElementsByTagName("img") || []
|
||||
|
||||
if (slideImages.length > 0) {
|
||||
const image = slideImages[0]
|
||||
|
||||
if (!image.complete) {
|
||||
// if the image is still loading, the size won't be available so we trigger a new render after it's done
|
||||
const onImageLoad = () => {
|
||||
this.forceUpdate()
|
||||
image.removeEventListener("load", onImageLoad)
|
||||
}
|
||||
|
||||
image.addEventListener("load", onImageLoad)
|
||||
}
|
||||
}
|
||||
|
||||
// try to get img first, if img not there find first display tag
|
||||
const displayItem = slideImages[0] || item.children[0]
|
||||
const height = displayItem.clientHeight
|
||||
return height > 0 ? height : null
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
renderItems(isClone?: boolean) {
|
||||
if (!this.props.children) {
|
||||
return []
|
||||
}
|
||||
|
||||
return Children.map(this.props.children, (item, index) => {
|
||||
const isSelected = index === this.state.selectedItem
|
||||
const isPrevious = index === this.state.previousItem
|
||||
|
||||
let style: React.CSSProperties =
|
||||
(isSelected && this.state.selectedStyle) ||
|
||||
(isPrevious && this.state.prevStyle) ||
|
||||
this.state.slideStyle ||
|
||||
{}
|
||||
|
||||
if (this.props.centerMode && this.props.axis === "horizontal") {
|
||||
style = { ...style, minWidth: this.props.centerSlidePercentage + "%" }
|
||||
}
|
||||
|
||||
if (this.state.swiping && this.state.swipeMovementStarted) {
|
||||
style = { ...style, pointerEvents: "none" }
|
||||
}
|
||||
|
||||
const slideProps = {
|
||||
ref: (e: HTMLLIElement) => this.setItemsRef(e, index),
|
||||
key: "itemKey" + index + (isClone ? "clone" : ""),
|
||||
className: klass.ITEM(
|
||||
true,
|
||||
index === this.state.selectedItem,
|
||||
index === this.state.previousItem,
|
||||
),
|
||||
onClick: this.handleClickItem.bind(this, index, item),
|
||||
style,
|
||||
}
|
||||
|
||||
return (
|
||||
<li {...slideProps}>
|
||||
{this.props.renderItem(item, {
|
||||
isSelected: index === this.state.selectedItem,
|
||||
isPrevious: index === this.state.previousItem,
|
||||
})}
|
||||
</li>
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
renderControls() {
|
||||
const { showIndicators, labels, renderIndicator, children } = this.props
|
||||
if (!showIndicators) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<ul className="control-dots">
|
||||
{Children.map(children, (_, index) => {
|
||||
return (
|
||||
renderIndicator &&
|
||||
renderIndicator(
|
||||
this.changeItem(index),
|
||||
index === this.state.selectedItem,
|
||||
index,
|
||||
labels.item,
|
||||
)
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
|
||||
renderStatus() {
|
||||
if (!this.props.showStatus) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<p className="carousel-status">
|
||||
{this.props.statusFormatter(
|
||||
this.state.selectedItem + 1,
|
||||
Children.count(this.props.children),
|
||||
)}
|
||||
</p>
|
||||
)
|
||||
}
|
||||
|
||||
renderThumbs() {
|
||||
if (
|
||||
!this.props.showThumbs ||
|
||||
!this.props.children ||
|
||||
Children.count(this.props.children) === 0
|
||||
) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<Thumbs
|
||||
ref={this.setThumbsRef}
|
||||
onSelectItem={this.handleClickThumb}
|
||||
selectedItem={this.state.selectedItem}
|
||||
transitionTime={this.props.transitionTime}
|
||||
thumbWidth={this.props.thumbWidth}
|
||||
labels={this.props.labels}
|
||||
emulateTouch={this.props.emulateTouch}
|
||||
>
|
||||
{this.props.renderThumbs(this.props.children)}
|
||||
</Thumbs>
|
||||
)
|
||||
}
|
||||
|
||||
render() {
|
||||
if (!this.props.children || Children.count(this.props.children) === 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
const isSwipeable =
|
||||
this.props.swipeable && Children.count(this.props.children) > 1
|
||||
|
||||
const isHorizontal = this.props.axis === "horizontal"
|
||||
|
||||
const canShowArrows =
|
||||
this.props.showArrows && Children.count(this.props.children) > 1
|
||||
|
||||
// show left arrow?
|
||||
const hasPrev =
|
||||
(canShowArrows &&
|
||||
(this.state.selectedItem > 0 || this.props.infiniteLoop)) ||
|
||||
false
|
||||
// show right arrow
|
||||
const hasNext =
|
||||
(canShowArrows &&
|
||||
(this.state.selectedItem < Children.count(this.props.children) - 1 ||
|
||||
this.props.infiniteLoop)) ||
|
||||
false
|
||||
|
||||
const itemsClone = this.renderItems(true)
|
||||
const firstClone = itemsClone?.shift()
|
||||
const lastClone = itemsClone?.pop()
|
||||
|
||||
let swiperProps: SwiperProps = {
|
||||
className: klass.SLIDER(true, this.state.swiping),
|
||||
onSwipeMove: this.onSwipeMove,
|
||||
onSwipeStart: this.onSwipeStart,
|
||||
onSwipeEnd: this.onSwipeEnd,
|
||||
style: this.state.itemListStyle || {},
|
||||
tolerance: this.props.swipeScrollTolerance,
|
||||
}
|
||||
|
||||
const containerStyles: React.CSSProperties = {}
|
||||
|
||||
if (isHorizontal) {
|
||||
swiperProps.onSwipeLeft = this.onSwipeForward
|
||||
swiperProps.onSwipeRight = this.onSwipeBackwards
|
||||
|
||||
if (this.props.dynamicHeight) {
|
||||
const itemHeight = this.getVariableItemHeight(this.state.selectedItem)
|
||||
// swiperProps.style.height = itemHeight || 'auto';
|
||||
containerStyles.height = itemHeight || "auto"
|
||||
}
|
||||
} else {
|
||||
swiperProps.onSwipeUp =
|
||||
this.props.verticalSwipe === "natural"
|
||||
? this.onSwipeBackwards
|
||||
: this.onSwipeForward
|
||||
swiperProps.onSwipeDown =
|
||||
this.props.verticalSwipe === "natural"
|
||||
? this.onSwipeForward
|
||||
: this.onSwipeBackwards
|
||||
swiperProps.style = { ...swiperProps.style, height: this.state.itemSize }
|
||||
containerStyles.height = this.state.itemSize
|
||||
}
|
||||
return (
|
||||
<div
|
||||
aria-label={this.props.ariaLabel}
|
||||
className={`ar-Carousel ${klass.ROOT(this.props.className)}${
|
||||
this.props.classes ? " " + this.props.classes : ""
|
||||
}`}
|
||||
ref={this.setCarouselWrapperRef}
|
||||
tabIndex={this.props.useKeyboardArrows ? 0 : undefined}
|
||||
>
|
||||
<div
|
||||
className={klass.CAROUSEL(true)}
|
||||
style={{ width: this.props.width }}
|
||||
>
|
||||
{!this.props.noMarkers && this.renderControls()}
|
||||
{this.props.renderArrowPrev(
|
||||
this.onClickPrev,
|
||||
hasPrev,
|
||||
this.props.labels.leftArrow,
|
||||
)}
|
||||
<div
|
||||
className={klass.WRAPPER(true, this.props.axis)}
|
||||
style={containerStyles}
|
||||
>
|
||||
{isSwipeable ? (
|
||||
<Swiper
|
||||
tagName="ul"
|
||||
innerRef={this.setListRef}
|
||||
{...swiperProps}
|
||||
allowMouseEvents={this.props.emulateTouch}
|
||||
>
|
||||
{this.props.infiniteLoop && lastClone}
|
||||
{this.renderItems()}
|
||||
{this.props.infiniteLoop && firstClone}
|
||||
</Swiper>
|
||||
) : (
|
||||
<ul
|
||||
className={klass.SLIDER(true, this.state.swiping)}
|
||||
ref={(node: HTMLUListElement) => this.setListRef(node)}
|
||||
style={this.state.itemListStyle || {}}
|
||||
>
|
||||
{this.props.infiniteLoop && lastClone}
|
||||
{this.renderItems()}
|
||||
{this.props.infiniteLoop && firstClone}
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
{this.props.renderArrowNext(
|
||||
this.onClickNext,
|
||||
hasNext,
|
||||
this.props.labels.rightArrow,
|
||||
)}
|
||||
{this.renderStatus()}
|
||||
</div>
|
||||
{this.renderThumbs()}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,17 @@
|
||||
import { ArPillSizes, BasicFilterConfig, BasicFilterType } from "@armco/types"
|
||||
import { ReactNode } from "react"
|
||||
import { ArPillSizes } from "./enums"
|
||||
import { BasicFilterConfig, BasicFilterType } from "@armco/types"
|
||||
import { toCamelCase } from "@armco/utils/helper"
|
||||
import SelectionPill from "./SelectionPill"
|
||||
import "./CategoryFilter.component.scss"
|
||||
|
||||
interface CategoryFilterProps {
|
||||
export interface CategoryFilterProps {
|
||||
categoryGroups: { [key: string]: { [key: string]: Array<string> } }
|
||||
currentCategoryFilters?: { [key: string]: Array<BasicFilterConfig> }
|
||||
onFilterChange: Function
|
||||
}
|
||||
|
||||
const CategoryFilter = (props: CategoryFilterProps): JSX.Element => {
|
||||
const CategoryFilter = (props: CategoryFilterProps): ReactNode => {
|
||||
const { categoryGroups, currentCategoryFilters, onFilterChange } = props
|
||||
|
||||
const onCategorySelection = (
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
import { useState } from "react"
|
||||
import { CheckboxProps } from "@armco/types"
|
||||
import { ReactNode, useState } from "react"
|
||||
import { CheckBoxTypes, FunctionType } from "@armco/types"
|
||||
import { FormInputProps } from "./types"
|
||||
import Toggle from "./Toggle"
|
||||
import "./Checkbox.component.scss"
|
||||
|
||||
const Checkbox = (props: CheckboxProps): JSX.Element => {
|
||||
export interface CheckboxProps extends FormInputProps {
|
||||
id?: string
|
||||
label?: string
|
||||
type?: CheckBoxTypes
|
||||
onChange: FunctionType
|
||||
}
|
||||
|
||||
const Checkbox = (props: CheckboxProps): ReactNode => {
|
||||
const { classes, label, id, onChange } = props
|
||||
const [checked, setChecked] = useState<boolean>()
|
||||
const { type, ...toggleProps } = props
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
import { ReactElement, ReactNode } from "react"
|
||||
import { ChunkProps } from "@armco/types"
|
||||
import { TextFormat } from "@armco/types"
|
||||
import { BaseProps } from "./types"
|
||||
|
||||
export interface ChunkProps extends BaseProps {
|
||||
id: string
|
||||
text: string
|
||||
formats: TextFormat
|
||||
}
|
||||
|
||||
const Chunk = (props: ChunkProps): ReactNode => {
|
||||
const { id, text, formats } = props
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
import { useState } from "react"
|
||||
import { ColorPickerProps } from "@armco/types"
|
||||
import { ReactNode, useState } from "react"
|
||||
import { BaseProps } from "./types"
|
||||
import { generateRandomId } from "@armco/utils/helper"
|
||||
import "./ColorPicker.component.scss"
|
||||
|
||||
const ColorPicker = (props: ColorPickerProps): JSX.Element => {
|
||||
export interface ColorPickerProps extends BaseProps {
|
||||
id?: string
|
||||
label?: string
|
||||
onChange?: Function
|
||||
value?: string
|
||||
}
|
||||
|
||||
const ColorPicker = (props: ColorPickerProps): ReactNode => {
|
||||
const { id, label, onChange, value: externalValue } = props
|
||||
const [value, setValue] = useState<string | undefined>(externalValue)
|
||||
const idFinal = id || generateRandomId()
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
import { useState } from "react"
|
||||
import { ColorSelectorProps } from "@armco/types"
|
||||
import { ReactNode, useState } from "react"
|
||||
import { FunctionType } from "@armco/types"
|
||||
import { BaseProps } from "./types"
|
||||
import TextInput from "./TextInput"
|
||||
import "./ColorSelector.component.scss"
|
||||
|
||||
const ColorSelector = (props: ColorSelectorProps): JSX.Element => {
|
||||
export interface ColorSelectorProps extends BaseProps {
|
||||
label?: string
|
||||
onChange?: FunctionType
|
||||
withSample?: boolean
|
||||
}
|
||||
|
||||
const ColorSelector = (props: ColorSelectorProps): ReactNode => {
|
||||
const { classes, label, onChange, withSample } = props
|
||||
const [iconColor, setIconColor] = useState<string>()
|
||||
|
||||
@@ -37,16 +44,15 @@ const ColorSelector = (props: ColorSelectorProps): JSX.Element => {
|
||||
<div className="ar-ColorSelector w-100">
|
||||
{label && <div className="mb-3 fw-bold text-center">{label}</div>}
|
||||
<ul
|
||||
className={`ar-ColorSelector__list d-flex flex-column list-unstyled${
|
||||
classes ? " " + classes : ""
|
||||
}`}
|
||||
className={`ar-ColorSelector__list d-flex flex-column list-unstyled${classes ? " " + classes : ""
|
||||
}`}
|
||||
style={{ height: label ? "calc(100% - 2rem)" : "100%" }}
|
||||
>
|
||||
{selectors}
|
||||
<TextInput
|
||||
classes="ar-ColorSelector__picker"
|
||||
type="color"
|
||||
onChange={(e) => onColorChange((e.target as HTMLInputElement).value)}
|
||||
onChange={(e: any) => onColorChange((e.target as HTMLInputElement).value)}
|
||||
/>
|
||||
</ul>
|
||||
{withSample && (
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
import { Component_404Props } from "@armco/types"
|
||||
import { ReactNode } from "react"
|
||||
import { BaseProps } from "./types"
|
||||
import Icon from "@armco/icon"
|
||||
import "./Component_404.component.scss"
|
||||
|
||||
const Component_404 = (props: Component_404Props): JSX.Element => {
|
||||
export interface Component_404Props extends BaseProps {
|
||||
iconSize?: string
|
||||
}
|
||||
|
||||
|
||||
const Component_404 = (props: Component_404Props): ReactNode => {
|
||||
const { iconSize } = props
|
||||
return (
|
||||
<div className="ar-Component_404 flex-center h-100">
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React from "react"
|
||||
import { ReactNode } from "react"
|
||||
import "./Contact.component.scss"
|
||||
|
||||
interface ContactProps {}
|
||||
export interface ContactProps { }
|
||||
|
||||
const Contact = (props: any): JSX.Element => {
|
||||
const Contact = (props: ContactProps): ReactNode => {
|
||||
return (
|
||||
<div className="ar-Contact">
|
||||
In Component Contact
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { ReactNode } from "react"
|
||||
import "./Content.component.scss"
|
||||
|
||||
interface ContentProps {
|
||||
export interface ContentProps {
|
||||
children?: ReactNode
|
||||
classes?: string
|
||||
}
|
||||
|
||||
const Content = (props: ContentProps): JSX.Element => {
|
||||
const Content = (props: ContentProps): ReactNode => {
|
||||
const { children, classes } = props
|
||||
return (
|
||||
<div className={`ar-Content flex-grow-1${classes ? " " + classes : ""}`}>
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
import { useEffect, useRef, useState } from "react"
|
||||
import { ContextMenuProps } from "@armco/types"
|
||||
import { ReactNode, useEffect, useRef, useState } from "react"
|
||||
import { BaseProps } from "./types"
|
||||
import InlineMenu from "./InlineMenu"
|
||||
import "./ContextMenu.component.scss"
|
||||
|
||||
const ContextMenu = (props: ContextMenuProps): JSX.Element => {
|
||||
export interface ContextMenuProps extends BaseProps {
|
||||
children?: ReactNode
|
||||
data: { [key: string]: any }
|
||||
}
|
||||
|
||||
const ContextMenu = (props: ContextMenuProps): ReactNode => {
|
||||
const { children, classes, data, demo, style } = props
|
||||
const [clickCoordinates, setClickCoordinates] = useState<{
|
||||
[key: string]: number
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React from "react"
|
||||
import { ReactNode } from "react"
|
||||
import "./Cookies.component.scss"
|
||||
|
||||
interface CookiesProps {}
|
||||
export interface CookiesProps { }
|
||||
|
||||
const Cookies = (props: any): JSX.Element => {
|
||||
const Cookies = (props: CookiesProps): ReactNode => {
|
||||
return (
|
||||
<div className="ar-Cookies">
|
||||
In Component Cookies
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
import { ChangeEvent, useEffect, useState } from "react"
|
||||
import { CronTabProps, FunctionType } from "@armco/types"
|
||||
import { ChangeEvent, ReactNode, useEffect, useState } from "react"
|
||||
import { FunctionType, ObjectType } from "@armco/types"
|
||||
import Icon from "@armco/icon"
|
||||
import { BaseProps } from "./types"
|
||||
import TextInput from "./TextInput"
|
||||
import "./CronTab.component.scss"
|
||||
|
||||
export interface CronTabProps extends BaseProps {
|
||||
onChange: FunctionType
|
||||
value?: ObjectType | string
|
||||
}
|
||||
|
||||
const cronFields = ["min", "hour", "day", "week", "month"]
|
||||
const CronTab = (props: CronTabProps): JSX.Element => {
|
||||
const CronTab = (props: CronTabProps): ReactNode => {
|
||||
const { onChange, value } = props
|
||||
const [cronTab, setCronTab] = useState<{ [key: string]: string }>({})
|
||||
const [helpExpanded, toggleHelpExpanded] = useState<boolean>()
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React from "react"
|
||||
import { ReactNode } from "react"
|
||||
import "./Cta.component.scss"
|
||||
|
||||
interface CtaProps {}
|
||||
export interface CtaProps { }
|
||||
|
||||
const Cta = (props: any): JSX.Element => {
|
||||
const Cta = (props: CtaProps): ReactNode => {
|
||||
return (
|
||||
<div className="ar-Cta">
|
||||
In Component Cta
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import React from "react"
|
||||
import { ReactNode } from "react"
|
||||
import { BaseProps } from "./types"
|
||||
import "./Dashboard.component.scss"
|
||||
|
||||
interface DashboardProps {}
|
||||
export interface DashboardProps extends BaseProps { }
|
||||
|
||||
const Dashboard = (props: any): JSX.Element => {
|
||||
const Dashboard = (props: DashboardProps): ReactNode => {
|
||||
return (
|
||||
<div className="ar-Dashboard">
|
||||
In Component Dashboard
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
import { ReactNode } from "react"
|
||||
import { useEffect, useState } from "react"
|
||||
import { DateInputProps } from "@armco/types"
|
||||
import { FormInputProps } from "./types"
|
||||
import "./DateInput.component.scss"
|
||||
|
||||
const DateInput = (props: DateInputProps): JSX.Element => {
|
||||
export interface DateInputProps extends FormInputProps {
|
||||
placeholder?: string
|
||||
}
|
||||
|
||||
const DateInput = (props: DateInputProps): ReactNode => {
|
||||
const {
|
||||
classes,
|
||||
containerClasses,
|
||||
@@ -20,24 +25,21 @@ const DateInput = (props: DateInputProps): JSX.Element => {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`ar-DateInput${
|
||||
containerClasses ? " " + containerClasses : ""
|
||||
}`}
|
||||
className={`ar-DateInput${containerClasses ? " " + containerClasses : ""
|
||||
}`}
|
||||
>
|
||||
{label && (
|
||||
<label
|
||||
className={`ar-DateInput__label${
|
||||
labelClasses ? " " + labelClasses : ""
|
||||
}`}
|
||||
className={`ar-DateInput__label${labelClasses ? " " + labelClasses : ""
|
||||
}`}
|
||||
htmlFor={id}
|
||||
>
|
||||
{label}
|
||||
</label>
|
||||
)}
|
||||
<input
|
||||
className={`ar-DateInput__picker form-component p-2${
|
||||
classes ? " " + classes : ""
|
||||
}`}
|
||||
className={`ar-DateInput__picker form-component p-2${classes ? " " + classes : ""
|
||||
}`}
|
||||
id={id}
|
||||
onChange={(e) => setLocalValue(e.target.value)}
|
||||
placeholder={placeholder}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import { DetailsPanelProps } from "@armco/types"
|
||||
import { ReactNode } from "react"
|
||||
import { BaseProps } from "./types"
|
||||
import "./DetailsPanel.component.scss"
|
||||
|
||||
const DetailsPanel = (props: DetailsPanelProps): JSX.Element => {
|
||||
export interface DetailsPanelProps extends BaseProps { }
|
||||
|
||||
const DetailsPanel = (props: DetailsPanelProps): ReactNode => {
|
||||
return <div className="ar-DetailsPanel">In Component DetailsPanel</div>
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import { DialogProps } from "@armco/types"
|
||||
import { ReactNode } from "react"
|
||||
import { BaseProps } from "./types"
|
||||
import "./Dialog.component.scss"
|
||||
|
||||
const Dialog = (props: DialogProps): JSX.Element => {
|
||||
export interface DialogProps extends BaseProps { }
|
||||
|
||||
const Dialog = (props: DialogProps): ReactNode => {
|
||||
return <div className="ar-Dialog">In Component Dialog</div>
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import React from "react"
|
||||
import { ReactNode } from "react"
|
||||
import { BaseProps } from "./types"
|
||||
import "./Download.component.scss"
|
||||
|
||||
interface DownloadProps {}
|
||||
export interface DownloadProps extends BaseProps { }
|
||||
|
||||
const Download = (props: any): JSX.Element => {
|
||||
const Download = (props: DownloadProps): ReactNode => {
|
||||
return (
|
||||
<div className="ar-Download">
|
||||
In Component Download
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
import {
|
||||
import React, {
|
||||
Children,
|
||||
MutableRefObject,
|
||||
RefObject,
|
||||
ReactElement,
|
||||
cloneElement,
|
||||
forwardRef,
|
||||
useEffect,
|
||||
useRef,
|
||||
Ref,
|
||||
} from "react"
|
||||
import { findDOMNode } from "react-dom"
|
||||
import { useDrag } from "react-dnd"
|
||||
import { getEmptyImage } from "react-dnd-html5-backend"
|
||||
import { ArDndItemTypes, DraggableProps } from "@armco/types"
|
||||
import { ArDndItemTypes } from "./enums"
|
||||
import { BaseProps } from "./types"
|
||||
import "./Draggable.component.scss"
|
||||
|
||||
const dummyChildren = (
|
||||
@@ -19,6 +20,15 @@ const dummyChildren = (
|
||||
></div>
|
||||
)
|
||||
|
||||
|
||||
export interface DraggableProps extends BaseProps {
|
||||
itemType?: ArDndItemTypes | string
|
||||
canDrag?: boolean
|
||||
itemData?: any
|
||||
hideDefaultPreview?: boolean
|
||||
}
|
||||
|
||||
|
||||
const Draggable = forwardRef((props: DraggableProps, ref) => {
|
||||
const {
|
||||
canDrag,
|
||||
@@ -30,7 +40,8 @@ const Draggable = forwardRef((props: DraggableProps, ref) => {
|
||||
} = props
|
||||
|
||||
const localRef = useRef(null)
|
||||
ref = ref || localRef
|
||||
const dragRef = (ref || localRef) as RefObject<HTMLElement>
|
||||
|
||||
let firstChild
|
||||
if (typeof children === "string") {
|
||||
firstChild = <span>{children}</span>
|
||||
@@ -58,36 +69,67 @@ const Draggable = forwardRef((props: DraggableProps, ref) => {
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
const node = findDOMNode((ref as MutableRefObject<HTMLElement>).current)
|
||||
const node = dragRef.current
|
||||
if (node && node.nodeType === Node.ELEMENT_NODE) {
|
||||
drag(node as Element)
|
||||
}
|
||||
}, [drag])
|
||||
}, [drag, dragRef])
|
||||
|
||||
useEffect(() => {
|
||||
if (hideDefaultPreview && preview) {
|
||||
preview(getEmptyImage(), { captureDraggingState: true })
|
||||
}
|
||||
}, [hideDefaultPreview, preview])
|
||||
if (hideDefaultPreview && preview) {
|
||||
preview(getEmptyImage(), { captureDraggingState: true })
|
||||
}
|
||||
}, [hideDefaultPreview, preview])
|
||||
|
||||
const {
|
||||
style: childStyles,
|
||||
className: childClasses,
|
||||
...restProps
|
||||
} = (firstChild as ReactElement)?.props || {}
|
||||
} = (firstChild as ReactElement<any>)?.props || {}
|
||||
|
||||
// Clone the first child and attach the drag function to it
|
||||
return cloneElement(firstChild as ReactElement, {
|
||||
ref,
|
||||
style: {
|
||||
cursor: "move",
|
||||
opacity: isDragging ? 0.5 : 1,
|
||||
...(style || {}),
|
||||
...(childStyles || {}),
|
||||
},
|
||||
className: `ar-Draggable ${childClasses || ""}`.trim(),
|
||||
...(restProps || {}),
|
||||
})
|
||||
// Helper to ensure only plain style objects are merged
|
||||
function toPlainStyle(styleObj: any): { [key: string]: string } {
|
||||
if (!styleObj) return {}
|
||||
// If it's a CSSStyleDeclaration, convert to plain object
|
||||
if (typeof styleObj.getPropertyValue === 'function') {
|
||||
const plain: { [key: string]: string } = {}
|
||||
for (let i = 0; i < styleObj.length; i++) {
|
||||
const key = styleObj[i]
|
||||
plain[key] = styleObj.getPropertyValue(key)
|
||||
}
|
||||
return plain
|
||||
}
|
||||
return styleObj as { [key: string]: string }
|
||||
}
|
||||
|
||||
const isDOMElement = typeof (firstChild as any)?.type === "string"
|
||||
const mergedStyle = {
|
||||
...toPlainStyle(childStyles),
|
||||
...toPlainStyle(style),
|
||||
cursor: "move",
|
||||
opacity: isDragging ? 0.5 : 1,
|
||||
} as React.CSSProperties
|
||||
|
||||
if (isDOMElement) {
|
||||
return cloneElement(firstChild as ReactElement<any>, {
|
||||
ref: dragRef,
|
||||
style: mergedStyle,
|
||||
className: `ar-Draggable ${childClasses || ""}`.trim(),
|
||||
...(restProps || {}),
|
||||
})
|
||||
} else {
|
||||
const spanRef: Ref<HTMLSpanElement> = dragRef as Ref<HTMLSpanElement>
|
||||
return (
|
||||
<span
|
||||
ref={spanRef}
|
||||
style={mergedStyle}
|
||||
className={`ar-Draggable ${childClasses || ""}`.trim()}
|
||||
{...restProps}
|
||||
>
|
||||
{firstChild}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
export default Draggable
|
||||
|
||||
@@ -1,14 +1,23 @@
|
||||
import { useEffect, useRef } from "react"
|
||||
import { ArThemes, DrawerProps } from "@armco/types"
|
||||
import { ReactNode, useEffect, useRef } from "react"
|
||||
import { useDrawerState, useSlotted, useTheme } from "@armco/utils/hooks"
|
||||
import { isMobile as checkMobile } from "@armco/utils/helper"
|
||||
import Icon from "@armco/icon"
|
||||
import { ArThemes } from "./enums"
|
||||
import { BaseProps } from "./types"
|
||||
import "./Drawer.component.scss"
|
||||
|
||||
export interface DrawerProps extends BaseProps {
|
||||
children?: ReactNode
|
||||
collapsed?: boolean
|
||||
contentClasses?: string
|
||||
isCollapsible?: boolean
|
||||
title?: string
|
||||
}
|
||||
|
||||
const isMobile = checkMobile()
|
||||
let clickedSelf: boolean
|
||||
|
||||
const Drawer = (props: DrawerProps): JSX.Element => {
|
||||
const Drawer = (props: DrawerProps): ReactNode => {
|
||||
const { children, classes, contentClasses, isCollapsible, title } = props
|
||||
const drawerRef = useRef<HTMLDivElement>(null)
|
||||
const { drawerState, setDrawerState } = useDrawerState()
|
||||
@@ -25,11 +34,9 @@ const Drawer = (props: DrawerProps): JSX.Element => {
|
||||
|
||||
return (
|
||||
<aside
|
||||
className={`ar-Drawer overflow-auto d-flex flex-column${
|
||||
classes ? " " + classes : ""
|
||||
}${isCollapsible ? " position-relative" : ""}${
|
||||
drawerState?.collapsed ? " collapsed" : ""
|
||||
}${title ? " has-title" : ""}`}
|
||||
className={`ar-Drawer overflow-auto d-flex flex-column${classes ? " " + classes : ""
|
||||
}${isCollapsible ? " position-relative" : ""}${drawerState?.collapsed ? " collapsed" : ""
|
||||
}${title ? " has-title" : ""}`}
|
||||
tabIndex={-1}
|
||||
ref={drawerRef}
|
||||
onMouseDown={() => {
|
||||
@@ -71,9 +78,8 @@ const Drawer = (props: DrawerProps): JSX.Element => {
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
className={`ar-Drawer__content${
|
||||
contentClasses ? " " + contentClasses : ""
|
||||
}`}
|
||||
className={`ar-Drawer__content${contentClasses ? " " + contentClasses : ""
|
||||
}`}
|
||||
>
|
||||
{!drawerState?.collapsed && children}
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { ReactNode } from "react"
|
||||
import { useEffect, useState } from "react"
|
||||
import { FunctionType, OptionType, PRIMITIVES } from "@armco/types"
|
||||
import Icon from "@armco/icon"
|
||||
import {
|
||||
ArButtonVariants,
|
||||
ArDropdownVariants,
|
||||
@@ -6,11 +9,8 @@ import {
|
||||
ArPopoverPositions,
|
||||
ArPopoverSlots,
|
||||
ArThemes,
|
||||
DropdownProps,
|
||||
OptionType,
|
||||
PRIMITIVES,
|
||||
} from "@armco/types"
|
||||
import Icon from "@armco/icon"
|
||||
} from "./enums"
|
||||
import { FormInputProps } from "./types"
|
||||
import Button from "./Button"
|
||||
import List from "./List"
|
||||
import Pill from "./Pill"
|
||||
@@ -25,7 +25,28 @@ const demoOptions: Array<OptionType> = [
|
||||
{ label: "Chennai", name: "Chennai", value: "CH" },
|
||||
]
|
||||
|
||||
const Dropdown = (props: DropdownProps): JSX.Element => {
|
||||
export interface DropdownProps extends FormInputProps {
|
||||
anchorClasses?: string
|
||||
contentClasses?: string
|
||||
contentMatchAnchorWidth?: boolean
|
||||
context?: string
|
||||
hasBorder?: boolean
|
||||
hideDropdownMarker?: boolean
|
||||
id?: string
|
||||
isMultiSelect?: boolean
|
||||
label?: string
|
||||
onSelectionChanged: FunctionType
|
||||
options?: Array<OptionType>
|
||||
placeholder?: string
|
||||
selected?: Array<PRIMITIVES>
|
||||
showCheckBoxes?: boolean
|
||||
stretch?: boolean
|
||||
subtitle?: string
|
||||
variant?: ArDropdownVariants
|
||||
}
|
||||
|
||||
|
||||
const Dropdown = (props: DropdownProps): ReactNode => {
|
||||
const {
|
||||
assistiveContent,
|
||||
anchorClasses,
|
||||
@@ -166,8 +187,8 @@ const Dropdown = (props: DropdownProps): JSX.Element => {
|
||||
|
||||
const assistiveContentRender = assistiveContent ? (
|
||||
typeof assistiveContent === "object" &&
|
||||
"content" in assistiveContent &&
|
||||
"onClick" in assistiveContent ? (
|
||||
"content" in assistiveContent &&
|
||||
"onClick" in assistiveContent ? (
|
||||
<Button
|
||||
classes="mb-2 p-0 f3"
|
||||
variant={ArButtonVariants.LINK}
|
||||
@@ -201,18 +222,15 @@ const Dropdown = (props: DropdownProps): JSX.Element => {
|
||||
stretch
|
||||
>
|
||||
<span
|
||||
className={`ar-Dropdown__input-and-selections d-inline-flex cursor-pointer flex-v-center${
|
||||
anchorClasses ? " " + anchorClasses : ""
|
||||
}${stretch ? " w-100" : ""}`}
|
||||
className={`ar-Dropdown__input-and-selections d-inline-flex cursor-pointer flex-v-center${anchorClasses ? " " + anchorClasses : ""
|
||||
}${stretch ? " w-100" : ""}`}
|
||||
slot={ArPopoverSlots.ANCHOR}
|
||||
>
|
||||
{hasBorder ? (
|
||||
<span
|
||||
className={`ar-Dropdown__selection-anchor form-component p-2 d-inline-flex justify-content-between fw-bold h-100${
|
||||
!isMultiSelect && hasBorder ? " flex-center" : " flex-v-center"
|
||||
}${context === "search" ? " border-right-0" : ""}${
|
||||
stretch ? " w-100" : ""
|
||||
}`}
|
||||
className={`ar-Dropdown__selection-anchor form-component p-2 d-inline-flex justify-content-between fw-bold h-100${!isMultiSelect && hasBorder ? " flex-center" : " flex-v-center"
|
||||
}${context === "search" ? " border-right-0" : ""}${stretch ? " w-100" : ""
|
||||
}`}
|
||||
>
|
||||
{variant === ArDropdownVariants.SELECTIONSASPILLS ? (
|
||||
pillsRender
|
||||
@@ -266,9 +284,8 @@ const Dropdown = (props: DropdownProps): JSX.Element => {
|
||||
)}
|
||||
</span>
|
||||
<div
|
||||
className={`ar-Dropdown__options w-100${
|
||||
contentClasses ? " " + contentClasses : ""
|
||||
}`}
|
||||
className={`ar-Dropdown__options w-100${contentClasses ? " " + contentClasses : ""
|
||||
}`}
|
||||
slot={ArPopoverSlots.POPOVER}
|
||||
>
|
||||
<List
|
||||
@@ -277,12 +294,12 @@ const Dropdown = (props: DropdownProps): JSX.Element => {
|
||||
data={
|
||||
localOptions
|
||||
? localOptions.map((option) => ({
|
||||
label: option.label as string,
|
||||
name: option.name,
|
||||
value: option.value,
|
||||
isSelected: option.isSelected,
|
||||
onClick: onLocalChange,
|
||||
}))
|
||||
label: option.label as string,
|
||||
name: option.name,
|
||||
value: option.value,
|
||||
isSelected: option.isSelected,
|
||||
onClick: onLocalChange,
|
||||
}))
|
||||
: []
|
||||
}
|
||||
theme={theme}
|
||||
@@ -293,21 +310,17 @@ const Dropdown = (props: DropdownProps): JSX.Element => {
|
||||
|
||||
const labelRender = (
|
||||
<div
|
||||
className={`ar-TextInput__label-container${
|
||||
isLabelLR
|
||||
? ` flex-v-center${
|
||||
labelPlacement === ArPlacement.LEFT ? " me-3" : ""
|
||||
}`
|
||||
: ""
|
||||
}`}
|
||||
className={`ar-TextInput__label-container${isLabelLR
|
||||
? ` flex-v-center${labelPlacement === ArPlacement.LEFT ? " me-3" : ""
|
||||
}`
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
<div className="ar-TextInput__label-container__label-assistive-text flex-v-center justify-content-between">
|
||||
<label
|
||||
className={`ar-TextInput__label h-100 fw-bold${
|
||||
labelClasses ? " " + labelClasses : ""
|
||||
}${required ? " required" : ""}${
|
||||
subtitle || isLabelLR ? "" : " mb-2"
|
||||
}`}
|
||||
className={`ar-TextInput__label h-100 fw-bold${labelClasses ? " " + labelClasses : ""
|
||||
}${required ? " required" : ""}${subtitle || isLabelLR ? "" : " mb-2"
|
||||
}`}
|
||||
htmlFor={id}
|
||||
>
|
||||
{label}
|
||||
@@ -367,11 +380,9 @@ const Dropdown = (props: DropdownProps): JSX.Element => {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`ar-Dropdown d-inline-flex${classes ? " " + classes : ""}${
|
||||
size ? " " + size : ""
|
||||
}${variant ? " " + variant : ""}${
|
||||
isDisabled ? " disabled pointer-events-none" : ""
|
||||
} ${flexClass}`}
|
||||
className={`ar-Dropdown d-inline-flex${classes ? " " + classes : ""}${size ? " " + size : ""
|
||||
}${variant ? " " + variant : ""}${isDisabled ? " disabled pointer-events-none" : ""
|
||||
} ${flexClass}`}
|
||||
id={id}
|
||||
>
|
||||
{contentRender}
|
||||
|
||||
@@ -1,18 +1,27 @@
|
||||
import { findDOMNode } from "react-dom"
|
||||
import {
|
||||
Children,
|
||||
cloneElement,
|
||||
ForwardedRef,
|
||||
forwardRef,
|
||||
MutableRefObject,
|
||||
isValidElement,
|
||||
ReactElement,
|
||||
useEffect,
|
||||
useRef,
|
||||
RefObject,
|
||||
} from "react"
|
||||
import { useDrop } from "react-dnd"
|
||||
import { ArDndItemTypes, DroppableProps } from "@armco/types"
|
||||
import { FunctionType } from "@armco/types"
|
||||
import { ArDndItemTypes } from "./enums"
|
||||
import { BaseProps } from "./types"
|
||||
import "./Droppable.component.scss"
|
||||
|
||||
export interface DroppableProps extends BaseProps {
|
||||
acceptTypes?: ArDndItemTypes | string | Array<string | ArDndItemTypes>
|
||||
dropHandler: FunctionType
|
||||
canDrop?: FunctionType
|
||||
hideHoverEffect?: boolean
|
||||
}
|
||||
|
||||
const Droppable = forwardRef(
|
||||
(props: DroppableProps, ref: ForwardedRef<HTMLElement>) => {
|
||||
const {
|
||||
@@ -23,8 +32,8 @@ const Droppable = forwardRef(
|
||||
hideHoverEffect,
|
||||
style,
|
||||
} = props
|
||||
const localRef = useRef(null)
|
||||
ref = ref || localRef
|
||||
const localRef = useRef<HTMLElement | null>(null)
|
||||
const dropRef = (ref as RefObject<HTMLElement>) || localRef
|
||||
// Convert children to an array and use the first child
|
||||
const childrenArray = Children.toArray(children)
|
||||
const firstChild = childrenArray[0]
|
||||
@@ -50,33 +59,47 @@ const Droppable = forwardRef(
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
const node = findDOMNode((ref as MutableRefObject<HTMLElement>).current)
|
||||
const node = dropRef.current
|
||||
if (node && node.nodeType === Node.ELEMENT_NODE) {
|
||||
drop(node as Element)
|
||||
}
|
||||
}, [drop])
|
||||
}, [drop, dropRef])
|
||||
|
||||
const {
|
||||
style: childStyles,
|
||||
className: childClasses,
|
||||
...restProps
|
||||
} = (firstChild as ReactElement)?.props || {}
|
||||
|
||||
// Clone the first child and attach the drop function to it
|
||||
return firstChild
|
||||
? cloneElement(firstChild as ReactElement, {
|
||||
ref,
|
||||
style: {
|
||||
...(style || {}),
|
||||
...(childStyles || {}),
|
||||
},
|
||||
className: `ar-Droppable ${childClasses || ""} ${
|
||||
isOver ? "drag-over" : ""
|
||||
}${hideHoverEffect ? " hide-hover-effect" : ""}`.trim(),
|
||||
onDragOver: (e: any) => e.preventDefault(),
|
||||
...(restProps || {}),
|
||||
})
|
||||
: null
|
||||
let childProps: any = {}
|
||||
let childStyles = {}
|
||||
let childClasses = ""
|
||||
let restProps = {}
|
||||
if (
|
||||
isValidElement(firstChild) &&
|
||||
typeof (firstChild as any).type === "string"
|
||||
) {
|
||||
const {
|
||||
style: cs,
|
||||
className: cc,
|
||||
...rest
|
||||
} = (firstChild as ReactElement<any>).props || {}
|
||||
childStyles = cs || {}
|
||||
childClasses = cc || ""
|
||||
restProps = rest
|
||||
childProps = {
|
||||
ref: dropRef,
|
||||
style: {
|
||||
...(style || {}),
|
||||
...childStyles,
|
||||
},
|
||||
className: `ar-Droppable ${childClasses} ${isOver ? "drag-over" : ""}${hideHoverEffect ? " hide-hover-effect" : ""}`.trim(),
|
||||
onDragOver: (e: any) => e.preventDefault(),
|
||||
...restProps,
|
||||
}
|
||||
} else if (isValidElement(firstChild)) {
|
||||
// For non-DOM elements, only pass restProps and onDragOver
|
||||
const { ...rest } = (firstChild as ReactElement<any>).props || {}
|
||||
childProps = {
|
||||
onDragOver: (e: any) => e.preventDefault(),
|
||||
...rest,
|
||||
}
|
||||
}
|
||||
return firstChild ? cloneElement(firstChild as ReactElement, childProps) : null
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -1,20 +1,29 @@
|
||||
/* eslint-disable react/jsx-pascal-case */
|
||||
import { lazy, ReactNode, Suspense, useEffect, useState } from "react"
|
||||
import { NativeTypes } from "react-dnd-html5-backend"
|
||||
import { FunctionType, ObjectType, TreeListData } from "@armco/types"
|
||||
import Icon from "@armco/icon"
|
||||
import {
|
||||
ArContentTypes,
|
||||
ArDndItemTypes,
|
||||
ArLoaderTypes,
|
||||
DroppableContainerProps,
|
||||
TreeListData,
|
||||
} from "@armco/types"
|
||||
import Icon from "@armco/icon"
|
||||
} from "./enums"
|
||||
import { BaseProps } from "./types"
|
||||
import Loader from "./Loader"
|
||||
import Droppable from "./Droppable"
|
||||
import Component_404 from "./Component_404"
|
||||
import "./DroppableContainer.component.scss"
|
||||
|
||||
const DroppableContainer = (props: DroppableContainerProps): JSX.Element => {
|
||||
export interface DroppableContainerProps extends BaseProps {
|
||||
allowedDropCount?: number
|
||||
dropHandler?: FunctionType
|
||||
placeholder?: ReactNode
|
||||
placeholderProps?: ObjectType
|
||||
placeholderType?: ArContentTypes
|
||||
}
|
||||
|
||||
|
||||
const DroppableContainer = (props: DroppableContainerProps): ReactNode => {
|
||||
const {
|
||||
allowedDropCount = 1,
|
||||
classes,
|
||||
@@ -111,9 +120,8 @@ const DroppableContainer = (props: DroppableContainerProps): JSX.Element => {
|
||||
dropHandler={dropHandler}
|
||||
>
|
||||
<div
|
||||
className={`ar-DroppableContainer${classes ? " " + classes : ""}${
|
||||
children ? "" : " bg border"
|
||||
}`}
|
||||
className={`ar-DroppableContainer${classes ? " " + classes : ""}${children ? "" : " bg border"
|
||||
}`}
|
||||
style={{
|
||||
minWidth: children ? "auto" : "10rem",
|
||||
minHeight: children ? "auto" : "10rem",
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import React from "react"
|
||||
import { ReactNode } from "react"
|
||||
import { BaseProps } from "./types"
|
||||
import "./EcommOrders.component.scss"
|
||||
|
||||
interface EcommOrdersProps {}
|
||||
export interface EcommOrdersProps extends BaseProps { }
|
||||
|
||||
const EcommOrders = (props: any): JSX.Element => {
|
||||
const EcommOrders = (props: any): ReactNode => {
|
||||
return <div className="ar-EcommOrders">In Component EcommOrders</div>
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import React from "react"
|
||||
import { ReactNode } from "react"
|
||||
import { BaseProps } from "./types"
|
||||
import "./EcommProducts.component.scss"
|
||||
|
||||
interface EcommProductsProps {}
|
||||
export interface EcommProductsProps extends BaseProps { }
|
||||
|
||||
const EcommProducts = (props: any): JSX.Element => {
|
||||
const EcommProducts = (props: any): ReactNode => {
|
||||
return <div className="ar-EcommProducts">In Component EcommProducts</div>
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
import React from "react"
|
||||
import { ReactNode } from "react"
|
||||
import { BaseProps } from "./types"
|
||||
import "./Empty.component.scss"
|
||||
|
||||
interface EmptyProps {}
|
||||
|
||||
const Empty = (props: any): JSX.Element => {
|
||||
export interface EmptyProps extends BaseProps { }
|
||||
/**
|
||||
* Component to display empty content message, like empty cart or no data available.
|
||||
*
|
||||
* @param props
|
||||
* @returns
|
||||
*/
|
||||
const Empty = (props: any): ReactNode => {
|
||||
return <div className="ar-Empty">In Component Empty</div>
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { Component, ErrorInfo, ReactNode } from "react"
|
||||
import Icon from "@armco/icon"
|
||||
import { BaseProps } from "./types"
|
||||
import "./ErrorBoundary.component.scss"
|
||||
|
||||
interface ErrorBoundaryProps {
|
||||
export interface ErrorBoundaryProps extends BaseProps {
|
||||
children?: ReactNode
|
||||
}
|
||||
|
||||
@@ -26,7 +27,7 @@ class ErrorBoundary extends Component<ErrorBoundaryProps, State> {
|
||||
public render() {
|
||||
if (this.state.hasError) {
|
||||
return (
|
||||
<div className="ar-ErrorBoundary h-100 flex-center flex-1">
|
||||
<div className={`ar-ErrorBoundary h-100 flex-center flex-1${this.props.classes ? " " + this.props.classes : ""}`}>
|
||||
<div className="ar-ErrorBoundary__container text-center p-5">
|
||||
<Icon
|
||||
icon="md/MdSmsFailed"
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
import { FacetedFilterProps } from "@armco/types"
|
||||
import { ReactNode } from "react"
|
||||
import { BaseProps } from "./types"
|
||||
import "./FacetedFilter.component.scss"
|
||||
|
||||
const FacetedFilter = (props: FacetedFilterProps): JSX.Element => {
|
||||
return <div className="ar-FacetedFilter">In Component FacetedFilter</div>
|
||||
export interface FacetedFilterProps extends BaseProps { }
|
||||
|
||||
const FacetedFilter = (props: FacetedFilterProps): ReactNode => {
|
||||
const { classes } = props
|
||||
return <div className={`ar-FacetedFilter${classes ? " " + classes : ""}`}>In Component FacetedFilter</div>
|
||||
}
|
||||
|
||||
export default FacetedFilter
|
||||
|
||||
10
src/Faq.tsx
10
src/Faq.tsx
@@ -1,10 +1,12 @@
|
||||
import React from "react"
|
||||
import { ReactNode } from "react"
|
||||
import { BaseProps } from "./types"
|
||||
import "./Faq.component.scss"
|
||||
|
||||
interface FaqProps {}
|
||||
export interface FaqProps extends BaseProps { }
|
||||
|
||||
const Faq = (props: any): JSX.Element => {
|
||||
return <div className="ar-Faq">In Component Faq</div>
|
||||
const Faq = (props: FaqProps): ReactNode => {
|
||||
const { classes } = props
|
||||
return <div className={`ar-Faq${classes ? " " + classes : ""}`}>In Component Faq</div>
|
||||
}
|
||||
|
||||
export default Faq
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import React from "react"
|
||||
import { ReactNode } from "react"
|
||||
import { BaseProps } from "./types"
|
||||
import "./Features.component.scss"
|
||||
|
||||
interface FeaturesProps {}
|
||||
export interface FeaturesProps extends BaseProps { }
|
||||
|
||||
const Features = (props: any): JSX.Element => {
|
||||
return <div className="ar-Features">In Component Features</div>
|
||||
const Features = (props: FeaturesProps): ReactNode => {
|
||||
const { classes } = props
|
||||
return <div className={`ar-Features${classes ? " " + classes : ""}`}>In Component Features</div>
|
||||
}
|
||||
|
||||
export default Features
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import { useState } from "react"
|
||||
import { ReactNode, useState } from "react"
|
||||
import {
|
||||
BasicFilterConfig,
|
||||
BasicFilterType,
|
||||
FilterConfig,
|
||||
FilterState,
|
||||
FiltersProps,
|
||||
PillProps,
|
||||
FunctionType,
|
||||
} from "@armco/types"
|
||||
import { generateSlices, generateCategories } from "@armco/utils/helper"
|
||||
import { PillProps } from "./Pill"
|
||||
import { BaseProps } from "./types"
|
||||
import AlphabetFilter from "./AlphabetFilter"
|
||||
import CategoryFilter from "./CategoryFilter"
|
||||
import Dropdown from "./Dropdown"
|
||||
@@ -14,7 +16,16 @@ import Pillbox from "./Pillbox"
|
||||
import Tags from "./Tags"
|
||||
import "./Filters.component.scss"
|
||||
|
||||
const Filters = (props: FiltersProps): JSX.Element => {
|
||||
export interface FiltersProps extends BaseProps {
|
||||
clickHandler: FunctionType
|
||||
data?: Array<any>
|
||||
filteredData?: Array<any>
|
||||
config: FilterConfig
|
||||
initialFilters?: FilterState
|
||||
onFilterChange: Function
|
||||
}
|
||||
|
||||
const Filters = (props: FiltersProps): ReactNode => {
|
||||
const {
|
||||
config,
|
||||
clickHandler,
|
||||
@@ -61,8 +72,8 @@ const Filters = (props: FiltersProps): JSX.Element => {
|
||||
} else if (filterType === "categories") {
|
||||
const catFilter:
|
||||
| {
|
||||
[key: string]: Array<BasicFilterConfig>
|
||||
}
|
||||
[key: string]: Array<BasicFilterConfig>
|
||||
}
|
||||
| undefined =
|
||||
filters &&
|
||||
(filters[filterType] as {
|
||||
@@ -168,8 +179,8 @@ const Filters = (props: FiltersProps): JSX.Element => {
|
||||
currentCategoryFilters={
|
||||
filters && filters.categories
|
||||
? (filters.categories as {
|
||||
[key: string]: Array<BasicFilterConfig>
|
||||
})
|
||||
[key: string]: Array<BasicFilterConfig>
|
||||
})
|
||||
: {}
|
||||
}
|
||||
/>
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
import { ReactNode } from "react"
|
||||
import { useEffect } from "react"
|
||||
import { useNavigate } from "react-router-dom"
|
||||
import { FunctionType } from "@armco/types"
|
||||
import { useTheme } from "@armco/utils/hooks"
|
||||
import { isMobile as checkMobile } from "@armco/utils/helper"
|
||||
import NAVIGATOR from "@armco/configs/navigator"
|
||||
import Icon from "@armco/icon"
|
||||
import {
|
||||
ArAnimations,
|
||||
ArLoginProviders,
|
||||
ArPopoverSlots,
|
||||
ArTabType,
|
||||
ArThemes,
|
||||
FlexToolsProps,
|
||||
TabBarProps,
|
||||
TabProps,
|
||||
} from "@armco/types"
|
||||
import { useTheme } from "@armco/utils/hooks"
|
||||
import { isMobile as checkMobile } from "@armco/utils/helper"
|
||||
import NAVIGATOR from "@armco/configs/navigator"
|
||||
import Icon from "@armco/icon"
|
||||
} from "./enums"
|
||||
import { BaseProps } from "./types"
|
||||
import { TabBarProps } from "./TabBar"
|
||||
import { TabProps } from "./Tab"
|
||||
import AppAndToolsSelector from "./AppAndToolsSelector"
|
||||
import Popover from "./Popover"
|
||||
import TabBar from "./TabBar"
|
||||
@@ -27,8 +29,16 @@ const userOptions = [
|
||||
|
||||
const isMobile = checkMobile()
|
||||
|
||||
const FlexTools = (props: FlexToolsProps): JSX.Element => {
|
||||
const { isLanding, route, hideAppLogo, onLogout } = props
|
||||
export interface FlexToolsProps extends BaseProps {
|
||||
isLanding?: boolean
|
||||
route?: string
|
||||
hideAppLogo?: boolean
|
||||
onLogout?: FunctionType
|
||||
}
|
||||
|
||||
|
||||
const FlexTools = (props: FlexToolsProps): ReactNode => {
|
||||
const { classes, isLanding, route, hideAppLogo, onLogout } = props
|
||||
const { theme } = useTheme()
|
||||
const navigate = useNavigate()
|
||||
|
||||
@@ -91,9 +101,8 @@ const FlexTools = (props: FlexToolsProps): JSX.Element => {
|
||||
)
|
||||
return (
|
||||
<div
|
||||
className={`ar-FlexTools h-100 w-100 ${
|
||||
hideAppLogo ? "flex-v-center justify-content-end" : "flex-center"
|
||||
}`}
|
||||
className={`ar-FlexTools h-100 w-100 ${classes ? " " + classes : ""} ${hideAppLogo ? "flex-v-center justify-content-end" : "flex-center"
|
||||
}`}
|
||||
>
|
||||
{!isMobile ? (
|
||||
<>
|
||||
@@ -103,9 +112,8 @@ const FlexTools = (props: FlexToolsProps): JSX.Element => {
|
||||
</>
|
||||
) : (
|
||||
<div
|
||||
className={`w-100${
|
||||
hideAppLogo ? " d-flex justify-content-end" : " row"
|
||||
}`}
|
||||
className={`w-100${hideAppLogo ? " d-flex justify-content-end" : " row"
|
||||
}`}
|
||||
>
|
||||
{!hideAppLogo && (
|
||||
<div className="col flex-center" onClick={() => navigate("/")}>
|
||||
@@ -117,9 +125,8 @@ const FlexTools = (props: FlexToolsProps): JSX.Element => {
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
className={`ar-FlexTools__app-selector flex-center${
|
||||
hideAppLogo ? "" : " col"
|
||||
}`}
|
||||
className={`ar-FlexTools__app-selector flex-center${hideAppLogo ? "" : " col"
|
||||
}`}
|
||||
>
|
||||
{appSelector}
|
||||
</div>
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
import { ArThemes, FooterProps } from "@armco/types"
|
||||
import { ReactNode } from "react"
|
||||
import { FunctionType } from "@armco/types"
|
||||
import { useSlotted, useTheme } from "@armco/utils/hooks"
|
||||
import { isMobile as checkMobile } from "@armco/utils/helper"
|
||||
import Icon from "@armco/icon"
|
||||
import { ArThemes } from "./enums"
|
||||
import { BaseProps } from "./types"
|
||||
import FlexTools from "./FlexTools"
|
||||
import "./Footer.component.scss"
|
||||
|
||||
const isMobile = checkMobile()
|
||||
|
||||
const Footer = ({ onThemeToggle }: FooterProps): JSX.Element => {
|
||||
export interface FooterProps extends BaseProps {
|
||||
onThemeToggle?: FunctionType
|
||||
}
|
||||
|
||||
const Footer = ({ onThemeToggle }: FooterProps): ReactNode => {
|
||||
const { theme, setTheme } = useTheme()
|
||||
useSlotted("Footer")
|
||||
|
||||
|
||||
10
src/Form.tsx
10
src/Form.tsx
@@ -1,10 +1,12 @@
|
||||
import React from "react"
|
||||
import { ReactNode } from "react"
|
||||
import { BaseProps } from "./types"
|
||||
import "./Form.component.scss"
|
||||
|
||||
interface FormProps {}
|
||||
export interface FormProps extends BaseProps { }
|
||||
|
||||
const Form = (props: any): JSX.Element => {
|
||||
return <div className="ar-Form">In Component Form</div>
|
||||
const Form = (props: FormProps): ReactNode => {
|
||||
const { classes } = props
|
||||
return <div className={`ar-Form${classes ? " " + classes : ""}`}>In Component Form</div>
|
||||
}
|
||||
|
||||
export default Form
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import React from "react"
|
||||
import { ReactNode } from "react"
|
||||
import { BaseProps } from "./types"
|
||||
import "./Gallery.component.scss"
|
||||
|
||||
interface GalleryProps {}
|
||||
export interface GalleryProps extends BaseProps { }
|
||||
|
||||
const Gallery = (props: any): JSX.Element => {
|
||||
return <div className="ar-Gallery">In Component Gallery</div>
|
||||
const Gallery = (props: GalleryProps): ReactNode => {
|
||||
const { classes } = props
|
||||
return <div className={`ar-Gallery${classes ? " " + classes : ""}`}>In Component Gallery</div>
|
||||
}
|
||||
|
||||
export default Gallery
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import React from "react"
|
||||
import { ReactNode } from "react"
|
||||
import { BaseProps } from "./types"
|
||||
import "./Graph.component.scss"
|
||||
|
||||
interface GraphProps {}
|
||||
export interface GraphProps extends BaseProps { }
|
||||
|
||||
const Graph = (props: any): JSX.Element => {
|
||||
return <div className="ar-Graph">In Component Graph</div>
|
||||
const Graph = (props: GraphProps): ReactNode => {
|
||||
const { classes } = props
|
||||
return <div className={`ar-Graph${classes ? " " + classes : ""}`}>In Component Graph</div>
|
||||
}
|
||||
|
||||
export default Graph
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import React from "react"
|
||||
import { ReactNode } from "react"
|
||||
import { BaseProps } from "./types"
|
||||
import "./GraphTiles.component.scss"
|
||||
|
||||
interface GraphTilesProps {}
|
||||
export interface GraphTilesProps extends BaseProps { }
|
||||
|
||||
const GraphTiles = (props: any): JSX.Element => {
|
||||
return <div className="ar-GraphTiles">In Component GraphTiles</div>
|
||||
const GraphTiles = (props: GraphTilesProps): ReactNode => {
|
||||
const { classes } = props
|
||||
return <div className={`ar-GraphTiles${classes ? " " + classes : ""}`}>In Component GraphTiles</div>
|
||||
}
|
||||
|
||||
export default GraphTiles
|
||||
|
||||
@@ -1,22 +1,43 @@
|
||||
import { Children } from "react"
|
||||
import { ArHeaderSlots, HeaderProps } from "@armco/types"
|
||||
import { Children, ReactNode } from "react"
|
||||
import { useSlotted } from "@armco/utils/hooks"
|
||||
import { ArHeaderSlots } from "./enums"
|
||||
import { BaseProps } from "./types"
|
||||
import "./Header.component.scss"
|
||||
|
||||
const Header = (props: HeaderProps): JSX.Element => {
|
||||
export interface HeaderProps extends BaseProps {
|
||||
isFluid?: boolean
|
||||
isSticky?: boolean
|
||||
children?: ReactNode
|
||||
order?: Array<ArHeaderSlots>
|
||||
}
|
||||
|
||||
const Header = (props: HeaderProps): ReactNode => {
|
||||
const { classes, isFluid, children, order } = props
|
||||
const childItems: { [key: string]: JSX.Element } = {}
|
||||
const shuffledItems: Array<JSX.Element> = []
|
||||
const childItems: Record<string, ReactNode> = {}
|
||||
const shuffledItems: ReactNode[] = []
|
||||
useSlotted("Header")
|
||||
|
||||
children &&
|
||||
Children.forEach(children, (child: JSX.Element | null) => {
|
||||
if (child?.props?.slot) {
|
||||
childItems[child.props.slot as keyof object] = child
|
||||
if (children) {
|
||||
Children.forEach(children, (child) => {
|
||||
if (
|
||||
typeof child === "object" &&
|
||||
child !== null &&
|
||||
"props" in child &&
|
||||
child.props &&
|
||||
typeof child.props === "object" &&
|
||||
child.props !== null &&
|
||||
Object.prototype.hasOwnProperty.call(child.props, "slot")
|
||||
) {
|
||||
childItems[String((child.props as { slot?: string | number }).slot)] = child
|
||||
}
|
||||
})
|
||||
}
|
||||
if (order) {
|
||||
order.forEach((slot) => shuffledItems.push(childItems[slot]))
|
||||
order.forEach((slot) => {
|
||||
if (childItems[slot]) {
|
||||
shuffledItems.push(childItems[slot])
|
||||
}
|
||||
})
|
||||
}
|
||||
return (
|
||||
<header className={`ar-Header w-100${classes ? " " + classes : ""}`}>
|
||||
|
||||
10
src/Hero.tsx
10
src/Hero.tsx
@@ -1,9 +1,13 @@
|
||||
import { ArButtonVariants, ArThemes, HeroProps } from "@armco/types"
|
||||
import Button from "./Button"
|
||||
import { ReactNode } from "react"
|
||||
import { useSlotted } from "@armco/utils/hooks"
|
||||
import { ArButtonVariants, ArThemes } from "./enums"
|
||||
import { BaseProps } from "./types"
|
||||
import Button from "./Button"
|
||||
import "./Hero.component.scss"
|
||||
|
||||
const Hero = (props: HeroProps): JSX.Element => {
|
||||
export interface HeroProps extends BaseProps { }
|
||||
|
||||
const Hero = (props: HeroProps): ReactNode => {
|
||||
const { classes, theme } = props
|
||||
useSlotted("Hero")
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import React from "react"
|
||||
import { ReactNode } from "react"
|
||||
import { BaseProps } from "./types"
|
||||
import "./HowItWorks.component.scss"
|
||||
|
||||
interface HowItWorksProps {}
|
||||
export interface HowItWorksProps extends BaseProps { }
|
||||
|
||||
const HowItWorks = (props: any): JSX.Element => {
|
||||
return <div className="ar-HowItWorks">In Component HowItWorks</div>
|
||||
const HowItWorks = (props: HowItWorksProps): ReactNode => {
|
||||
const { classes } = props
|
||||
return <div className={`ar-HowItWorks${classes ? " " + classes : ""}`}>In Component HowItWorks</div>
|
||||
}
|
||||
|
||||
export default HowItWorks
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import React from "react"
|
||||
import { ReactNode } from "react"
|
||||
import { BaseProps } from "./types"
|
||||
import "./HttpCode.component.scss"
|
||||
|
||||
interface HttpCodeProps {}
|
||||
export interface HttpCodeProps extends BaseProps { }
|
||||
|
||||
const HttpCode = (props: any): JSX.Element => {
|
||||
return <div className="ar-HttpCode">In Component HttpCode</div>
|
||||
const HttpCode = (props: HttpCodeProps): ReactNode => {
|
||||
const { classes } = props
|
||||
return <div className={`ar-HttpCode${classes ? " " + classes : ""}`}>In Component HttpCode</div>
|
||||
}
|
||||
|
||||
export default HttpCode
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { CSSProperties, ForwardedRef, forwardRef } from "react"
|
||||
import { ImageProps } from "@armco/types"
|
||||
import { CSSProperties, ForwardedRef, forwardRef, ReactNode } from "react"
|
||||
import { BaseProps } from "./types"
|
||||
import "./Image.component.scss"
|
||||
|
||||
const getDomainFromUrl = (url: string) => {
|
||||
@@ -16,8 +16,29 @@ const determineCrossOrigin = (url: string) => {
|
||||
return "anonymous"
|
||||
}
|
||||
|
||||
export interface ImageProps extends BaseProps {
|
||||
image: string
|
||||
alt?: string
|
||||
title?: string
|
||||
fill?: boolean
|
||||
preserveAspectRatio?: boolean
|
||||
flipHorizontal?: boolean
|
||||
flipVertical?: boolean
|
||||
rotateBy?: number
|
||||
opacity?: number
|
||||
brightness?: number
|
||||
contrast?: number
|
||||
saturate?: number
|
||||
scale?: number
|
||||
blur?: number
|
||||
grayscale?: number
|
||||
sepia?: number
|
||||
isBackground?: boolean
|
||||
customBgZIndex?: number
|
||||
}
|
||||
|
||||
const Image = forwardRef(
|
||||
(props: ImageProps, ref: ForwardedRef<HTMLImageElement>): JSX.Element => {
|
||||
(props: ImageProps, ref: ForwardedRef<HTMLImageElement>): ReactNode => {
|
||||
const {
|
||||
alt,
|
||||
blur,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useEffect, useState } from "react"
|
||||
import { InlineMenuProps } from "@armco/types"
|
||||
import { ReactNode, Ref, useEffect, useState } from "react"
|
||||
import { BaseProps } from "./types"
|
||||
import List from "./List"
|
||||
import "./InlineMenu.component.scss"
|
||||
|
||||
@@ -10,7 +10,14 @@ const dummyData = {
|
||||
Suspend: {},
|
||||
}
|
||||
|
||||
const InlineMenu = (props: InlineMenuProps): JSX.Element => {
|
||||
export interface InlineMenuProps extends BaseProps {
|
||||
data: { [key: string]: any }
|
||||
top?: number
|
||||
left?: number
|
||||
ref?: Ref<HTMLDivElement>
|
||||
}
|
||||
|
||||
const InlineMenu = (props: InlineMenuProps): ReactNode => {
|
||||
const { classes, data, demo, ref, top, left, theme } = props
|
||||
const [displayed, show] = useState<boolean>()
|
||||
|
||||
@@ -22,9 +29,8 @@ const InlineMenu = (props: InlineMenuProps): JSX.Element => {
|
||||
const finalData = data || (demo && dummyData)
|
||||
return (
|
||||
<div
|
||||
className={`ar-InlineMenu${classes ? " " + classes : ""}${
|
||||
displayed ? " show px-1 py-2" : ""
|
||||
}`}
|
||||
className={`ar-InlineMenu${classes ? " " + classes : ""}${displayed ? " show px-1 py-2" : ""
|
||||
}`}
|
||||
style={{ top, left }}
|
||||
ref={ref}
|
||||
>
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import React from "react"
|
||||
import { ReactNode } from "react"
|
||||
import { BaseProps } from "./types"
|
||||
import "./InstaPhotos.component.scss"
|
||||
|
||||
interface InstaPhotosProps {}
|
||||
export interface InstaPhotosProps extends BaseProps { }
|
||||
|
||||
const InstaPhotos = (props: any): JSX.Element => {
|
||||
return <div className="ar-InstaPhotos">In Component InstaPhotos</div>
|
||||
const InstaPhotos = (props: InstaPhotosProps): ReactNode => {
|
||||
const { classes } = props
|
||||
return <div className={`ar-InstaPhotos${classes ? " " + classes : ""}`}>In Component InstaPhotos</div>
|
||||
}
|
||||
|
||||
export default InstaPhotos
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import React from "react"
|
||||
import { ReactNode } from "react"
|
||||
import { BaseProps } from "./types"
|
||||
import "./Integrations.component.scss"
|
||||
|
||||
interface IntegrationsProps {}
|
||||
export interface IntegrationsProps extends BaseProps { }
|
||||
|
||||
const Integrations = (props: any): JSX.Element => {
|
||||
return <div className="ar-Integrations">In Component Integrations</div>
|
||||
const Integrations = (props: IntegrationsProps): ReactNode => {
|
||||
const { classes } = props
|
||||
return <div className={`ar-Integrations${classes ? " " + classes : ""}`}>In Component Integrations</div>
|
||||
}
|
||||
|
||||
export default Integrations
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
import { LabelProps } from "@armco/types"
|
||||
import { ReactNode } from "react"
|
||||
import { BaseProps } from "./types"
|
||||
import "./Label.component.scss"
|
||||
|
||||
const Label = (props: LabelProps): JSX.Element => {
|
||||
export interface LabelProps extends BaseProps {
|
||||
htmlFor?: string
|
||||
label: string
|
||||
}
|
||||
|
||||
const Label = (props: LabelProps): ReactNode => {
|
||||
const { htmlFor, label, style, classes } = props
|
||||
return (
|
||||
<label
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
import { LabelValueProps, ArLabelValueVariants } from "@armco/types"
|
||||
import { ReactNode } from "react"
|
||||
import { ArLabelValueVariants } from "./enums"
|
||||
import { BaseProps } from "./types"
|
||||
import "./LabelValue.component.scss"
|
||||
|
||||
const LabelValue = (props: LabelValueProps): JSX.Element => {
|
||||
export interface LabelValueProps extends BaseProps {
|
||||
label?: string
|
||||
value?: string
|
||||
variant?: ArLabelValueVariants
|
||||
}
|
||||
|
||||
const LabelValue = (props: LabelValueProps): ReactNode => {
|
||||
const { classes, label, value, variant, demo } = props
|
||||
const useLabel = label ? label : demo ? "First Name" : ""
|
||||
const useValue = value !== undefined ? value : demo ? "SRK" : ""
|
||||
@@ -16,15 +24,13 @@ const LabelValue = (props: LabelValueProps): JSX.Element => {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`ar-LabelValue d-inline-flex border-radius l2 overflow-hidden${
|
||||
isLeftLabel ? " flex-v-center" : " flex-column"
|
||||
}${isBoxed ? " p-2 border" : ""} mb-2${classes ? " " + classes : ""}`}
|
||||
className={`ar-LabelValue d-inline-flex border-radius l2 overflow-hidden${isLeftLabel ? " flex-v-center" : " flex-column"
|
||||
}${isBoxed ? " p-2 border" : ""} mb-2${classes ? " " + classes : ""}`}
|
||||
>
|
||||
{useLabel && (
|
||||
<span
|
||||
className={`ar-LabelValue__label fw-bold d-inline-block${
|
||||
isLeftLabel ? " me-3" : " mb-2"
|
||||
}`}
|
||||
className={`ar-LabelValue__label fw-bold d-inline-block${isLeftLabel ? " me-3" : " mb-2"
|
||||
}`}
|
||||
>
|
||||
{useLabel}
|
||||
</span>
|
||||
|
||||
@@ -1,14 +1,32 @@
|
||||
import { CSSProperties, Children, cloneElement } from "react"
|
||||
import { CSSProperties, Children, cloneElement, ReactNode } from "react"
|
||||
import { useSlotted } from "@armco/utils/hooks"
|
||||
import { WebPageLayout } from "@armco/configs/constants"
|
||||
import {
|
||||
ArComponentLevels,
|
||||
ArLayoutSlots,
|
||||
ArWebPageLayout,
|
||||
LayoutGeneratorProps,
|
||||
} from "@armco/types"
|
||||
import { useSlotted } from "@armco/utils/hooks"
|
||||
import { WebPageLayout } from "@armco/configs/constants"
|
||||
} from "./enums"
|
||||
import { BaseProps } from "./types"
|
||||
import "./LayoutGenerator.component.scss"
|
||||
|
||||
|
||||
export interface LayoutGeneratorProps extends BaseProps {
|
||||
children?: ReactNode
|
||||
cardSize?: string
|
||||
demoChildCount?: number
|
||||
drawerLevel?: ArComponentLevels
|
||||
gridSize?: string
|
||||
hasHeader?: boolean
|
||||
hasFooter?: boolean
|
||||
hasDrawer?: boolean
|
||||
hasSidepanel?: boolean
|
||||
isFooterFixed?: boolean
|
||||
selectable?: boolean
|
||||
sidepanelLevel?: ArComponentLevels
|
||||
variant?: ArWebPageLayout
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
const getDummies = (count: number) => {
|
||||
return Array(count)
|
||||
.fill(null)
|
||||
@@ -16,35 +34,45 @@ const getDummies = (count: number) => {
|
||||
}
|
||||
|
||||
const cloneAndStyleElement = (
|
||||
element: JSX.Element | null,
|
||||
element: ReactNode | null,
|
||||
slot: ArLayoutSlots,
|
||||
children?: Array<JSX.Element>,
|
||||
children?: Array<ReactNode>,
|
||||
style?: CSSProperties,
|
||||
demo?: boolean,
|
||||
) => {
|
||||
if (element) {
|
||||
if (
|
||||
element &&
|
||||
typeof element === "object" &&
|
||||
element !== null &&
|
||||
"props" in element &&
|
||||
(element as any).props &&
|
||||
typeof (element as any).type === "string"
|
||||
) {
|
||||
children?.splice(children.indexOf(element), 1)
|
||||
return cloneElement(element, {
|
||||
className: demo
|
||||
? `border border-radius l2 m-05 p-1 ${element.props.className || ""}${
|
||||
slot === ArLayoutSlots.HEADER || slot === ArLayoutSlots.FOOTER
|
||||
? " mih-2"
|
||||
: ""
|
||||
}${
|
||||
slot === ArLayoutSlots.DRAWER || slot === ArLayoutSlots.SIDEPANEL
|
||||
? " miw-2"
|
||||
: ""
|
||||
}`
|
||||
: element.props.className,
|
||||
style,
|
||||
slot,
|
||||
})
|
||||
const elProps = (element as { props: any }).props
|
||||
const newProps: any = {}
|
||||
if ('className' in elProps) {
|
||||
newProps.className = demo
|
||||
? `border border-radius l2 m-05 p-1 ${elProps.className || ""}${slot === ArLayoutSlots.HEADER || slot === ArLayoutSlots.FOOTER
|
||||
? " mih-2"
|
||||
: ""
|
||||
}${slot === ArLayoutSlots.DRAWER || slot === ArLayoutSlots.SIDEPANEL
|
||||
? " miw-2"
|
||||
: ""
|
||||
}`
|
||||
: elProps.className
|
||||
}
|
||||
if ('style' in elProps) {
|
||||
newProps.style = style
|
||||
}
|
||||
newProps.slot = slot
|
||||
return cloneElement(element as React.ReactElement, newProps)
|
||||
}
|
||||
return null
|
||||
return element
|
||||
}
|
||||
|
||||
const getSlots = (args: {
|
||||
children?: Array<JSX.Element>
|
||||
children?: Array<ReactNode>
|
||||
demo?: boolean
|
||||
drawerLevel?: ArComponentLevels
|
||||
hasDrawer?: boolean
|
||||
@@ -63,35 +91,44 @@ const getSlots = (args: {
|
||||
hasSidepanel,
|
||||
// sidepanelLevel,
|
||||
} = args
|
||||
const slots: { [key: string]: JSX.Element | null } = {
|
||||
const slots: Record<string, ReactNode | null> = {
|
||||
header: null,
|
||||
footer: null,
|
||||
drawer: null,
|
||||
sidepanel: null,
|
||||
}
|
||||
Children.forEach(children, (child) => {
|
||||
child?.props?.slot && (slots[child.props.slot] = child)
|
||||
if (
|
||||
typeof child === "object" &&
|
||||
child !== null &&
|
||||
"props" in child &&
|
||||
(child as any).props &&
|
||||
Object.prototype.hasOwnProperty.call((child as any).props, "slot")
|
||||
) {
|
||||
const slotKey = String((child as { props: any }).props.slot)
|
||||
slots[slotKey] = child
|
||||
}
|
||||
})
|
||||
|
||||
if (!slots.header && hasHeader) {
|
||||
slots.header = (children as Array<JSX.Element>)[0]
|
||||
slots.header = (children as Array<ReactNode>)[0]
|
||||
}
|
||||
|
||||
if (!slots.footer && hasFooter) {
|
||||
slots.footer = (children as Array<JSX.Element>)[
|
||||
(children as Array<JSX.Element>).length - 1
|
||||
slots.footer = (children as Array<ReactNode>)[
|
||||
(children as Array<ReactNode>).length - 1
|
||||
]
|
||||
}
|
||||
|
||||
// TODO: wrong child item calculated currently, good for phase 1, change in phase 2 when
|
||||
// drawer and sidepanel can be at a higher level like header and footer
|
||||
if (!slots.drawer && hasDrawer) {
|
||||
slots.drawer = (children as Array<JSX.Element>)[1]
|
||||
slots.drawer = (children as Array<ReactNode>)[1]
|
||||
}
|
||||
|
||||
if (!slots.sidepanel && hasSidepanel) {
|
||||
slots.sidepanel = (children as Array<JSX.Element>)[
|
||||
(children as Array<JSX.Element>).length - 2
|
||||
slots.sidepanel = (children as Array<ReactNode>)[
|
||||
(children as Array<ReactNode>).length - 2
|
||||
]
|
||||
}
|
||||
|
||||
@@ -252,35 +289,45 @@ const LayoutGenerator = ({
|
||||
childStyle = {}
|
||||
}
|
||||
|
||||
return (
|
||||
if (
|
||||
child &&
|
||||
cloneElement(child, {
|
||||
className: demo
|
||||
? `border ${
|
||||
header ||
|
||||
footer ||
|
||||
(variant !== ArWebPageLayout.FULL &&
|
||||
variant !== ArWebPageLayout.CAROUSEL)
|
||||
? "border-radius l2 m-05 p-1"
|
||||
: ""
|
||||
} ${child.props.className || ""}`
|
||||
: child.props.className,
|
||||
style: childStyle,
|
||||
})
|
||||
)
|
||||
typeof child === "object" &&
|
||||
child !== null &&
|
||||
"props" in child &&
|
||||
(child as any).props &&
|
||||
typeof (child as any).type === "string"
|
||||
) {
|
||||
const elProps = (child as { props: any }).props
|
||||
const newProps: any = {}
|
||||
if ('className' in elProps) {
|
||||
newProps.className = demo
|
||||
? `border ${header ||
|
||||
footer ||
|
||||
(variant !== ArWebPageLayout.FULL &&
|
||||
variant !== ArWebPageLayout.CAROUSEL)
|
||||
? "border-radius l2 m-05 p-1"
|
||||
: ""
|
||||
} ${elProps.className || ""}`
|
||||
: elProps.className
|
||||
}
|
||||
if ('style' in elProps) {
|
||||
newProps.style = childStyle
|
||||
}
|
||||
return cloneElement(child as React.ReactElement, newProps)
|
||||
}
|
||||
return child
|
||||
})
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`ar-LayoutGenerator d-grid${selectable ? "" : " h-100 w-100"}${
|
||||
hasContainerGrid ? " header-main-footer-layout" : ""
|
||||
}${demo ? " bg" : ""}${classes ? " " + classes : ""}`}
|
||||
className={`ar-LayoutGenerator d-grid${selectable ? "" : " h-100 w-100"}${hasContainerGrid ? " header-main-footer-layout" : ""
|
||||
}${demo ? " bg" : ""}${classes ? " " + classes : ""}`}
|
||||
style={
|
||||
hasContainerGrid
|
||||
? { gridTemplateRows }
|
||||
: hasSecondaryGrid
|
||||
? { gridTemplateColumns }
|
||||
: style
|
||||
? { gridTemplateColumns }
|
||||
: style
|
||||
}
|
||||
>
|
||||
{hasContainerGrid ? (
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
import { LearnLinkProps } from "@armco/types"
|
||||
import { ReactNode } from "react"
|
||||
import { BaseProps } from "./types"
|
||||
import "./LearnLink.component.scss"
|
||||
|
||||
const LearnLink = (props: LearnLinkProps): JSX.Element => {
|
||||
return <div className="ar-LearnLink">In Component LearnLink</div>
|
||||
export interface LearnLinkProps extends BaseProps { }
|
||||
|
||||
const LearnLink = (props: LearnLinkProps): ReactNode => {
|
||||
const { classes } = props
|
||||
return <div className={`ar-LearnLink${classes ? " " + classes : ""}`}>In Component LearnLink</div>
|
||||
}
|
||||
|
||||
export default LearnLink
|
||||
|
||||
22
src/Link.tsx
22
src/Link.tsx
@@ -1,8 +1,26 @@
|
||||
import { MouseEventHandler, ReactNode } from "react"
|
||||
import { useNavigate } from "react-router-dom"
|
||||
import { LinkProps } from "@armco/types"
|
||||
import { BaseProps } from "./types"
|
||||
import "./Link.component.scss"
|
||||
|
||||
const Link = (props: LinkProps): JSX.Element => {
|
||||
interface LinkBaseProps extends BaseProps {
|
||||
to: string
|
||||
onClick?: MouseEventHandler
|
||||
openInNew?: boolean
|
||||
preemptNavigation?: boolean
|
||||
}
|
||||
interface LinkLabelProps extends LinkBaseProps {
|
||||
label: string
|
||||
}
|
||||
|
||||
interface LinkChildrenProps extends LinkBaseProps {
|
||||
children: ReactNode
|
||||
}
|
||||
export type LinkProps =
|
||||
| (LinkLabelProps & Partial<LinkChildrenProps>)
|
||||
| (Partial<LinkLabelProps> & LinkChildrenProps)
|
||||
|
||||
const Link = (props: LinkProps): ReactNode => {
|
||||
const {
|
||||
classes,
|
||||
label,
|
||||
|
||||
27
src/List.tsx
27
src/List.tsx
@@ -1,6 +1,9 @@
|
||||
import { ReactNode } from "react"
|
||||
import { useEffect, useState } from "react"
|
||||
import { v4 as uuid } from "uuid"
|
||||
import { ArListStyles, ListItemContent, ListProps } from "@armco/types"
|
||||
import { FunctionType, ListActionItem, ListItemContent } from "@armco/types"
|
||||
import { BaseProps } from "./types"
|
||||
import { ArListVariants, ArListStyles } from "./enums"
|
||||
import ListItem from "./ListItem"
|
||||
import "./List.component.scss"
|
||||
|
||||
@@ -12,7 +15,22 @@ const dummyData = [
|
||||
{ name: "+ Upload Icon" },
|
||||
]
|
||||
|
||||
const List = (props: ListProps): JSX.Element => {
|
||||
export interface ListProps extends BaseProps {
|
||||
actions?: Array<ListActionItem>
|
||||
data: Array<ListItemContent>
|
||||
invertBg?: boolean
|
||||
isRaw?: boolean
|
||||
isMultiSelect?: boolean
|
||||
itemClasses?: string
|
||||
itemRenderer?: FunctionType
|
||||
itemVariant?: "soft" | "dynamic"
|
||||
onItemClick?: FunctionType
|
||||
showCheckBoxes?: boolean
|
||||
variant?: ArListVariants
|
||||
}
|
||||
|
||||
|
||||
const List = (props: ListProps): ReactNode => {
|
||||
const {
|
||||
actions,
|
||||
isRaw,
|
||||
@@ -83,9 +101,8 @@ const List = (props: ListProps): JSX.Element => {
|
||||
getListItem(item, "" + index),
|
||||
)
|
||||
|
||||
const commonClasses = `ar-List mb-0${invertBg ? " invert-bg" : '"'} ${
|
||||
classes ? " " + classes : ""
|
||||
}${isRaw ? " is-raw" : ""}${showCheckBoxes ? " with-check-boxes" : ""}`
|
||||
const commonClasses = `ar-List mb-0${invertBg ? " invert-bg" : '"'} ${classes ? " " + classes : ""
|
||||
}${isRaw ? " is-raw" : ""}${showCheckBoxes ? " with-check-boxes" : ""}`
|
||||
|
||||
switch (style) {
|
||||
case ArListStyles.ORDERED as string:
|
||||
|
||||
@@ -1,18 +1,40 @@
|
||||
import { memo, useEffect, useState } from "react"
|
||||
import {
|
||||
ArButtonVariants,
|
||||
ArListVariants,
|
||||
ArSizes,
|
||||
ArThemes,
|
||||
FunctionType,
|
||||
ListItemProps,
|
||||
ListActionItem,
|
||||
ListItemContent,
|
||||
ObjectType,
|
||||
} from "@armco/types"
|
||||
import { search } from "@armco/utils/helper"
|
||||
import { useTheme } from "@armco/utils/hooks"
|
||||
import Icon from "@armco/icon"
|
||||
import {
|
||||
ArButtonVariants,
|
||||
ArListVariants,
|
||||
ArSizes,
|
||||
ArThemes,
|
||||
} from "./enums"
|
||||
import { BaseProps } from "./types"
|
||||
import Button from "./Button"
|
||||
|
||||
export interface ListItemProps extends BaseProps {
|
||||
actions?: Array<ListActionItem>
|
||||
index: string
|
||||
isMultiSelect?: boolean
|
||||
isRaw?: boolean
|
||||
item: ListItemContent
|
||||
items: Array<ListItemContent>
|
||||
itemClasses?: string
|
||||
itemRenderer?: FunctionType
|
||||
itemVariant?: "soft" | "dynamic"
|
||||
onClick?: FunctionType
|
||||
selected?: ListItemContent
|
||||
setItems: FunctionType
|
||||
setSelected: FunctionType
|
||||
showCheckBoxes?: boolean
|
||||
variant?: ArListVariants
|
||||
}
|
||||
|
||||
const ListItem = memo((props: ListItemProps) => {
|
||||
const {
|
||||
actions,
|
||||
@@ -46,19 +68,17 @@ const ListItem = memo((props: ListItemProps) => {
|
||||
) : (
|
||||
<li
|
||||
key={"list-item-" + index}
|
||||
className={`ar-List__item mb-0 px-1 flex-v-center${
|
||||
itemClasses ? " " + itemClasses : ""
|
||||
}${isRaw ? "" : " cursor-pointer"}${
|
||||
(
|
||||
className={`ar-List__item mb-0 px-1 flex-v-center${itemClasses ? " " + itemClasses : ""
|
||||
}${isRaw ? "" : " cursor-pointer"}${(
|
||||
isMultiSelect
|
||||
? isSelected
|
||||
: !Array.isArray(selected) &&
|
||||
!Array.isArray(item) &&
|
||||
(selected?.uid || selected?.name || selected?.label) === (uid || name || label)
|
||||
!Array.isArray(item) &&
|
||||
(selected?.uid || selected?.name || selected?.label) === (uid || name || label)
|
||||
)
|
||||
? " is-selected"
|
||||
: ""
|
||||
} ${variant} ${itemVariant}`}
|
||||
} ${variant} ${itemVariant}`}
|
||||
onClick={() => {
|
||||
if (!isRaw) {
|
||||
setLocalSelected(!isSelected)
|
||||
@@ -96,8 +116,8 @@ const ListItem = memo((props: ListItemProps) => {
|
||||
: "io.IoIosRadioButtonOff"
|
||||
: (item.uid || item.name || item.label) ===
|
||||
(selected?.uid || selected?.name || selected?.label)
|
||||
? "io.IoIosRadioButtonOn"
|
||||
: "io.IoIosRadioButtonOff"
|
||||
? "io.IoIosRadioButtonOn"
|
||||
: "io.IoIosRadioButtonOff"
|
||||
: ""
|
||||
}
|
||||
attributes={{
|
||||
@@ -139,9 +159,8 @@ const ListItem = memo((props: ListItemProps) => {
|
||||
<div className="ms-auto border-left ps-2">
|
||||
{actions?.map((actionItem, index) => (
|
||||
<Icon
|
||||
key={`list-action-item-${
|
||||
!Array.isArray(item) ? uid || label || name : ""
|
||||
}-${index}`}
|
||||
key={`list-action-item-${!Array.isArray(item) ? uid || label || name : ""
|
||||
}-${index}`}
|
||||
icon={actionItem.icon}
|
||||
attributes={{
|
||||
colors: {
|
||||
|
||||
@@ -1,10 +1,23 @@
|
||||
import { ArIconSourceTypes, ArLoaderTypes, LoaderProps } from "@armco/types"
|
||||
import ProgressIndicator from "./ProgressIndicator"
|
||||
import { ReactNode } from "react"
|
||||
import Icon from "@armco/icon"
|
||||
import ProgressIndicator, { ProgressIndicatorProps } from "./ProgressIndicator"
|
||||
import { BaseProps } from "./types"
|
||||
import { ArProgress, ArSizes, ArIconSourceTypes, ArLoaderTypes } from "./enums"
|
||||
import "./Loader.component.scss"
|
||||
|
||||
export interface LoaderProps extends BaseProps {
|
||||
barVariant?: ProgressIndicatorProps["variant"]
|
||||
type?: ArLoaderTypes
|
||||
size?: ArSizes
|
||||
label?: string
|
||||
icon?: string
|
||||
progress?: number
|
||||
rightEndContent?: ReactNode
|
||||
status?: ArProgress
|
||||
}
|
||||
|
||||
// Add ability to provide custom loader: an icon or image that rotates
|
||||
const Loader = (props: LoaderProps): JSX.Element => {
|
||||
const Loader = (props: LoaderProps): ReactNode => {
|
||||
const {
|
||||
barVariant,
|
||||
classes,
|
||||
@@ -83,16 +96,13 @@ const Loader = (props: LoaderProps): JSX.Element => {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`position-absolute ar-Loader top-0 start-0 h-100 w-100${
|
||||
classes ? " " + classes : ""
|
||||
}`}
|
||||
className={`position-absolute ar-Loader top-0 start-0 h-100 w-100${classes ? " " + classes : ""
|
||||
}`}
|
||||
>
|
||||
<div
|
||||
className={`ar-Loader-content flex-center w-100 h-100${
|
||||
type ? " " + type : ""
|
||||
}${size ? " " + size : ""}${
|
||||
type !== ArLoaderTypes.SHAPES ? " flex-column" : ""
|
||||
}`}
|
||||
className={`ar-Loader-content flex-center w-100 h-100${type ? " " + type : ""
|
||||
}${size ? " " + size : ""}${type !== ArLoaderTypes.SHAPES ? " flex-column" : ""
|
||||
}`}
|
||||
>
|
||||
{loaderContent}
|
||||
</div>
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
import { ArButtonVariants, ArSizes, LoginProviderProps } from "@armco/types"
|
||||
import { ReactNode } from "react"
|
||||
import { IAMCLIENT } from "@armco/configs/endpoints"
|
||||
import { usePanelContent } from "@armco/utils/hooks"
|
||||
import { BaseProps } from "./types"
|
||||
import { ArButtonVariants, ArSizes } from "./enums"
|
||||
import Button from "./Button"
|
||||
import "./LoginProvider.component.scss"
|
||||
|
||||
const LoginProvider = (props: LoginProviderProps): JSX.Element => {
|
||||
export interface LoginProviderProps extends BaseProps {
|
||||
url?: string
|
||||
}
|
||||
|
||||
const LoginProvider = (props: LoginProviderProps): ReactNode => {
|
||||
const { url } = props
|
||||
const { setPanelContent: setRightPanelContent } = usePanelContent(false)
|
||||
return (
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import React from "react"
|
||||
import { ReactNode } from "react"
|
||||
import { BaseProps } from "./types"
|
||||
import "./LogoClouds.component.scss"
|
||||
|
||||
interface LogoCloudsProps {}
|
||||
export interface LogoCloudsProps extends BaseProps { }
|
||||
|
||||
const LogoClouds = (props: any): JSX.Element => {
|
||||
return <div className="ar-LogoClouds">In Component LogoClouds</div>
|
||||
const LogoClouds = (props: LogoCloudsProps): ReactNode => {
|
||||
const { classes } = props
|
||||
return <div className={`ar-LogoClouds${classes ? " " + classes : ""}`}>In Component LogoClouds</div>
|
||||
}
|
||||
|
||||
export default LogoClouds
|
||||
|
||||
33
src/Main.tsx
33
src/Main.tsx
@@ -1,12 +1,31 @@
|
||||
import { ArPlacement, MainProps } from "@armco/types"
|
||||
import { ReactNode } from "react"
|
||||
import { ObjectType } from "@armco/types"
|
||||
import { usePanelContent } from "@armco/utils/hooks"
|
||||
import { BaseProps } from "./types"
|
||||
import { ArPlacement } from "./enums"
|
||||
import ErrorBoundary from "./ErrorBoundary"
|
||||
import SidePanel from "./SidePanel"
|
||||
import Content from "./Content"
|
||||
import Drawer from "./Drawer"
|
||||
import "./Main.component.scss"
|
||||
|
||||
const Main = (props: MainProps): JSX.Element => {
|
||||
export interface MainProps extends BaseProps {
|
||||
contentClasses?: string
|
||||
drawerContent?: ReactNode | false
|
||||
drawerTitle?: string
|
||||
mainContent?: ReactNode | false
|
||||
hideSidepanelCloseButton?: boolean
|
||||
rightPanelContent?:
|
||||
| { name?: string; component?: ReactNode; props?: ObjectType }
|
||||
| false
|
||||
leftPanelContent?:
|
||||
| { name?: string; component?: ReactNode; props?: ObjectType }
|
||||
| false
|
||||
rightPanelHeader?: ReactNode
|
||||
leftPanelHeader?: ReactNode
|
||||
}
|
||||
|
||||
const Main = (props: MainProps): ReactNode => {
|
||||
const {
|
||||
classes,
|
||||
contentClasses,
|
||||
@@ -23,9 +42,8 @@ const Main = (props: MainProps): JSX.Element => {
|
||||
|
||||
return (
|
||||
<main
|
||||
className={`ar-Main d-flex flex-grow-1 w-100${
|
||||
classes ? " " + classes : ""
|
||||
}`}
|
||||
className={`ar-Main d-flex flex-grow-1 w-100${classes ? " " + classes : ""
|
||||
}`}
|
||||
>
|
||||
{drawerContent && (
|
||||
<Drawer
|
||||
@@ -51,9 +69,8 @@ const Main = (props: MainProps): JSX.Element => {
|
||||
/>
|
||||
<ErrorBoundary>
|
||||
<Content
|
||||
classes={`flex-center position-relative overflow-auto${
|
||||
contentClasses ? " " + contentClasses : ""
|
||||
}`}
|
||||
classes={`flex-center position-relative overflow-auto${contentClasses ? " " + contentClasses : ""
|
||||
}`}
|
||||
>
|
||||
{mainContent}
|
||||
</Content>
|
||||
|
||||
10
src/Mask.tsx
10
src/Mask.tsx
@@ -1,8 +1,12 @@
|
||||
import { MaskProps } from "@armco/types"
|
||||
import { ReactNode } from "react"
|
||||
import { BaseProps } from "./types"
|
||||
import "./Mask.component.scss"
|
||||
|
||||
const Mask = (props: MaskProps): JSX.Element => {
|
||||
return <div className="ar-Mask">In Component Mask</div>
|
||||
export interface MaskProps extends BaseProps { }
|
||||
|
||||
const Mask = (props: MaskProps): ReactNode => {
|
||||
const { classes } = props
|
||||
return <div className={`ar-Mask${classes ? " " + classes : ""}`}>In Component Mask</div>
|
||||
}
|
||||
|
||||
export default Mask
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { useState } from "react"
|
||||
import { ListItemContent } from "@armco/types"
|
||||
import Icon from "@armco/icon"
|
||||
import { BaseProps } from "./types"
|
||||
import {
|
||||
ArAnimations,
|
||||
ArButtonVariants,
|
||||
@@ -7,13 +10,10 @@ import {
|
||||
ArPopoverTriggers,
|
||||
ArSizes,
|
||||
ArThemes,
|
||||
ListItemContent,
|
||||
MenuButtonProps,
|
||||
} from "@armco/types"
|
||||
import Icon from "@armco/icon"
|
||||
} from "./enums"
|
||||
import List from "./List"
|
||||
import Popover from "./Popover"
|
||||
import Button from "./Button"
|
||||
import Button, { ButtonProps } from "./Button"
|
||||
import "./Button.component.scss"
|
||||
|
||||
const demoSplitOptions: Array<ListItemContent> = [
|
||||
@@ -22,6 +22,14 @@ const demoSplitOptions: Array<ListItemContent> = [
|
||||
{ name: "Publish" },
|
||||
]
|
||||
|
||||
export interface MenuButtonProps extends BaseProps {
|
||||
buttonProps?: ButtonProps
|
||||
splitButtonClasses?: string
|
||||
splitOptions?: Array<ListItemContent>
|
||||
splitPopoverVersion?: string
|
||||
splitTrigger?: ArPopoverTriggers
|
||||
}
|
||||
|
||||
const MenuButton = (props: MenuButtonProps) => {
|
||||
const {
|
||||
buttonProps,
|
||||
@@ -62,8 +70,8 @@ const MenuButton = (props: MenuButtonProps) => {
|
||||
? "black"
|
||||
: "white"
|
||||
: theme === ArThemes.DARK1
|
||||
? "white"
|
||||
: "#3232d8"
|
||||
? "white"
|
||||
: "#3232d8"
|
||||
} else {
|
||||
setColor = "white"
|
||||
}
|
||||
@@ -92,16 +100,15 @@ const MenuButton = (props: MenuButtonProps) => {
|
||||
splitPopoverVersion
|
||||
? ArPopoverPositions.AUTO
|
||||
: hasButton
|
||||
? ArPopoverPositions.BOTTOMLEFT
|
||||
: ArPopoverPositions.BOTTOMCENTER
|
||||
? ArPopoverPositions.BOTTOMLEFT
|
||||
: ArPopoverPositions.BOTTOMCENTER
|
||||
}
|
||||
disabled={disabled}
|
||||
hideMarker
|
||||
>
|
||||
<button
|
||||
className={`ar-Button ar-Button__split px-1${
|
||||
splitButtonClasses ? " " + splitButtonClasses : ""
|
||||
}${variant ? " ar-" + variant : ""}${size ? " ar-" + size : ""}`}
|
||||
className={`ar-Button ar-Button__split px-1${splitButtonClasses ? " " + splitButtonClasses : ""
|
||||
}${variant ? " ar-" + variant : ""}${size ? " ar-" + size : ""}`}
|
||||
type="button"
|
||||
title="Extra Button Options"
|
||||
slot={ArPopoverSlots.ANCHOR}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { ReactNode, useCallback, useEffect, useRef, useState } from "react"
|
||||
import { ArButtonVariants, ArSizes, ModalProps, ObjectType } from "@armco/types"
|
||||
import { FunctionType, ObjectType } from "@armco/types"
|
||||
import { useSlotted } from "@armco/utils/hooks"
|
||||
import Icon from "@armco/icon"
|
||||
import { BaseProps } from "./types"
|
||||
import { ArButtonVariants, ArSizes } from "./enums"
|
||||
import Button from "./Button"
|
||||
import Portal from "./Portal"
|
||||
|
||||
import "./Modal.component.scss"
|
||||
|
||||
const dummyBody = (
|
||||
@@ -20,6 +21,25 @@ const dummyBody = (
|
||||
</div>
|
||||
)
|
||||
|
||||
export interface ModalProps extends BaseProps {
|
||||
body?: ReactNode
|
||||
closeHandler?: FunctionType
|
||||
content?: ReactNode
|
||||
contentClasses?: string
|
||||
footer?: ReactNode
|
||||
header?: ReactNode
|
||||
hideClose?: boolean
|
||||
isSticky?: boolean
|
||||
modalClasses?: string
|
||||
primaryButtonLabel?: string
|
||||
primaryHandler?: FunctionType
|
||||
secondaryButtonLabel?: string
|
||||
shouldScale?: boolean
|
||||
shouldFadeIn?: boolean
|
||||
show?: boolean
|
||||
}
|
||||
|
||||
|
||||
const Modal = (props: ModalProps): ReactNode => {
|
||||
const {
|
||||
body,
|
||||
@@ -76,10 +96,10 @@ const Modal = (props: ModalProps): ReactNode => {
|
||||
}
|
||||
}
|
||||
}
|
||||
;(modalRoot.current as HTMLElement).addEventListener(
|
||||
"keydown",
|
||||
escCallback,
|
||||
)
|
||||
; (modalRoot.current as HTMLElement).addEventListener(
|
||||
"keydown",
|
||||
escCallback,
|
||||
)
|
||||
}
|
||||
}, 10)
|
||||
}, [modalRoot, closeModal, isSticky])
|
||||
@@ -98,15 +118,13 @@ const Modal = (props: ModalProps): ReactNode => {
|
||||
|
||||
return show ? (
|
||||
<Portal
|
||||
classes={`position-fixed top-0 left-0 w-100 h-100 modal-container ${
|
||||
isDisplayed ? "z-2000" : "invisible"
|
||||
}${classes ? " " + classes : ""}`}
|
||||
classes={`position-fixed top-0 left-0 w-100 h-100 modal-container ${isDisplayed ? "z-2000" : "invisible"
|
||||
}${classes ? " " + classes : ""}`}
|
||||
demo={demo}
|
||||
>
|
||||
<div
|
||||
className={`ar-Modal w-100 h-100${
|
||||
onBlurCloseAttempted ? " stubborn-effect" : ""
|
||||
}${modalClasses ? " " + modalClasses : ""}`}
|
||||
className={`ar-Modal w-100 h-100${onBlurCloseAttempted ? " stubborn-effect" : ""
|
||||
}${modalClasses ? " " + modalClasses : ""}`}
|
||||
ref={modalRoot}
|
||||
tabIndex={-1} // Needed for escape to work
|
||||
onClick={() => {
|
||||
@@ -121,11 +139,9 @@ const Modal = (props: ModalProps): ReactNode => {
|
||||
<div className="ar-Modal__backdrop w-100 h-100 flex-center">
|
||||
<div
|
||||
ref={contentRef}
|
||||
className={`ar-Modal__floating-box d-flex position-relative h-100 overflow-hidden${
|
||||
shouldScale ? " should-scale" : ""
|
||||
}${shouldFadeIn ? " should-fade-in" : ""}${
|
||||
scaleUp ? " scale-up" : ""
|
||||
}${fadeIn ? " fade-in" : ""}`}
|
||||
className={`ar-Modal__floating-box d-flex position-relative h-100 overflow-hidden${shouldScale ? " should-scale" : ""
|
||||
}${shouldFadeIn ? " should-fade-in" : ""}${scaleUp ? " scale-up" : ""
|
||||
}${fadeIn ? " fade-in" : ""}`}
|
||||
tabIndex={-1}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
@@ -143,9 +159,8 @@ const Modal = (props: ModalProps): ReactNode => {
|
||||
content
|
||||
) : (
|
||||
<div
|
||||
className={`ar-Modal__content border d-flex flex-1 flex-column overflow-auto${
|
||||
contentClasses ? " " + contentClasses : ""
|
||||
}`}
|
||||
className={`ar-Modal__content border d-flex flex-1 flex-column overflow-auto${contentClasses ? " " + contentClasses : ""
|
||||
}`}
|
||||
>
|
||||
{header ? (
|
||||
typeof header === "string" ? (
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import React from "react"
|
||||
import { ReactNode } from "react"
|
||||
import { BaseProps } from "./types"
|
||||
import "./Newsletter.component.scss"
|
||||
|
||||
interface NewsletterProps {}
|
||||
export interface NewsletterProps extends BaseProps { }
|
||||
|
||||
const Newsletter = (props: any): JSX.Element => {
|
||||
return <div className="ar-Newsletter">In Component Newsletter</div>
|
||||
const Newsletter = (props: NewsletterProps): ReactNode => {
|
||||
const { classes } = props
|
||||
return <div className={`ar-Newsletter${classes ? " " + classes : ""}`}>In Component Newsletter</div>
|
||||
}
|
||||
|
||||
export default Newsletter
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
import { NotificationProps } from "@armco/types"
|
||||
import { ReactNode } from "react"
|
||||
import type { BaseProps } from "./types"
|
||||
import "./Notification.component.scss"
|
||||
|
||||
const Notification = (props: NotificationProps): JSX.Element => {
|
||||
return <div className="ar-Notification">In Component Notification</div>
|
||||
export interface NotificationProps extends BaseProps { }
|
||||
|
||||
const Notification = (props: NotificationProps): ReactNode => {
|
||||
const { classes } = props
|
||||
return <div className={`ar-Notification${classes ? " " + classes : ""}`}>In Component Notification</div>
|
||||
}
|
||||
|
||||
export default Notification
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
.ar-Notifications {
|
||||
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
import React from "react"
|
||||
import "./Notifications.component.scss"
|
||||
|
||||
interface NotificationsProps {}
|
||||
|
||||
const Notifications = (props: any): JSX.Element => {
|
||||
return <div className="ar-Notifications">In Component Notifications</div>
|
||||
}
|
||||
|
||||
export default Notifications
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user