@kaizen/components 0.0.0-canary-update-floating-fms-20250715035144 → 0.0.0-canary-handle-avatar-error-20250716233812

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 (140) hide show
  1. package/dist/cjs/alpha.cjs +4 -0
  2. package/dist/cjs/src/Avatar/Avatar.cjs +3 -2
  3. package/dist/cjs/src/Button/Button/Button.cjs +5 -0
  4. package/dist/cjs/src/Button/IconButton/IconButton.cjs +5 -0
  5. package/dist/cjs/src/Filter/FilterMultiSelect/FilterMultiSelect.cjs +3 -7
  6. package/dist/cjs/src/Filter/FilterMultiSelect/subcomponents/ListBox/ListBox.cjs +1 -1
  7. package/dist/cjs/src/Filter/FilterMultiSelect/subcomponents/ListBox/ListBox.module.scss.cjs +9 -0
  8. package/dist/cjs/src/Filter/FilterMultiSelect/subcomponents/ListBoxSection/ListBoxSection.cjs +2 -1
  9. package/dist/cjs/src/Filter/FilterMultiSelect/subcomponents/MenuPopup/MenuPopup.cjs +38 -69
  10. package/dist/cjs/src/Filter/FilterMultiSelect/subcomponents/MenuPopup/{MenuPopup.module.css.cjs → MenuPopup.module.scss.cjs} +1 -1
  11. package/dist/cjs/src/LikertScaleLegacy/LikertScaleLegacy.cjs +3 -0
  12. package/dist/cjs/src/Modal/GenericModal/GenericModal.cjs +11 -1
  13. package/dist/cjs/src/Skirt/Skirt.cjs +3 -0
  14. package/dist/cjs/src/Skirt/subcomponents/SkirtCard/SkirtCard.cjs +4 -0
  15. package/dist/cjs/src/SplitButton/SplitButton.cjs +2 -0
  16. package/dist/cjs/src/TitleBlockZen/TitleBlockZen.cjs +3 -0
  17. package/dist/cjs/src/__alpha__/SingleSelect/SingleSelect.cjs +32 -0
  18. package/dist/cjs/src/__alpha__/SingleSelect/SingleSelect.module.css.cjs +6 -0
  19. package/dist/cjs/src/__alpha__/SingleSelect/subcomponents/List/List.cjs +24 -0
  20. package/dist/cjs/src/__alpha__/SingleSelect/subcomponents/List/List.module.css.cjs +6 -0
  21. package/dist/cjs/src/__alpha__/SingleSelect/subcomponents/ListItem/ListItem.cjs +24 -0
  22. package/dist/cjs/src/__alpha__/SingleSelect/subcomponents/ListItem/ListItem.module.css.cjs +6 -0
  23. package/dist/cjs/src/__alpha__/SingleSelect/subcomponents/ListSection/ListSection.cjs +25 -0
  24. package/dist/cjs/src/__alpha__/SingleSelect/subcomponents/ListSection/ListSection.module.css.cjs +6 -0
  25. package/dist/cjs/src/__alpha__/SingleSelect/subcomponents/Trigger/Trigger.cjs +21 -0
  26. package/dist/cjs/src/__alpha__/SingleSelect/subcomponents/Trigger/Trigger.module.css.cjs +6 -0
  27. package/dist/esm/alpha.mjs +1 -0
  28. package/dist/esm/src/Avatar/Avatar.mjs +3 -2
  29. package/dist/esm/src/Button/Button/Button.mjs +5 -0
  30. package/dist/esm/src/Button/IconButton/IconButton.mjs +5 -0
  31. package/dist/esm/src/Filter/FilterMultiSelect/FilterMultiSelect.mjs +3 -7
  32. package/dist/esm/src/Filter/FilterMultiSelect/subcomponents/ListBox/ListBox.mjs +1 -1
  33. package/dist/esm/src/Filter/FilterMultiSelect/subcomponents/ListBox/ListBox.module.scss.mjs +7 -0
  34. package/dist/esm/src/Filter/FilterMultiSelect/subcomponents/ListBoxSection/ListBoxSection.mjs +2 -1
  35. package/dist/esm/src/Filter/FilterMultiSelect/subcomponents/MenuPopup/MenuPopup.mjs +41 -70
  36. package/dist/esm/src/Filter/FilterMultiSelect/subcomponents/MenuPopup/MenuPopup.module.scss.mjs +4 -0
  37. package/dist/esm/src/LikertScaleLegacy/LikertScaleLegacy.mjs +3 -0
  38. package/dist/esm/src/Modal/GenericModal/GenericModal.mjs +11 -1
  39. package/dist/esm/src/Skirt/Skirt.mjs +3 -0
  40. package/dist/esm/src/Skirt/subcomponents/SkirtCard/SkirtCard.mjs +4 -0
  41. package/dist/esm/src/SplitButton/SplitButton.mjs +2 -0
  42. package/dist/esm/src/TitleBlockZen/TitleBlockZen.mjs +3 -0
  43. package/dist/esm/src/__alpha__/SingleSelect/SingleSelect.mjs +27 -0
  44. package/dist/esm/src/__alpha__/SingleSelect/SingleSelect.module.css.mjs +4 -0
  45. package/dist/esm/src/__alpha__/SingleSelect/subcomponents/List/List.mjs +18 -0
  46. package/dist/esm/src/__alpha__/SingleSelect/subcomponents/List/List.module.css.mjs +4 -0
  47. package/dist/esm/src/__alpha__/SingleSelect/subcomponents/ListItem/ListItem.mjs +18 -0
  48. package/dist/esm/src/__alpha__/SingleSelect/subcomponents/ListItem/ListItem.module.css.mjs +4 -0
  49. package/dist/esm/src/__alpha__/SingleSelect/subcomponents/ListSection/ListSection.mjs +19 -0
  50. package/dist/esm/src/__alpha__/SingleSelect/subcomponents/ListSection/ListSection.module.css.mjs +4 -0
  51. package/dist/esm/src/__alpha__/SingleSelect/subcomponents/Trigger/Trigger.mjs +13 -0
  52. package/dist/esm/src/__alpha__/SingleSelect/subcomponents/Trigger/Trigger.module.css.mjs +4 -0
  53. package/dist/styles.css +81 -29
  54. package/dist/types/Button/Button/Button.d.ts +5 -0
  55. package/dist/types/Button/IconButton/IconButton.d.ts +5 -0
  56. package/dist/types/Filter/FilterMultiSelect/FilterMultiSelect.d.ts +1 -1
  57. package/dist/types/Filter/FilterMultiSelect/_docs/MockData.d.ts +0 -1
  58. package/dist/types/Filter/FilterMultiSelect/subcomponents/MenuPopup/MenuPopup.d.ts +4 -11
  59. package/dist/types/LikertScaleLegacy/LikertScaleLegacy.d.ts +3 -0
  60. package/dist/types/Skirt/Skirt.d.ts +3 -0
  61. package/dist/types/Skirt/subcomponents/SkirtCard/SkirtCard.d.ts +3 -0
  62. package/dist/types/SplitButton/SplitButton.d.ts +2 -0
  63. package/dist/types/TitleBlockZen/TitleBlockZen.d.ts +3 -0
  64. package/dist/types/__alpha__/SingleSelect/SingleSelect.d.ts +23 -0
  65. package/dist/types/__alpha__/SingleSelect/_docs/mockData.d.ts +59 -0
  66. package/dist/types/__alpha__/SingleSelect/index.d.ts +1 -0
  67. package/dist/types/__alpha__/SingleSelect/subcomponents/List/List.d.ts +6 -0
  68. package/dist/types/__alpha__/SingleSelect/subcomponents/List/index.d.ts +1 -0
  69. package/dist/types/__alpha__/SingleSelect/subcomponents/ListItem/ListItem.d.ts +6 -0
  70. package/dist/types/__alpha__/SingleSelect/subcomponents/ListItem/index.d.ts +1 -0
  71. package/dist/types/__alpha__/SingleSelect/subcomponents/ListSection/ListSection.d.ts +8 -0
  72. package/dist/types/__alpha__/SingleSelect/subcomponents/ListSection/index.d.ts +1 -0
  73. package/dist/types/__alpha__/SingleSelect/subcomponents/Trigger/Trigger.d.ts +1 -0
  74. package/dist/types/__alpha__/SingleSelect/subcomponents/Trigger/index.d.ts +1 -0
  75. package/dist/types/__alpha__/SingleSelect/subcomponents/index.d.ts +4 -0
  76. package/dist/types/__alpha__/index.d.ts +1 -0
  77. package/package.json +1 -1
  78. package/src/Avatar/Avatar.tsx +5 -2
  79. package/src/Avatar/_docs/Avatar.stickersheet.stories.tsx +2 -2
  80. package/src/Button/Button/Button.tsx +5 -0
  81. package/src/Button/IconButton/IconButton.tsx +5 -0
  82. package/src/Filter/FilterBar/subcomponents/FilterBarMultiSelect/FilterBarMultiSelect.spec.tsx +0 -1
  83. package/src/Filter/FilterMultiSelect/FilterMultiSelect.tsx +2 -3
  84. package/src/Filter/FilterMultiSelect/_docs/FilterMultiSelect.mdx +0 -10
  85. package/src/Filter/FilterMultiSelect/_docs/FilterMultiSelect.stories.tsx +1 -178
  86. package/src/Filter/FilterMultiSelect/_docs/MockData.ts +0 -39
  87. package/src/Filter/FilterMultiSelect/context/MenuTriggerProvider/MenuTriggerProvider.spec.tsx +18 -2
  88. package/src/Filter/FilterMultiSelect/subcomponents/ListBox/ListBox.module.scss +25 -0
  89. package/src/Filter/FilterMultiSelect/subcomponents/ListBox/ListBox.tsx +1 -1
  90. package/src/Filter/FilterMultiSelect/subcomponents/ListBoxSection/ListBoxSection.tsx +1 -1
  91. package/src/Filter/FilterMultiSelect/subcomponents/MenuPopup/MenuPopup.module.scss +24 -0
  92. package/src/Filter/FilterMultiSelect/subcomponents/MenuPopup/MenuPopup.tsx +42 -89
  93. package/src/LikertScaleLegacy/LikertScaleLegacy.tsx +3 -0
  94. package/src/LikertScaleLegacy/_docs/LikertScaleLegacy.mdx +3 -2
  95. package/src/LikertScaleLegacy/_docs/LikertScaleLegacy.stickersheet.stories.tsx +1 -1
  96. package/src/LikertScaleLegacy/_docs/LikertScaleLegacy.stories.tsx +1 -1
  97. package/src/Modal/GenericModal/GenericModal.tsx +18 -1
  98. package/src/Skirt/Skirt.tsx +4 -0
  99. package/src/Skirt/_docs/Skirt.mdx +3 -1
  100. package/src/Skirt/_docs/Skirt.stories.tsx +1 -1
  101. package/src/Skirt/subcomponents/SkirtCard/SkirtCard.tsx +4 -0
  102. package/src/SplitButton/SplitButton.tsx +2 -0
  103. package/src/SplitButton/_docs/SplitButton.mdx +3 -1
  104. package/src/SplitButton/_docs/SplitButton.stickersheet.stories.tsx +1 -1
  105. package/src/SplitButton/_docs/SplitButton.stories.tsx +1 -1
  106. package/src/TitleBlockZen/TitleBlockZen.tsx +3 -0
  107. package/src/TitleBlockZen/_docs/TitleBlockZen.mdx +3 -2
  108. package/src/__alpha__/SingleSelect/SingleSelect.module.css +9 -0
  109. package/src/__alpha__/SingleSelect/SingleSelect.spec.tsx +26 -0
  110. package/src/__alpha__/SingleSelect/SingleSelect.tsx +27 -0
  111. package/src/__alpha__/SingleSelect/_docs/SingleSelect.mdx +27 -0
  112. package/src/__alpha__/SingleSelect/_docs/SingleSelect.stickersheet.stories.tsx +83 -0
  113. package/src/__alpha__/SingleSelect/_docs/SingleSelect.stories.tsx +23 -0
  114. package/src/__alpha__/SingleSelect/_docs/mockData.ts +92 -0
  115. package/src/__alpha__/SingleSelect/index.ts +1 -0
  116. package/src/__alpha__/SingleSelect/subcomponents/List/List.module.css +7 -0
  117. package/src/__alpha__/SingleSelect/subcomponents/List/List.tsx +17 -0
  118. package/src/__alpha__/SingleSelect/subcomponents/List/index.ts +1 -0
  119. package/src/__alpha__/SingleSelect/subcomponents/ListItem/ListItem.module.css +9 -0
  120. package/src/__alpha__/SingleSelect/subcomponents/ListItem/ListItem.tsx +17 -0
  121. package/src/__alpha__/SingleSelect/subcomponents/ListItem/index.ts +1 -0
  122. package/src/__alpha__/SingleSelect/subcomponents/ListSection/ListSection.module.css +9 -0
  123. package/src/__alpha__/SingleSelect/subcomponents/ListSection/ListSection.tsx +23 -0
  124. package/src/__alpha__/SingleSelect/subcomponents/ListSection/index.ts +1 -0
  125. package/src/__alpha__/SingleSelect/subcomponents/Trigger/Trigger.module.css +18 -0
  126. package/src/__alpha__/SingleSelect/subcomponents/Trigger/Trigger.tsx +13 -0
  127. package/src/__alpha__/SingleSelect/subcomponents/Trigger/index.ts +1 -0
  128. package/src/__alpha__/SingleSelect/subcomponents/index.ts +4 -0
  129. package/src/__alpha__/index.ts +1 -0
  130. package/src/__next__/Button/_docs/Button--api-specification.mdx +6 -0
  131. package/src/__next__/Button/_docs/Button.docs.stories.tsx +29 -0
  132. package/src/__next__/Menu/_docs/Menu--api-specification.mdx +6 -0
  133. package/src/__next__/Menu/_docs/Menu.stories.tsx +29 -0
  134. package/src/__next__/Tabs/subcomponents/TabList/TabList.module.css +3 -1
  135. package/dist/cjs/src/Filter/FilterMultiSelect/subcomponents/ListBox/ListBox.module.css.cjs +0 -9
  136. package/dist/esm/src/Filter/FilterMultiSelect/subcomponents/ListBox/ListBox.module.css.mjs +0 -7
  137. package/dist/esm/src/Filter/FilterMultiSelect/subcomponents/MenuPopup/MenuPopup.module.css.mjs +0 -4
  138. package/src/Filter/FilterMultiSelect/_docs/FilterMultiSelectReportsTest.stories.tsx +0 -328
  139. package/src/Filter/FilterMultiSelect/subcomponents/ListBox/ListBox.module.css +0 -22
  140. package/src/Filter/FilterMultiSelect/subcomponents/MenuPopup/MenuPopup.module.css +0 -22
@@ -0,0 +1,24 @@
1
+ @import '~@kaizen/design-tokens/sass/spacing';
2
+ @import '~@kaizen/design-tokens/sass/shadow';
3
+ @import '~@kaizen/design-tokens/sass/border';
4
+ @import '~@kaizen/design-tokens/sass/color';
5
+
6
+ @layer kz-components {
7
+ // figma hard coded: https://www.figma.com/file/eZKEE5kXbEMY3lx84oz8iN/%E2%9D%A4%EF%B8%8F-UI-Kit%3A-Heart?node-id=22814%3A96966
8
+ $menu-container-width: 294px;
9
+ $menu-container-max-height: 312px;
10
+
11
+ .menuPopup {
12
+ position: absolute;
13
+ z-index: 1000; // from $ca-z-index-dropdown
14
+ box-sizing: border-box;
15
+ background: $color-white;
16
+ color: $color-purple-800;
17
+ border-radius: $border-solid-border-radius;
18
+ box-shadow: $shadow-large-box-shadow;
19
+ padding: $spacing-sm 0;
20
+ margin-top: $spacing-xs;
21
+ text-align: start;
22
+ width: $menu-container-width;
23
+ }
24
+ }
@@ -1,105 +1,58 @@
1
- import React, { useEffect, useState, type HTMLAttributes } from 'react'
2
- import {
3
- autoPlacement,
4
- autoUpdate,
5
- offset,
6
- size,
7
- useFloating,
8
- type UseFloatingOptions,
9
- } from '@floating-ui/react-dom'
10
- import classnames from 'classnames'
11
- import { FocusOn } from 'react-focus-on'
12
- import { type OverrideClassName } from '~components/types/OverrideClassName'
1
+ import React from 'react'
2
+ import { FocusScope } from '@react-aria/focus'
3
+ import { DismissButton, useOverlay } from '@react-aria/overlays'
13
4
  import { useMenuTriggerContext } from '../../context'
14
- import styles from './MenuPopup.module.css'
15
-
16
- export type FloatingConfig = Pick<
17
- UseFloatingOptions,
18
- 'placement' | 'strategy' | 'whileElementsMounted'
19
- > & {
20
- shouldResize?: boolean
21
- shouldFlip?: boolean
22
- }
5
+ import styles from './MenuPopup.module.scss'
23
6
 
24
7
  export type MenuPopupProps = {
25
- children: React.ReactNode
26
8
  isLoading?: boolean
27
9
  loadingSkeleton?: React.ReactNode
28
- floatingConfig?: FloatingConfig
29
- } & OverrideClassName<HTMLAttributes<HTMLDivElement>>
10
+ children: React.ReactNode
11
+ }
30
12
 
31
13
  export const MenuPopup = ({
32
- children,
33
- floatingConfig = {
34
- placement: 'bottom-start',
35
- strategy: 'absolute',
36
- whileElementsMounted: autoUpdate,
37
- },
38
- classNameOverride,
39
14
  isLoading,
40
15
  loadingSkeleton,
41
- ...restProps
16
+ children,
42
17
  }: MenuPopupProps): JSX.Element => {
43
- const [floatingElement, setFloatingElement] = useState<HTMLDivElement | null>(null)
44
- const { menuTriggerState, buttonRef } = useMenuTriggerContext()
45
- const referenceElement = buttonRef.current
46
-
47
- const { floatingStyles, update } = useFloating({
48
- elements: {
49
- reference: referenceElement,
50
- floating: floatingElement,
18
+ const { menuTriggerState } = useMenuTriggerContext()
19
+
20
+ const onClose = (): void => menuTriggerState.close()
21
+
22
+ // Handle events that should cause the menu to close,
23
+ // e.g. blur, clicking outside, or pressing the escape key.
24
+ const overlayRef = React.createRef<HTMLDivElement>()
25
+ const { overlayProps } = useOverlay(
26
+ {
27
+ onClose,
28
+ isOpen: menuTriggerState.isOpen,
29
+ isDismissable: true,
51
30
  },
52
- middleware: [
53
- offset(6),
54
- floatingConfig.shouldFlip &&
55
- autoPlacement({ allowedPlacements: ['bottom-start', 'top-start'] }),
56
- floatingConfig.shouldResize &&
57
- size({
58
- apply({ availableHeight, elements }) {
59
- Object.assign(elements.floating.style, {
60
- maxHeight: Math.max(250, Math.min(availableHeight - 12, 500)) + 'px',
61
- })
62
- },
63
- }),
64
- ],
65
- ...floatingConfig,
66
- })
67
-
68
- const handleReturnFocus = (): void => {
69
- requestAnimationFrame(() => {
70
- buttonRef.current?.focus()
71
- })
72
- }
73
-
74
- useEffect(() => {
75
- if (floatingElement && referenceElement) {
76
- floatingElement.showPopover?.()
77
- update()
78
- }
79
- }, [floatingElement, referenceElement, update])
31
+ overlayRef,
32
+ )
80
33
 
34
+ // Wrap in <FocusScope> so that focus is restored back to the trigger when the menu is closed
35
+ // and auto focus on the first focusable item after loading. (disable eslint no-autofocus error for it)
36
+ // In addition, add hidden <DismissButton> components at the start and end of the list
37
+ // to allow screen reader users to dismiss the popup easily.
81
38
  return menuTriggerState.isOpen ? (
82
- <FocusOn
83
- enabled={menuTriggerState.isOpen}
84
- scrollLock={false}
85
- returnFocus={false}
86
- onClickOutside={menuTriggerState.close}
87
- onEscapeKey={menuTriggerState.close}
88
- onDeactivation={handleReturnFocus}
89
- >
90
- <div
91
- ref={setFloatingElement}
92
- style={floatingStyles}
93
- className={classnames(styles.menuPopup, classNameOverride)}
94
- role="dialog"
95
- aria-modal="true"
96
- // @ts-expect-error: popover is valid in supported browsers
97
- popover="manual"
98
- {...restProps}
99
- >
100
- {isLoading && loadingSkeleton ? loadingSkeleton : children}
101
- </div>
102
- </FocusOn>
39
+ <div {...overlayProps} ref={overlayRef} className={styles.menuPopup}>
40
+ {isLoading && loadingSkeleton ? (
41
+ <>
42
+ <DismissButton onDismiss={onClose} />
43
+ {loadingSkeleton}
44
+ <DismissButton onDismiss={onClose} />
45
+ </>
46
+ ) : (
47
+ // eslint-disable-next-line jsx-a11y/no-autofocus
48
+ <FocusScope contain autoFocus restoreFocus>
49
+ <DismissButton onDismiss={onClose} />
50
+
51
+ {children}
52
+ <DismissButton onDismiss={onClose} />
53
+ </FocusScope>
54
+ )}
55
+ </div>
103
56
  ) : (
104
57
  <></>
105
58
  )
@@ -37,6 +37,9 @@ const SelectedItemIcon = (): JSX.Element => (
37
37
  )
38
38
 
39
39
  /**
40
+ * @deprecated This component will be renamed to LikertScale in v2.
41
+ * Start importing as LikertScale instead.
42
+ *
40
43
  * {@link https://cultureamp.atlassian.net/wiki/spaces/DesignSystem/pages/3082060201/Likert+Scale Guidance} |
41
44
  * {@link https://cultureamp.design/?path=/docs/components-likertscalelegacy--docs Storybook}
42
45
  */
@@ -1,5 +1,5 @@
1
1
  import { Canvas, Controls, Meta } from '@storybook/blocks'
2
- import { ResourceLinks, KAIOInstallation } from '~storybook/components'
2
+ import { ResourceLinks, KAIOInstallation, RenameNotice } from '~storybook/components'
3
3
  import * as LikertScaleLegacyStories from './LikertScaleLegacy.stories'
4
4
 
5
5
  <Meta of={LikertScaleLegacyStories} />
@@ -10,9 +10,10 @@ import * as LikertScaleLegacyStories from './LikertScaleLegacy.stories'
10
10
  sourceCode="https://github.com/cultureamp/kaizen-design-system/tree/main/packages/components/src/LikertScaleLegacy"
11
11
  figma="https://www.figma.com/file/ZRfnoNUXbGZv4eVWLbF4Az/%EF%B8%8F%F0%9F%96%BC%EF%B8%8F-Component-Gallery?node-id=9%3A39905&t=P1w10jr2cpPuaayw-1"
12
12
  designGuidelines="https://cultureamp.atlassian.net/wiki/spaces/DesignSystem/pages/3082060201/Likert+Scale"
13
-
14
13
  />
15
14
 
15
+ <RenameNotice />
16
+
16
17
  <KAIOInstallation exportNames="LikertScaleLegacy" />
17
18
 
18
19
  ## Overview
@@ -5,7 +5,7 @@ import { LikertScaleLegacy, type LikertScaleProps } from '../index'
5
5
  import { type Scale } from '../types'
6
6
 
7
7
  export default {
8
- title: 'Components/LikertScaleLegacy',
8
+ title: 'Components/LikertScaleLegacy (deprecated)',
9
9
  parameters: {
10
10
  chromatic: { disable: false },
11
11
  controls: { disable: true },
@@ -33,7 +33,7 @@ const scale: Scale = [
33
33
  ]
34
34
 
35
35
  const meta = {
36
- title: 'Components/LikertScaleLegacy',
36
+ title: 'Components/LikertScaleLegacy (deprecated)',
37
37
  component: LikertScaleLegacy,
38
38
  args: {
39
39
  scale,
@@ -3,6 +3,7 @@ import { createPortal } from 'react-dom'
3
3
  import { Transition } from '@headlessui/react'
4
4
  import classnames from 'classnames'
5
5
  import FocusLock from 'react-focus-lock'
6
+ import { useIsClientReady } from '../../utils/useIsClientReady'
6
7
  import { warn } from '../util/console'
7
8
  import { ModalContext } from './context/ModalContext'
8
9
  import styles from './GenericModal.module.scss'
@@ -38,6 +39,8 @@ export const GenericModal = ({
38
39
  const labelledByID = useId()
39
40
  const describedByID = useId()
40
41
 
42
+ const isClientReady = useIsClientReady()
43
+
41
44
  const [scrollLayer, setScrollLayer] = useState<HTMLDivElement | null>(null)
42
45
  const [modalLayer, setModalLayer] = useState<HTMLDivElement | null>(null)
43
46
 
@@ -58,6 +61,8 @@ export const GenericModal = ({
58
61
  }
59
62
 
60
63
  const focusOnAccessibleLabel = (): void => {
64
+ if (!isClientReady) return
65
+
61
66
  // Check if focus already exists within the modal
62
67
  if (modalLayer?.contains(document.activeElement)) {
63
68
  return
@@ -69,6 +74,8 @@ export const GenericModal = ({
69
74
  }
70
75
 
71
76
  const a11yWarn = (): void => {
77
+ if (!isClientReady) return
78
+
72
79
  // Ensure that consumers have provided an element that labels the modal
73
80
  // to meet ARIA accessibility guidelines.
74
81
  if (!document.getElementById(labelledByID)) {
@@ -80,6 +87,8 @@ export const GenericModal = ({
80
87
  }
81
88
 
82
89
  const preventBodyScroll = (): void => {
90
+ if (!isClientReady) return
91
+
83
92
  const hasScrollbar = window.innerWidth > document.documentElement.clientWidth
84
93
  const scrollStyles = [styles.unscrollable]
85
94
 
@@ -111,12 +120,14 @@ export const GenericModal = ({
111
120
  const onBeforeEnterHandler = (): void => {
112
121
  preventBodyScroll()
113
122
 
114
- if (onEscapeKeyup) {
123
+ if (onEscapeKeyup && isClientReady) {
115
124
  document.addEventListener('keyup', escapeKeyHandler)
116
125
  }
117
126
  }
118
127
 
119
128
  const cleanUpAfterClose = (): void => {
129
+ if (!isClientReady) return
130
+
120
131
  document.documentElement.classList.remove(styles.unscrollable, styles.pseudoScrollbar)
121
132
 
122
133
  if (onEscapeKeyup) {
@@ -133,6 +144,12 @@ export const GenericModal = ({
133
144
  cleanUpAfterClose()
134
145
  propsOnAfterLeave?.()
135
146
  }
147
+
148
+ // Don't render portal during SSR
149
+ if (!isClientReady) {
150
+ return <></>
151
+ }
152
+
136
153
  return createPortal(
137
154
  <Transition
138
155
  appear={true}
@@ -17,6 +17,10 @@ export type SkirtProps = {
17
17
  titleBlockHasNavigation?: boolean
18
18
  } & ContentProps
19
19
 
20
+ /**
21
+ * @deprecated This component will be removed in v2. Please remove any usages.
22
+ */
23
+
20
24
  export const Skirt = ({
21
25
  children,
22
26
  variant = 'default',
@@ -1,5 +1,5 @@
1
1
  import { Canvas, Controls, Meta } from '@storybook/blocks'
2
- import { ResourceLinks, KAIOInstallation } from '~storybook/components'
2
+ import { ResourceLinks, KAIOInstallation, RemovalNotice } from '~storybook/components'
3
3
  import * as SkirtStories from './Skirt.stories'
4
4
 
5
5
  <Meta of={SkirtStories} />
@@ -13,6 +13,8 @@ import * as SkirtStories from './Skirt.stories'
13
13
 
14
14
  />
15
15
 
16
+ <RemovalNotice />
17
+
16
18
  <KAIOInstallation exportNames={['Skirt', 'SkirtCard']} />
17
19
 
18
20
  ## Overview
@@ -5,7 +5,7 @@ import { Skirt } from '../index'
5
5
  import { SkirtCard } from '../subcomponents/SkirtCard'
6
6
 
7
7
  const meta = {
8
- title: 'Components/Skirt',
8
+ title: 'Components/Skirt (deprecated)',
9
9
  component: Skirt,
10
10
  args: {
11
11
  children: (
@@ -5,6 +5,10 @@ import styles from './SkirtCard.module.scss'
5
5
 
6
6
  export type SkirtCardProps = CardProps
7
7
 
8
+ /**
9
+ * @deprecated This component will be removed in v2. Use a regular Card component instead.
10
+ */
11
+
8
12
  export const SkirtCard = (props: SkirtCardProps): JSX.Element => {
9
13
  const { classNameOverride, ...restProps } = props
10
14
  return <Card classNameOverride={classnames(styles.wrapper, classNameOverride)} {...restProps} />
@@ -41,6 +41,8 @@ export type SplitButtonProps = {
41
41
  } & OverrideClassName<HTMLAttributes<HTMLDivElement>>
42
42
 
43
43
  /**
44
+ * @deprecated This component will be removed in v2. Use a Button and Menu component instead.
45
+ *
44
46
  * {@link https://cultureamp.atlassian.net/wiki/spaces/DesignSystem/pages/3081896196/Split+Button Guidance} |
45
47
  * {@link https://cultureamp.design/storybook/?path=/docs/components-splitbutton--docs Storybook}
46
48
  */
@@ -1,5 +1,5 @@
1
1
  import { Canvas, Controls, DocsStory, Meta } from '@storybook/blocks'
2
- import { ResourceLinks, KAIOInstallation, LinkTo } from '~storybook/components'
2
+ import { ResourceLinks, KAIOInstallation, LinkTo, RemovalNotice } from '~storybook/components'
3
3
  import * as SplitButtonStories from './SplitButton.stories'
4
4
 
5
5
  <Meta of={SplitButtonStories} />
@@ -13,6 +13,8 @@ import * as SplitButtonStories from './SplitButton.stories'
13
13
 
14
14
  />
15
15
 
16
+ <RemovalNotice />
17
+
16
18
  <KAIOInstallation exportNames="SplitButton" />
17
19
 
18
20
  ## Overview
@@ -9,7 +9,7 @@ import { StickerSheet, type StickerSheetStory } from '~storybook/components/Stic
9
9
  import { SplitButton, type SplitButtonProps } from '../index'
10
10
 
11
11
  export default {
12
- title: 'Components/SplitButton',
12
+ title: 'Components/SplitButton (deprecated)',
13
13
  parameters: {
14
14
  chromatic: { disable: false },
15
15
  controls: { disable: true },
@@ -8,7 +8,7 @@ import {
8
8
  import { SplitButton } from '../index'
9
9
 
10
10
  const meta = {
11
- title: 'Components/SplitButton',
11
+ title: 'Components/SplitButton (deprecated)',
12
12
  component: SplitButton,
13
13
  argTypes: {
14
14
  actionButtonProps: {
@@ -228,6 +228,9 @@ const renderNavigationTabs = (
228
228
  )
229
229
 
230
230
  /**
231
+ * @deprecated This component will be renamed to TitleBlock in v2.
232
+ * Start importing as TitleBlock instead.
233
+ *
231
234
  * {@link https://cultureamp.atlassian.net/wiki/spaces/DesignSystem/pages/3075605782/Title+Block Guidance} |
232
235
  * {@link https://cultureamp.design/?path=/story/components-titleblock--docs Storybook}
233
236
  */
@@ -1,5 +1,5 @@
1
1
  import { Canvas, Meta } from '@storybook/blocks'
2
- import { ResourceLinks, KAIOInstallation } from '~storybook/components'
2
+ import { ResourceLinks, KAIOInstallation, RenameNotice } from '~storybook/components'
3
3
  import * as TitleBlockZenStories from './TitleBlockZen.stories'
4
4
 
5
5
  <Meta of={TitleBlockZenStories} />
@@ -9,9 +9,10 @@ import * as TitleBlockZenStories from './TitleBlockZen.stories'
9
9
  <ResourceLinks
10
10
  sourceCode="https://github.com/cultureamp/kaizen-design-system/tree/main/packages/components/src/TitleBlockZen"
11
11
  designGuidelines="https://cultureamp.atlassian.net/wiki/spaces/DesignSystem/pages/3075605782/Title+Block"
12
-
13
12
  />
14
13
 
14
+ <RenameNotice />
15
+
15
16
  <KAIOInstallation exportNames="TitleBlockZen" />
16
17
 
17
18
  ## Overview
@@ -0,0 +1,9 @@
1
+ @layer kz-components {
2
+ .popover {
3
+ background-color: var(--color-white);
4
+ border-radius: var(--spacing-8);
5
+ padding: var(--spacing-8);
6
+ width: 200px;
7
+ box-shadow: var(--shadow-small-box-shadow);
8
+ }
9
+ }
@@ -0,0 +1,26 @@
1
+ import React from 'react'
2
+ import { render } from '@testing-library/react'
3
+ import { SingleSelect } from './SingleSelect'
4
+ import { singleMockItems } from './_docs/mockData'
5
+
6
+ const SingleSelectWrapper = (): JSX.Element => (
7
+ <SingleSelect>
8
+ <SingleSelect.List>
9
+ {singleMockItems.map((item) => (
10
+ <SingleSelect.ListItem key={item.value} value={{ value: item.value }}>
11
+ {item.label}
12
+ </SingleSelect.ListItem>
13
+ ))}
14
+ </SingleSelect.List>
15
+ </SingleSelect>
16
+ )
17
+
18
+ describe('<SingleSelect />', () => {
19
+ describe('renders', () => {
20
+ it('a basic select component', () => {
21
+ const { getByRole } = render(<SingleSelectWrapper />)
22
+ const select = getByRole('button')
23
+ expect(select).toBeInTheDocument()
24
+ })
25
+ })
26
+ })
@@ -0,0 +1,27 @@
1
+ import React, { type HTMLAttributes, type PropsWithChildren } from 'react'
2
+ import { Popover as RACPopover, Select as RACSelect } from 'react-aria-components'
3
+ import { type OverrideClassName } from '~components/types/OverrideClassName'
4
+ import { List, ListItem, ListSection, Trigger } from './subcomponents'
5
+ import styles from './SingleSelect.module.css'
6
+
7
+ export type SingleSelectProps = {
8
+ children?: React.ReactNode
9
+ } & OverrideClassName<HTMLAttributes<Element>>
10
+
11
+ export const SingleSelect = ({
12
+ classNameOverride,
13
+ children,
14
+ ...restProps
15
+ }: PropsWithChildren<SingleSelectProps>): JSX.Element => {
16
+ return (
17
+ <RACSelect className={classNameOverride} placeholder="" {...restProps}>
18
+ <Trigger />
19
+ <RACPopover className={styles.popover}>{children}</RACPopover>
20
+ </RACSelect>
21
+ )
22
+ }
23
+
24
+ SingleSelect.displayName = 'SingleSelect'
25
+ SingleSelect.List = List
26
+ SingleSelect.ListItem = ListItem
27
+ SingleSelect.ListSection = ListSection
@@ -0,0 +1,27 @@
1
+ import { Canvas, Controls, DocsStory, Meta } from '@storybook/blocks'
2
+ import { ResourceLinks, KAIOInstallation, AlphaNotice } from '~storybook/components'
3
+ import * as SingleSelectStories from './SingleSelect.stories'
4
+
5
+ <Meta of={SingleSelectStories} />
6
+
7
+ # SingleSelect
8
+
9
+ <ResourceLinks
10
+ sourceCode="https://github.com/cultureamp/kaizen-design-system/tree/main/packages/components/src/__alpha__/SingleSelect"
11
+ figma=""
12
+ designGuidelines=""
13
+ />
14
+
15
+ <AlphaNotice />
16
+
17
+ <KAIOInstallation exportNames="SingleSelect" isAlpha />
18
+
19
+ ## Overview
20
+
21
+ {/* @todo: Update summary. */}
22
+ Brief summary of the component here.
23
+
24
+ <Canvas of={SingleSelectStories.Playground} />
25
+ <Controls of={SingleSelectStories.Playground} />
26
+
27
+ ## API
@@ -0,0 +1,83 @@
1
+ import React from 'react'
2
+ import { type Meta } from '@storybook/react'
3
+ import { StickerSheet, type StickerSheetStory } from '~storybook/components/StickerSheet'
4
+ import { SingleSelect } from '../index'
5
+ import { groupedMockItems, singleMockItems } from './mockData'
6
+
7
+ export default {
8
+ title: 'Components/SingleSelect/SingleSelect (alpha)',
9
+ parameters: {
10
+ chromatic: { disable: false },
11
+ controls: { disable: true },
12
+ },
13
+ } satisfies Meta
14
+
15
+ const StickerSheetTemplate: StickerSheetStory = {
16
+ render: ({ isReversed }) => {
17
+ return (
18
+ <StickerSheet isReversed={isReversed} title="SingleSelect" headers={['Items', 'Grouped']}>
19
+ <StickerSheet.Row>
20
+ <SingleSelect>
21
+ <SingleSelect.List>
22
+ {singleMockItems.map((item) => (
23
+ <SingleSelect.ListItem key={item.value} value={{ value: item.value }}>
24
+ {item.label}
25
+ </SingleSelect.ListItem>
26
+ ))}
27
+ </SingleSelect.List>
28
+ </SingleSelect>
29
+
30
+ <SingleSelect>
31
+ <SingleSelect.List>
32
+ {groupedMockItems.map((section) => (
33
+ <SingleSelect.ListSection name={section.label} key={section.label}>
34
+ {section.options.map((item) => (
35
+ <SingleSelect.ListItem key={item.value} value={{ value: item.value }}>
36
+ {item.label}
37
+ </SingleSelect.ListItem>
38
+ ))}
39
+ </SingleSelect.ListSection>
40
+ ))}
41
+ </SingleSelect.List>
42
+ </SingleSelect>
43
+ </StickerSheet.Row>
44
+ </StickerSheet>
45
+ )
46
+ },
47
+ /** @note: Only required if you have pseudo states, otherwise this can be removed */
48
+ parameters: {
49
+ /** @todo: Remove any inapplicable pseudo states */
50
+ pseudo: {
51
+ hover: '[data-sb-pseudo-styles="hover"]',
52
+ active: '[data-sb-pseudo-styles="active"]',
53
+ focus: '[data-sb-pseudo-styles="focus"]',
54
+ focusVisible: '[data-sb-pseudo-styles="focus"]',
55
+ },
56
+ },
57
+ }
58
+
59
+ export const StickerSheetDefault: StickerSheetStory = {
60
+ ...StickerSheetTemplate,
61
+ name: 'Sticker Sheet (Default)',
62
+ }
63
+
64
+ export const StickerSheetReversed: StickerSheetStory = {
65
+ ...StickerSheetTemplate,
66
+ name: 'Sticker Sheet (Reversed)',
67
+ parameters: {
68
+ /** @note: Only required if template has parameters, otherwise this spread can be removed */
69
+ ...StickerSheetTemplate.parameters,
70
+ backgrounds: { default: 'Purple 700' },
71
+ },
72
+ args: { isReversed: true },
73
+ }
74
+
75
+ export const StickerSheetRTL: StickerSheetStory = {
76
+ ...StickerSheetTemplate,
77
+ name: 'Sticker Sheet (RTL)',
78
+ parameters: {
79
+ /** @note: Only required if template has parameters, otherwise this spread can be removed */
80
+ ...StickerSheetTemplate.parameters,
81
+ textDirection: 'rtl',
82
+ },
83
+ }
@@ -0,0 +1,23 @@
1
+ import { type Meta, type StoryObj } from '@storybook/react'
2
+ import { SingleSelect } from '../index'
3
+
4
+ const meta = {
5
+ title: 'Components/SingleSelect/SingleSelect (alpha)',
6
+ component: SingleSelect,
7
+ args: {},
8
+ } satisfies Meta<typeof SingleSelect>
9
+
10
+ export default meta
11
+
12
+ type Story = StoryObj<typeof meta>
13
+
14
+ export const Playground: Story = {
15
+ args: {},
16
+ parameters: {
17
+ docs: {
18
+ canvas: {
19
+ sourceState: 'shown',
20
+ },
21
+ },
22
+ },
23
+ }