@launchpad-ui/dropdown 0.5.0 → 0.5.2

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;AAO1D,aAAK,aAAa,GAAG;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,aAAK,aAAa,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,MAAM,IAAI,YAAY,GAAG;IACtE,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;CAChD,CAAC;AAEF,QAAA,MAAM,QAAQ,8EAoGb,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":";AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAO1D,aAAK,aAAa,GAAG;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,aAAK,aAAa,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,MAAM,IAAI,YAAY,GAAG;IACtE,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;CAChD,CAAC;AAEF,QAAA,MAAM,QAAQ,8EAsGb,CAAC;AAEF,OAAO,EAAE,QAAQ,EAAE,CAAC;AACpB,YAAY,EAAE,aAAa,EAAE,CAAC"}
@@ -17,6 +17,7 @@ declare const DropdownButton: import("react").ForwardRefExoticComponent<import("
17
17
  }, string | import("react").JSXElementConstructor<any>> | undefined;
18
18
  renderIconFirst?: boolean | undefined;
19
19
  asChild?: boolean | undefined;
20
+ 'data-test-id'?: string | undefined;
20
21
  } & {
21
22
  hideCaret?: boolean | undefined;
22
23
  } & import("react").RefAttributes<HTMLButtonElement>>;
@@ -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,aAAK,mBAAmB,GAAG,WAAW,GAAG;IACvC,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,QAAA,MAAM,cAAc;;;;;;;;;;;;;;;;qDAQlB,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":";AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAMxD,aAAK,mBAAmB,GAAG,WAAW,GAAG;IACvC,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,QAAA,MAAM,cAAc;;;;;;;;;;;;;;;;;qDAQlB,CAAC;AAIH,OAAO,EAAE,cAAc,EAAE,CAAC;AAC1B,YAAY,EAAE,mBAAmB,EAAE,CAAC"}
package/dist/index.es.js CHANGED
@@ -15,6 +15,7 @@ const Dropdown = (props) => {
15
15
  onSelect,
16
16
  onStateChange,
17
17
  children,
18
+ "data-test-id": testId = "dropdown",
18
19
  ...rest
19
20
  } = props;
20
21
  const triggerRef = useRef(null);
@@ -83,6 +84,7 @@ const Dropdown = (props) => {
83
84
  disabled,
84
85
  targetClassName: popoverTargetClasses,
85
86
  popoverClassName: popoverClasses,
87
+ "data-test-id": testId,
86
88
  ...rest,
87
89
  children: [renderTrigger(), renderContent()]
88
90
  });
@@ -91,10 +93,12 @@ const DropdownButton = forwardRef((props, ref) => {
91
93
  const {
92
94
  children,
93
95
  hideCaret,
96
+ "data-test-id": testId = "dropdown-button",
94
97
  ...rest
95
98
  } = props;
96
99
  return /* @__PURE__ */ jsxs(Button, {
97
100
  ...rest,
101
+ "data-test-id": testId,
98
102
  ref,
99
103
  children: [children, " ", !hideCaret && /* @__PURE__ */ jsx(ExpandMore, {
100
104
  size: "small"
@@ -1 +1 @@
1
- {"version":3,"file":"index.es.js","sources":["../src/Dropdown.tsx","../src/DropdownButton.tsx"],"sourcesContent":["import type { PopoverProps } from '@launchpad-ui/popover';\nimport type { ReactElement } from 'react';\n\nimport { Popover } from '@launchpad-ui/popover';\nimport { cx } from 'classix';\nimport { Children, cloneElement, useEffect, useRef, useState } from 'react';\n\ntype DropdownState = {\n isOpen?: boolean;\n};\n\ntype DropdownProps<T extends string | object | number> = PopoverProps & {\n onSelect?: (item: T, stateChanges: DropdownState) => void;\n onStateChange?: (state: DropdownState) => void;\n};\n\nconst Dropdown = <T extends string | object | number>(props: DropdownProps<T>) => {\n const {\n placement,\n disabled,\n targetClassName,\n popoverClassName,\n isOpen: isOpenProp,\n onInteraction,\n onSelect,\n onStateChange,\n children,\n ...rest\n } = props;\n\n const triggerRef = useRef<HTMLElement>(null);\n const [isOpen, setIsOpen] = useState(isOpenProp ?? false);\n const [hasOpened, setHasOpened] = useState(isOpen);\n\n useEffect(() => {\n if (isOpenProp !== undefined) {\n setIsOpen(isOpenProp);\n }\n }, [isOpenProp]);\n\n useEffect(() => {\n // Focus the button upon closing for convenient tabbing\n if (hasOpened && isOpen === false) {\n setTimeout(() => {\n const current = triggerRef.current;\n if (!current) {\n return;\n }\n\n // If a dropdown menu item triggers a modal, we do not want to focus the trigger. Instead\n // we let the modal components control their own focus.\n // Note that this is not ideal since closing the modal will not cause the dropdown trigger\n // to regain focus.\n const hasModal = current.closest?.('.has-modal');\n\n !hasModal && current.focus?.();\n });\n }\n }, [isOpen, hasOpened]);\n\n useEffect(() => {\n setHasOpened(isOpen);\n onStateChange?.({ isOpen });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen]);\n\n const renderTrigger = () => {\n return cloneElement(parseChildren().target, {\n 'aria-haspopup': true,\n 'aria-expanded': isOpen ? true : false,\n ref: triggerRef,\n isopen: isOpen?.toString(),\n });\n };\n\n const renderContent = () => {\n return cloneElement(parseChildren().content, {\n onSelect: handleSelect,\n });\n };\n\n const handleSelect = (item: T) => {\n setIsOpen(false);\n onSelect?.(item, { isOpen: false });\n };\n\n const handlePopoverInteraction = (nextIsOpen: boolean) => {\n setIsOpen(nextIsOpen);\n };\n\n const parseChildren = () => {\n const [targetChild, contentChild] = Children.toArray(children);\n return {\n target: targetChild as ReactElement,\n content: contentChild as ReactElement,\n };\n };\n\n const popoverTargetClasses = cx('Dropdown-target', targetClassName);\n const popoverClasses = cx('Dropdown', popoverClassName);\n\n return (\n <Popover\n isOpen={isOpen}\n placement={placement}\n onInteraction={onInteraction || handlePopoverInteraction}\n restrictHeight={false}\n disabled={disabled}\n targetClassName={popoverTargetClasses}\n popoverClassName={popoverClasses}\n {...rest}\n >\n {renderTrigger()}\n {renderContent()}\n </Popover>\n );\n};\n\nexport { Dropdown };\nexport type { DropdownProps };\n","import type { ButtonProps } from '@launchpad-ui/button';\n\nimport { Button } from '@launchpad-ui/button';\nimport { ExpandMore } from '@launchpad-ui/icons';\nimport { forwardRef } from 'react';\n\ntype DropdownButtonProps = ButtonProps & {\n hideCaret?: boolean;\n};\n\nconst DropdownButton = forwardRef<HTMLButtonElement, DropdownButtonProps>((props, ref) => {\n const { children, hideCaret, ...rest } = props;\n\n return (\n <Button {...rest} ref={ref}>\n {children} {!hideCaret && <ExpandMore size=\"small\" />}\n </Button>\n );\n});\n\nDropdownButton.displayName = 'DropdownButton';\n\nexport { DropdownButton };\nexport type { DropdownButtonProps };\n"],"names":["Dropdown","props","placement","disabled","targetClassName","popoverClassName","isOpen","isOpenProp","onInteraction","onSelect","onStateChange","children","rest","triggerRef","useRef","setIsOpen","useState","hasOpened","setHasOpened","useEffect","undefined","setTimeout","current","hasModal","closest","focus","renderTrigger","cloneElement","parseChildren","target","ref","isopen","toString","renderContent","content","handleSelect","item","handlePopoverInteraction","nextIsOpen","targetChild","contentChild","Children","toArray","popoverTargetClasses","cx","popoverClasses","DropdownButton","forwardRef","hideCaret","displayName"],"mappings":";;;;;;AAgBMA,MAAAA,WAAW,CAAqCC,UAA4B;AAC1E,QAAA;AAAA,IACJC;AAAAA,IACAC;AAAAA,IACAC;AAAAA,IACAC;AAAAA,IACAC,QAAQC;AAAAA,IACRC;AAAAA,IACAC;AAAAA,IACAC;AAAAA,IACAC;AAAAA,OACGC;AAAAA,EACDX,IAAAA;AAEEY,QAAAA,aAAaC,OAAoB,IAAd;AACzB,QAAM,CAACR,QAAQS,SAAT,IAAsBC,SAAST,kCAAc,KAAf;AACpC,QAAM,CAACU,WAAWC,YAAZ,IAA4BF,SAASV,MAAD;AAE1Ca,YAAU,MAAM;AACd,QAAIZ,eAAea,QAAW;AAC5BL,gBAAUR,UAAD;AAAA,IACV;AAAA,EAAA,GACA,CAACA,UAAD,CAJM;AAMTY,YAAU,MAAM;AAEVF,QAAAA,aAAaX,WAAW,OAAO;AACjCe,iBAAW,MAAM;;AACf,cAAMC,UAAUT,WAAWS;AAC3B,YAAI,CAACA,SAAS;AACZ;AAAA,QACD;AAMKC,cAAAA,YAAWD,aAAQE,YAARF,iCAAkB;AAElCC,SAAAA,cAAYD,aAAQG,UAARH;AAAAA,MAAb,CAZQ;AAAA,IAcX;AAAA,EAAA,GACA,CAAChB,QAAQW,SAAT,CAlBM;AAoBTE,YAAU,MAAM;AACdD,iBAAaZ,MAAD;AACI,mDAAA;AAAA,MAAEA;AAAAA,IAAAA;AAAAA,EAAL,GAEZ,CAACA,MAAD,CAJM;AAMT,QAAMoB,gBAAgB,MAAM;AACnBC,WAAAA,aAAaC,cAAa,EAAGC,QAAQ;AAAA,MAC1C,iBAAiB;AAAA,MACjB,iBAAiBvB,SAAS,OAAO;AAAA,MACjCwB,KAAKjB;AAAAA,MACLkB,QAAQzB,iCAAQ0B;AAAAA,IAAR,CAJS;AAAA,EAAA;AAQrB,QAAMC,gBAAgB,MAAM;AACnBN,WAAAA,aAAaC,cAAa,EAAGM,SAAS;AAAA,MAC3CzB,UAAU0B;AAAAA,IAAAA,CADO;AAAA,EAAA;AAKfA,QAAAA,eAAe,CAACC,SAAY;AAChCrB,cAAU,KAAD;AACTN,yCAAW2B,MAAM;AAAA,MAAE9B,QAAQ;AAAA,IAAA;AAAA,EAAnB;AAGJ+B,QAAAA,2BAA2B,CAACC,eAAwB;AACxDvB,cAAUuB,UAAD;AAAA,EAAA;AAGX,QAAMV,gBAAgB,MAAM;AAC1B,UAAM,CAACW,aAAaC,YAAd,IAA8BC,SAASC,QAAQ/B,QAAjB;AAC7B,WAAA;AAAA,MACLkB,QAAQU;AAAAA,MACRL,SAASM;AAAAA,IAAAA;AAAAA,EAFJ;AAMHG,QAAAA,uBAAuBC,GAAG,mBAAmBxC,eAApB;AACzByC,QAAAA,iBAAiBD,GAAG,YAAYvC,gBAAb;AAEzB,8BACG,SAAD;AAAA,IACE;AAAA,IACA;AAAA,IACA,eAAeG,iBAAiB6B;AAAAA,IAChC,gBAAgB;AAAA,IAChB;AAAA,IACA,iBAAiBM;AAAAA,IACjB,kBAAkBE;AAAAA,IAPpB,GAQMjC;AAAAA,IARN,UAAA,CAUGc,iBACAO,eAXH;AAAA,EAAA,CADF;AAeD;AC1GD,MAAMa,iBAAiBC,WAAmD,CAAC9C,OAAO6B,QAAQ;AAClF,QAAA;AAAA,IAAEnB;AAAAA,IAAUqC;AAAAA,OAAcpC;AAAAA,EAASX,IAAAA;AAEzC,8BACG,QAAD;AAAA,IAAA,GAAYW;AAAAA,IAAM;AAAA,IAAlB,UAAA,CACGD,UAAW,KAAA,CAACqC,iCAAc,YAAD;AAAA,MAAY,MAAK;AAAA,IAAA,CAD7C,CAAA;AAAA,EAAA,CADF;AAKD,CARgC;AAUjCF,eAAeG,cAAc;"}
1
+ {"version":3,"file":"index.es.js","sources":["../src/Dropdown.tsx","../src/DropdownButton.tsx"],"sourcesContent":["import type { PopoverProps } from '@launchpad-ui/popover';\nimport type { ReactElement } from 'react';\n\nimport { Popover } from '@launchpad-ui/popover';\nimport { cx } from 'classix';\nimport { Children, cloneElement, useEffect, useRef, useState } from 'react';\n\ntype DropdownState = {\n isOpen?: boolean;\n};\n\ntype DropdownProps<T extends string | object | number> = PopoverProps & {\n onSelect?: (item: T, stateChanges: DropdownState) => void;\n onStateChange?: (state: DropdownState) => void;\n};\n\nconst Dropdown = <T extends string | object | number>(props: DropdownProps<T>) => {\n const {\n placement,\n disabled,\n targetClassName,\n popoverClassName,\n isOpen: isOpenProp,\n onInteraction,\n onSelect,\n onStateChange,\n children,\n 'data-test-id': testId = 'dropdown',\n ...rest\n } = props;\n\n const triggerRef = useRef<HTMLElement>(null);\n const [isOpen, setIsOpen] = useState(isOpenProp ?? false);\n const [hasOpened, setHasOpened] = useState(isOpen);\n\n useEffect(() => {\n if (isOpenProp !== undefined) {\n setIsOpen(isOpenProp);\n }\n }, [isOpenProp]);\n\n useEffect(() => {\n // Focus the button upon closing for convenient tabbing\n if (hasOpened && isOpen === false) {\n setTimeout(() => {\n const current = triggerRef.current;\n if (!current) {\n return;\n }\n\n // If a dropdown menu item triggers a modal, we do not want to focus the trigger. Instead\n // we let the modal components control their own focus.\n // Note that this is not ideal since closing the modal will not cause the dropdown trigger\n // to regain focus.\n const hasModal = current.closest?.('.has-modal');\n\n !hasModal && current.focus?.();\n });\n }\n }, [isOpen, hasOpened]);\n\n useEffect(() => {\n setHasOpened(isOpen);\n onStateChange?.({ isOpen });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen]);\n\n const renderTrigger = () => {\n return cloneElement(parseChildren().target, {\n 'aria-haspopup': true,\n 'aria-expanded': isOpen ? true : false,\n ref: triggerRef,\n isopen: isOpen?.toString(),\n });\n };\n\n const renderContent = () => {\n return cloneElement(parseChildren().content, {\n onSelect: handleSelect,\n });\n };\n\n const handleSelect = (item: T) => {\n setIsOpen(false);\n onSelect?.(item, { isOpen: false });\n };\n\n const handlePopoverInteraction = (nextIsOpen: boolean) => {\n setIsOpen(nextIsOpen);\n };\n\n const parseChildren = () => {\n const [targetChild, contentChild] = Children.toArray(children);\n return {\n target: targetChild as ReactElement,\n content: contentChild as ReactElement,\n };\n };\n\n const popoverTargetClasses = cx('Dropdown-target', targetClassName);\n const popoverClasses = cx('Dropdown', popoverClassName);\n\n return (\n <Popover\n isOpen={isOpen}\n placement={placement}\n onInteraction={onInteraction || handlePopoverInteraction}\n restrictHeight={false}\n disabled={disabled}\n targetClassName={popoverTargetClasses}\n popoverClassName={popoverClasses}\n data-test-id={testId}\n {...rest}\n >\n {renderTrigger()}\n {renderContent()}\n </Popover>\n );\n};\n\nexport { Dropdown };\nexport type { DropdownProps };\n","import type { ButtonProps } from '@launchpad-ui/button';\n\nimport { Button } from '@launchpad-ui/button';\nimport { ExpandMore } from '@launchpad-ui/icons';\nimport { forwardRef } from 'react';\n\ntype DropdownButtonProps = ButtonProps & {\n hideCaret?: boolean;\n};\n\nconst DropdownButton = forwardRef<HTMLButtonElement, DropdownButtonProps>((props, ref) => {\n const { children, hideCaret, 'data-test-id': testId = 'dropdown-button', ...rest } = props;\n\n return (\n <Button {...rest} data-test-id={testId} ref={ref}>\n {children} {!hideCaret && <ExpandMore size=\"small\" />}\n </Button>\n );\n});\n\nDropdownButton.displayName = 'DropdownButton';\n\nexport { DropdownButton };\nexport type { DropdownButtonProps };\n"],"names":["Dropdown","props","placement","disabled","targetClassName","popoverClassName","isOpen","isOpenProp","onInteraction","onSelect","onStateChange","children","testId","rest","triggerRef","useRef","setIsOpen","useState","hasOpened","setHasOpened","useEffect","undefined","setTimeout","current","hasModal","closest","focus","renderTrigger","cloneElement","parseChildren","target","ref","isopen","toString","renderContent","content","handleSelect","item","handlePopoverInteraction","nextIsOpen","targetChild","contentChild","Children","toArray","popoverTargetClasses","cx","popoverClasses","DropdownButton","forwardRef","hideCaret","displayName"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -17,6 +17,7 @@ const Dropdown = (props) => {
17
17
  onSelect,
18
18
  onStateChange,
19
19
  children,
20
+ "data-test-id": testId = "dropdown",
20
21
  ...rest
21
22
  } = props;
22
23
  const triggerRef = react.useRef(null);
@@ -85,6 +86,7 @@ const Dropdown = (props) => {
85
86
  disabled,
86
87
  targetClassName: popoverTargetClasses,
87
88
  popoverClassName: popoverClasses,
89
+ "data-test-id": testId,
88
90
  ...rest,
89
91
  children: [renderTrigger(), renderContent()]
90
92
  });
@@ -93,10 +95,12 @@ const DropdownButton = react.forwardRef((props, ref) => {
93
95
  const {
94
96
  children,
95
97
  hideCaret,
98
+ "data-test-id": testId = "dropdown-button",
96
99
  ...rest
97
100
  } = props;
98
101
  return /* @__PURE__ */ jsxRuntime.jsxs(button.Button, {
99
102
  ...rest,
103
+ "data-test-id": testId,
100
104
  ref,
101
105
  children: [children, " ", !hideCaret && /* @__PURE__ */ jsxRuntime.jsx(icons.ExpandMore, {
102
106
  size: "small"
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/Dropdown.tsx","../src/DropdownButton.tsx"],"sourcesContent":["import type { PopoverProps } from '@launchpad-ui/popover';\nimport type { ReactElement } from 'react';\n\nimport { Popover } from '@launchpad-ui/popover';\nimport { cx } from 'classix';\nimport { Children, cloneElement, useEffect, useRef, useState } from 'react';\n\ntype DropdownState = {\n isOpen?: boolean;\n};\n\ntype DropdownProps<T extends string | object | number> = PopoverProps & {\n onSelect?: (item: T, stateChanges: DropdownState) => void;\n onStateChange?: (state: DropdownState) => void;\n};\n\nconst Dropdown = <T extends string | object | number>(props: DropdownProps<T>) => {\n const {\n placement,\n disabled,\n targetClassName,\n popoverClassName,\n isOpen: isOpenProp,\n onInteraction,\n onSelect,\n onStateChange,\n children,\n ...rest\n } = props;\n\n const triggerRef = useRef<HTMLElement>(null);\n const [isOpen, setIsOpen] = useState(isOpenProp ?? false);\n const [hasOpened, setHasOpened] = useState(isOpen);\n\n useEffect(() => {\n if (isOpenProp !== undefined) {\n setIsOpen(isOpenProp);\n }\n }, [isOpenProp]);\n\n useEffect(() => {\n // Focus the button upon closing for convenient tabbing\n if (hasOpened && isOpen === false) {\n setTimeout(() => {\n const current = triggerRef.current;\n if (!current) {\n return;\n }\n\n // If a dropdown menu item triggers a modal, we do not want to focus the trigger. Instead\n // we let the modal components control their own focus.\n // Note that this is not ideal since closing the modal will not cause the dropdown trigger\n // to regain focus.\n const hasModal = current.closest?.('.has-modal');\n\n !hasModal && current.focus?.();\n });\n }\n }, [isOpen, hasOpened]);\n\n useEffect(() => {\n setHasOpened(isOpen);\n onStateChange?.({ isOpen });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen]);\n\n const renderTrigger = () => {\n return cloneElement(parseChildren().target, {\n 'aria-haspopup': true,\n 'aria-expanded': isOpen ? true : false,\n ref: triggerRef,\n isopen: isOpen?.toString(),\n });\n };\n\n const renderContent = () => {\n return cloneElement(parseChildren().content, {\n onSelect: handleSelect,\n });\n };\n\n const handleSelect = (item: T) => {\n setIsOpen(false);\n onSelect?.(item, { isOpen: false });\n };\n\n const handlePopoverInteraction = (nextIsOpen: boolean) => {\n setIsOpen(nextIsOpen);\n };\n\n const parseChildren = () => {\n const [targetChild, contentChild] = Children.toArray(children);\n return {\n target: targetChild as ReactElement,\n content: contentChild as ReactElement,\n };\n };\n\n const popoverTargetClasses = cx('Dropdown-target', targetClassName);\n const popoverClasses = cx('Dropdown', popoverClassName);\n\n return (\n <Popover\n isOpen={isOpen}\n placement={placement}\n onInteraction={onInteraction || handlePopoverInteraction}\n restrictHeight={false}\n disabled={disabled}\n targetClassName={popoverTargetClasses}\n popoverClassName={popoverClasses}\n {...rest}\n >\n {renderTrigger()}\n {renderContent()}\n </Popover>\n );\n};\n\nexport { Dropdown };\nexport type { DropdownProps };\n","import type { ButtonProps } from '@launchpad-ui/button';\n\nimport { Button } from '@launchpad-ui/button';\nimport { ExpandMore } from '@launchpad-ui/icons';\nimport { forwardRef } from 'react';\n\ntype DropdownButtonProps = ButtonProps & {\n hideCaret?: boolean;\n};\n\nconst DropdownButton = forwardRef<HTMLButtonElement, DropdownButtonProps>((props, ref) => {\n const { children, hideCaret, ...rest } = props;\n\n return (\n <Button {...rest} ref={ref}>\n {children} {!hideCaret && <ExpandMore size=\"small\" />}\n </Button>\n );\n});\n\nDropdownButton.displayName = 'DropdownButton';\n\nexport { DropdownButton };\nexport type { DropdownButtonProps };\n"],"names":["Dropdown","props","placement","disabled","targetClassName","popoverClassName","isOpen","isOpenProp","onInteraction","onSelect","onStateChange","children","rest","triggerRef","useRef","setIsOpen","useState","hasOpened","setHasOpened","useEffect","undefined","setTimeout","current","hasModal","closest","focus","renderTrigger","cloneElement","parseChildren","target","ref","isopen","toString","renderContent","content","handleSelect","item","handlePopoverInteraction","nextIsOpen","targetChild","contentChild","Children","toArray","popoverTargetClasses","cx","popoverClasses","Popover","DropdownButton","forwardRef","hideCaret","Button","ExpandMore","displayName"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/Dropdown.tsx","../src/DropdownButton.tsx"],"sourcesContent":["import type { PopoverProps } from '@launchpad-ui/popover';\nimport type { ReactElement } from 'react';\n\nimport { Popover } from '@launchpad-ui/popover';\nimport { cx } from 'classix';\nimport { Children, cloneElement, useEffect, useRef, useState } from 'react';\n\ntype DropdownState = {\n isOpen?: boolean;\n};\n\ntype DropdownProps<T extends string | object | number> = PopoverProps & {\n onSelect?: (item: T, stateChanges: DropdownState) => void;\n onStateChange?: (state: DropdownState) => void;\n};\n\nconst Dropdown = <T extends string | object | number>(props: DropdownProps<T>) => {\n const {\n placement,\n disabled,\n targetClassName,\n popoverClassName,\n isOpen: isOpenProp,\n onInteraction,\n onSelect,\n onStateChange,\n children,\n 'data-test-id': testId = 'dropdown',\n ...rest\n } = props;\n\n const triggerRef = useRef<HTMLElement>(null);\n const [isOpen, setIsOpen] = useState(isOpenProp ?? false);\n const [hasOpened, setHasOpened] = useState(isOpen);\n\n useEffect(() => {\n if (isOpenProp !== undefined) {\n setIsOpen(isOpenProp);\n }\n }, [isOpenProp]);\n\n useEffect(() => {\n // Focus the button upon closing for convenient tabbing\n if (hasOpened && isOpen === false) {\n setTimeout(() => {\n const current = triggerRef.current;\n if (!current) {\n return;\n }\n\n // If a dropdown menu item triggers a modal, we do not want to focus the trigger. Instead\n // we let the modal components control their own focus.\n // Note that this is not ideal since closing the modal will not cause the dropdown trigger\n // to regain focus.\n const hasModal = current.closest?.('.has-modal');\n\n !hasModal && current.focus?.();\n });\n }\n }, [isOpen, hasOpened]);\n\n useEffect(() => {\n setHasOpened(isOpen);\n onStateChange?.({ isOpen });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen]);\n\n const renderTrigger = () => {\n return cloneElement(parseChildren().target, {\n 'aria-haspopup': true,\n 'aria-expanded': isOpen ? true : false,\n ref: triggerRef,\n isopen: isOpen?.toString(),\n });\n };\n\n const renderContent = () => {\n return cloneElement(parseChildren().content, {\n onSelect: handleSelect,\n });\n };\n\n const handleSelect = (item: T) => {\n setIsOpen(false);\n onSelect?.(item, { isOpen: false });\n };\n\n const handlePopoverInteraction = (nextIsOpen: boolean) => {\n setIsOpen(nextIsOpen);\n };\n\n const parseChildren = () => {\n const [targetChild, contentChild] = Children.toArray(children);\n return {\n target: targetChild as ReactElement,\n content: contentChild as ReactElement,\n };\n };\n\n const popoverTargetClasses = cx('Dropdown-target', targetClassName);\n const popoverClasses = cx('Dropdown', popoverClassName);\n\n return (\n <Popover\n isOpen={isOpen}\n placement={placement}\n onInteraction={onInteraction || handlePopoverInteraction}\n restrictHeight={false}\n disabled={disabled}\n targetClassName={popoverTargetClasses}\n popoverClassName={popoverClasses}\n data-test-id={testId}\n {...rest}\n >\n {renderTrigger()}\n {renderContent()}\n </Popover>\n );\n};\n\nexport { Dropdown };\nexport type { DropdownProps };\n","import type { ButtonProps } from '@launchpad-ui/button';\n\nimport { Button } from '@launchpad-ui/button';\nimport { ExpandMore } from '@launchpad-ui/icons';\nimport { forwardRef } from 'react';\n\ntype DropdownButtonProps = ButtonProps & {\n hideCaret?: boolean;\n};\n\nconst DropdownButton = forwardRef<HTMLButtonElement, DropdownButtonProps>((props, ref) => {\n const { children, hideCaret, 'data-test-id': testId = 'dropdown-button', ...rest } = props;\n\n return (\n <Button {...rest} data-test-id={testId} ref={ref}>\n {children} {!hideCaret && <ExpandMore size=\"small\" />}\n </Button>\n );\n});\n\nDropdownButton.displayName = 'DropdownButton';\n\nexport { DropdownButton };\nexport type { DropdownButtonProps };\n"],"names":["Dropdown","props","placement","disabled","targetClassName","popoverClassName","isOpen","isOpenProp","onInteraction","onSelect","onStateChange","children","testId","rest","triggerRef","useRef","setIsOpen","useState","hasOpened","setHasOpened","useEffect","undefined","setTimeout","current","hasModal","closest","focus","renderTrigger","cloneElement","parseChildren","target","ref","isopen","toString","renderContent","content","handleSelect","item","handlePopoverInteraction","nextIsOpen","targetChild","contentChild","Children","toArray","popoverTargetClasses","cx","popoverClasses","Popover","DropdownButton","forwardRef","hideCaret","Button","ExpandMore","displayName"],"mappings":";;;;;;;;AAgBMA,MAAAA,WAAW,CAAqCC,UAA4B;AAC1E,QAAA;AAAA,IACJC;AAAAA,IACAC;AAAAA,IACAC;AAAAA,IACAC;AAAAA,IACAC,QAAQC;AAAAA,IACRC;AAAAA,IACAC;AAAAA,IACAC;AAAAA,IACAC;AAAAA,IACA,gBAAgBC,SAAS;AAAA,OACtBC;AAAAA,EACDZ,IAAAA;AAEEa,QAAAA,aAAaC,aAAoB,IAAd;AACzB,QAAM,CAACT,QAAQU,SAAT,IAAsBC,MAAAA,SAASV,kCAAc,KAAf;AACpC,QAAM,CAACW,WAAWC,YAAZ,IAA4BF,eAASX,MAAD;AAE1Cc,QAAAA,UAAU,MAAM;AACd,QAAIb,eAAec,QAAW;AAC5BL,gBAAUT,UAAD;AAAA,IACV;AAAA,EAAA,GACA,CAACA,UAAD,CAJM;AAMTa,QAAAA,UAAU,MAAM;AAEVF,QAAAA,aAAaZ,WAAW,OAAO;AACjCgB,iBAAW,MAAM;;AACf,cAAMC,UAAUT,WAAWS;AAC3B,YAAI,CAACA,SAAS;AACZ;AAAA,QACD;AAMKC,cAAAA,YAAWD,aAAQE,YAARF,iCAAkB;AAElCC,SAAAA,cAAYD,aAAQG,UAARH;AAAAA,MAAb,CAZQ;AAAA,IAcX;AAAA,EAAA,GACA,CAACjB,QAAQY,SAAT,CAlBM;AAoBTE,QAAAA,UAAU,MAAM;AACdD,iBAAab,MAAD;AACI,mDAAA;AAAA,MAAEA;AAAAA,IAAAA;AAAAA,EAAL,GAEZ,CAACA,MAAD,CAJM;AAMT,QAAMqB,gBAAgB,MAAM;AACnBC,WAAAA,MAAAA,aAAaC,cAAa,EAAGC,QAAQ;AAAA,MAC1C,iBAAiB;AAAA,MACjB,iBAAiBxB,SAAS,OAAO;AAAA,MACjCyB,KAAKjB;AAAAA,MACLkB,QAAQ1B,iCAAQ2B;AAAAA,IAAR,CAJS;AAAA,EAAA;AAQrB,QAAMC,gBAAgB,MAAM;AACnBN,WAAAA,MAAAA,aAAaC,cAAa,EAAGM,SAAS;AAAA,MAC3C1B,UAAU2B;AAAAA,IAAAA,CADO;AAAA,EAAA;AAKfA,QAAAA,eAAe,CAACC,SAAY;AAChCrB,cAAU,KAAD;AACTP,yCAAW4B,MAAM;AAAA,MAAE/B,QAAQ;AAAA,IAAA;AAAA,EAAnB;AAGJgC,QAAAA,2BAA2B,CAACC,eAAwB;AACxDvB,cAAUuB,UAAD;AAAA,EAAA;AAGX,QAAMV,gBAAgB,MAAM;AAC1B,UAAM,CAACW,aAAaC,YAAd,IAA8BC,MAAAA,SAASC,QAAQhC,QAAjB;AAC7B,WAAA;AAAA,MACLmB,QAAQU;AAAAA,MACRL,SAASM;AAAAA,IAAAA;AAAAA,EAFJ;AAMHG,QAAAA,uBAAuBC,QAAAA,GAAG,mBAAmBzC,eAApB;AACzB0C,QAAAA,iBAAiBD,QAAAA,GAAG,YAAYxC,gBAAb;AAEzB,yCACG0C,QAAAA,SAAD;AAAA,IACE;AAAA,IACA;AAAA,IACA,eAAevC,iBAAiB8B;AAAAA,IAChC,gBAAgB;AAAA,IAChB;AAAA,IACA,iBAAiBM;AAAAA,IACjB,kBAAkBE;AAAAA,IAClB,gBAAclC;AAAAA,IARhB,GASMC;AAAAA,IATN,UAAA,CAWGc,iBACAO,eAZH;AAAA,EAAA,CADF;AAgBD;AC5GD,MAAMc,iBAAiBC,MAAAA,WAAmD,CAAChD,OAAO8B,QAAQ;AAClF,QAAA;AAAA,IAAEpB;AAAAA,IAAUuC;AAAAA,IAAW,gBAAgBtC,SAAS;AAAA,OAAsBC;AAAAA,EAASZ,IAAAA;AAErF,yCACGkD,OAAAA,QAAD;AAAA,IAAA,GAAYtC;AAAAA,IAAM,gBAAcD;AAAAA,IAAQ;AAAA,IAAxC,UAAA,CACGD,UAAW,KAAA,CAACuC,4CAAcE,kBAAD;AAAA,MAAY,MAAK;AAAA,IAAA,CAD7C,CAAA;AAAA,EAAA,CADF;AAKD,CARgC;AAUjCJ,eAAeK,cAAc;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@launchpad-ui/dropdown",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "status": "beta",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -25,9 +25,9 @@
25
25
  },
26
26
  "source": "src/index.ts",
27
27
  "dependencies": {
28
- "@launchpad-ui/button": "~0.7.0",
29
- "@launchpad-ui/icons": "~0.5.0",
30
- "@launchpad-ui/popover": "~0.8.0",
28
+ "@launchpad-ui/button": "~0.7.1",
29
+ "@launchpad-ui/icons": "~0.5.2",
30
+ "@launchpad-ui/popover": "~0.8.2",
31
31
  "@launchpad-ui/tokens": "~0.1.5",
32
32
  "classix": "^2.1.13"
33
33
  },