@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.
- package/dist/components/DatePicker/DatePicker.types.d.ts +3 -0
- package/dist/components/Dropdown/Dropdown.d.ts +2 -2
- package/dist/components/Dropdown/Dropdown.types.d.ts +5 -1
- package/dist/components/Popover/Popover.d.ts +9 -3
- package/dist/components/Popover/Popover.stories.d.ts +1 -1
- package/dist/components/Popover/Popover.types.d.ts +33 -0
- package/dist/components/Popover/index.d.ts +2 -2
- package/dist/components/TablePagination/RowsPerPage.d.ts +1 -1
- package/dist/components/TablePagination/TablePagination.types.d.ts +7 -1
- package/dist/components/Text/Text.d.ts +1 -1
- package/dist/components/Tooltip/Tooltip.d.ts +3 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +442 -481
- package/dist/index.js.map +1 -1
- package/dist/miranda-compatibility.theme-f37aba71.js +2 -0
- package/dist/miranda-compatibility.theme-f37aba71.js.map +1 -0
- package/dist/prop-ee1dfc7f.js +2 -0
- package/dist/{prop-a330029f.js.map → prop-ee1dfc7f.js.map} +1 -1
- package/dist/testing/index.js +1 -1
- package/dist/testing/index.js.map +1 -1
- package/dist/theming/index.js +1 -1
- package/dist/theming/themes/alice.theme.d.ts +4 -0
- package/dist/theming/themes/loadsmart.theme.d.ts +4 -0
- package/dist/theming/themes/miranda-compatibility.theme.d.ts +4 -0
- package/dist/tools/index.js +1 -1
- package/package.json +4 -5
- package/src/components/DatePicker/DatePicker.tsx +8 -4
- package/src/components/DatePicker/DatePicker.types.ts +3 -0
- package/src/components/DatePicker/DateRangePicker.tsx +16 -12
- package/src/components/Dropdown/Dropdown.stories.tsx +41 -40
- package/src/components/Dropdown/Dropdown.tsx +35 -11
- package/src/components/Dropdown/Dropdown.types.ts +7 -1
- package/src/components/Dropdown/DropdownMenu.tsx +10 -14
- package/src/components/Dropdown/DropdownTrigger.tsx +8 -5
- package/src/components/Popover/Popover.stories.tsx +27 -4
- package/src/components/Popover/Popover.tsx +145 -13
- package/src/components/Popover/Popover.types.ts +41 -0
- package/src/components/Popover/index.ts +11 -2
- package/src/components/Select/Select.test.tsx +3 -3
- package/src/components/Select/Select.tsx +0 -1
- package/src/components/Select/SelectOption.tsx +0 -1
- package/src/components/Select/SelectTrigger.tsx +18 -1
- package/src/components/Table/Table.stories.tsx +0 -1
- package/src/components/Table/Table.tsx +2 -2
- package/src/components/TablePagination/RowsPerPage.tsx +9 -4
- package/src/components/TablePagination/TablePagination.tsx +3 -0
- package/src/components/TablePagination/TablePagination.types.ts +12 -5
- package/src/components/Tooltip/Tooltip.tsx +59 -85
- package/src/components/TopNavigation/Menu/MenuItemDropdown.tsx +11 -8
- package/src/index.ts +10 -2
- package/src/testing/DatePickerEvent/DatePickerEvent.ts +1 -1
- package/src/theming/themes/alice.theme.ts +6 -0
- package/src/theming/themes/loadsmart.theme.ts +6 -0
- package/dist/miranda-compatibility.theme-4cecc6cf.js +0 -2
- package/dist/miranda-compatibility.theme-4cecc6cf.js.map +0 -1
- package/dist/prop-a330029f.js +0 -2
package/dist/theming/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../miranda-compatibility.theme-
|
|
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;
|
package/dist/tools/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../prop-
|
|
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.
|
|
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": "
|
|
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
|
-
<
|
|
127
|
-
<
|
|
128
|
-
|
|
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
|
-
<
|
|
89
|
-
<
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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
|
|
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
|
-
<
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
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
|
-
<
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
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
|
-
<
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
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
|
|
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
|
-
<
|
|
218
|
-
{
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
<
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
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, {
|
|
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
|
|
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
|
-
{
|
|
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
|
|
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
|
|
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
|
|
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,
|
|
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
|
-
<
|
|
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
|
-
</
|
|
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
|
-
<
|
|
346
|
-
<
|
|
347
|
-
{children}
|
|
348
|
-
|
|
349
|
-
|
|
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
|
-
<
|
|
18
|
-
<div
|
|
19
|
-
|
|
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
|
}
|