@heliosgraphics/ui 2.0.0-alpha.89 → 2.0.0-alpha.91

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.
Files changed (104) hide show
  1. package/components/Alert/Alert.tsx +1 -1
  2. package/components/Breadcrumb/Breadcrumb.meta.ts +1 -1
  3. package/components/Breadcrumb/Breadcrumb.tsx +4 -4
  4. package/components/Browser/Browser.tsx +6 -2
  5. package/components/Button/Button.tsx +175 -173
  6. package/components/ButtonGroup/ButtonGroup.tsx +2 -4
  7. package/components/Checkbox/Checkbox.tsx +61 -55
  8. package/components/Clock/Clock.module.css +1 -1
  9. package/components/Clock/Clock.tsx +1 -1
  10. package/components/Column/Column.tsx +2 -2
  11. package/components/Confirm/Confirm.tsx +1 -1
  12. package/components/DatePicker/DatePicker.tsx +6 -2
  13. package/components/Debug/Debug.tsx +2 -2
  14. package/components/Details/Details.tsx +1 -1
  15. package/components/Dialog/Dialog.tsx +32 -5
  16. package/components/Donut/Donut.module.css +1 -1
  17. package/components/Donut/Donut.tsx +8 -1
  18. package/components/Dot/Dot.tsx +1 -1
  19. package/components/Dropdown/Dropdown.tsx +46 -19
  20. package/components/Fieldset/Fieldset.tsx +1 -1
  21. package/components/Flex/Flex.tsx +7 -6
  22. package/components/Flex/Flex.types.ts +2 -2
  23. package/components/Grid/Grid.tsx +7 -3
  24. package/components/Heading/Heading.tsx +15 -10
  25. package/components/Heading/components/H0/H0.tsx +1 -1
  26. package/components/Icon/Icon.tsx +1 -1
  27. package/components/Input/Input.tsx +13 -3
  28. package/components/Layout/components/LayoutAside/LayoutAside.tsx +1 -1
  29. package/components/Layout/components/LayoutAside/components/LayoutAsideContent/LayoutAsideContent.tsx +1 -1
  30. package/components/Layout/components/LayoutAside/components/LayoutAsideFooter/LayoutAsideFooter.tsx +1 -1
  31. package/components/Layout/components/LayoutAside/components/LayoutAsideToggle/LayoutAsideToggle.tsx +1 -1
  32. package/components/Layout/components/LayoutMain/LayoutMain.tsx +1 -1
  33. package/components/Layout/components/LayoutMain/components/LayoutMainContent/LayoutMainContent.tsx +1 -1
  34. package/components/Layout/components/LayoutNavigation/LayoutNavigation.tsx +1 -1
  35. package/components/Loading/Loading.tsx +10 -2
  36. package/components/Markdown/Markdown.meta.ts +7 -0
  37. package/components/Markdown/Markdown.tsx +15 -6
  38. package/components/Markdown/Markdown.types.ts +4 -1
  39. package/components/Markdown/Markdown.utils.spec.ts +3 -3
  40. package/components/Markdown/Markdown.utils.ts +9 -7
  41. package/components/Masonry/Masonry.meta.ts +1 -1
  42. package/components/Masonry/Masonry.tsx +2 -2
  43. package/components/Masonry/Masonry.types.ts +1 -1
  44. package/components/Menu/Menu.tsx +1 -3
  45. package/components/Menu/components/MenuCategory/MenuCategory.tsx +13 -2
  46. package/components/Menu/components/MenuFilter/MenuFilter.tsx +1 -1
  47. package/components/Menu/components/MenuItem/MenuItem.tsx +14 -1
  48. package/components/Overlay/Overlay.tsx +1 -1
  49. package/components/Pie/Pie.tsx +7 -4
  50. package/components/Pill/Pill.tsx +1 -1
  51. package/components/Placeholder/Placeholder.tsx +1 -0
  52. package/components/Progress/Progress.tsx +9 -1
  53. package/components/Radio/Radio.tsx +64 -58
  54. package/components/Segments/Segments.tsx +7 -12
  55. package/components/Segments/components/SegmentButton/SegmentButton.meta.ts +4 -0
  56. package/components/Segments/components/SegmentButton/SegmentButton.tsx +13 -16
  57. package/components/Segments/components/SegmentButton/SegmentButton.types.ts +2 -0
  58. package/components/Select/Select.tsx +5 -4
  59. package/components/Separator/components/HorizontalSeparator/HorizontalSeparator.tsx +1 -1
  60. package/components/Separator/components/VerticalSeparator/VerticalSeparator.tsx +1 -1
  61. package/{components.css → components/Setup/Setup.components.css} +2 -2
  62. package/components/Setup/Setup.meta.ts +2 -2
  63. package/components/Setup/Setup.tsx +10 -7
  64. package/components/Setup/Setup.types.ts +1 -0
  65. package/components/Shimmer/Shimmer.tsx +3 -2
  66. package/components/Slider/Slider.tsx +4 -4
  67. package/components/Spacer/Spacer.tsx +1 -1
  68. package/components/Table/Table.tsx +1 -1
  69. package/components/Tabs/Tabs.tsx +36 -12
  70. package/components/Text/Text.tsx +5 -2
  71. package/components/Textarea/Textarea.tsx +10 -5
  72. package/components/Tile/Tile.tsx +2 -9
  73. package/components/Tile/Tile.types.ts +1 -1
  74. package/components/Timestamp/Timestamp.meta.ts +5 -1
  75. package/components/Timestamp/Timestamp.tsx +3 -3
  76. package/components/Timestamp/Timestamp.types.ts +1 -1
  77. package/components/Toggle/Toggle.tsx +2 -2
  78. package/components/Tooltip/Tooltip.module.css +32 -0
  79. package/components/Tooltip/Tooltip.tsx +36 -72
  80. package/components/Tooltip/Tooltip.types.ts +1 -0
  81. package/components/Tooltip/components/TooltipContent/TooltipContent.tsx +5 -3
  82. package/components/Tooltip/components/TooltipTrigger/TooltipTrigger.tsx +10 -4
  83. package/components/shared/InputLabel/InputLabel.tsx +1 -1
  84. package/components/shared/ResultList/ResultList.meta.ts +4 -0
  85. package/components/shared/ResultList/ResultList.tsx +8 -10
  86. package/components/shared/ResultList/ResultList.types.ts +1 -0
  87. package/constants/hooks.ts +1 -1
  88. package/contexts/LayoutContext/LayoutContext.tsx +30 -20
  89. package/contexts/LayoutContext/LayoutContext.types.ts +1 -0
  90. package/hooks/useDebounce.tsx +2 -2
  91. package/hooks/useLayoutContext.tsx +1 -0
  92. package/hooks/usePrint.tsx +31 -0
  93. package/index.ts +4 -0
  94. package/package.json +20 -12
  95. package/utils/date.ts +54 -0
  96. package/utils/dayjs.ts +0 -21
  97. /package/{css → components/Setup/css}/core.colors-helpers.css +0 -0
  98. /package/{css → components/Setup/css}/core.colors.css +0 -0
  99. /package/{css → components/Setup/css}/core.scale.css +0 -0
  100. /package/{css → components/Setup/css}/core.setup.css +0 -0
  101. /package/{css → components/Setup/css}/core.typography.css +0 -0
  102. /package/{css → components/Setup/css}/feat.atomics.css +0 -0
  103. /package/{css → components/Setup/css}/feat.markdown.css +0 -0
  104. /package/{css → components/Setup/css}/feat.responsive.css +0 -0
@@ -4,7 +4,7 @@ import { Masonry as MasonryPlock } from "react-plock"
4
4
  import { Children, type ReactElement, type FC } from "react"
5
5
  import type { MasonryProps } from "./Masonry.types"
6
6
 
7
- export const Masonry: FC<MasonryProps> = ({ children, columns, gap, brakepoints, useBalancedLayout }) => {
7
+ export const Masonry: FC<MasonryProps> = ({ children, columns, gap, breakpoints, useBalancedLayout }) => {
8
8
  if (!children) return null
9
9
 
10
10
  const mappedChildren = Children.toArray(children).map((child) => <div className="Row">{child}</div>) as ReactElement[]
@@ -16,7 +16,7 @@ export const Masonry: FC<MasonryProps> = ({ children, columns, gap, brakepoints,
16
16
  config={{
17
17
  columns: columns,
18
18
  gap: gap,
19
- media: brakepoints,
19
+ media: breakpoints,
20
20
  useBalancedLayout: Boolean(useBalancedLayout),
21
21
  }}
22
22
  />
@@ -3,7 +3,7 @@ import type { PropsWithChildren } from "react"
3
3
  export interface MasonryBaseProps {
4
4
  columns: [number, number, number]
5
5
  gap: [number, number, number]
6
- brakepoints: [number, number, number]
6
+ breakpoints: [number, number, number]
7
7
  useBalancedLayout?: boolean
8
8
  }
9
9
 
@@ -1,6 +1,4 @@
1
- "use client"
2
-
3
- import { FC } from "react"
1
+ import type { FC } from "react"
4
2
  import type { MenuProps } from "./Menu.types"
5
3
  import { getClasses } from "@heliosgraphics/utils"
6
4
  import { getFlexUtility, getSafeFlexProps } from "../Flex/Flex.utils"
@@ -1,6 +1,6 @@
1
1
  "use client"
2
2
 
3
- import { useState, type FC } from "react"
3
+ import { useCallback, useState, type FC, type KeyboardEvent } from "react"
4
4
  import { Flex } from "../../../Flex"
5
5
  import { Icon } from "../../../Icon"
6
6
  import { Text } from "../../../Text"
@@ -26,6 +26,16 @@ export const MenuCategory: FC<MenuCategoryProps> = ({
26
26
  }
27
27
  }
28
28
 
29
+ const handleKeyDown = useCallback(
30
+ (event: KeyboardEvent<HTMLDivElement>): void => {
31
+ if (event.key === "Enter" || event.key === " ") {
32
+ event.preventDefault()
33
+ onToggle()
34
+ }
35
+ },
36
+ [isControlled],
37
+ )
38
+
29
39
  const menuCategoryClasses: string = getClasses(styles.menuCategory, {
30
40
  [styles.menuCategoryFolder]: category,
31
41
  [styles.menuCategoryFolderOpen]: isOpen,
@@ -46,10 +56,11 @@ export const MenuCategory: FC<MenuCategoryProps> = ({
46
56
  <Flex isColumn={true} isXCentered={true} data-ui-component="Menu.Category" className={menuCategoryClasses}>
47
57
  {showHeader && (
48
58
  <Flex
49
- {...(isFolder && onToggle && { onClick: onToggle })}
59
+ {...(isFolder && { onClick: onToggle, onKeyDown: handleKeyDown, role: "button" as const, tabIndex: 0 })}
50
60
  isBetween={true}
51
61
  isYCentered={true}
52
62
  gap={4}
63
+ aria-expanded={isFolder ? isOpen : undefined}
53
64
  className={styles.menuCategoryTitle}
54
65
  >
55
66
  <Text type="tiny" emphasis={isOpen ? "secondary" : "primary"} fontWeight="medium" isNonSelectable={true}>
@@ -1,6 +1,6 @@
1
1
  "use client"
2
2
 
3
- import { FC } from "react"
3
+ import type { FC } from "react"
4
4
  import { Input } from "../../../Input"
5
5
  import { getClasses } from "@heliosgraphics/utils"
6
6
  import styles from "./MenuFilter.module.css"
@@ -1,6 +1,6 @@
1
1
  "use client"
2
2
 
3
- import { FC } from "react"
3
+ import { useCallback, type FC, type KeyboardEvent } from "react"
4
4
  import { Flex } from "../../../Flex"
5
5
  import { Pill } from "../../../Pill"
6
6
  import { Icon } from "../../../Icon"
@@ -24,11 +24,24 @@ export const MenuItem: FC<MenuItemProps> = ({
24
24
  [styles.menuItemActive]: isActive,
25
25
  })
26
26
 
27
+ const handleKeyDown = useCallback(
28
+ (event: KeyboardEvent<HTMLDivElement>): void => {
29
+ if (event.key === "Enter" || event.key === " ") {
30
+ event.preventDefault()
31
+ onAsideClose()
32
+ }
33
+ },
34
+ [onAsideClose],
35
+ )
36
+
27
37
  return (
28
38
  <Flex
29
39
  className={menuItemClasses}
30
40
  data-ui-component="MenuItem"
41
+ role="menuitem"
42
+ tabIndex={0}
31
43
  onClick={onAsideClose}
44
+ onKeyDown={handleKeyDown}
32
45
  isBetween={true}
33
46
  gap={4}
34
47
  isYCentered={true}
@@ -18,7 +18,7 @@ export const Overlay: FC<OverlayProps> = ({ onClose, isCentered, children, isOpe
18
18
  })
19
19
 
20
20
  return (
21
- <section className={styles.overlay}>
21
+ <section className={styles.overlay} data-ui-component="Overlay">
22
22
  <div className={contentClasses}>{children}</div>
23
23
  <div className={styles.overlay__layer} onClick={hideFunction} />
24
24
  </section>
@@ -15,15 +15,18 @@ export const Pie: FC<PieProps> = ({ color, size, data }) => {
15
15
  width={size}
16
16
  viewBox={`0 0 ${size} ${size}`}
17
17
  style={{ backgroundColor: backgroundColor }}
18
+ role="img"
19
+ aria-label={`Pie chart with ${data.length} segments`}
20
+ data-ui-component="Pie"
18
21
  >
19
- {data.map((item, key) => {
20
- const thisData: Array<PieItem> = data.slice(0, key)
22
+ {data.map((item, index) => {
23
+ const thisData: Array<PieItem> = data.slice(0, index)
21
24
  const thisSize = thisData?.reduce((a, b) => a + b.value, 0)
22
- const thisColor: string = `hsl(var(--${color}-hue), ${(key + 1) * 20}%, 50%)`
25
+ const thisColor: string = `hsl(var(--${color}-hue), ${(index + 1) * 20}%, 50%)`
23
26
 
24
27
  return (
25
28
  <circle
26
- key={key}
29
+ key={item.name ?? `segment-${index}`}
27
30
  r={size / 4}
28
31
  cx={size / 2}
29
32
  cy={size / 2}
@@ -1,4 +1,4 @@
1
- import { getClasses } from "@heliosgraphics/utils/classnames"
1
+ import { getClasses } from "@heliosgraphics/utils"
2
2
  import { getColorClasses } from "../../utils/colors"
3
3
  import { Flex } from "../Flex"
4
4
  import { Text } from "../Text"
@@ -9,6 +9,7 @@ export const Placeholder: FC<PlaceholderProps> = ({ children, height }) => {
9
9
  <Flex
10
10
  className={styles.placeholder}
11
11
  padding={16}
12
+ data-ui-component="Placeholder"
12
13
  style={{
13
14
  height: height ? `${height}px` : "inherit",
14
15
  }}
@@ -10,5 +10,13 @@ export const Progress: FC<ProgressProps> = ({ color = "blue", isSmall, max = 100
10
10
  [styles.progressSmall]: isSmall,
11
11
  })
12
12
 
13
- return <progress className={progressClasses} max={max} value={value} />
13
+ return (
14
+ <progress
15
+ className={progressClasses}
16
+ max={max}
17
+ value={value}
18
+ aria-label={`Progress: ${value} of ${max}`}
19
+ data-ui-component="Progress"
20
+ />
21
+ )
14
22
  }
@@ -1,7 +1,7 @@
1
1
  "use client"
2
2
 
3
- import { useId } from "react"
4
- import { getClasses } from "@heliosgraphics/utils/classnames"
3
+ import { useId, memo } from "react"
4
+ import { getClasses } from "@heliosgraphics/utils"
5
5
  import { getColorClasses } from "../../utils/colors"
6
6
  import { Flex } from "../Flex"
7
7
  import { Text } from "../Text"
@@ -9,63 +9,69 @@ import styles from "./Radio.module.css"
9
9
  import type { FC } from "react"
10
10
  import type { RadioProps } from "./Radio.types"
11
11
 
12
- export const Radio: FC<RadioProps> = ({
13
- color = "gray",
14
- isChecked,
15
- isVertical,
16
- isLabelHidden = false,
17
- isSmall,
18
- description,
19
- isDisabled,
20
- isRequired,
21
- onChange,
22
- label,
23
- name,
24
- value,
25
- }) => {
26
- const radioId: string = useId()
12
+ export const Radio: FC<RadioProps> = memo(
13
+ ({
14
+ color = "gray",
15
+ isChecked,
16
+ isVertical,
17
+ isLabelHidden = false,
18
+ isSmall,
19
+ description,
20
+ isDisabled,
21
+ isRequired,
22
+ onChange,
23
+ label,
24
+ name,
25
+ value,
26
+ }) => {
27
+ const radioId: string = useId()
27
28
 
28
- const colorClasses = getColorClasses(color, "dark")
29
- const radioClasses = getClasses(styles.radio, ...colorClasses, {
30
- [styles.radioDisabled]: isDisabled,
31
- [styles.radioSmall]: isSmall,
32
- })
29
+ const colorClasses = getColorClasses(color, "dark")
30
+ const radioClasses = getClasses(styles.radio, ...colorClasses, {
31
+ [styles.radioDisabled]: isDisabled,
32
+ [styles.radioSmall]: isSmall,
33
+ })
33
34
 
34
- const radioLabelClasses = getClasses(styles.radio__radioLabel, "flex gap-4", {
35
- "flex-x-center flex-column": isVertical,
36
- "flex-y-center": !isVertical,
37
- })
35
+ const radioLabelClasses = getClasses(styles.radio__radioLabel, "flex gap-4", {
36
+ "flex-x-center flex-column": isVertical,
37
+ "flex-y-center": !isVertical,
38
+ })
38
39
 
39
- return (
40
- <div className={radioClasses}>
41
- <label className={radioLabelClasses} htmlFor={radioId}>
42
- <span className={styles.radio__mark}>
43
- <input
44
- type="radio"
45
- checked={isChecked}
46
- onChange={onChange}
47
- disabled={isDisabled}
48
- required={isRequired}
49
- aria-label={isLabelHidden ? label : undefined}
50
- id={radioId}
51
- name={name}
52
- value={value}
53
- />
54
- <div className={styles.radio__radioMark} />
55
- </span>
56
- {!isLabelHidden && (
57
- <Flex isColumn={true}>
58
- <Text type={isSmall ? "tiny" : "small"} fontWeight="medium" emphasis={isDisabled ? "tertiary" : "inherit"}>
59
- {label}
60
- </Text>
61
- {description && (
62
- <Text type="tiny" emphasis="secondary">
63
- {description}
40
+ return (
41
+ <div className={radioClasses} data-ui-component="Radio">
42
+ <label className={radioLabelClasses} htmlFor={radioId}>
43
+ <span className={styles.radio__mark}>
44
+ <input
45
+ type="radio"
46
+ checked={isChecked}
47
+ onChange={onChange}
48
+ disabled={isDisabled}
49
+ required={isRequired}
50
+ aria-label={isLabelHidden ? label : undefined}
51
+ id={radioId}
52
+ name={name}
53
+ value={value}
54
+ />
55
+ <div className={styles.radio__radioMark} />
56
+ </span>
57
+ {!isLabelHidden && (
58
+ <Flex isColumn={true}>
59
+ <Text
60
+ type={isSmall ? "tiny" : "small"}
61
+ fontWeight="medium"
62
+ emphasis={isDisabled ? "tertiary" : "inherit"}
63
+ >
64
+ {label}
64
65
  </Text>
65
- )}
66
- </Flex>
67
- )}
68
- </label>
69
- </div>
70
- )
71
- }
66
+ {description && (
67
+ <Text type="tiny" emphasis="secondary">
68
+ {description}
69
+ </Text>
70
+ )}
71
+ </Flex>
72
+ )}
73
+ </label>
74
+ </div>
75
+ )
76
+ },
77
+ )
@@ -2,10 +2,10 @@
2
2
 
3
3
  import {
4
4
  type FC,
5
- type Ref,
6
5
  useState,
7
6
  useRef,
8
7
  useEffect,
8
+ useCallback,
9
9
  Children,
10
10
  isValidElement,
11
11
  cloneElement,
@@ -18,10 +18,6 @@ import { SegmentButton } from "./components/SegmentButton"
18
18
  import type { SegmentsProps } from "./Segments.types"
19
19
  import type { SegmentButtonProps } from "./components/SegmentButton/SegmentButton.types"
20
20
 
21
- type SegmentButtonWithRef = SegmentButtonProps & {
22
- ref?: Ref<HTMLButtonElement>
23
- }
24
-
25
21
  export const Segments: FC<SegmentsProps> = ({ children, isFullWidth, isSmall }) => {
26
22
  const validChildren: ReactElement<SegmentButtonProps>[] = Children.toArray(children).filter(
27
23
  (child): child is ReactElement<SegmentButtonProps> => isValidElement(child) && child.type === SegmentButton,
@@ -35,7 +31,7 @@ export const Segments: FC<SegmentsProps> = ({ children, isFullWidth, isSmall })
35
31
  const containerRef = useRef<HTMLDivElement>(null)
36
32
  const sliderRef = useRef<HTMLDivElement>(null)
37
33
 
38
- const updateSliderPosition = (): void => {
34
+ const updateSliderPosition = useCallback((): void => {
39
35
  if (!containerRef.current || !sliderRef.current || !activeValue) return
40
36
 
41
37
  const activeIndex: number = validChildren.findIndex((child) => child.props.value === activeValue)
@@ -52,19 +48,18 @@ export const Segments: FC<SegmentsProps> = ({ children, isFullWidth, isSmall })
52
48
  sliderRef.current.style.transform = `translateX(${left}px)`
53
49
  sliderRef.current.style.width = `${width}px`
54
50
  sliderRef.current.style.opacity = "1"
55
- }
51
+ }, [activeValue, validChildren])
56
52
 
57
53
  useEffect(() => {
58
54
  const timer: ReturnType<typeof setTimeout> = setTimeout(updateSliderPosition, 0)
59
- const handleResize = (): void => updateSliderPosition()
60
55
 
61
- globalThis.addEventListener("resize", handleResize)
56
+ globalThis.addEventListener("resize", updateSliderPosition)
62
57
 
63
58
  return (): void => {
64
59
  globalThis.clearTimeout(timer)
65
- globalThis.removeEventListener("resize", handleResize)
60
+ globalThis.removeEventListener("resize", updateSliderPosition)
66
61
  }
67
- }, [activeValue])
62
+ }, [updateSliderPosition])
68
63
 
69
64
  const segmentedControlClasses: string = getClasses(styles.segmentedControl, {
70
65
  [styles.segmentedControlSmall]: isSmall,
@@ -74,7 +69,7 @@ export const Segments: FC<SegmentsProps> = ({ children, isFullWidth, isSmall })
74
69
  return (
75
70
  <Flex className={segmentedControlClasses} isYCentered={true} gap={2} isInline={!isFullWidth} ref={containerRef}>
76
71
  {validChildren.map((child: ReactElement<SegmentButtonProps>, index: number) =>
77
- cloneElement<SegmentButtonWithRef>(child, {
72
+ cloneElement<SegmentButtonProps>(child, {
78
73
  key: child.props.value,
79
74
  isActive: child.props.value === activeValue,
80
75
  onClick: () => {
@@ -26,6 +26,10 @@ export const meta: HeliosAttributeMeta<SegmentButtonProps> = {
26
26
  type: "() => void",
27
27
  isOptional: true,
28
28
  },
29
+ ref: {
30
+ type: "Ref<HTMLButtonElement>",
31
+ isOptional: true,
32
+ },
29
33
  value: {
30
34
  type: "string",
31
35
  },
@@ -1,24 +1,21 @@
1
1
  import styles from "./SegmentButton.module.css"
2
- import { forwardRef } from "react"
3
2
  import { getClasses } from "@heliosgraphics/utils"
4
3
  import { Icon } from "../../../Icon"
5
4
  import type { HeliosIconType } from "../../../../types/icons"
6
5
  import type { SegmentButtonProps } from "./SegmentButton.types"
7
6
 
8
- export const SegmentButton = forwardRef<HTMLButtonElement, SegmentButtonProps>(
9
- ({ isActive, value, icon, iconLeft, iconRight, onClick }, ref) => {
10
- const segmentButtonClasses: string = getClasses(styles.segmentButton, {
11
- [styles.segmentButtonActive]: isActive,
12
- })
7
+ export const SegmentButton = ({ isActive, value, icon, iconLeft, iconRight, onClick, ref }: SegmentButtonProps) => {
8
+ const segmentButtonClasses: string = getClasses(styles.segmentButton, {
9
+ [styles.segmentButtonActive]: isActive,
10
+ })
13
11
 
14
- const iconL: HeliosIconType | undefined = iconLeft || icon
12
+ const iconL: HeliosIconType | undefined = iconLeft || icon
15
13
 
16
- return (
17
- <button ref={ref} className={segmentButtonClasses} onClick={onClick} data-ui-component="SegmentButton">
18
- {iconL && <Icon icon={iconL} size={16} />}
19
- {value}
20
- {iconRight && <Icon icon={iconRight} size={16} />}
21
- </button>
22
- )
23
- },
24
- )
14
+ return (
15
+ <button ref={ref} className={segmentButtonClasses} onClick={onClick} data-ui-component="SegmentButton">
16
+ {iconL && <Icon icon={iconL} size={16} />}
17
+ {value}
18
+ {iconRight && <Icon icon={iconRight} size={16} />}
19
+ </button>
20
+ )
21
+ }
@@ -1,3 +1,4 @@
1
+ import type { Ref } from "react"
1
2
  import type { HeliosIconType } from "../../../../types/icons"
2
3
 
3
4
  export interface SegmentButtonProps {
@@ -6,5 +7,6 @@ export interface SegmentButtonProps {
6
7
  iconRight?: HeliosIconType
7
8
  isActive?: boolean
8
9
  onClick?: () => void
10
+ ref?: Ref<HTMLButtonElement>
9
11
  value: string
10
12
  }
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { Flex } from "../Flex"
4
4
  import { Icon } from "../Icon"
5
- import { getClasses } from "@heliosgraphics/utils/classnames"
5
+ import { getClasses } from "@heliosgraphics/utils"
6
6
  import { useId, type FC } from "react"
7
7
  import { InputLabel } from "../shared/InputLabel"
8
8
  import styles from "./Select.module.css"
@@ -26,7 +26,7 @@ export const Select: FC<SelectProps> = ({
26
26
  })
27
27
 
28
28
  return (
29
- <Flex isColumn={true} className={selectClasses}>
29
+ <Flex isColumn={true} className={selectClasses} data-ui-component="Select">
30
30
  <InputLabel label={label} id={htmlFor} isHidden={!!isLabelHidden} isDisabled={!!isDisabled} />
31
31
  <Flex>
32
32
  <select
@@ -34,11 +34,12 @@ export const Select: FC<SelectProps> = ({
34
34
  onChange={onChange}
35
35
  id={htmlFor}
36
36
  value={selectedValue}
37
+ disabled={isDisabled}
37
38
  aria-label={isLabelHidden ? label : undefined}
38
39
  >
39
- {items?.map((item, key) => {
40
+ {items?.map((item) => {
40
41
  return (
41
- <option key={key} value={item.value} disabled={item.isDisabled}>
42
+ <option key={item.value} value={item.value} disabled={item.isDisabled}>
42
43
  {item.name}
43
44
  </option>
44
45
  )
@@ -1,4 +1,4 @@
1
- import { getClasses } from "@heliosgraphics/utils/classnames"
1
+ import { getClasses } from "@heliosgraphics/utils"
2
2
  import { HRMarkup } from "../HRMarkup"
3
3
  import styles from "./HorizontalSeparator.module.css"
4
4
  import type { FC } from "react"
@@ -1,4 +1,4 @@
1
- import { getClasses } from "@heliosgraphics/utils/classnames"
1
+ import { getClasses } from "@heliosgraphics/utils"
2
2
  import { HRMarkup } from "../HRMarkup"
3
3
  import styles from "./VerticalSeparator.module.css"
4
4
  import type { FC } from "react"
@@ -1,7 +1,7 @@
1
1
  @layer helios;
2
2
 
3
- @import "@heliosgraphics/css/dist/css.min.layered.css";
4
- @import "@heliosgraphics/css/dist/css.easings.layered.css";
3
+ @import "@heliosgraphics/css/layered";
4
+ @import "@heliosgraphics/css/easings/layered";
5
5
 
6
6
  @import "./css/core.colors.css";
7
7
  @import "./css/core.colors-helpers.css";
@@ -12,11 +12,11 @@ export const meta: HeliosAttributeMeta<SetupProps> = {
12
12
  _status: "nominal",
13
13
  _category: "meta",
14
14
  fixedTheme: {
15
- type: "HeliosThemeType",
15
+ type: "HeliosFixedThemeType",
16
16
  isOptional: true,
17
17
  },
18
18
  theme: {
19
- type: "HeliosFixedThemeType",
19
+ type: "HeliosThemeType",
20
20
  isOptional: true,
21
21
  },
22
22
  }
@@ -1,4 +1,4 @@
1
- import "../../components.css"
1
+ import "./Setup.components.css"
2
2
 
3
3
  import type { FC } from "react"
4
4
  import type { HeliosFixedThemeType } from "../../types/themes"
@@ -19,13 +19,15 @@ declare global {
19
19
 
20
20
  export const Setup: FC<SetupProps> = ({ theme = "system", fixedTheme }) => {
21
21
  const preconnectLinks: Array<SetupLinkProps> = [
22
- { rel: "preconnect", href: "https://rsms.me/", crossOrigin: "anonymous" },
22
+ { id: "rsms", rel: "preconnect", href: "https://rsms.me/", crossOrigin: "anonymous" },
23
23
  {
24
+ id: "googleapis",
24
25
  rel: "preconnect",
25
26
  href: "https://fonts.googleapis.com",
26
27
  crossOrigin: "anonymous",
27
28
  },
28
29
  {
30
+ id: "gstatic",
29
31
  rel: "preconnect",
30
32
  href: "https://fonts.gstatic.com",
31
33
  crossOrigin: "anonymous",
@@ -33,8 +35,9 @@ export const Setup: FC<SetupProps> = ({ theme = "system", fixedTheme }) => {
33
35
  ]
34
36
 
35
37
  const stylesheetLinks: Array<SetupLinkProps> = [
36
- { rel: "stylesheet", href: "https://rsms.me/inter/inter.css" },
38
+ { id: "rsms", rel: "stylesheet", href: "https://rsms.me/inter/inter.css" },
37
39
  {
40
+ id: "googleapis",
38
41
  rel: "stylesheet",
39
42
  href: "https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&display=swap",
40
43
  },
@@ -44,11 +47,11 @@ export const Setup: FC<SetupProps> = ({ theme = "system", fixedTheme }) => {
44
47
 
45
48
  return (
46
49
  <>
47
- {preconnectLinks.map((linkProps, index) => (
48
- <link key={`preconnect-${index}`} {...linkProps} />
50
+ {preconnectLinks.map((linkProps) => (
51
+ <link key={`preconnect-${linkProps.id}`} {...linkProps} />
49
52
  ))}
50
- {stylesheetLinks.map((linkProps, index) => (
51
- <link key={`stylesheet-${index}`} {...linkProps} />
53
+ {stylesheetLinks.map((linkProps) => (
54
+ <link key={`stylesheet-${linkProps.id}`} {...linkProps} />
52
55
  ))}
53
56
  <script
54
57
  dangerouslySetInnerHTML={{
@@ -6,6 +6,7 @@ export interface SetupProps {
6
6
  }
7
7
 
8
8
  export interface SetupLinkProps {
9
+ id: string
9
10
  rel: string
10
11
  href: string
11
12
  crossOrigin?: "anonymous" | "use-credentials"
@@ -1,5 +1,5 @@
1
- import { ShimmerProps } from "./Shimmer.types"
2
- import { getClasses } from "@heliosgraphics/utils/classnames"
1
+ import type { ShimmerProps } from "./Shimmer.types"
2
+ import { getClasses } from "@heliosgraphics/utils"
3
3
  import styles from "./Shimmer.module.css"
4
4
  import type { FC } from "react"
5
5
 
@@ -12,6 +12,7 @@ export const Shimmer: FC<ShimmerProps> = ({ isRounded, paddingTop, paddingBottom
12
12
  return (
13
13
  <div
14
14
  className={styles.shimmer}
15
+ data-ui-component="Shimmer"
15
16
  role="status"
16
17
  aria-busy={true}
17
18
  aria-label="Loading"
@@ -1,4 +1,4 @@
1
- import { getClasses } from "@heliosgraphics/utils/classnames"
1
+ import { getClasses } from "@heliosgraphics/utils"
2
2
  import styles from "./Slider.module.css"
3
3
  import type { FC } from "react"
4
4
  import type { SliderProps } from "./Slider.types"
@@ -7,9 +7,9 @@ export const Slider: FC<SliderProps> = ({ items }) => {
7
7
  const sliderClasses: string = getClasses(styles.slider, "flex")
8
8
 
9
9
  return (
10
- <ul className={sliderClasses}>
11
- {items?.map((item, key) => (
12
- <li key={key}>{item}</li>
10
+ <ul className={sliderClasses} data-ui-component="Slider">
11
+ {items?.map((item, index) => (
12
+ <li key={`slider-${index}`}>{item}</li>
13
13
  ))}
14
14
  </ul>
15
15
  )
@@ -2,5 +2,5 @@ import { memo, type FC } from "react"
2
2
  import type { SpacerProps } from "./Spacer.types"
3
3
 
4
4
  export const Spacer: FC<SpacerProps> = memo(({ gap }) => {
5
- return <div style={{ height: `${gap ?? 0}px` }} />
5
+ return <div style={{ height: `${gap ?? 0}px` }} data-ui-component="Spacer" />
6
6
  })
@@ -12,7 +12,7 @@ export const Table: FC<TableProps> = ({ children, hasBorder, isMonoHeader }) =>
12
12
  })
13
13
 
14
14
  return (
15
- <div className={tableClasses}>
15
+ <div className={tableClasses} data-ui-component="Table">
16
16
  <table className={tableElementClasses}>{children}</table>
17
17
  </div>
18
18
  )