@launchpad-ui/dropdown 0.10.16 → 0.10.18

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.
@@ -1 +1 @@
1
- {"version":3,"file":"Dropdown.d.ts","sourceRoot":"","sources":["../src/Dropdown.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAQ1D,KAAK,aAAa,GAAG;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,KAAK,aAAa,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,MAAM,IAAI,YAAY,GAAG;IACvE,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,YAAY,EAAE,aAAa,KAAK,IAAI,CAAC;IAC1D,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;CAC/C,CAAC;AAEF;;;;GAIG;AACH,QAAA,MAAM,QAAQ,GAAI,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,OAAO,aAAa,CAAC,CAAC,CAAC,4CA0G5E,CAAC;AAEF,OAAO,EAAE,QAAQ,EAAE,CAAC;AACpB,YAAY,EAAE,aAAa,EAAE,CAAC"}
1
+ {"version":3,"file":"Dropdown.d.ts","sourceRoot":"","sources":["../src/Dropdown.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAG1D,KAAK,aAAa,GAAG;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,KAAK,aAAa,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,MAAM,IAAI,YAAY,GAAG;IACvE,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,YAAY,EAAE,aAAa,KAAK,IAAI,CAAC;IAC1D,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;CAC/C,CAAC;AAEF;;;;GAIG;AACH,QAAA,MAAM,QAAQ,GAAI,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,OAAO,aAAa,CAAC,CAAC,CAAC,4CAyG5E,CAAC;AAEF,OAAO,EAAE,QAAQ,EAAE,CAAC;AACpB,YAAY,EAAE,aAAa,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"DropdownButton.d.ts","sourceRoot":"","sources":["../src/DropdownButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAMxD,KAAK,mBAAmB,GAAG,WAAW,GAAG;IACxC,SAAS,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,QAAA,MAAM,cAAc;;;;;;;;;;;;gBAHP,OAAO;qDAWlB,CAAC;AAIH,OAAO,EAAE,cAAc,EAAE,CAAC;AAC1B,YAAY,EAAE,mBAAmB,EAAE,CAAC"}
1
+ {"version":3,"file":"DropdownButton.d.ts","sourceRoot":"","sources":["../src/DropdownButton.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAIxD,KAAK,mBAAmB,GAAG,WAAW,GAAG;IACxC,SAAS,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,QAAA,MAAM,cAAc;;;;;;;;;;;;gBAHP,OAAO;qDAWlB,CAAC;AAIH,OAAO,EAAE,cAAc,EAAE,CAAC;AAC1B,YAAY,EAAE,mBAAmB,EAAE,CAAC"}
package/dist/index.es.js CHANGED
@@ -1,87 +1,108 @@
1
- import { Popover } from "@launchpad-ui/popover";
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { useRef, useState, useEffect, cloneElement, Children, forwardRef } from "react";
2
3
  import { mergeRefs } from "@react-aria/utils";
3
4
  import { cx } from "classix";
4
- import { Children, cloneElement, forwardRef, useEffect, useRef, useState } from "react";
5
- import { jsx, jsxs } from "react/jsx-runtime";
5
+ import { Popover } from "@launchpad-ui/popover";
6
6
  import { Button } from "@launchpad-ui/button";
7
7
  import { Icon } from "@launchpad-ui/icons";
8
- var Dropdown = (props) => {
9
- const { placement, disabled, targetClassName, popoverClassName, isOpen: isOpenProp, onInteraction, onSelect, onStateChange, children, "data-test-id": testId = "dropdown", ...rest } = props;
10
- const triggerRef = useRef(null);
11
- const [isOpen, setIsOpen] = useState(isOpenProp ?? false);
12
- const [hasOpened, setHasOpened] = useState(isOpen);
13
- useEffect(() => {
14
- if (isOpenProp !== void 0) setIsOpen(isOpenProp);
15
- }, [isOpenProp]);
16
- useEffect(() => {
17
- if (hasOpened && isOpen === false) setTimeout(() => {
18
- const current = triggerRef.current;
19
- if (!current) return;
20
- !current.closest?.(".has-overlay") && current.focus?.();
21
- });
22
- }, [isOpen, hasOpened]);
23
- useEffect(() => {
24
- setHasOpened(isOpen);
25
- onStateChange?.({ isOpen });
26
- }, [isOpen]);
27
- const renderTrigger = () => {
28
- const { target } = parseChildren();
29
- return /* @__PURE__ */ cloneElement(target, {
30
- "aria-haspopup": true,
31
- "aria-expanded": !!isOpen,
32
- ref: target.ref ? mergeRefs(target.ref, triggerRef) : triggerRef,
33
- isopen: isOpen?.toString()
34
- });
35
- };
36
- const renderContent = () => {
37
- return /* @__PURE__ */ cloneElement(parseChildren().content, { onSelect: handleSelect });
38
- };
39
- const handleSelect = (item) => {
40
- setIsOpen(false);
41
- onSelect?.(item, { isOpen: false });
42
- };
43
- const handlePopoverInteraction = (nextIsOpen) => {
44
- setIsOpen(nextIsOpen);
45
- };
46
- const parseChildren = () => {
47
- const [targetChild, contentChild] = Children.toArray(children);
48
- return {
49
- target: targetChild,
50
- content: contentChild
51
- };
52
- };
53
- const popoverTargetClasses = cx("Dropdown-target", targetClassName);
54
- const popoverClasses = cx("Dropdown", popoverClassName);
55
- return /* @__PURE__ */ jsxs(Popover, {
56
- isOpen,
57
- placement,
58
- onInteraction: onInteraction || handlePopoverInteraction,
59
- restrictHeight: false,
60
- disabled,
61
- targetClassName: popoverTargetClasses,
62
- popoverClassName: popoverClasses,
63
- "data-test-id": testId,
64
- ...rest,
65
- children: [renderTrigger(), renderContent()]
66
- });
8
+ const Dropdown = (props) => {
9
+ const {
10
+ placement,
11
+ disabled,
12
+ targetClassName,
13
+ popoverClassName,
14
+ isOpen: isOpenProp,
15
+ onInteraction,
16
+ onSelect,
17
+ onStateChange,
18
+ children,
19
+ "data-test-id": testId = "dropdown",
20
+ ...rest
21
+ } = props;
22
+ const triggerRef = useRef(null);
23
+ const [isOpen, setIsOpen] = useState(isOpenProp ?? false);
24
+ const [hasOpened, setHasOpened] = useState(isOpen);
25
+ useEffect(() => {
26
+ if (isOpenProp !== void 0) {
27
+ setIsOpen(isOpenProp);
28
+ }
29
+ }, [isOpenProp]);
30
+ useEffect(() => {
31
+ if (hasOpened && isOpen === false) {
32
+ setTimeout(() => {
33
+ const current = triggerRef.current;
34
+ if (!current) {
35
+ return;
36
+ }
37
+ const hasModal = current.closest?.(".has-overlay");
38
+ !hasModal && current.focus?.();
39
+ });
40
+ }
41
+ }, [isOpen, hasOpened]);
42
+ useEffect(() => {
43
+ setHasOpened(isOpen);
44
+ onStateChange?.({ isOpen });
45
+ }, [isOpen]);
46
+ const renderTrigger = () => {
47
+ const { target } = parseChildren();
48
+ return /* @__PURE__ */ cloneElement(target, {
49
+ "aria-haspopup": true,
50
+ "aria-expanded": !!isOpen,
51
+ ref: target.ref ? mergeRefs(target.ref, triggerRef) : triggerRef,
52
+ isopen: isOpen?.toString()
53
+ });
54
+ };
55
+ const renderContent = () => {
56
+ return /* @__PURE__ */ cloneElement(parseChildren().content, {
57
+ onSelect: handleSelect
58
+ });
59
+ };
60
+ const handleSelect = (item) => {
61
+ setIsOpen(false);
62
+ onSelect?.(item, { isOpen: false });
63
+ };
64
+ const handlePopoverInteraction = (nextIsOpen) => {
65
+ setIsOpen(nextIsOpen);
66
+ };
67
+ const parseChildren = () => {
68
+ const [targetChild, contentChild] = Children.toArray(children);
69
+ return {
70
+ target: targetChild,
71
+ content: contentChild
72
+ };
73
+ };
74
+ const popoverTargetClasses = cx("Dropdown-target", targetClassName);
75
+ const popoverClasses = cx("Dropdown", popoverClassName);
76
+ return /* @__PURE__ */ jsxs(
77
+ Popover,
78
+ {
79
+ isOpen,
80
+ placement,
81
+ onInteraction: onInteraction || handlePopoverInteraction,
82
+ restrictHeight: false,
83
+ disabled,
84
+ targetClassName: popoverTargetClasses,
85
+ popoverClassName: popoverClasses,
86
+ "data-test-id": testId,
87
+ ...rest,
88
+ children: [
89
+ renderTrigger(),
90
+ renderContent()
91
+ ]
92
+ }
93
+ );
67
94
  };
68
- var DropdownButton = /* @__PURE__ */ forwardRef((props, ref) => {
69
- const { children, hideCaret, "data-test-id": testId = "dropdown-button", ...rest } = props;
70
- return /* @__PURE__ */ jsxs(Button, {
71
- ...rest,
72
- "data-test-id": testId,
73
- ref,
74
- children: [
75
- children,
76
- " ",
77
- !hideCaret && /* @__PURE__ */ jsx(Icon, {
78
- name: "chevron-down",
79
- size: "small"
80
- })
81
- ]
82
- });
95
+ const DropdownButton = /* @__PURE__ */ forwardRef((props, ref) => {
96
+ const { children, hideCaret, "data-test-id": testId = "dropdown-button", ...rest } = props;
97
+ return /* @__PURE__ */ jsxs(Button, { ...rest, "data-test-id": testId, ref, children: [
98
+ children,
99
+ " ",
100
+ !hideCaret && /* @__PURE__ */ jsx(Icon, { name: "chevron-down", size: "small" })
101
+ ] });
83
102
  });
84
103
  DropdownButton.displayName = "DropdownButton";
85
- export { Dropdown, DropdownButton };
86
-
87
- //# sourceMappingURL=index.es.js.map
104
+ export {
105
+ Dropdown,
106
+ DropdownButton
107
+ };
108
+ //# sourceMappingURL=index.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.es.js","names":[],"sources":["../src/Dropdown.tsx","../src/DropdownButton.tsx"],"sourcesContent":["import type { PopoverProps } from '@launchpad-ui/popover';\nimport type { AriaAttributes, ForwardedRef, FunctionComponentElement, ReactElement } from 'react';\n\nimport { Popover } from '@launchpad-ui/popover';\nimport { mergeRefs } from '@react-aria/utils';\nimport { cx } from 'classix';\nimport { Children, cloneElement, useEffect, useRef, useState } from 'react';\n\ntype DropdownState = {\n\tisOpen?: boolean;\n};\n\ntype DropdownProps<T extends string | object | number> = PopoverProps & {\n\tonSelect?: (item: T, stateChanges: DropdownState) => void;\n\tonStateChange?: (state: DropdownState) => void;\n};\n\n/**\n * @deprecated use `Menu` from `@launchpad-ui/components` instead\n *\n * https://launchpad.launchdarkly.com/?path=/docs/components-collections-menu--docs\n */\nconst Dropdown = <T extends string | object | number>(props: DropdownProps<T>) => {\n\tconst {\n\t\tplacement,\n\t\tdisabled,\n\t\ttargetClassName,\n\t\tpopoverClassName,\n\t\tisOpen: isOpenProp,\n\t\tonInteraction,\n\t\tonSelect,\n\t\tonStateChange,\n\t\tchildren,\n\t\t'data-test-id': testId = 'dropdown',\n\t\t...rest\n\t} = props;\n\n\tconst triggerRef = useRef<HTMLElement | null>(null);\n\tconst [isOpen, setIsOpen] = useState(isOpenProp ?? false);\n\tconst [hasOpened, setHasOpened] = useState(isOpen);\n\n\tuseEffect(() => {\n\t\tif (isOpenProp !== undefined) {\n\t\t\tsetIsOpen(isOpenProp);\n\t\t}\n\t}, [isOpenProp]);\n\n\tuseEffect(() => {\n\t\t// Focus the button upon closing for convenient tabbing\n\t\tif (hasOpened && isOpen === false) {\n\t\t\tsetTimeout(() => {\n\t\t\t\tconst current = triggerRef.current;\n\t\t\t\tif (!current) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// If a dropdown menu item triggers a modal, we do not want to focus the trigger. Instead\n\t\t\t\t// we let the modal components control their own focus.\n\t\t\t\t// Note that this is not ideal since closing the modal will not cause the dropdown trigger\n\t\t\t\t// to regain focus.\n\t\t\t\tconst hasModal = current.closest?.('.has-overlay');\n\n\t\t\t\t!hasModal && current.focus?.();\n\t\t\t});\n\t\t}\n\t}, [isOpen, hasOpened]);\n\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: ignore\n\tuseEffect(() => {\n\t\tsetHasOpened(isOpen);\n\t\tonStateChange?.({ isOpen });\n\t}, [isOpen]);\n\n\tconst renderTrigger = () => {\n\t\tconst { target } = parseChildren();\n\t\treturn cloneElement(target, {\n\t\t\t'aria-haspopup': true,\n\t\t\t'aria-expanded': !!isOpen,\n\t\t\tref: target.ref ? mergeRefs(target.ref, triggerRef) : triggerRef,\n\t\t\tisopen: isOpen?.toString(),\n\t\t});\n\t};\n\n\tconst renderContent = () => {\n\t\treturn cloneElement(parseChildren().content, {\n\t\t\tonSelect: handleSelect,\n\t\t});\n\t};\n\n\tconst handleSelect = (item: T) => {\n\t\tsetIsOpen(false);\n\t\tonSelect?.(item, { isOpen: false });\n\t};\n\n\tconst handlePopoverInteraction = (nextIsOpen: boolean) => {\n\t\tsetIsOpen(nextIsOpen);\n\t};\n\n\tconst parseChildren = () => {\n\t\tconst [targetChild, contentChild] = Children.toArray(children);\n\t\treturn {\n\t\t\ttarget: targetChild as FunctionComponentElement<\n\t\t\t\tAriaAttributes & { ref: ForwardedRef<HTMLElement | undefined>; isopen: string }\n\t\t\t>,\n\t\t\t// biome-ignore lint/suspicious/noExplicitAny: ignore\n\t\t\tcontent: contentChild as ReactElement<any>,\n\t\t};\n\t};\n\n\tconst popoverTargetClasses = cx('Dropdown-target', targetClassName);\n\tconst popoverClasses = cx('Dropdown', popoverClassName);\n\n\treturn (\n\t\t<Popover\n\t\t\tisOpen={isOpen}\n\t\t\tplacement={placement}\n\t\t\tonInteraction={onInteraction || handlePopoverInteraction}\n\t\t\trestrictHeight={false}\n\t\t\tdisabled={disabled}\n\t\t\ttargetClassName={popoverTargetClasses}\n\t\t\tpopoverClassName={popoverClasses}\n\t\t\tdata-test-id={testId}\n\t\t\t{...rest}\n\t\t>\n\t\t\t{renderTrigger()}\n\t\t\t{renderContent()}\n\t\t</Popover>\n\t);\n};\n\nexport { Dropdown };\nexport type { DropdownProps };\n","import type { ButtonProps } from '@launchpad-ui/button';\n\nimport { Button } from '@launchpad-ui/button';\nimport { Icon } from '@launchpad-ui/icons';\nimport { forwardRef } from 'react';\n\ntype DropdownButtonProps = ButtonProps & {\n\thideCaret?: boolean;\n};\n\nconst DropdownButton = forwardRef<HTMLButtonElement, DropdownButtonProps>((props, ref) => {\n\tconst { children, hideCaret, 'data-test-id': testId = 'dropdown-button', ...rest } = props;\n\n\treturn (\n\t\t<Button {...rest} data-test-id={testId} ref={ref}>\n\t\t\t{children} {!hideCaret && <Icon name=\"chevron-down\" size=\"small\" />}\n\t\t</Button>\n\t);\n});\n\nDropdownButton.displayName = 'DropdownButton';\n\nexport { DropdownButton };\nexport type { DropdownButtonProps };\n"],"mappings":";;;;;;;AAsBA,IAAM,YAAgD,UAA4B;CACjF,MAAM,EACL,WACA,UACA,iBACA,kBACA,QAAQ,YACR,eACA,UACA,eACA,UACA,gBAAgB,SAAS,YACzB,GAAG,SACA;CAEJ,MAAM,aAAa,OAA2B,KAAK;CACnD,MAAM,CAAC,QAAQ,aAAa,SAAS,cAAc,MAAM;CACzD,MAAM,CAAC,WAAW,gBAAgB,SAAS,OAAO;AAElD,iBAAgB;AACf,MAAI,eAAe,KAAA,EAClB,WAAU,WAAW;IAEpB,CAAC,WAAW,CAAC;AAEhB,iBAAgB;AAEf,MAAI,aAAa,WAAW,MAC3B,kBAAiB;GAChB,MAAM,UAAU,WAAW;AAC3B,OAAI,CAAC,QACJ;AASD,IAFiB,QAAQ,UAAU,eAAe,IAErC,QAAQ,SAAS;IAC7B;IAED,CAAC,QAAQ,UAAU,CAAC;AAGvB,iBAAgB;AACf,eAAa,OAAO;AACpB,kBAAgB,EAAE,QAAQ,CAAC;IACzB,CAAC,OAAO,CAAC;CAEZ,MAAM,sBAAsB;EAC3B,MAAM,EAAE,WAAW,eAAe;AAClC,SAAO,6BAAa,QAAQ;GAC3B,iBAAiB;GACjB,iBAAiB,CAAC,CAAC;GACnB,KAAK,OAAO,MAAM,UAAU,OAAO,KAAK,WAAW,GAAG;GACtD,QAAQ,QAAQ,UAAA;GAChB,CAAC;;CAGH,MAAM,sBAAsB;AAC3B,SAAO,6BAAa,eAAe,CAAC,SAAS,EAC5C,UAAU,cACV,CAAC;;CAGH,MAAM,gBAAgB,SAAY;AACjC,YAAU,MAAM;AAChB,aAAW,MAAM,EAAE,QAAQ,OAAO,CAAC;;CAGpC,MAAM,4BAA4B,eAAwB;AACzD,YAAU,WAAW;;CAGtB,MAAM,sBAAsB;EAC3B,MAAM,CAAC,aAAa,gBAAgB,SAAS,QAAQ,SAAS;AAC9D,SAAO;GACN,QAAQ;GAIR,SAAS;GACT;;CAGF,MAAM,uBAAuB,GAAG,mBAAmB,gBAAgB;CACnE,MAAM,iBAAiB,GAAG,YAAY,iBAAiB;AAEvD,QACC,qBAAC,SAAA;EACQ;EACG;EACX,eAAe,iBAAiB;EAChC,gBAAgB;EACN;EACV,iBAAiB;EACjB,kBAAkB;EAClB,gBAAc;EACd,GAAI;aAEH,eAAe,EACf,eAAe,CAAA;GACP;;ACpHZ,IAAM,iBAAiB,4BAAoD,OAAO,QAAQ;CACzF,MAAM,EAAE,UAAU,WAAW,gBAAgB,SAAS,mBAAmB,GAAG,SAAS;AAErF,QACC,qBAAC,QAAA;EAAO,GAAI;EAAM,gBAAc;EAAa;;GAC3C;GAAS;GAAE,CAAC,aAAa,oBAAC,MAAA;IAAK,MAAK;IAAe,MAAK;;;GACjD;EAET;AAEF,eAAe,cAAc"}
1
+ {"version":3,"file":"index.es.js","sources":["../src/Dropdown.tsx","../src/DropdownButton.tsx"],"sourcesContent":["import type { AriaAttributes, ForwardedRef, FunctionComponentElement, ReactElement } from 'react';\nimport { Children, cloneElement, useEffect, useRef, useState } from 'react';\nimport { mergeRefs } from '@react-aria/utils';\nimport { cx } from 'classix';\n\nimport type { PopoverProps } from '@launchpad-ui/popover';\nimport { Popover } from '@launchpad-ui/popover';\n\ntype DropdownState = {\n\tisOpen?: boolean;\n};\n\ntype DropdownProps<T extends string | object | number> = PopoverProps & {\n\tonSelect?: (item: T, stateChanges: DropdownState) => void;\n\tonStateChange?: (state: DropdownState) => void;\n};\n\n/**\n * @deprecated use `Menu` from `@launchpad-ui/components` instead\n *\n * https://launchpad.launchdarkly.com/?path=/docs/components-collections-menu--docs\n */\nconst Dropdown = <T extends string | object | number>(props: DropdownProps<T>) => {\n\tconst {\n\t\tplacement,\n\t\tdisabled,\n\t\ttargetClassName,\n\t\tpopoverClassName,\n\t\tisOpen: isOpenProp,\n\t\tonInteraction,\n\t\tonSelect,\n\t\tonStateChange,\n\t\tchildren,\n\t\t'data-test-id': testId = 'dropdown',\n\t\t...rest\n\t} = props;\n\n\tconst triggerRef = useRef<HTMLElement | null>(null);\n\tconst [isOpen, setIsOpen] = useState(isOpenProp ?? false);\n\tconst [hasOpened, setHasOpened] = useState(isOpen);\n\n\tuseEffect(() => {\n\t\tif (isOpenProp !== undefined) {\n\t\t\tsetIsOpen(isOpenProp);\n\t\t}\n\t}, [isOpenProp]);\n\n\tuseEffect(() => {\n\t\t// Focus the button upon closing for convenient tabbing\n\t\tif (hasOpened && isOpen === false) {\n\t\t\tsetTimeout(() => {\n\t\t\t\tconst current = triggerRef.current;\n\t\t\t\tif (!current) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// If a dropdown menu item triggers a modal, we do not want to focus the trigger. Instead\n\t\t\t\t// we let the modal components control their own focus.\n\t\t\t\t// Note that this is not ideal since closing the modal will not cause the dropdown trigger\n\t\t\t\t// to regain focus.\n\t\t\t\tconst hasModal = current.closest?.('.has-overlay');\n\n\t\t\t\t!hasModal && current.focus?.();\n\t\t\t});\n\t\t}\n\t}, [isOpen, hasOpened]);\n\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: ignore\n\tuseEffect(() => {\n\t\tsetHasOpened(isOpen);\n\t\tonStateChange?.({ isOpen });\n\t}, [isOpen]);\n\n\tconst renderTrigger = () => {\n\t\tconst { target } = parseChildren();\n\t\treturn cloneElement(target, {\n\t\t\t'aria-haspopup': true,\n\t\t\t'aria-expanded': !!isOpen,\n\t\t\tref: target.ref ? mergeRefs(target.ref, triggerRef) : triggerRef,\n\t\t\tisopen: isOpen?.toString(),\n\t\t});\n\t};\n\n\tconst renderContent = () => {\n\t\treturn cloneElement(parseChildren().content, {\n\t\t\tonSelect: handleSelect,\n\t\t});\n\t};\n\n\tconst handleSelect = (item: T) => {\n\t\tsetIsOpen(false);\n\t\tonSelect?.(item, { isOpen: false });\n\t};\n\n\tconst handlePopoverInteraction = (nextIsOpen: boolean) => {\n\t\tsetIsOpen(nextIsOpen);\n\t};\n\n\tconst parseChildren = () => {\n\t\tconst [targetChild, contentChild] = Children.toArray(children);\n\t\treturn {\n\t\t\ttarget: targetChild as FunctionComponentElement<\n\t\t\t\tAriaAttributes & { ref: ForwardedRef<HTMLElement | undefined>; isopen: string }\n\t\t\t>,\n\t\t\tcontent: contentChild as ReactElement<{ onSelect?: (item: T) => void }>,\n\t\t};\n\t};\n\n\tconst popoverTargetClasses = cx('Dropdown-target', targetClassName);\n\tconst popoverClasses = cx('Dropdown', popoverClassName);\n\n\treturn (\n\t\t<Popover\n\t\t\tisOpen={isOpen}\n\t\t\tplacement={placement}\n\t\t\tonInteraction={onInteraction || handlePopoverInteraction}\n\t\t\trestrictHeight={false}\n\t\t\tdisabled={disabled}\n\t\t\ttargetClassName={popoverTargetClasses}\n\t\t\tpopoverClassName={popoverClasses}\n\t\t\tdata-test-id={testId}\n\t\t\t{...rest}\n\t\t>\n\t\t\t{renderTrigger()}\n\t\t\t{renderContent()}\n\t\t</Popover>\n\t);\n};\n\nexport { Dropdown };\nexport type { DropdownProps };\n","import { forwardRef } from 'react';\n\nimport type { ButtonProps } from '@launchpad-ui/button';\nimport { Button } from '@launchpad-ui/button';\nimport { Icon } from '@launchpad-ui/icons';\n\ntype DropdownButtonProps = ButtonProps & {\n\thideCaret?: boolean;\n};\n\nconst DropdownButton = forwardRef<HTMLButtonElement, DropdownButtonProps>((props, ref) => {\n\tconst { children, hideCaret, 'data-test-id': testId = 'dropdown-button', ...rest } = props;\n\n\treturn (\n\t\t<Button {...rest} data-test-id={testId} ref={ref}>\n\t\t\t{children} {!hideCaret && <Icon name=\"chevron-down\" size=\"small\" />}\n\t\t</Button>\n\t);\n});\n\nDropdownButton.displayName = 'DropdownButton';\n\nexport { DropdownButton };\nexport type { DropdownButtonProps };\n"],"names":[],"mappings":";;;;;;;AAsBA,MAAM,WAAW,CAAqC,UAA4B;AACjF,QAAM;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,gBAAgB,SAAS;AAAA,IACzB,GAAG;AAAA,EAAA,IACA;AAEJ,QAAM,aAAa,OAA2B,IAAI;AAClD,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,cAAc,KAAK;AACxD,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,MAAM;AAEjD,YAAU,MAAM;AACf,QAAI,eAAe,QAAW;AAC7B,gBAAU,UAAU;AAAA,IACrB;AAAA,EACD,GAAG,CAAC,UAAU,CAAC;AAEf,YAAU,MAAM;AAEf,QAAI,aAAa,WAAW,OAAO;AAClC,iBAAW,MAAM;AAChB,cAAM,UAAU,WAAW;AAC3B,YAAI,CAAC,SAAS;AACb;AAAA,QACD;AAMA,cAAM,WAAW,QAAQ,UAAU,cAAc;AAEjD,SAAC,YAAY,QAAQ,QAAA;AAAA,MACtB,CAAC;AAAA,IACF;AAAA,EACD,GAAG,CAAC,QAAQ,SAAS,CAAC;AAGtB,YAAU,MAAM;AACf,iBAAa,MAAM;AACnB,oBAAgB,EAAE,QAAQ;AAAA,EAC3B,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,gBAAgB,MAAM;AAC3B,UAAM,EAAE,OAAA,IAAW,cAAA;AACnB,WAAO,6BAAa,QAAQ;AAAA,MAC3B,iBAAiB;AAAA,MACjB,iBAAiB,CAAC,CAAC;AAAA,MACnB,KAAK,OAAO,MAAM,UAAU,OAAO,KAAK,UAAU,IAAI;AAAA,MACtD,QAAQ,QAAQ,SAAA;AAAA,IAAS,CACzB;AAAA,EACF;AAEA,QAAM,gBAAgB,MAAM;AAC3B,WAAO,6BAAa,cAAA,EAAgB,SAAS;AAAA,MAC5C,UAAU;AAAA,IAAA,CACV;AAAA,EACF;AAEA,QAAM,eAAe,CAAC,SAAY;AACjC,cAAU,KAAK;AACf,eAAW,MAAM,EAAE,QAAQ,MAAA,CAAO;AAAA,EACnC;AAEA,QAAM,2BAA2B,CAAC,eAAwB;AACzD,cAAU,UAAU;AAAA,EACrB;AAEA,QAAM,gBAAgB,MAAM;AAC3B,UAAM,CAAC,aAAa,YAAY,IAAI,SAAS,QAAQ,QAAQ;AAC7D,WAAO;AAAA,MACN,QAAQ;AAAA,MAGR,SAAS;AAAA,IAAA;AAAA,EAEX;AAEA,QAAM,uBAAuB,GAAG,mBAAmB,eAAe;AAClE,QAAM,iBAAiB,GAAG,YAAY,gBAAgB;AAEtD,SACC;AAAA,IAAC;AAAA,IAAA;AAAA,MACA;AAAA,MACA;AAAA,MACA,eAAe,iBAAiB;AAAA,MAChC,gBAAgB;AAAA,MAChB;AAAA,MACA,iBAAiB;AAAA,MACjB,kBAAkB;AAAA,MAClB,gBAAc;AAAA,MACb,GAAG;AAAA,MAEH,UAAA;AAAA,QAAA,cAAA;AAAA,QACA,cAAA;AAAA,MAAc;AAAA,IAAA;AAAA,EAAA;AAGlB;ACrHA,MAAM,iBAAiB,2BAAmD,CAAC,OAAO,QAAQ;AACzF,QAAM,EAAE,UAAU,WAAW,gBAAgB,SAAS,mBAAmB,GAAG,SAAS;AAErF,8BACE,QAAA,EAAQ,GAAG,MAAM,gBAAc,QAAQ,KACtC,UAAA;AAAA,IAAA;AAAA,IAAS;AAAA,IAAE,CAAC,aAAa,oBAAC,QAAK,MAAK,gBAAe,MAAK,QAAA,CAAQ;AAAA,EAAA,GAClE;AAEF,CAAC;AAED,eAAe,cAAc;"}
package/dist/index.js CHANGED
@@ -1,89 +1,108 @@
1
+ "use strict";
1
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- let __launchpad_ui_popover = require("@launchpad-ui/popover");
3
- let __react_aria_utils = require("@react-aria/utils");
4
- let classix = require("classix");
5
- let react = require("react");
6
- let react_jsx_runtime = require("react/jsx-runtime");
7
- let __launchpad_ui_button = require("@launchpad-ui/button");
8
- let __launchpad_ui_icons = require("@launchpad-ui/icons");
9
- var Dropdown = (props) => {
10
- const { placement, disabled, targetClassName, popoverClassName, isOpen: isOpenProp, onInteraction, onSelect, onStateChange, children, "data-test-id": testId = "dropdown", ...rest } = props;
11
- const triggerRef = (0, react.useRef)(null);
12
- const [isOpen, setIsOpen] = (0, react.useState)(isOpenProp ?? false);
13
- const [hasOpened, setHasOpened] = (0, react.useState)(isOpen);
14
- (0, react.useEffect)(() => {
15
- if (isOpenProp !== void 0) setIsOpen(isOpenProp);
16
- }, [isOpenProp]);
17
- (0, react.useEffect)(() => {
18
- if (hasOpened && isOpen === false) setTimeout(() => {
19
- const current = triggerRef.current;
20
- if (!current) return;
21
- !current.closest?.(".has-overlay") && current.focus?.();
22
- });
23
- }, [isOpen, hasOpened]);
24
- (0, react.useEffect)(() => {
25
- setHasOpened(isOpen);
26
- onStateChange?.({ isOpen });
27
- }, [isOpen]);
28
- const renderTrigger = () => {
29
- const { target } = parseChildren();
30
- return /* @__PURE__ */ (0, react.cloneElement)(target, {
31
- "aria-haspopup": true,
32
- "aria-expanded": !!isOpen,
33
- ref: target.ref ? (0, __react_aria_utils.mergeRefs)(target.ref, triggerRef) : triggerRef,
34
- isopen: isOpen?.toString()
35
- });
36
- };
37
- const renderContent = () => {
38
- return /* @__PURE__ */ (0, react.cloneElement)(parseChildren().content, { onSelect: handleSelect });
39
- };
40
- const handleSelect = (item) => {
41
- setIsOpen(false);
42
- onSelect?.(item, { isOpen: false });
43
- };
44
- const handlePopoverInteraction = (nextIsOpen) => {
45
- setIsOpen(nextIsOpen);
46
- };
47
- const parseChildren = () => {
48
- const [targetChild, contentChild] = react.Children.toArray(children);
49
- return {
50
- target: targetChild,
51
- content: contentChild
52
- };
53
- };
54
- const popoverTargetClasses = (0, classix.cx)("Dropdown-target", targetClassName);
55
- const popoverClasses = (0, classix.cx)("Dropdown", popoverClassName);
56
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__launchpad_ui_popover.Popover, {
57
- isOpen,
58
- placement,
59
- onInteraction: onInteraction || handlePopoverInteraction,
60
- restrictHeight: false,
61
- disabled,
62
- targetClassName: popoverTargetClasses,
63
- popoverClassName: popoverClasses,
64
- "data-test-id": testId,
65
- ...rest,
66
- children: [renderTrigger(), renderContent()]
67
- });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const react = require("react");
5
+ const utils = require("@react-aria/utils");
6
+ const classix = require("classix");
7
+ const popover = require("@launchpad-ui/popover");
8
+ const button = require("@launchpad-ui/button");
9
+ const icons = require("@launchpad-ui/icons");
10
+ const Dropdown = (props) => {
11
+ const {
12
+ placement,
13
+ disabled,
14
+ targetClassName,
15
+ popoverClassName,
16
+ isOpen: isOpenProp,
17
+ onInteraction,
18
+ onSelect,
19
+ onStateChange,
20
+ children,
21
+ "data-test-id": testId = "dropdown",
22
+ ...rest
23
+ } = props;
24
+ const triggerRef = react.useRef(null);
25
+ const [isOpen, setIsOpen] = react.useState(isOpenProp ?? false);
26
+ const [hasOpened, setHasOpened] = react.useState(isOpen);
27
+ react.useEffect(() => {
28
+ if (isOpenProp !== void 0) {
29
+ setIsOpen(isOpenProp);
30
+ }
31
+ }, [isOpenProp]);
32
+ react.useEffect(() => {
33
+ if (hasOpened && isOpen === false) {
34
+ setTimeout(() => {
35
+ const current = triggerRef.current;
36
+ if (!current) {
37
+ return;
38
+ }
39
+ const hasModal = current.closest?.(".has-overlay");
40
+ !hasModal && current.focus?.();
41
+ });
42
+ }
43
+ }, [isOpen, hasOpened]);
44
+ react.useEffect(() => {
45
+ setHasOpened(isOpen);
46
+ onStateChange?.({ isOpen });
47
+ }, [isOpen]);
48
+ const renderTrigger = () => {
49
+ const { target } = parseChildren();
50
+ return /* @__PURE__ */ react.cloneElement(target, {
51
+ "aria-haspopup": true,
52
+ "aria-expanded": !!isOpen,
53
+ ref: target.ref ? utils.mergeRefs(target.ref, triggerRef) : triggerRef,
54
+ isopen: isOpen?.toString()
55
+ });
56
+ };
57
+ const renderContent = () => {
58
+ return /* @__PURE__ */ react.cloneElement(parseChildren().content, {
59
+ onSelect: handleSelect
60
+ });
61
+ };
62
+ const handleSelect = (item) => {
63
+ setIsOpen(false);
64
+ onSelect?.(item, { isOpen: false });
65
+ };
66
+ const handlePopoverInteraction = (nextIsOpen) => {
67
+ setIsOpen(nextIsOpen);
68
+ };
69
+ const parseChildren = () => {
70
+ const [targetChild, contentChild] = react.Children.toArray(children);
71
+ return {
72
+ target: targetChild,
73
+ content: contentChild
74
+ };
75
+ };
76
+ const popoverTargetClasses = classix.cx("Dropdown-target", targetClassName);
77
+ const popoverClasses = classix.cx("Dropdown", popoverClassName);
78
+ return /* @__PURE__ */ jsxRuntime.jsxs(
79
+ popover.Popover,
80
+ {
81
+ isOpen,
82
+ placement,
83
+ onInteraction: onInteraction || handlePopoverInteraction,
84
+ restrictHeight: false,
85
+ disabled,
86
+ targetClassName: popoverTargetClasses,
87
+ popoverClassName: popoverClasses,
88
+ "data-test-id": testId,
89
+ ...rest,
90
+ children: [
91
+ renderTrigger(),
92
+ renderContent()
93
+ ]
94
+ }
95
+ );
68
96
  };
69
- var DropdownButton = /* @__PURE__ */ (0, react.forwardRef)((props, ref) => {
70
- const { children, hideCaret, "data-test-id": testId = "dropdown-button", ...rest } = props;
71
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__launchpad_ui_button.Button, {
72
- ...rest,
73
- "data-test-id": testId,
74
- ref,
75
- children: [
76
- children,
77
- " ",
78
- !hideCaret && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__launchpad_ui_icons.Icon, {
79
- name: "chevron-down",
80
- size: "small"
81
- })
82
- ]
83
- });
97
+ const DropdownButton = /* @__PURE__ */ react.forwardRef((props, ref) => {
98
+ const { children, hideCaret, "data-test-id": testId = "dropdown-button", ...rest } = props;
99
+ return /* @__PURE__ */ jsxRuntime.jsxs(button.Button, { ...rest, "data-test-id": testId, ref, children: [
100
+ children,
101
+ " ",
102
+ !hideCaret && /* @__PURE__ */ jsxRuntime.jsx(icons.Icon, { name: "chevron-down", size: "small" })
103
+ ] });
84
104
  });
85
105
  DropdownButton.displayName = "DropdownButton";
86
106
  exports.Dropdown = Dropdown;
87
107
  exports.DropdownButton = DropdownButton;
88
-
89
- //# sourceMappingURL=index.js.map
108
+ //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/Dropdown.tsx","../src/DropdownButton.tsx"],"sourcesContent":["import type { PopoverProps } from '@launchpad-ui/popover';\nimport type { AriaAttributes, ForwardedRef, FunctionComponentElement, ReactElement } from 'react';\n\nimport { Popover } from '@launchpad-ui/popover';\nimport { mergeRefs } from '@react-aria/utils';\nimport { cx } from 'classix';\nimport { Children, cloneElement, useEffect, useRef, useState } from 'react';\n\ntype DropdownState = {\n\tisOpen?: boolean;\n};\n\ntype DropdownProps<T extends string | object | number> = PopoverProps & {\n\tonSelect?: (item: T, stateChanges: DropdownState) => void;\n\tonStateChange?: (state: DropdownState) => void;\n};\n\n/**\n * @deprecated use `Menu` from `@launchpad-ui/components` instead\n *\n * https://launchpad.launchdarkly.com/?path=/docs/components-collections-menu--docs\n */\nconst Dropdown = <T extends string | object | number>(props: DropdownProps<T>) => {\n\tconst {\n\t\tplacement,\n\t\tdisabled,\n\t\ttargetClassName,\n\t\tpopoverClassName,\n\t\tisOpen: isOpenProp,\n\t\tonInteraction,\n\t\tonSelect,\n\t\tonStateChange,\n\t\tchildren,\n\t\t'data-test-id': testId = 'dropdown',\n\t\t...rest\n\t} = props;\n\n\tconst triggerRef = useRef<HTMLElement | null>(null);\n\tconst [isOpen, setIsOpen] = useState(isOpenProp ?? false);\n\tconst [hasOpened, setHasOpened] = useState(isOpen);\n\n\tuseEffect(() => {\n\t\tif (isOpenProp !== undefined) {\n\t\t\tsetIsOpen(isOpenProp);\n\t\t}\n\t}, [isOpenProp]);\n\n\tuseEffect(() => {\n\t\t// Focus the button upon closing for convenient tabbing\n\t\tif (hasOpened && isOpen === false) {\n\t\t\tsetTimeout(() => {\n\t\t\t\tconst current = triggerRef.current;\n\t\t\t\tif (!current) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// If a dropdown menu item triggers a modal, we do not want to focus the trigger. Instead\n\t\t\t\t// we let the modal components control their own focus.\n\t\t\t\t// Note that this is not ideal since closing the modal will not cause the dropdown trigger\n\t\t\t\t// to regain focus.\n\t\t\t\tconst hasModal = current.closest?.('.has-overlay');\n\n\t\t\t\t!hasModal && current.focus?.();\n\t\t\t});\n\t\t}\n\t}, [isOpen, hasOpened]);\n\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: ignore\n\tuseEffect(() => {\n\t\tsetHasOpened(isOpen);\n\t\tonStateChange?.({ isOpen });\n\t}, [isOpen]);\n\n\tconst renderTrigger = () => {\n\t\tconst { target } = parseChildren();\n\t\treturn cloneElement(target, {\n\t\t\t'aria-haspopup': true,\n\t\t\t'aria-expanded': !!isOpen,\n\t\t\tref: target.ref ? mergeRefs(target.ref, triggerRef) : triggerRef,\n\t\t\tisopen: isOpen?.toString(),\n\t\t});\n\t};\n\n\tconst renderContent = () => {\n\t\treturn cloneElement(parseChildren().content, {\n\t\t\tonSelect: handleSelect,\n\t\t});\n\t};\n\n\tconst handleSelect = (item: T) => {\n\t\tsetIsOpen(false);\n\t\tonSelect?.(item, { isOpen: false });\n\t};\n\n\tconst handlePopoverInteraction = (nextIsOpen: boolean) => {\n\t\tsetIsOpen(nextIsOpen);\n\t};\n\n\tconst parseChildren = () => {\n\t\tconst [targetChild, contentChild] = Children.toArray(children);\n\t\treturn {\n\t\t\ttarget: targetChild as FunctionComponentElement<\n\t\t\t\tAriaAttributes & { ref: ForwardedRef<HTMLElement | undefined>; isopen: string }\n\t\t\t>,\n\t\t\t// biome-ignore lint/suspicious/noExplicitAny: ignore\n\t\t\tcontent: contentChild as ReactElement<any>,\n\t\t};\n\t};\n\n\tconst popoverTargetClasses = cx('Dropdown-target', targetClassName);\n\tconst popoverClasses = cx('Dropdown', popoverClassName);\n\n\treturn (\n\t\t<Popover\n\t\t\tisOpen={isOpen}\n\t\t\tplacement={placement}\n\t\t\tonInteraction={onInteraction || handlePopoverInteraction}\n\t\t\trestrictHeight={false}\n\t\t\tdisabled={disabled}\n\t\t\ttargetClassName={popoverTargetClasses}\n\t\t\tpopoverClassName={popoverClasses}\n\t\t\tdata-test-id={testId}\n\t\t\t{...rest}\n\t\t>\n\t\t\t{renderTrigger()}\n\t\t\t{renderContent()}\n\t\t</Popover>\n\t);\n};\n\nexport { Dropdown };\nexport type { DropdownProps };\n","import type { ButtonProps } from '@launchpad-ui/button';\n\nimport { Button } from '@launchpad-ui/button';\nimport { Icon } from '@launchpad-ui/icons';\nimport { forwardRef } from 'react';\n\ntype DropdownButtonProps = ButtonProps & {\n\thideCaret?: boolean;\n};\n\nconst DropdownButton = forwardRef<HTMLButtonElement, DropdownButtonProps>((props, ref) => {\n\tconst { children, hideCaret, 'data-test-id': testId = 'dropdown-button', ...rest } = props;\n\n\treturn (\n\t\t<Button {...rest} data-test-id={testId} ref={ref}>\n\t\t\t{children} {!hideCaret && <Icon name=\"chevron-down\" size=\"small\" />}\n\t\t</Button>\n\t);\n});\n\nDropdownButton.displayName = 'DropdownButton';\n\nexport { DropdownButton };\nexport type { DropdownButtonProps };\n"],"mappings":";;;;;;;;AAsBA,IAAM,YAAgD,UAA4B;CACjF,MAAM,EACL,WACA,UACA,iBACA,kBACA,QAAQ,YACR,eACA,UACA,eACA,UACA,gBAAgB,SAAS,YACzB,GAAG,SACA;CAEJ,MAAM,cAAA,GAAA,MAAA,QAAwC,KAAK;CACnD,MAAM,CAAC,QAAQ,cAAA,GAAA,MAAA,UAAsB,cAAc,MAAM;CACzD,MAAM,CAAC,WAAW,iBAAA,GAAA,MAAA,UAAyB,OAAO;AAElD,EAAA,GAAA,MAAA,iBAAgB;AACf,MAAI,eAAe,KAAA,EAClB,WAAU,WAAW;IAEpB,CAAC,WAAW,CAAC;AAEhB,EAAA,GAAA,MAAA,iBAAgB;AAEf,MAAI,aAAa,WAAW,MAC3B,kBAAiB;GAChB,MAAM,UAAU,WAAW;AAC3B,OAAI,CAAC,QACJ;AASD,IAFiB,QAAQ,UAAU,eAAe,IAErC,QAAQ,SAAS;IAC7B;IAED,CAAC,QAAQ,UAAU,CAAC;AAGvB,EAAA,GAAA,MAAA,iBAAgB;AACf,eAAa,OAAO;AACpB,kBAAgB,EAAE,QAAQ,CAAC;IACzB,CAAC,OAAO,CAAC;CAEZ,MAAM,sBAAsB;EAC3B,MAAM,EAAE,WAAW,eAAe;AAClC,SAAO,iBAAA,GAAA,MAAA,cAAa,QAAQ;GAC3B,iBAAiB;GACjB,iBAAiB,CAAC,CAAC;GACnB,KAAK,OAAO,OAAA,GAAA,mBAAA,WAAgB,OAAO,KAAK,WAAW,GAAG;GACtD,QAAQ,QAAQ,UAAA;GAChB,CAAC;;CAGH,MAAM,sBAAsB;AAC3B,SAAO,iBAAA,GAAA,MAAA,cAAa,eAAe,CAAC,SAAS,EAC5C,UAAU,cACV,CAAC;;CAGH,MAAM,gBAAgB,SAAY;AACjC,YAAU,MAAM;AAChB,aAAW,MAAM,EAAE,QAAQ,OAAO,CAAC;;CAGpC,MAAM,4BAA4B,eAAwB;AACzD,YAAU,WAAW;;CAGtB,MAAM,sBAAsB;EAC3B,MAAM,CAAC,aAAa,gBAAgB,MAAA,SAAS,QAAQ,SAAS;AAC9D,SAAO;GACN,QAAQ;GAIR,SAAS;GACT;;CAGF,MAAM,wBAAA,GAAA,QAAA,IAA0B,mBAAmB,gBAAgB;CACnE,MAAM,kBAAA,GAAA,QAAA,IAAoB,YAAY,iBAAiB;AAEvD,QACC,iBAAA,GAAA,kBAAA,MAAC,uBAAA,SAAA;EACQ;EACG;EACX,eAAe,iBAAiB;EAChC,gBAAgB;EACN;EACV,iBAAiB;EACjB,kBAAkB;EAClB,gBAAc;EACd,GAAI;aAEH,eAAe,EACf,eAAe,CAAA;GACP;;ACpHZ,IAAM,iBAAiB,iBAAA,GAAA,MAAA,aAAoD,OAAO,QAAQ;CACzF,MAAM,EAAE,UAAU,WAAW,gBAAgB,SAAS,mBAAmB,GAAG,SAAS;AAErF,QACC,iBAAA,GAAA,kBAAA,MAAC,sBAAA,QAAA;EAAO,GAAI;EAAM,gBAAc;EAAa;;GAC3C;GAAS;GAAE,CAAC,aAAa,iBAAA,GAAA,kBAAA,KAAC,qBAAA,MAAA;IAAK,MAAK;IAAe,MAAK;;;GACjD;EAET;AAEF,eAAe,cAAc"}
1
+ {"version":3,"file":"index.js","sources":["../src/Dropdown.tsx","../src/DropdownButton.tsx"],"sourcesContent":["import type { AriaAttributes, ForwardedRef, FunctionComponentElement, ReactElement } from 'react';\nimport { Children, cloneElement, useEffect, useRef, useState } from 'react';\nimport { mergeRefs } from '@react-aria/utils';\nimport { cx } from 'classix';\n\nimport type { PopoverProps } from '@launchpad-ui/popover';\nimport { Popover } from '@launchpad-ui/popover';\n\ntype DropdownState = {\n\tisOpen?: boolean;\n};\n\ntype DropdownProps<T extends string | object | number> = PopoverProps & {\n\tonSelect?: (item: T, stateChanges: DropdownState) => void;\n\tonStateChange?: (state: DropdownState) => void;\n};\n\n/**\n * @deprecated use `Menu` from `@launchpad-ui/components` instead\n *\n * https://launchpad.launchdarkly.com/?path=/docs/components-collections-menu--docs\n */\nconst Dropdown = <T extends string | object | number>(props: DropdownProps<T>) => {\n\tconst {\n\t\tplacement,\n\t\tdisabled,\n\t\ttargetClassName,\n\t\tpopoverClassName,\n\t\tisOpen: isOpenProp,\n\t\tonInteraction,\n\t\tonSelect,\n\t\tonStateChange,\n\t\tchildren,\n\t\t'data-test-id': testId = 'dropdown',\n\t\t...rest\n\t} = props;\n\n\tconst triggerRef = useRef<HTMLElement | null>(null);\n\tconst [isOpen, setIsOpen] = useState(isOpenProp ?? false);\n\tconst [hasOpened, setHasOpened] = useState(isOpen);\n\n\tuseEffect(() => {\n\t\tif (isOpenProp !== undefined) {\n\t\t\tsetIsOpen(isOpenProp);\n\t\t}\n\t}, [isOpenProp]);\n\n\tuseEffect(() => {\n\t\t// Focus the button upon closing for convenient tabbing\n\t\tif (hasOpened && isOpen === false) {\n\t\t\tsetTimeout(() => {\n\t\t\t\tconst current = triggerRef.current;\n\t\t\t\tif (!current) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// If a dropdown menu item triggers a modal, we do not want to focus the trigger. Instead\n\t\t\t\t// we let the modal components control their own focus.\n\t\t\t\t// Note that this is not ideal since closing the modal will not cause the dropdown trigger\n\t\t\t\t// to regain focus.\n\t\t\t\tconst hasModal = current.closest?.('.has-overlay');\n\n\t\t\t\t!hasModal && current.focus?.();\n\t\t\t});\n\t\t}\n\t}, [isOpen, hasOpened]);\n\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: ignore\n\tuseEffect(() => {\n\t\tsetHasOpened(isOpen);\n\t\tonStateChange?.({ isOpen });\n\t}, [isOpen]);\n\n\tconst renderTrigger = () => {\n\t\tconst { target } = parseChildren();\n\t\treturn cloneElement(target, {\n\t\t\t'aria-haspopup': true,\n\t\t\t'aria-expanded': !!isOpen,\n\t\t\tref: target.ref ? mergeRefs(target.ref, triggerRef) : triggerRef,\n\t\t\tisopen: isOpen?.toString(),\n\t\t});\n\t};\n\n\tconst renderContent = () => {\n\t\treturn cloneElement(parseChildren().content, {\n\t\t\tonSelect: handleSelect,\n\t\t});\n\t};\n\n\tconst handleSelect = (item: T) => {\n\t\tsetIsOpen(false);\n\t\tonSelect?.(item, { isOpen: false });\n\t};\n\n\tconst handlePopoverInteraction = (nextIsOpen: boolean) => {\n\t\tsetIsOpen(nextIsOpen);\n\t};\n\n\tconst parseChildren = () => {\n\t\tconst [targetChild, contentChild] = Children.toArray(children);\n\t\treturn {\n\t\t\ttarget: targetChild as FunctionComponentElement<\n\t\t\t\tAriaAttributes & { ref: ForwardedRef<HTMLElement | undefined>; isopen: string }\n\t\t\t>,\n\t\t\tcontent: contentChild as ReactElement<{ onSelect?: (item: T) => void }>,\n\t\t};\n\t};\n\n\tconst popoverTargetClasses = cx('Dropdown-target', targetClassName);\n\tconst popoverClasses = cx('Dropdown', popoverClassName);\n\n\treturn (\n\t\t<Popover\n\t\t\tisOpen={isOpen}\n\t\t\tplacement={placement}\n\t\t\tonInteraction={onInteraction || handlePopoverInteraction}\n\t\t\trestrictHeight={false}\n\t\t\tdisabled={disabled}\n\t\t\ttargetClassName={popoverTargetClasses}\n\t\t\tpopoverClassName={popoverClasses}\n\t\t\tdata-test-id={testId}\n\t\t\t{...rest}\n\t\t>\n\t\t\t{renderTrigger()}\n\t\t\t{renderContent()}\n\t\t</Popover>\n\t);\n};\n\nexport { Dropdown };\nexport type { DropdownProps };\n","import { forwardRef } from 'react';\n\nimport type { ButtonProps } from '@launchpad-ui/button';\nimport { Button } from '@launchpad-ui/button';\nimport { Icon } from '@launchpad-ui/icons';\n\ntype DropdownButtonProps = ButtonProps & {\n\thideCaret?: boolean;\n};\n\nconst DropdownButton = forwardRef<HTMLButtonElement, DropdownButtonProps>((props, ref) => {\n\tconst { children, hideCaret, 'data-test-id': testId = 'dropdown-button', ...rest } = props;\n\n\treturn (\n\t\t<Button {...rest} data-test-id={testId} ref={ref}>\n\t\t\t{children} {!hideCaret && <Icon name=\"chevron-down\" size=\"small\" />}\n\t\t</Button>\n\t);\n});\n\nDropdownButton.displayName = 'DropdownButton';\n\nexport { DropdownButton };\nexport type { DropdownButtonProps };\n"],"names":["useRef","useState","useEffect","cloneElement","mergeRefs","Children","cx","jsxs","Popover","forwardRef","Button","jsx","Icon"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@launchpad-ui/dropdown",
3
- "version": "0.10.16",
3
+ "version": "0.10.18",
4
4
  "description": "An element that displays a list of actions or options to a user.",
5
5
  "repository": "launchdarkly/launchpad-ui",
6
6
  "license": "Apache-2.0",
@@ -20,21 +20,21 @@
20
20
  ],
21
21
  "dependencies": {
22
22
  "classix": "2.2.0",
23
- "@launchpad-ui/button": "~0.15.16",
24
- "@launchpad-ui/icons": "~0.26.0",
25
- "@launchpad-ui/popover": "~0.14.4",
26
- "@launchpad-ui/tokens": "~0.16.0"
23
+ "@launchpad-ui/button": "~0.15.18",
24
+ "@launchpad-ui/icons": "~0.26.3",
25
+ "@launchpad-ui/popover": "~0.14.6",
26
+ "@launchpad-ui/tokens": "~0.17.1"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@react-aria/utils": "3.34.1",
30
- "@react-types/shared": "3.35.0",
31
- "react": "19.2.6",
32
- "react-dom": "19.2.6"
30
+ "@react-types/shared": "3.36.0",
31
+ "react": "19.2.8",
32
+ "react-dom": "19.2.8"
33
33
  },
34
34
  "peerDependencies": {
35
- "@react-aria/utils": "3.34.1",
36
- "react": "19.2.6",
37
- "react-dom": "19.2.6"
35
+ "@react-aria/utils": "^3.34.1",
36
+ "react": "^19",
37
+ "react-dom": "^19"
38
38
  },
39
39
  "exports": {
40
40
  ".": {