@loadsmart/loadsmart-ui 5.19.1 → 5.20.0

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 (56) hide show
  1. package/dist/components/DatePicker/DatePicker.types.d.ts +3 -0
  2. package/dist/components/Dropdown/Dropdown.d.ts +2 -2
  3. package/dist/components/Dropdown/Dropdown.types.d.ts +5 -1
  4. package/dist/components/Popover/Popover.d.ts +9 -3
  5. package/dist/components/Popover/Popover.stories.d.ts +1 -1
  6. package/dist/components/Popover/Popover.types.d.ts +33 -0
  7. package/dist/components/Popover/index.d.ts +2 -2
  8. package/dist/components/TablePagination/RowsPerPage.d.ts +1 -1
  9. package/dist/components/TablePagination/TablePagination.types.d.ts +7 -1
  10. package/dist/components/Text/Text.d.ts +1 -1
  11. package/dist/components/Tooltip/Tooltip.d.ts +3 -2
  12. package/dist/index.d.ts +2 -2
  13. package/dist/index.js +442 -481
  14. package/dist/index.js.map +1 -1
  15. package/dist/miranda-compatibility.theme-f37aba71.js +2 -0
  16. package/dist/miranda-compatibility.theme-f37aba71.js.map +1 -0
  17. package/dist/prop-ee1dfc7f.js +2 -0
  18. package/dist/{prop-a330029f.js.map → prop-ee1dfc7f.js.map} +1 -1
  19. package/dist/testing/index.js +1 -1
  20. package/dist/testing/index.js.map +1 -1
  21. package/dist/theming/index.js +1 -1
  22. package/dist/theming/themes/alice.theme.d.ts +4 -0
  23. package/dist/theming/themes/loadsmart.theme.d.ts +4 -0
  24. package/dist/theming/themes/miranda-compatibility.theme.d.ts +4 -0
  25. package/dist/tools/index.js +1 -1
  26. package/package.json +4 -5
  27. package/src/components/DatePicker/DatePicker.tsx +8 -4
  28. package/src/components/DatePicker/DatePicker.types.ts +3 -0
  29. package/src/components/DatePicker/DateRangePicker.tsx +16 -12
  30. package/src/components/Dropdown/Dropdown.stories.tsx +41 -40
  31. package/src/components/Dropdown/Dropdown.tsx +35 -11
  32. package/src/components/Dropdown/Dropdown.types.ts +7 -1
  33. package/src/components/Dropdown/DropdownMenu.tsx +10 -14
  34. package/src/components/Dropdown/DropdownTrigger.tsx +8 -5
  35. package/src/components/Popover/Popover.stories.tsx +27 -4
  36. package/src/components/Popover/Popover.tsx +145 -13
  37. package/src/components/Popover/Popover.types.ts +41 -0
  38. package/src/components/Popover/index.ts +11 -2
  39. package/src/components/Select/Select.test.tsx +3 -3
  40. package/src/components/Select/Select.tsx +0 -1
  41. package/src/components/Select/SelectOption.tsx +0 -1
  42. package/src/components/Select/SelectTrigger.tsx +18 -1
  43. package/src/components/Table/Table.stories.tsx +0 -1
  44. package/src/components/Table/Table.tsx +2 -2
  45. package/src/components/TablePagination/RowsPerPage.tsx +9 -4
  46. package/src/components/TablePagination/TablePagination.tsx +3 -0
  47. package/src/components/TablePagination/TablePagination.types.ts +12 -5
  48. package/src/components/Tooltip/Tooltip.tsx +59 -85
  49. package/src/components/TopNavigation/Menu/MenuItemDropdown.tsx +11 -8
  50. package/src/index.ts +10 -2
  51. package/src/testing/DatePickerEvent/DatePickerEvent.ts +1 -1
  52. package/src/theming/themes/alice.theme.ts +6 -0
  53. package/src/theming/themes/loadsmart.theme.ts +6 -0
  54. package/dist/miranda-compatibility.theme-4cecc6cf.js +0 -2
  55. package/dist/miranda-compatibility.theme-4cecc6cf.js.map +0 -1
  56. package/dist/prop-a330029f.js +0 -2
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../miranda-compatibility.theme-4cecc6cf.js");require("@loadsmart/miranda-tokens");var t=Object.freeze({__proto__:null,Alice:e.alice,Loadsmart:e.loadsmart,Miranda:e.mirandaCompatibility});function r(t,r){const i=e.isFunction(t)?t(r):t;return r.theme[i]}exports.Themes=t,exports.getToken=function(e,t){return void 0===t?t=>r(e,t):r(e,t)};
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../miranda-compatibility.theme-f37aba71.js");require("@loadsmart/miranda-tokens");var t=Object.freeze({__proto__:null,Alice:e.alice,Loadsmart:e.loadsmart,Miranda:e.mirandaCompatibility});function r(t,r){const a=e.isFunction(t)?t(r):t;return r.theme[a]}exports.Themes=t,exports.getToken=function(e,t){return void 0===t?t=>r(e,t):r(e,t)};
2
2
  //# sourceMappingURL=index.js.map
@@ -584,6 +584,10 @@ declare const alice: {
584
584
  'card-title-font-height': string | number;
585
585
  'card-title-font-size': string | number;
586
586
  'card-title-font-weight': string | number;
587
+ 'dropdown-background': string | number;
588
+ 'dropdown-border-color': string | number;
589
+ 'dropdown-border-radius': string | number;
590
+ 'dropdown-shadow': string | number;
587
591
  'popover-background': string | number;
588
592
  'popover-border-color': string | number;
589
593
  'popover-border-radius': string | number;
@@ -566,6 +566,10 @@ declare const loadsmart: {
566
566
  'card-title-font-height': string | number;
567
567
  'card-title-font-size': string | number;
568
568
  'card-title-font-weight': string | number;
569
+ 'dropdown-background': string | number;
570
+ 'dropdown-border-color': string | number;
571
+ 'dropdown-border-radius': string | number;
572
+ 'dropdown-shadow': string | number;
569
573
  'popover-background': string | number;
570
574
  'popover-border-color': string | number;
571
575
  'popover-border-radius': string | number;
@@ -739,6 +739,10 @@ declare const mirandaCompatibility: {
739
739
  'border-radius-m': string;
740
740
  'border-radius-l': string;
741
741
  'border-radius-circle': string;
742
+ 'dropdown-background': string | number;
743
+ 'dropdown-border-color': string | number;
744
+ 'dropdown-border-radius': string | number;
745
+ 'dropdown-shadow': string | number;
742
746
  left: string;
743
747
  center: string;
744
748
  right: string;
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../prop-a330029f.js");require("../toArray-b56541b4.js"),require("../miranda-compatibility.theme-4cecc6cf.js"),require("@loadsmart/miranda-tokens"),require("../theming/index.js"),exports.conditional=e.conditional,exports.prop=e.prop,exports.whenProps=e.whenProps;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../prop-ee1dfc7f.js");require("../toArray-b56541b4.js"),require("../miranda-compatibility.theme-f37aba71.js"),require("@loadsmart/miranda-tokens"),require("../theming/index.js"),exports.conditional=e.conditional,exports.prop=e.prop,exports.whenProps=e.whenProps;
2
2
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loadsmart/loadsmart-ui",
3
- "version": "5.19.1",
3
+ "version": "5.20.0",
4
4
  "description": "Miranda UI, a React UI library",
5
5
  "main": "dist",
6
6
  "files": [
@@ -44,7 +44,7 @@
44
44
  "@babel/preset-typescript": "^7.18.6",
45
45
  "@commitlint/cli": "16.0.2",
46
46
  "@commitlint/config-conventional": "16.0.0",
47
- "@loadsmart/miranda-tokens": "1.3.0",
47
+ "@loadsmart/miranda-tokens": "^2.2.1",
48
48
  "@loadsmart/stylelint-config": "0.0.3",
49
49
  "@rollup/plugin-babel": "5.3.0",
50
50
  "@rollup/plugin-commonjs": "19.0.0",
@@ -120,7 +120,6 @@
120
120
  "postcss": "^7.0.39",
121
121
  "postcss-cli": "^7.1.2",
122
122
  "prettier": "2.2.1",
123
- "prop-types": "15.7.2",
124
123
  "react": "17.0.2",
125
124
  "react-dom": "17.0.2",
126
125
  "react-is": "17.0.2",
@@ -150,15 +149,15 @@
150
149
  "webpack": "^5.75.0"
151
150
  },
152
151
  "peerDependencies": {
153
- "@loadsmart/miranda-tokens": "1.3.0",
152
+ "@loadsmart/miranda-tokens": ">=1.3.0",
154
153
  "@testing-library/dom": ">=5.12.0",
155
154
  "@testing-library/react": ">=11.2.6",
156
- "prop-types": ">=15.7.2",
157
155
  "react": ">=16.8.0",
158
156
  "react-dom": ">=16.8.0",
159
157
  "styled-components": ">=5.3.0"
160
158
  },
161
159
  "dependencies": {
160
+ "@floating-ui/react-dom": "^1.3.0",
162
161
  "@loadsmart/utils-function": "0.3.1",
163
162
  "@loadsmart/utils-object": "0.3.1",
164
163
  "@loadsmart/utils-string": "0.3.1",
@@ -9,6 +9,7 @@ import { Icon } from 'components/Icon'
9
9
  import { TextField as DefaultTextField } from 'components/TextField'
10
10
  import CloseButton from 'common/CloseButton'
11
11
  import useDatePicker from './useDatePicker'
12
+ import { Popover } from 'components/Popover'
12
13
 
13
14
  import type { CalendarDate } from 'components/Calendar'
14
15
  import type { ChangeEvent } from 'react'
@@ -91,6 +92,7 @@ function DatePicker(props: DatePickerProps): JSX.Element {
91
92
  constraints,
92
93
  getInputProps,
93
94
  getCalendarProps,
95
+ placement,
94
96
  } = props
95
97
 
96
98
  const datePicker = useDatePicker({
@@ -122,10 +124,12 @@ function DatePicker(props: DatePickerProps): JSX.Element {
122
124
  }
123
125
 
124
126
  return (
125
- <GenericDropdown {...datePicker.getDropdownProps()}>
126
- <Group space="s">
127
- <DateInput trailing={renderTrailing()} {...datePicker.getInputProps()} />
128
- </Group>
127
+ <GenericDropdown {...placement} {...datePicker.getDropdownProps()}>
128
+ <Popover.Reference>
129
+ <Group space="s">
130
+ <DateInput trailing={renderTrailing()} {...datePicker.getInputProps()} />
131
+ </Group>
132
+ </Popover.Reference>
129
133
  <DropdownMenu>
130
134
  <GenericCalendar {...datePicker.getCalendarProps()} />
131
135
  </DropdownMenu>
@@ -2,6 +2,7 @@ import type { CalendarProps, GenericCalendarProps, useCalendarProps } from 'comp
2
2
 
3
3
  import type { TextFieldProps } from 'components/TextField'
4
4
  import type EventLike from 'utils/types/EventLike'
5
+ import type { PopoverPlacement } from 'components/Popover'
5
6
 
6
7
  export interface DatePickerProps {
7
8
  id?: string
@@ -12,6 +13,7 @@ export interface DatePickerProps {
12
13
  onChange?: (event: EventLike<string | null>) => void
13
14
  getInputProps?: () => Partial<TextFieldProps>
14
15
  getCalendarProps?: () => Partial<GenericCalendarProps>
16
+ placement?: PopoverPlacement
15
17
  }
16
18
 
17
19
  export interface DateRangePickerProps {
@@ -24,4 +26,5 @@ export interface DateRangePickerProps {
24
26
  getRangeStartInputProps?: () => Partial<TextFieldProps>
25
27
  getRangeEndInputProps?: () => Partial<TextFieldProps>
26
28
  getCalendarProps?: () => Partial<GenericCalendarProps>
29
+ placement?: PopoverPlacement
27
30
  }
@@ -7,6 +7,7 @@ import { DateFormatHelper, GenericCalendar } from 'components/Calendar'
7
7
  import { Dropdown, GenericDropdown } from 'components/Dropdown'
8
8
  import { getToken as token } from 'theming'
9
9
  import { Group } from 'components/Layout'
10
+ import { Popover } from 'components/Popover'
10
11
  import useDateRangePicker from './useDateRangePicker'
11
12
 
12
13
  import type { DateRangePickerProps } from './DatePicker.types'
@@ -37,6 +38,7 @@ function DateRangePicker(props: DateRangePickerProps): JSX.Element {
37
38
  getRangeStartInputProps,
38
39
  getRangeEndInputProps,
39
40
  getCalendarProps,
41
+ placement,
40
42
  } = props
41
43
 
42
44
  const dateRangePicker = useDateRangePicker({
@@ -84,18 +86,20 @@ function DateRangePicker(props: DateRangePickerProps): JSX.Element {
84
86
  }
85
87
 
86
88
  return (
87
- <GenericDropdown {...dateRangePicker.getDropdownProps()}>
88
- <Group space="s">
89
- <DateInput
90
- {...dateRangePicker.getRangeStartInputProps()}
91
- data-testid="input-date-range-start"
92
- />
93
- <DateInput
94
- trailing={renderRangeEndTrailing()}
95
- {...dateRangePicker.getRangeEndInputProps()}
96
- data-testid="input-date-range-end"
97
- />
98
- </Group>
89
+ <GenericDropdown {...placement} {...dateRangePicker.getDropdownProps()}>
90
+ <Popover.Reference>
91
+ <Group space="s">
92
+ <DateInput
93
+ {...dateRangePicker.getRangeStartInputProps()}
94
+ data-testid="input-date-range-start"
95
+ />
96
+ <DateInput
97
+ trailing={renderRangeEndTrailing()}
98
+ {...dateRangePicker.getRangeEndInputProps()}
99
+ data-testid="input-date-range-end"
100
+ />
101
+ </Group>
102
+ </Popover.Reference>
99
103
  <DropdownMenu footer={renderDropdownFooter()}>
100
104
  <GenericCalendar {...dateRangePicker.getCalendarProps()} />
101
105
  </DropdownMenu>
@@ -9,17 +9,12 @@ import Dropdown from './Dropdown'
9
9
  import DropdownContext from './Dropdown.context'
10
10
 
11
11
  import type { DropdownProps, DropdownMenuProps, DropdownTriggerProps } from './Dropdown.types'
12
+ import { Popover } from 'components/Popover'
12
13
 
13
14
  export default {
14
15
  title: 'Components/Dropdown',
15
16
  component: Dropdown,
16
17
  argTypes: {
17
- align: {
18
- control: {
19
- type: 'select',
20
- options: ['start', 'end'],
21
- },
22
- },
23
18
  onBlur: {
24
19
  table: {
25
20
  disable: true,
@@ -40,7 +35,7 @@ export const Playground: Story<DropdownStoryProps> = (args) => {
40
35
  <div className="flex flex-col">
41
36
  <Dropdown {...args}>
42
37
  <Dropdown.Trigger outlined={args.outlined}>Actions</Dropdown.Trigger>
43
- <Dropdown.Menu align={args.align}>
38
+ <Dropdown.Menu>
44
39
  {ACTIONS.map(({ label, value }) => (
45
40
  <Dropdown.Item
46
41
  key={value}
@@ -157,23 +152,25 @@ function ActionTrigger() {
157
152
  const { toggle, disabled } = React.useContext(DropdownContext)
158
153
 
159
154
  return (
160
- <IconButton
161
- disabled={disabled}
162
- onClick={() => {
163
- toggle()
164
- }}
165
- >
166
- <svg
167
- xmlns="http://www.w3.org/2000/svg"
168
- height="24px"
169
- viewBox="0 0 24 24"
170
- width="24px"
171
- fill="#000000"
155
+ <Popover.Reference>
156
+ <IconButton
157
+ disabled={disabled}
158
+ onClick={() => {
159
+ toggle()
160
+ }}
172
161
  >
173
- <path d="M0 0h24v24H0V0z" fill="none" />
174
- <path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z" />
175
- </svg>
176
- </IconButton>
162
+ <svg
163
+ xmlns="http://www.w3.org/2000/svg"
164
+ height="24px"
165
+ viewBox="0 0 24 24"
166
+ width="24px"
167
+ fill="#000000"
168
+ >
169
+ <path d="M0 0h24v24H0V0z" fill="none" />
170
+ <path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z" />
171
+ </svg>
172
+ </IconButton>
173
+ </Popover.Reference>
177
174
  )
178
175
  }
179
176
 
@@ -181,12 +178,14 @@ function InputTrigger() {
181
178
  const { toggle, disabled } = React.useContext(DropdownContext)
182
179
 
183
180
  return (
184
- <TextField
185
- onFocus={() => {
186
- toggle()
187
- }}
188
- disabled={disabled}
189
- />
181
+ <Popover.Reference>
182
+ <TextField
183
+ onFocus={() => {
184
+ toggle()
185
+ }}
186
+ disabled={disabled}
187
+ />
188
+ </Popover.Reference>
190
189
  )
191
190
  }
192
191
 
@@ -195,7 +194,7 @@ export const CustomTrigger: Story<DropdownStoryProps> = (args) => {
195
194
 
196
195
  function renderMenu() {
197
196
  return (
198
- <Dropdown.Menu align={args.align}>
197
+ <Dropdown.Menu>
199
198
  {ACTIONS.map(({ label, value }) => (
200
199
  <Dropdown.Item
201
200
  key={value}
@@ -214,16 +213,18 @@ export const CustomTrigger: Story<DropdownStoryProps> = (args) => {
214
213
  <div className="flex flex-col">
215
214
  <div className="flex flex-row">
216
215
  <Dropdown {...args}>
217
- <Dropdown.Trigger.Button outlined={args.outlined} trailing={null}>
218
- {({ expanded }) => {
219
- return (
220
- <React.Fragment>
221
- <span className="mr-2">{expanded ? 'Hide' : 'See'} Options</span>
222
- <Icon name={expanded ? 'minus' : 'plus'} />
223
- </React.Fragment>
224
- )
225
- }}
226
- </Dropdown.Trigger.Button>
216
+ <Popover.Reference>
217
+ <Dropdown.Trigger.Button outlined={args.outlined} trailing={null}>
218
+ {({ expanded }) => {
219
+ return (
220
+ <React.Fragment>
221
+ <span className="mr-2">{expanded ? 'Hide' : 'See'} Options</span>
222
+ <Icon name={expanded ? 'minus' : 'plus'} />
223
+ </React.Fragment>
224
+ )
225
+ }}
226
+ </Dropdown.Trigger.Button>
227
+ </Popover.Reference>
227
228
  {renderMenu()}
228
229
  </Dropdown>
229
230
  <span className="inline-flex items-center mx-8 text-4xl font-thin border-l border-neutral"></span>
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useRef, useState } from 'react'
1
+ import React, { useMemo, useRef } from 'react'
2
2
  import styled from 'styled-components'
3
3
 
4
4
  import {
@@ -12,8 +12,10 @@ import DropdownContext from './Dropdown.context'
12
12
  import DropdownTrigger from './DropdownTrigger'
13
13
  import hidden from 'styles/hidden'
14
14
  import useDropdown from './useDropdown'
15
+ import { Popover } from 'components/Popover'
15
16
 
16
- import type { DropdownProps, GenericDropdownProps } from './Dropdown.types'
17
+ import type { DropdownProps, GenericDropdownProps, DropdownMenuProps } from './Dropdown.types'
18
+ import type { PopoverAlign } from 'components/Popover'
17
19
 
18
20
  const DropdownWrapper = styled.div`
19
21
  position: relative;
@@ -26,6 +28,25 @@ const HiddenCloseButton = styled.button.attrs({
26
28
  ${hidden(true)}
27
29
  `
28
30
 
31
+ function useDeprecatedAlignFromMenu({
32
+ children,
33
+ align,
34
+ }: React.PropsWithChildren<{ align?: PopoverAlign }>): PopoverAlign {
35
+ let result: PopoverAlign | undefined
36
+
37
+ if (align) {
38
+ return align
39
+ }
40
+
41
+ React.Children.forEach(children, (child) => {
42
+ if (React.isValidElement<DropdownMenuProps>(child) && child.type === DropdownMenu) {
43
+ result = child.props.align
44
+ }
45
+ })
46
+
47
+ return (result || align) as PopoverAlign
48
+ }
49
+
29
50
  // TODO: add focus trap here to allow navigating options with keyboard
30
51
 
31
52
  /**
@@ -46,11 +67,19 @@ export function GenericDropdown(props: GenericDropdownProps): JSX.Element {
46
67
  disabled = false,
47
68
  expandDisabled = false,
48
69
  onBlur,
70
+ position,
49
71
  ...others
50
72
  } = props
51
- const [contextValue, setContextValue] = useState({ expanded, toggle, disabled, expandDisabled })
73
+ const contextValue = useMemo(() => ({ expanded, toggle, disabled, expandDisabled }), [
74
+ expanded,
75
+ toggle,
76
+ disabled,
77
+ expandDisabled,
78
+ ])
52
79
  const ref = useRef(null)
53
80
 
81
+ const align = useDeprecatedAlignFromMenu(props)
82
+
54
83
  useClickOutside(
55
84
  ref,
56
85
  function handleClickOutside(event?: MouseEvent | TouchEvent | KeyboardEvent) {
@@ -64,20 +93,15 @@ export function GenericDropdown(props: GenericDropdownProps): JSX.Element {
64
93
  }
65
94
  )
66
95
 
67
- useEffect(
68
- function updateContextValue() {
69
- setContextValue({ expanded, toggle, disabled, expandDisabled })
70
- },
71
- [expanded, toggle, disabled, expandDisabled]
72
- )
73
-
74
96
  return (
75
97
  <DropdownWrapper {...others} role="menubar" ref={ref}>
76
98
  <DropdownContext.Provider value={contextValue}>
77
99
  <HiddenCloseButton disabled={disabled} onClick={toggle}>
78
100
  Close
79
101
  </HiddenCloseButton>
80
- {children}
102
+ <Popover strategy="fixed" position={position} align={align}>
103
+ {children}
104
+ </Popover>
81
105
  </DropdownContext.Provider>
82
106
  </DropdownWrapper>
83
107
  )
@@ -1,3 +1,4 @@
1
+ import type { PopoverPlacement } from 'components/Popover'
1
2
  import type { ButtonProps } from 'components/Button'
2
3
  import type { ButtonHTMLAttributes, HTMLAttributes, ReactNode } from 'react'
3
4
 
@@ -13,7 +14,9 @@ export interface useDropdownReturn {
13
14
  collapse: () => void
14
15
  }
15
16
 
16
- export interface DropdownProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onChange' | 'onBlur'> {
17
+ export interface DropdownProps
18
+ extends Omit<HTMLAttributes<HTMLDivElement>, 'onChange' | 'onBlur'>,
19
+ PopoverPlacement {
17
20
  disabled?: boolean
18
21
  /**
19
22
  * Use this prop to not allow the dropdown to be expanded.
@@ -32,6 +35,9 @@ export type DropdownTriggerProps = ButtonProps & {
32
35
  export interface DropdownMenuProps extends HTMLAttributes<HTMLDivElement> {
33
36
  header?: ReactNode
34
37
  footer?: ReactNode
38
+ /**
39
+ * @deprecated Use the `align` prop on <Dropdown> wrapper instead.
40
+ */
35
41
  align?: 'start' | 'end'
36
42
  }
37
43
 
@@ -2,7 +2,7 @@ import React, { forwardRef, useContext } from 'react'
2
2
  import styled from 'styled-components'
3
3
 
4
4
  import { getToken as token } from 'theming'
5
- import { Popover as DefaultPopover } from 'components/Popover'
5
+ import { Popover } from 'components/Popover'
6
6
  import disableable from 'styles/disableable'
7
7
  import DropdownContext from './Dropdown.context'
8
8
  import focusable from 'styles/focusable'
@@ -16,7 +16,6 @@ import type {
16
16
  DropdownMenuProps,
17
17
  DropdownMenuSectionProps,
18
18
  } from './Dropdown.types'
19
- import conditional, { whenProps } from 'tools/conditional'
20
19
 
21
20
  /**
22
21
  * TODO: add aria-labelledby that should refer to the dropdown label to the role="menu" container.
@@ -24,18 +23,15 @@ import conditional, { whenProps } from 'tools/conditional'
24
23
  * TODO: add animation for a smooth open/close effect.
25
24
  */
26
25
 
27
- const Popover = styled(DefaultPopover)<{ $align: 'start' | 'end' }>`
28
- position: absolute;
29
- top: calc(${token('dropdown-trigger-height')} + ${token('space-xs')});
30
-
31
- ${conditional({
32
- 'left: 0;': whenProps({ $align: 'start' }),
33
- 'right: 0;': whenProps({ $align: 'end' }),
34
- })}
35
-
26
+ const StyledPopover = styled(Popover.Floating)`
36
27
  z-index: ${token('z-index-droplist')};
37
28
 
38
29
  min-width: 10em;
30
+
31
+ background: ${token('dropdown-background')};
32
+ border: 1px solid ${token('dropdown-border-color')};
33
+ border-radius: ${token('dropdown-border-radius')};
34
+ box-shadow: ${token('dropdown-shadow')};
39
35
  `
40
36
 
41
37
  const StyledSpan = styled.span`
@@ -197,7 +193,7 @@ export const DropdownMenu = forwardRef<HTMLDivElement, DropdownMenuProps>(functi
197
193
  throw new Error('DropdownMenu must be inside a DropdownContext')
198
194
  }
199
195
 
200
- const { children, header, footer, align = 'start', ...others } = props
196
+ const { children, header, footer, ...others } = props
201
197
  const { expanded } = context
202
198
 
203
199
  if (!expanded) {
@@ -205,7 +201,7 @@ export const DropdownMenu = forwardRef<HTMLDivElement, DropdownMenuProps>(functi
205
201
  }
206
202
 
207
203
  return (
208
- <Popover role="presentation" $align={align}>
204
+ <StyledPopover role="presentation">
209
205
  {header && <GenericDropdownMenuWrapper>{header}</GenericDropdownMenuWrapper>}
210
206
  {children && (
211
207
  <DropdownMenuWrapper ref={ref} role="menu" data-testid="dropdown-menu" {...others}>
@@ -213,7 +209,7 @@ export const DropdownMenu = forwardRef<HTMLDivElement, DropdownMenuProps>(functi
213
209
  </DropdownMenuWrapper>
214
210
  )}
215
211
  {footer && <GenericDropdownMenuWrapper>{footer}</GenericDropdownMenuWrapper>}
216
- </Popover>
212
+ </StyledPopover>
217
213
  )
218
214
  })
219
215
 
@@ -20,6 +20,7 @@ import type { ButtonHTMLAttributes, HTMLAttributes, MouseEvent } from 'react'
20
20
  import type { DropdownTriggerProps, DropdownContextReturn } from './Dropdown.types'
21
21
  import type { IconProps } from 'components/Icon'
22
22
  import type ColorScheme from 'utils/types/ColorScheme'
23
+ import { Popover } from 'components/Popover'
23
24
 
24
25
  /**
25
26
  * TODO: throw an error if context is not available
@@ -342,11 +343,13 @@ function DropdownTrigger(props: DropdownTriggerProps): JSX.Element {
342
343
  const { children, className, ...others } = props
343
344
 
344
345
  return (
345
- <GenericDropdownTrigger className={className} outlined={props.outlined}>
346
- <DropdownTriggerButton {...others} data-text={children}>
347
- {children}
348
- </DropdownTriggerButton>
349
- </GenericDropdownTrigger>
346
+ <Popover.Reference>
347
+ <GenericDropdownTrigger className={className} outlined={props.outlined}>
348
+ <DropdownTriggerButton {...others} data-text={children}>
349
+ {children}
350
+ </DropdownTriggerButton>
351
+ </GenericDropdownTrigger>
352
+ </Popover.Reference>
350
353
  )
351
354
  }
352
355
 
@@ -3,20 +3,41 @@ import type { Story, Meta } from '@storybook/react/types-6-0'
3
3
 
4
4
  import Popover from './Popover'
5
5
 
6
- import type { PopoverProps } from './Popover'
6
+ import type { PopoverProps } from './Popover.types'
7
7
 
8
8
  export default {
9
9
  title: 'Components/Popover',
10
10
  component: Popover,
11
+ argTypes: {
12
+ position: {
13
+ control: {
14
+ type: 'radio',
15
+ options: ['top', 'right', 'bottom', 'left'],
16
+ },
17
+ },
18
+ align: {
19
+ control: {
20
+ type: 'radio',
21
+ options: ['start', 'center', 'end'],
22
+ },
23
+ },
24
+ },
11
25
  } as Meta
12
26
 
13
27
  export const Playground: Story<PopoverProps> = ({ children, ...args }: PopoverProps) => {
14
28
  return (
15
29
  <div className="flex flex-col space-y-2">
16
30
  <div className="flex items-center">
17
- <Popover {...args}>
18
- <div className="flex items-center p-4">{children}</div>
19
- </Popover>
31
+ <div style={{ maxHeight: 100, overflow: 'scroll', border: 'solid 1px black' }}>
32
+ <div style={{ height: 250, paddingTop: 100 }}>
33
+ <Popover {...args}>
34
+ <Popover.Reference>Reference</Popover.Reference>
35
+ <Popover.Floating style={{ background: 'white', pointerEvents: 'none' }}>
36
+ {children}
37
+ </Popover.Floating>
38
+ </Popover>
39
+ </div>
40
+ </div>
20
41
  </div>
21
42
  </div>
22
43
  )
@@ -24,4 +45,6 @@ export const Playground: Story<PopoverProps> = ({ children, ...args }: PopoverPr
24
45
 
25
46
  Playground.args = {
26
47
  children: 'Just a floating content',
48
+ position: 'bottom',
49
+ align: 'center',
27
50
  }