diff --git a/packages/admin-ui/package.json b/packages/admin-ui/package.json index 20755fdb0e..410a0417f1 100644 --- a/packages/admin-ui/package.json +++ b/packages/admin-ui/package.json @@ -15,6 +15,7 @@ "@radix-ui/react-checkbox": "^1.1.2", "@radix-ui/react-dropdown-menu": "^2.1.2", "@radix-ui/react-label": "^2.1.0", + "@radix-ui/react-popover": "^1.1.4", "@radix-ui/react-radio-group": "^1.2.1", "@radix-ui/react-select": "^2.1.2", "@radix-ui/react-separator": "^1.1.0", diff --git a/packages/admin-ui/src/AutoComplete/primitives/AutoCompletePrimitive.stories.tsx b/packages/admin-ui/src/AutoComplete/primitives/AutoCompletePrimitive.stories.tsx index 8209acf144..9b0a0fcfdc 100644 --- a/packages/admin-ui/src/AutoComplete/primitives/AutoCompletePrimitive.stories.tsx +++ b/packages/admin-ui/src/AutoComplete/primitives/AutoCompletePrimitive.stories.tsx @@ -310,7 +310,6 @@ export const WithCustomOptionRenderer: Story = { { label: "Fiji Time (FJT)", value: "fjt", - separator: true, item: { name: "Fiji Time (FJT)", time_difference: "+12:00", diff --git a/packages/admin-ui/src/AutoComplete/primitives/AutoCompletePrimitive.tsx b/packages/admin-ui/src/AutoComplete/primitives/AutoCompletePrimitive.tsx index e80a8c5450..a918d7b8d0 100644 --- a/packages/admin-ui/src/AutoComplete/primitives/AutoCompletePrimitive.tsx +++ b/packages/admin-ui/src/AutoComplete/primitives/AutoCompletePrimitive.tsx @@ -1,5 +1,6 @@ import React, { KeyboardEvent } from "react"; import { Command } from "~/Command"; +import { Popover } from "~/Popover"; import { InputPrimitiveProps } from "~/Input"; import { useAutoComplete } from "./useAutoComplete"; import { AutoCompleteInputIcons, AutoCompleteList } from "./components"; @@ -89,38 +90,50 @@ const AutoCompletePrimitive = (props: AutoCompletePrimitiveProps) => { ); return ( - - setListOpenState(!vm.optionsListVm.isOpen)} - /> - } - onBlur={() => setListOpenState(false)} - onFocus={() => setListOpenState(true)} - /> - - + setListOpenState(true)}> + + + + setListOpenState(!vm.optionsListVm.isOpen)} + /> + } + onBlur={() => setListOpenState(false)} + onFocus={() => setListOpenState(true)} + /> + + + + e.preventDefault()} + > + + + + + ); }; diff --git a/packages/admin-ui/src/AutoComplete/primitives/components/AutoCompleteList.tsx b/packages/admin-ui/src/AutoComplete/primitives/components/AutoCompleteList.tsx index 59cbcf2ecb..148c9ec40a 100644 --- a/packages/admin-ui/src/AutoComplete/primitives/components/AutoCompleteList.tsx +++ b/packages/admin-ui/src/AutoComplete/primitives/components/AutoCompleteList.tsx @@ -1,26 +1,12 @@ import React from "react"; import { CommandOptionFormatted } from "~/Command/domain/CommandOptionFormatted"; import { Command } from "~/Command"; -import { cn, cva } from "~/utils"; - -const autoCompleteListWrapperVariants = cva( - "animate-in fade-in-0 zoom-in-95 absolute top-xs-plus z-10 w-full outline-none", - { - variants: { - isOpen: { - true: "block", - false: "hidden" - } - } - } -); interface AutoCompleteListProps extends React.ComponentPropsWithoutRef { options: CommandOptionFormatted[]; emptyMessage?: React.ReactNode; isEmpty?: boolean; isLoading?: boolean; - isOpen?: boolean; loadingMessage?: React.ReactNode; onOptionSelect: (value: string) => void; optionRenderer?: (item: any, index: number) => React.ReactNode; @@ -30,7 +16,6 @@ export const AutoCompleteList = ({ emptyMessage, isEmpty, isLoading, - isOpen, loadingMessage, onOptionSelect, optionRenderer, @@ -74,17 +59,13 @@ export const AutoCompleteList = ({ ); return ( -
-
- - {isLoading ? ( - {loadingMessage} - ) : ( - renderOptions(options) - )} - {!isLoading && {emptyMessage}} - -
-
+ + {isLoading ? ( + {loadingMessage} + ) : ( + renderOptions(options) + )} + {!isLoading && {emptyMessage}} + ); }; diff --git a/packages/admin-ui/src/Command/components/List.tsx b/packages/admin-ui/src/Command/components/List.tsx index c4bc5f587e..9a8ddb5440 100644 --- a/packages/admin-ui/src/Command/components/List.tsx +++ b/packages/admin-ui/src/Command/components/List.tsx @@ -9,7 +9,7 @@ const List = ({ className, ...props }: ListProps) => { { ); return ( - - setListOpenState(false)} - openList={() => setListOpenState(true)} - variant={props.variant} - size={props.size} - invalid={props.invalid} - removeSelectedOption={removeSelectedOption} - selectedOptionRenderer={props.selectedOptionRenderer} - selectedOptions={vm.selectedOptionsVm.options} - disabled={props.disabled} - startIcon={props.startIcon} - endIcon={ - setListOpenState(!vm.optionsListVm.isOpen)} - /> - } - /> - - - + setListOpenState(true)}> + + + + setListOpenState(false)} + openList={() => setListOpenState(true)} + variant={props.variant} + size={props.size} + invalid={props.invalid} + removeSelectedOption={removeSelectedOption} + selectedOptionRenderer={props.selectedOptionRenderer} + selectedOptions={vm.selectedOptionsVm.options} + disabled={props.disabled} + startIcon={props.startIcon} + endIcon={ + setListOpenState(!vm.optionsListVm.isOpen)} + /> + } + /> + + + + e.preventDefault()} + > + + + + + ); }; diff --git a/packages/admin-ui/src/MultiAutoComplete/primitives/components/MultiAutoCompleteList.tsx b/packages/admin-ui/src/MultiAutoComplete/primitives/components/MultiAutoCompleteList.tsx index a0abbb1c9e..13a01a39ba 100644 --- a/packages/admin-ui/src/MultiAutoComplete/primitives/components/MultiAutoCompleteList.tsx +++ b/packages/admin-ui/src/MultiAutoComplete/primitives/components/MultiAutoCompleteList.tsx @@ -1,25 +1,11 @@ import React from "react"; import { CommandOptionFormatted } from "~/Command/domain/CommandOptionFormatted"; import { Command } from "~/Command"; -import { cn, cva } from "~/utils"; - -const multiAutoCompleteListWrapperVariants = cva( - "animate-in fade-in-0 zoom-in-95 absolute top-xs-plus z-10 w-full outline-none", - { - variants: { - isOpen: { - true: "block", - false: "hidden" - } - } - } -); interface MultiAutoCompleteListProps extends React.ComponentPropsWithoutRef { emptyMessage?: React.ReactNode; isEmpty?: boolean; isLoading?: boolean; - isOpen?: boolean; loadingMessage?: React.ReactNode; onOptionCreate?: (value: string) => void; onOptionSelect: (value: string) => void; @@ -32,7 +18,6 @@ export const MultiAutoCompleteList = ({ emptyMessage, isEmpty, isLoading, - isOpen, loadingMessage, onOptionCreate, onOptionSelect, @@ -98,17 +83,13 @@ export const MultiAutoCompleteList = ({ ); return ( -
-
- - {isLoading ? ( - {loadingMessage} - ) : ( - renderOptions(options) - )} - {!isLoading && {emptyMessage}} - -
-
+ + {isLoading ? ( + {loadingMessage} + ) : ( + renderOptions(options) + )} + {!isLoading && {emptyMessage}} + ); }; diff --git a/packages/admin-ui/src/Popover/Popover.tsx b/packages/admin-ui/src/Popover/Popover.tsx new file mode 100644 index 0000000000..4574cc5ef6 --- /dev/null +++ b/packages/admin-ui/src/Popover/Popover.tsx @@ -0,0 +1,37 @@ +import * as React from "react"; +import * as PopoverPrimitive from "@radix-ui/react-popover"; +import { cn, withStaticProps } from "~/utils"; + +type PopoverContentProps = PopoverPrimitive.PopoverContentProps; + +const PopoverContent = ({ + className, + align = "center", + sideOffset = 6, + ...props +}: PopoverContentProps) => ( + + + +); + +const Popover = withStaticProps(PopoverPrimitive.Root, { + Anchor: PopoverPrimitive.Anchor, + Content: PopoverContent, + Portal: PopoverPrimitive.Portal, + Trigger: PopoverPrimitive.Trigger +}); + +export { Popover, type PopoverContent }; diff --git a/packages/admin-ui/src/Popover/index.ts b/packages/admin-ui/src/Popover/index.ts new file mode 100644 index 0000000000..72f124f6d3 --- /dev/null +++ b/packages/admin-ui/src/Popover/index.ts @@ -0,0 +1 @@ +export * from "./Popover"; diff --git a/packages/admin-ui/src/index.ts b/packages/admin-ui/src/index.ts index 5946467991..df3ec4f644 100644 --- a/packages/admin-ui/src/index.ts +++ b/packages/admin-ui/src/index.ts @@ -13,6 +13,7 @@ export * from "./Icon"; export * from "./Input"; export * from "./Label"; export * from "./MultiAutoComplete"; +export * from "./Popover"; export * from "./Progress"; export * from "./Providers"; export * from "./RadioGroup"; diff --git a/yarn.lock b/yarn.lock index c121ecfbec..0f52185306 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8936,6 +8936,25 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-arrow@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/react-arrow@npm:1.1.1" + dependencies: + "@radix-ui/react-primitive": "npm:2.0.1" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10/c75505c2858cffff7c742e888b635879f9a6d95e08bf5ae939be33f97e1171379bc6b5354ec0cd3d12624bdbe5a830ee6aa0fb1f46b1af160b488bc54e64d486 + languageName: node + linkType: hard + "@radix-ui/react-avatar@npm:^1.1.0": version: 1.1.1 resolution: "@radix-ui/react-avatar@npm:1.1.1" @@ -9467,6 +9486,39 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-popover@npm:^1.1.4": + version: 1.1.4 + resolution: "@radix-ui/react-popover@npm:1.1.4" + dependencies: + "@radix-ui/primitive": "npm:1.1.1" + "@radix-ui/react-compose-refs": "npm:1.1.1" + "@radix-ui/react-context": "npm:1.1.1" + "@radix-ui/react-dismissable-layer": "npm:1.1.3" + "@radix-ui/react-focus-guards": "npm:1.1.1" + "@radix-ui/react-focus-scope": "npm:1.1.1" + "@radix-ui/react-id": "npm:1.1.0" + "@radix-ui/react-popper": "npm:1.2.1" + "@radix-ui/react-portal": "npm:1.1.3" + "@radix-ui/react-presence": "npm:1.1.2" + "@radix-ui/react-primitive": "npm:2.0.1" + "@radix-ui/react-slot": "npm:1.1.1" + "@radix-ui/react-use-controllable-state": "npm:1.1.0" + aria-hidden: "npm:^1.1.1" + react-remove-scroll: "npm:^2.6.1" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10/8f21bc61a752291319f64327fa9b2b310c93efe55bb6e0fec7d72a4d59e1e80b28a25ad13c3b9ac600bc0c0e68f155f2226ef76c54d9e8226b4066b70611a4f3 + languageName: node + linkType: hard + "@radix-ui/react-popper@npm:1.1.2": version: 1.1.2 resolution: "@radix-ui/react-popper@npm:1.1.2" @@ -9524,6 +9576,34 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-popper@npm:1.2.1": + version: 1.2.1 + resolution: "@radix-ui/react-popper@npm:1.2.1" + dependencies: + "@floating-ui/react-dom": "npm:^2.0.0" + "@radix-ui/react-arrow": "npm:1.1.1" + "@radix-ui/react-compose-refs": "npm:1.1.1" + "@radix-ui/react-context": "npm:1.1.1" + "@radix-ui/react-primitive": "npm:2.0.1" + "@radix-ui/react-use-callback-ref": "npm:1.1.0" + "@radix-ui/react-use-layout-effect": "npm:1.1.0" + "@radix-ui/react-use-rect": "npm:1.1.0" + "@radix-ui/react-use-size": "npm:1.1.0" + "@radix-ui/rect": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10/423506c2f862c3ee69956bdef3de668bf189b1ec4496c83bef01c3a962c88ab44f9154523afdcd4f0ed6a06eeb44005fcfca4ee0d68267187f58df1f65781b3c + languageName: node + linkType: hard + "@radix-ui/react-portal@npm:1.0.3": version: 1.0.3 resolution: "@radix-ui/react-portal@npm:1.0.3" @@ -15147,6 +15227,7 @@ __metadata: "@radix-ui/react-checkbox": "npm:^1.1.2" "@radix-ui/react-dropdown-menu": "npm:^2.1.2" "@radix-ui/react-label": "npm:^2.1.0" + "@radix-ui/react-popover": "npm:^1.1.4" "@radix-ui/react-radio-group": "npm:^1.2.1" "@radix-ui/react-select": "npm:^2.1.2" "@radix-ui/react-separator": "npm:^1.1.0"