@heliosgraphics/ui 2.0.0-alpha.95 → 2.0.0-alpha.96
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/Alert/Alert.tsx +2 -0
- package/components/Breadcrumb/Breadcrumb.tsx +17 -1
- package/components/Browser/Browser.tsx +2 -0
- package/components/Button/Button.tsx +7 -3
- package/components/ButtonGroup/ButtonGroup.tsx +2 -0
- package/components/Checkbox/Checkbox.tsx +66 -55
- package/components/Clock/Clock.tsx +23 -19
- package/components/Column/Column.tsx +2 -0
- package/components/Confirm/Confirm.tsx +2 -0
- package/components/DatePicker/DatePicker.meta.ts +12 -5
- package/components/DatePicker/DatePicker.module.css +70 -1
- package/components/DatePicker/DatePicker.tsx +116 -4
- package/components/DatePicker/DatePicker.types.ts +6 -1
- package/components/DatePicker/DatePicker.utils.ts +53 -0
- package/components/Debug/Debug.tsx +2 -0
- package/components/Details/Details.tsx +2 -0
- package/components/Dialog/Dialog.module.css +4 -6
- package/components/Dialog/Dialog.tsx +25 -16
- package/components/Donut/Donut.tsx +2 -0
- package/components/Dot/Dot.tsx +2 -0
- package/components/Dropdown/Dropdown.module.css +5 -0
- package/components/Dropdown/Dropdown.tsx +21 -26
- package/components/Fieldset/Fieldset.tsx +2 -0
- package/components/Flex/Flex.meta.ts +1 -0
- package/components/Flex/Flex.tsx +22 -2
- package/components/Flex/Flex.types.ts +1 -0
- package/components/Flex/Flex.utils.spec.ts +4 -1
- package/components/Flex/Flex.utils.ts +4 -1
- package/components/Grid/Grid.tsx +2 -0
- package/components/Heading/Heading.meta.ts +5 -0
- package/components/Heading/Heading.tsx +15 -9
- package/components/Heading/Heading.types.ts +1 -0
- package/components/Heading/components/H0/H0.tsx +2 -0
- package/components/Heading/components/H1/H1.tsx +2 -0
- package/components/Heading/components/H2/H2.tsx +2 -0
- package/components/Heading/components/H3/H3.tsx +2 -0
- package/components/Heading/components/H4/H4.tsx +2 -0
- package/components/Heading/components/H5/H5.tsx +2 -0
- package/components/Heading/components/H6/H6.tsx +2 -0
- package/components/Icon/Icon.tsx +2 -0
- package/components/Input/Input.tsx +103 -95
- package/components/Layout/Layout.tsx +2 -0
- package/components/Layout/components/LayoutAside/LayoutAside.tsx +2 -0
- package/components/Layout/components/LayoutAside/components/LayoutAsideContent/LayoutAsideContent.tsx +2 -0
- package/components/Layout/components/LayoutAside/components/LayoutAsideFooter/LayoutAsideFooter.tsx +2 -0
- package/components/Layout/components/LayoutAside/components/LayoutAsideToggle/LayoutAsideToggle.tsx +2 -0
- package/components/Layout/components/LayoutMain/LayoutMain.tsx +2 -0
- package/components/Layout/components/LayoutMain/components/LayoutMainContent/LayoutMainContent.tsx +2 -0
- package/components/Layout/components/LayoutNavigation/LayoutNavigation.tsx +2 -0
- package/components/Layout/components/LayoutSubNavigation/LayoutSubNavigation.tsx +2 -0
- package/components/Loading/Loading.tsx +2 -0
- package/components/Markdown/Markdown.tsx +2 -0
- package/components/Masonry/Masonry.tsx +5 -1
- package/components/Menu/Menu.tsx +2 -0
- package/components/Menu/components/MenuCategory/MenuCategory.tsx +2 -0
- package/components/Menu/components/MenuFilter/MenuFilter.tsx +2 -0
- package/components/Menu/components/MenuItem/MenuItem.tsx +2 -0
- package/components/Overlay/Overlay.tsx +18 -2
- package/components/Pie/Pie.tsx +2 -0
- package/components/Pill/Pill.meta.ts +9 -1
- package/components/Pill/Pill.module.css +11 -0
- package/components/Pill/Pill.tsx +28 -3
- package/components/Pill/Pill.types.ts +2 -0
- package/components/Placeholder/Placeholder.tsx +2 -0
- package/components/Progress/Progress.tsx +2 -0
- package/components/Radio/Radio.tsx +2 -0
- package/components/Range/Range.tsx +2 -0
- package/components/Segments/Segments.context.ts +19 -0
- package/components/Segments/Segments.meta.ts +4 -0
- package/components/Segments/Segments.tsx +34 -42
- package/components/Segments/Segments.types.ts +1 -0
- package/components/Segments/components/SegmentButton/SegmentButton.meta.ts +0 -4
- package/components/Segments/components/SegmentButton/SegmentButton.tsx +28 -3
- package/components/Segments/components/SegmentButton/SegmentButton.types.ts +0 -2
- package/components/Select/Select.tsx +40 -43
- package/components/Separator/Separator.tsx +2 -0
- package/components/Separator/components/HRMarkup/HRMarkup.tsx +2 -0
- package/components/Separator/components/HorizontalSeparator/HorizontalSeparator.tsx +2 -0
- package/components/Separator/components/VerticalSeparator/VerticalSeparator.tsx +2 -0
- package/components/Setup/Setup.tsx +3 -0
- package/components/Shimmer/Shimmer.tsx +2 -0
- package/components/Slider/Slider.tsx +2 -0
- package/components/Spacer/Spacer.tsx +2 -0
- package/components/Table/Table.tsx +2 -0
- package/components/Tabs/Tabs.meta.ts +12 -12
- package/components/Tabs/Tabs.module.css +25 -9
- package/components/Tabs/Tabs.tsx +49 -53
- package/components/Tabs/Tabs.types.ts +10 -3
- package/components/Text/Text.tsx +2 -0
- package/components/Text/components/Div/Div.tsx +2 -0
- package/components/Text/components/Micro/Micro.tsx +2 -0
- package/components/Text/components/P/P.tsx +2 -0
- package/components/Text/components/Small/Small.tsx +2 -0
- package/components/Text/components/Tiny/Tiny.tsx +2 -0
- package/components/Textarea/Textarea.tsx +14 -13
- package/components/Tile/Tile.tsx +2 -0
- package/components/Timestamp/Timestamp.tsx +2 -0
- package/components/Toggle/Toggle.tsx +2 -0
- package/components/Tooltip/Tooltip.tsx +17 -9
- package/components/Tooltip/Tooltip.types.ts +0 -1
- package/components/Tooltip/components/TooltipContent/TooltipContent.tsx +2 -0
- package/components/Tooltip/components/TooltipTrigger/TooltipTrigger.tsx +4 -2
- package/components/shared/InputLabel/InputLabel.tsx +2 -0
- package/components/shared/ResultList/ResultList.tsx +6 -4
- package/contexts/LayoutContext/LayoutContext.tsx +15 -34
- package/contexts/LayoutContext/LayoutContext.types.ts +0 -1
- package/hooks/useLayoutContext.tsx +0 -1
- package/index.ts +5 -0
- package/package.json +1 -1
|
@@ -31,7 +31,11 @@ export const Masonry: FC<MasonryProps> = ({
|
|
|
31
31
|
return (
|
|
32
32
|
<>
|
|
33
33
|
<style dangerouslySetInnerHTML={{ __html: mediaStyles }} />
|
|
34
|
-
<div className={id}>
|
|
34
|
+
<div className={id} data-ui-component="Masonry">
|
|
35
|
+
{children}
|
|
36
|
+
</div>
|
|
35
37
|
</>
|
|
36
38
|
)
|
|
37
39
|
}
|
|
40
|
+
|
|
41
|
+
Masonry.displayName = "Masonry"
|
package/components/Menu/Menu.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import styles from "./Overlay.module.css"
|
|
2
|
-
import type { FC, MouseEvent } from "react"
|
|
2
|
+
import type { FC, MouseEvent, KeyboardEvent } from "react"
|
|
3
3
|
import type { OverlayProps } from "./Overlay.types"
|
|
4
4
|
import { getClasses } from "@heliosgraphics/utils"
|
|
5
5
|
|
|
@@ -11,6 +11,13 @@ export const Overlay: FC<OverlayProps> = ({ onClose, isCentered, children, isOpe
|
|
|
11
11
|
return onClose?.()
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>): void => {
|
|
15
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
16
|
+
event.preventDefault()
|
|
17
|
+
onClose?.()
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
14
21
|
const contentClasses: string = getClasses(styles.overlay__content, {
|
|
15
22
|
[styles.overlay__contentCentered]: isCentered,
|
|
16
23
|
})
|
|
@@ -25,7 +32,16 @@ export const Overlay: FC<OverlayProps> = ({ onClose, isCentered, children, isOpe
|
|
|
25
32
|
data-open={isOpen}
|
|
26
33
|
>
|
|
27
34
|
<div className={contentClasses}>{children}</div>
|
|
28
|
-
<div
|
|
35
|
+
<div
|
|
36
|
+
className={styles.overlay__layer}
|
|
37
|
+
onClick={hideFunction}
|
|
38
|
+
onKeyDown={handleKeyDown}
|
|
39
|
+
role="button"
|
|
40
|
+
tabIndex={0}
|
|
41
|
+
aria-label="Close overlay"
|
|
42
|
+
/>
|
|
29
43
|
</section>
|
|
30
44
|
)
|
|
31
45
|
}
|
|
46
|
+
|
|
47
|
+
Overlay.displayName = "Overlay"
|
package/components/Pie/Pie.tsx
CHANGED
|
@@ -28,8 +28,16 @@ export const meta: HeliosAttributeMeta<PillProps> = {
|
|
|
28
28
|
type: "HeliosIconType",
|
|
29
29
|
isOptional: true,
|
|
30
30
|
},
|
|
31
|
+
isEllipsis: {
|
|
32
|
+
type: "boolean",
|
|
33
|
+
isOptional: true,
|
|
34
|
+
},
|
|
31
35
|
isLabelHidden: {
|
|
32
|
-
type: "
|
|
36
|
+
type: "boolean",
|
|
37
|
+
isOptional: true,
|
|
38
|
+
},
|
|
39
|
+
isLoading: {
|
|
40
|
+
type: "boolean",
|
|
33
41
|
isOptional: true,
|
|
34
42
|
},
|
|
35
43
|
isMono: {
|
|
@@ -51,3 +51,14 @@
|
|
|
51
51
|
.pillTiny.pillRounded:not(.pillIconOnly) {
|
|
52
52
|
padding: 0 8px;
|
|
53
53
|
}
|
|
54
|
+
|
|
55
|
+
.pillEllipsis {
|
|
56
|
+
overflow: hidden;
|
|
57
|
+
max-width: 100%;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.pillEllipsis :global(.text) {
|
|
61
|
+
overflow: hidden;
|
|
62
|
+
text-overflow: ellipsis;
|
|
63
|
+
white-space: nowrap;
|
|
64
|
+
}
|
package/components/Pill/Pill.tsx
CHANGED
|
@@ -3,8 +3,9 @@ import { getColorClasses } from "../../utils/colors"
|
|
|
3
3
|
import { Flex } from "../Flex"
|
|
4
4
|
import { Text } from "../Text"
|
|
5
5
|
import { Icon } from "../Icon"
|
|
6
|
+
import { Loading } from "../Loading"
|
|
6
7
|
import styles from "./Pill.module.css"
|
|
7
|
-
import { memo, type FC } from "react"
|
|
8
|
+
import { memo, type FC, type KeyboardEvent } from "react"
|
|
8
9
|
import type { PillProps } from "./Pill.types"
|
|
9
10
|
|
|
10
11
|
const PILL_ICON_SIZE = {
|
|
@@ -13,13 +14,21 @@ const PILL_ICON_SIZE = {
|
|
|
13
14
|
normal: 24,
|
|
14
15
|
} as const satisfies Record<string, number>
|
|
15
16
|
|
|
17
|
+
const PILL_LOADING_SIZE = {
|
|
18
|
+
tiny: 10,
|
|
19
|
+
small: 10,
|
|
20
|
+
normal: 20,
|
|
21
|
+
} as const satisfies Record<string, 10 | 20 | 40>
|
|
22
|
+
|
|
16
23
|
export const Pill: FC<PillProps> = memo(
|
|
17
24
|
({
|
|
18
25
|
appearance = "light",
|
|
19
26
|
color = "gray",
|
|
20
27
|
className,
|
|
21
28
|
icon,
|
|
29
|
+
isEllipsis,
|
|
22
30
|
isLabelHidden,
|
|
31
|
+
isLoading,
|
|
23
32
|
isMono,
|
|
24
33
|
isRounded,
|
|
25
34
|
label,
|
|
@@ -38,21 +47,35 @@ export const Pill: FC<PillProps> = memo(
|
|
|
38
47
|
[styles.pillTiny]: size === "tiny",
|
|
39
48
|
|
|
40
49
|
[styles.pillIconOnly]: !!icon && isLabelHidden,
|
|
50
|
+
[styles.pillEllipsis]: isEllipsis,
|
|
41
51
|
})
|
|
42
52
|
|
|
43
53
|
const isSmall: boolean = size !== "normal"
|
|
44
54
|
const pillTextSize = isSmall ? "tiny" : "small"
|
|
45
55
|
|
|
56
|
+
const onKeyDown = onClick
|
|
57
|
+
? (event: KeyboardEvent<HTMLDivElement>): void => {
|
|
58
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
59
|
+
event.preventDefault()
|
|
60
|
+
onClick(event as unknown as React.MouseEvent<HTMLDivElement>)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
: undefined
|
|
64
|
+
|
|
65
|
+
const isInteractive: boolean = !!onClick && !isLoading
|
|
66
|
+
|
|
46
67
|
return (
|
|
47
68
|
<Flex
|
|
48
|
-
{...(
|
|
69
|
+
{...(isInteractive && { onClick, role: "button", tabIndex: 0 })}
|
|
70
|
+
{...(isInteractive && onKeyDown && { onKeyDown })}
|
|
49
71
|
className={pillClasses}
|
|
50
72
|
isCentered={true}
|
|
51
73
|
gap={2}
|
|
52
74
|
aria-label={isLabelHidden ? label : undefined}
|
|
53
75
|
data-ui-component="Pill"
|
|
54
76
|
>
|
|
55
|
-
{
|
|
77
|
+
{isLoading && <Loading size={PILL_LOADING_SIZE[size] || 20} />}
|
|
78
|
+
{!isLoading && icon && <Icon size={PILL_ICON_SIZE[size] || 16} icon={icon} />}
|
|
56
79
|
{!isLabelHidden && (
|
|
57
80
|
<Text type={pillTextSize} whiteSpace="nowrap" {...(isMono && { fontFamily: "mono" })} fontWeight="medium">
|
|
58
81
|
{label}
|
|
@@ -62,3 +85,5 @@ export const Pill: FC<PillProps> = memo(
|
|
|
62
85
|
)
|
|
63
86
|
},
|
|
64
87
|
)
|
|
88
|
+
|
|
89
|
+
Pill.displayName = "Pill"
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { createContext, useContext } from "react"
|
|
4
|
+
|
|
5
|
+
export interface SegmentsContextValue {
|
|
6
|
+
activeValue: string
|
|
7
|
+
onSelect: (value: string) => void
|
|
8
|
+
registerRef: (value: string, el: HTMLButtonElement | null) => void
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const SegmentsContext = createContext<SegmentsContextValue | null>(null)
|
|
12
|
+
|
|
13
|
+
export const useSegments = (): SegmentsContextValue => {
|
|
14
|
+
const context = useContext(SegmentsContext)
|
|
15
|
+
|
|
16
|
+
if (!context) throw new Error("SegmentButton must be used within Segments")
|
|
17
|
+
|
|
18
|
+
return context
|
|
19
|
+
}
|
|
@@ -1,41 +1,22 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
type FC,
|
|
5
|
-
useState,
|
|
6
|
-
useRef,
|
|
7
|
-
useEffect,
|
|
8
|
-
useCallback,
|
|
9
|
-
Children,
|
|
10
|
-
isValidElement,
|
|
11
|
-
cloneElement,
|
|
12
|
-
type ReactElement,
|
|
13
|
-
} from "react"
|
|
3
|
+
import { type FC, useState, useRef, useEffect, useCallback } from "react"
|
|
14
4
|
import { Flex } from "../Flex"
|
|
15
5
|
import styles from "./Segments.module.css"
|
|
16
6
|
import { getClasses } from "@heliosgraphics/utils"
|
|
17
|
-
import {
|
|
7
|
+
import { SegmentsContext } from "./Segments.context"
|
|
18
8
|
import type { SegmentsProps } from "./Segments.types"
|
|
19
|
-
import type { SegmentButtonProps } from "./components/SegmentButton/SegmentButton.types"
|
|
20
9
|
|
|
21
|
-
export const Segments: FC<SegmentsProps> = ({ children, isFullWidth, isSmall }) => {
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
const firstValue: string = validChildren.length > 0 ? validChildren[0]?.props?.value || "" : ""
|
|
27
|
-
const defaultValue: string = ""
|
|
28
|
-
|
|
29
|
-
const [activeValue, setActiveValue] = useState<string>(defaultValue || firstValue)
|
|
30
|
-
const buttonRefs = useRef<(HTMLButtonElement | null)[]>([])
|
|
10
|
+
export const Segments: FC<SegmentsProps> = ({ children, isFullWidth, isSmall, defaultValue }) => {
|
|
11
|
+
const [activeValue, setActiveValue] = useState<string>(defaultValue ?? "")
|
|
12
|
+
const buttonRefs = useRef<Map<string, HTMLButtonElement>>(new Map())
|
|
31
13
|
const containerRef = useRef<HTMLDivElement>(null)
|
|
32
14
|
const sliderRef = useRef<HTMLDivElement>(null)
|
|
33
15
|
|
|
34
16
|
const updateSliderPosition = useCallback((): void => {
|
|
35
17
|
if (!containerRef.current || !sliderRef.current || !activeValue) return
|
|
36
18
|
|
|
37
|
-
const
|
|
38
|
-
const activeButton: HTMLButtonElement | null | undefined = buttonRefs.current[activeIndex]
|
|
19
|
+
const activeButton: HTMLButtonElement | undefined = buttonRefs.current.get(activeValue)
|
|
39
20
|
|
|
40
21
|
if (!activeButton) return
|
|
41
22
|
|
|
@@ -48,7 +29,7 @@ export const Segments: FC<SegmentsProps> = ({ children, isFullWidth, isSmall })
|
|
|
48
29
|
sliderRef.current.style.transform = `translateX(${left}px)`
|
|
49
30
|
sliderRef.current.style.width = `${width}px`
|
|
50
31
|
sliderRef.current.style.opacity = "1"
|
|
51
|
-
}, [activeValue
|
|
32
|
+
}, [activeValue])
|
|
52
33
|
|
|
53
34
|
useEffect(() => {
|
|
54
35
|
const timer: ReturnType<typeof setTimeout> = setTimeout(updateSliderPosition, 0)
|
|
@@ -61,27 +42,38 @@ export const Segments: FC<SegmentsProps> = ({ children, isFullWidth, isSmall })
|
|
|
61
42
|
}
|
|
62
43
|
}, [updateSliderPosition])
|
|
63
44
|
|
|
45
|
+
const onSelect = useCallback((value: string): void => {
|
|
46
|
+
setActiveValue(value)
|
|
47
|
+
}, [])
|
|
48
|
+
|
|
49
|
+
const registerRef = useCallback((value: string, el: HTMLButtonElement | null): void => {
|
|
50
|
+
if (el) {
|
|
51
|
+
buttonRefs.current.set(value, el)
|
|
52
|
+
} else {
|
|
53
|
+
buttonRefs.current.delete(value)
|
|
54
|
+
}
|
|
55
|
+
}, [])
|
|
56
|
+
|
|
64
57
|
const segmentedControlClasses: string = getClasses(styles.segmentedControl, {
|
|
65
58
|
[styles.segmentedControlSmall]: isSmall,
|
|
66
59
|
[styles.segmentedControlFull]: isFullWidth,
|
|
67
60
|
})
|
|
68
61
|
|
|
69
62
|
return (
|
|
70
|
-
<
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
)}
|
|
84
|
-
<div ref={sliderRef} className={styles.segments__slider} />
|
|
85
|
-
</Flex>
|
|
63
|
+
<SegmentsContext value={{ activeValue, onSelect, registerRef }}>
|
|
64
|
+
<Flex
|
|
65
|
+
className={segmentedControlClasses}
|
|
66
|
+
isYCentered={true}
|
|
67
|
+
gap={2}
|
|
68
|
+
isInline={!isFullWidth}
|
|
69
|
+
ref={containerRef}
|
|
70
|
+
data-ui-component="Segments"
|
|
71
|
+
>
|
|
72
|
+
{children}
|
|
73
|
+
<div ref={sliderRef} className={styles.segments__slider} />
|
|
74
|
+
</Flex>
|
|
75
|
+
</SegmentsContext>
|
|
86
76
|
)
|
|
87
77
|
}
|
|
78
|
+
|
|
79
|
+
Segments.displayName = "Segments"
|
|
@@ -1,22 +1,47 @@
|
|
|
1
1
|
import styles from "./SegmentButton.module.css"
|
|
2
2
|
import { getClasses } from "@heliosgraphics/utils"
|
|
3
3
|
import { Icon } from "../../../Icon"
|
|
4
|
-
import
|
|
4
|
+
import { useSegments } from "../../Segments.context"
|
|
5
|
+
import { useCallback, type FC } from "react"
|
|
5
6
|
import type { HeliosIconType } from "../../../../types/icons"
|
|
6
7
|
import type { SegmentButtonProps } from "./SegmentButton.types"
|
|
7
8
|
|
|
8
|
-
export const SegmentButton: FC<SegmentButtonProps> = ({
|
|
9
|
+
export const SegmentButton: FC<SegmentButtonProps> = ({
|
|
10
|
+
value,
|
|
11
|
+
icon,
|
|
12
|
+
iconLeft,
|
|
13
|
+
iconRight,
|
|
14
|
+
isActive: isActiveProp,
|
|
15
|
+
onClick,
|
|
16
|
+
}) => {
|
|
17
|
+
const { activeValue, onSelect, registerRef } = useSegments()
|
|
18
|
+
const isActive: boolean = isActiveProp ?? value === activeValue
|
|
19
|
+
|
|
9
20
|
const segmentButtonClasses: string = getClasses(styles.segmentButton, {
|
|
10
21
|
[styles.segmentButtonActive]: isActive,
|
|
11
22
|
})
|
|
12
23
|
|
|
13
24
|
const iconL: HeliosIconType | undefined = iconLeft || icon
|
|
14
25
|
|
|
26
|
+
const handleClick = useCallback((): void => {
|
|
27
|
+
onSelect(value)
|
|
28
|
+
onClick?.()
|
|
29
|
+
}, [value, onSelect, onClick])
|
|
30
|
+
|
|
31
|
+
const handleRef = useCallback(
|
|
32
|
+
(el: HTMLButtonElement | null): void => {
|
|
33
|
+
registerRef(value, el)
|
|
34
|
+
},
|
|
35
|
+
[value, registerRef],
|
|
36
|
+
)
|
|
37
|
+
|
|
15
38
|
return (
|
|
16
|
-
<button ref={
|
|
39
|
+
<button ref={handleRef} className={segmentButtonClasses} onClick={handleClick} data-ui-component="SegmentButton">
|
|
17
40
|
{iconL && <Icon icon={iconL} size={16} />}
|
|
18
41
|
{value}
|
|
19
42
|
{iconRight && <Icon icon={iconRight} size={16} />}
|
|
20
43
|
</button>
|
|
21
44
|
)
|
|
22
45
|
}
|
|
46
|
+
|
|
47
|
+
SegmentButton.displayName = "SegmentButton"
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { Ref } from "react"
|
|
2
1
|
import type { HeliosIconType } from "../../../../types/icons"
|
|
3
2
|
|
|
4
3
|
export interface SegmentButtonProps {
|
|
@@ -7,6 +6,5 @@ export interface SegmentButtonProps {
|
|
|
7
6
|
iconRight?: HeliosIconType
|
|
8
7
|
isActive?: boolean
|
|
9
8
|
onClick?: () => void
|
|
10
|
-
ref?: Ref<HTMLButtonElement>
|
|
11
9
|
value: string
|
|
12
10
|
}
|
|
@@ -3,54 +3,51 @@
|
|
|
3
3
|
import { Flex } from "../Flex"
|
|
4
4
|
import { Icon } from "../Icon"
|
|
5
5
|
import { getClasses } from "@heliosgraphics/utils"
|
|
6
|
-
import { useId,
|
|
6
|
+
import { useId, forwardRef } from "react"
|
|
7
7
|
import { InputLabel } from "../shared/InputLabel"
|
|
8
8
|
import styles from "./Select.module.css"
|
|
9
9
|
import type { SelectProps } from "./Select.types"
|
|
10
10
|
|
|
11
|
-
export const Select
|
|
12
|
-
selectedValue,
|
|
13
|
-
|
|
14
|
-
isLabelHidden,
|
|
15
|
-
isSmall,
|
|
16
|
-
isDisabled,
|
|
17
|
-
isRequired,
|
|
18
|
-
items,
|
|
19
|
-
label,
|
|
20
|
-
}) => {
|
|
21
|
-
const htmlFor: string = useId()
|
|
11
|
+
export const Select = forwardRef<HTMLSelectElement, SelectProps>(
|
|
12
|
+
({ selectedValue, onChange, isLabelHidden, isSmall, isDisabled, isRequired, items, label }, ref) => {
|
|
13
|
+
const htmlFor: string = useId()
|
|
22
14
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
15
|
+
const selectClasses: string = getClasses(styles.select, {
|
|
16
|
+
[styles.selectDisabled]: isDisabled,
|
|
17
|
+
[styles.selectSmall]: isSmall,
|
|
18
|
+
[styles.selectHiddenLabel]: !label || isLabelHidden,
|
|
19
|
+
})
|
|
28
20
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
21
|
+
return (
|
|
22
|
+
<Flex isColumn={true} className={selectClasses} data-ui-component="Select">
|
|
23
|
+
<InputLabel label={label} id={htmlFor} isHidden={!!isLabelHidden} isDisabled={!!isDisabled} />
|
|
24
|
+
<Flex>
|
|
25
|
+
<select
|
|
26
|
+
ref={ref}
|
|
27
|
+
className={styles.select__select}
|
|
28
|
+
onChange={onChange}
|
|
29
|
+
id={htmlFor}
|
|
30
|
+
value={selectedValue}
|
|
31
|
+
disabled={isDisabled}
|
|
32
|
+
required={isRequired}
|
|
33
|
+
aria-label={isLabelHidden ? label : undefined}
|
|
34
|
+
aria-required={isRequired || undefined}
|
|
35
|
+
>
|
|
36
|
+
{items?.map((item) => {
|
|
37
|
+
return (
|
|
38
|
+
<option key={item.value} value={item.value} disabled={item.isDisabled}>
|
|
39
|
+
{item.name}
|
|
40
|
+
</option>
|
|
41
|
+
)
|
|
42
|
+
})}
|
|
43
|
+
</select>
|
|
44
|
+
<Flex className={styles.select__icon} isCentered={true}>
|
|
45
|
+
<Icon icon="chevron-down" size={20} />
|
|
46
|
+
</Flex>
|
|
52
47
|
</Flex>
|
|
53
48
|
</Flex>
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
49
|
+
)
|
|
50
|
+
},
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
Select.displayName = "Select"
|