@webiny/admin-ui 6.5.0-beta.0 → 6.5.0-beta.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,5 +1,5 @@
1
1
  import * as React from "react";
2
2
  import { Command as CommandPrimitive } from "cmdk";
3
3
  type ListProps = React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>;
4
- declare const List: ({ className, ...props }: ListProps) => React.JSX.Element;
4
+ declare const List: ({ className, style, onScroll, ...props }: ListProps) => React.JSX.Element;
5
5
  export { List, type ListProps };
@@ -1,12 +1,16 @@
1
1
  import { Command } from "cmdk";
2
2
  import { cn } from "../../utils.js";
3
+ import { ScrollArea } from "../../ScrollArea/index.js";
3
4
  import * as __rspack_external_react from "react";
4
- const List = ({ className, ...props })=>/*#__PURE__*/ __rspack_external_react.createElement(Command.List, {
5
- className: cn([
6
- "block max-h-96 w-full py-sm overflow-y-auto overflow-x-hidden bg-neutral-base text-neutral-strong"
7
- ], className),
5
+ const List = ({ className, style, onScroll, ...props })=>/*#__PURE__*/ __rspack_external_react.createElement(ScrollArea, {
6
+ className: cn("w-full bg-neutral-base", className),
7
+ style: style,
8
+ viewportClassName: "max-h-96 overflow-x-hidden",
9
+ onViewportScroll: onScroll
10
+ }, /*#__PURE__*/ __rspack_external_react.createElement(Command.List, {
11
+ className: "block w-full py-sm text-neutral-strong",
8
12
  ...props
9
- });
13
+ }));
10
14
  export { List };
11
15
 
12
16
  //# sourceMappingURL=List.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Command/components/List.js","sources":["../../../src/Command/components/List.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { Command as CommandPrimitive } from \"cmdk\";\nimport { cn } from \"~/utils.js\";\n\ntype ListProps = React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>;\n\nconst List = ({ className, ...props }: ListProps) => {\n return (\n <CommandPrimitive.List\n className={cn(\n [\n \"block max-h-96 w-full py-sm overflow-y-auto overflow-x-hidden bg-neutral-base text-neutral-strong\"\n ],\n className\n )}\n {...props}\n />\n );\n};\n\nexport { List, type ListProps };\n"],"names":["List","className","props","CommandPrimitive","cn"],"mappings":";;;AAMA,MAAMA,OAAO,CAAC,EAAEC,SAAS,EAAE,GAAGC,OAAkB,GACrC,WAAP,GACI,sCAACC,QAAAA,IAAqB;QAClB,WAAWC,GACP;YACI;SACH,EACDH;QAEH,GAAGC,KAAK"}
1
+ {"version":3,"file":"Command/components/List.js","sources":["../../../src/Command/components/List.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { Command as CommandPrimitive } from \"cmdk\";\nimport { cn } from \"~/utils.js\";\nimport { ScrollArea } from \"~/ScrollArea/index.js\";\n\ntype ListProps = React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>;\n\nconst List = ({ className, style, onScroll, ...props }: ListProps) => {\n /*\n * The list scrolls inside a `ScrollArea`, whose scrollbar is an element rather than the\n * operating system's own, so it can keep focus on the input while it is dragged. Layout and\n * scroll props go to the scroll area, since that is the element that scrolls now.\n */\n return (\n <ScrollArea\n className={cn(\"w-full bg-neutral-base\", className)}\n style={style}\n viewportClassName={\"max-h-96 overflow-x-hidden\"}\n onViewportScroll={onScroll}\n >\n <CommandPrimitive.List\n className={\"block w-full py-sm text-neutral-strong\"}\n {...props}\n />\n </ScrollArea>\n );\n};\n\nexport { List, type ListProps };\n"],"names":["List","className","style","onScroll","props","ScrollArea","cn","CommandPrimitive"],"mappings":";;;;AAOA,MAAMA,OAAO,CAAC,EAAEC,SAAS,EAAEC,KAAK,EAAEC,QAAQ,EAAE,GAAGC,OAAkB,GAMtD,WAAP,GACI,sCAACC,YAAUA;QACP,WAAWC,GAAG,0BAA0BL;QACxC,OAAOC;QACP,mBAAmB;QACnB,kBAAkBC;qBAElB,sCAACI,QAAAA,IAAqB;QAClB,WAAW;QACV,GAAGH,KAAK"}
@@ -49,8 +49,7 @@ const IconPickerPrimitive = (props)=>{
49
49
  size: props.size
50
50
  }))), /*#__PURE__*/ react.createElement(PopoverPrimitive.Content, {
51
51
  align: "start",
52
- className: "min-w-96",
53
- onWheel: (e)=>e.stopPropagation()
52
+ className: "min-w-96"
54
53
  }, /*#__PURE__*/ react.createElement(IconPickerInput, {
55
54
  value: vm.searchQuery,
56
55
  onChange: searchIcon,
@@ -1 +1 @@
1
- {"version":3,"file":"IconPicker/primitives/IconPickerPrimitive.js","sources":["../../../src/IconPicker/primitives/IconPickerPrimitive.tsx"],"sourcesContent":["import React, { useEffect, useRef } from \"react\";\nimport type { InputPrimitiveProps } from \"~/Input/index.js\";\nimport { inputVariants } from \"~/Input/index.js\";\nimport { PopoverPrimitive } from \"~/Popover/index.js\";\nimport { cn, cva, type VariantProps } from \"~/utils.js\";\nimport { IconPickerGrid, IconPickerInput, IconPickerTrigger } from \"./components/index.js\";\nimport type { IconPickerIconDto } from \"../domains/index.js\";\nimport { useIconPicker } from \"./useIconPicker.js\";\n\nconst iconPickerVariants = cva(\"cursor-pointer text-neutral-strong\", {\n variants: {\n size: {\n md: \"w-16\",\n lg: \"w-16\",\n xl: \"w-20\"\n },\n disabled: {\n true: \"pointer-events-none\"\n }\n },\n defaultVariants: {\n size: \"lg\"\n }\n});\n\ninterface IconPickerPrimitiveProps extends VariantProps<typeof iconPickerVariants> {\n /**\n * Indicates if the field is disabled.\n */\n disabled?: boolean;\n /**\n * Callback triggered when the value changes.\n */\n onChange?: (value: string) => void;\n /**\n * List of icons to be displayed in the icon picker.\n */\n icons: IconPickerIconDto[];\n /**\n * Indicates if the input field is invalid.\n * Refer to `InputPrimitiveProps[\"invalid\"]` for possible values.\n */\n invalid?: InputPrimitiveProps[\"invalid\"];\n /**\n * Optional selected icon.\n */\n value?: string;\n /**\n * Variant of the input field.\n * Refer to `InputPrimitiveProps[\"variant\"]` for possible values.\n */\n variant?: InputPrimitiveProps[\"variant\"];\n}\n\nconst IconPickerPrimitive = (props: IconPickerPrimitiveProps) => {\n const { vm, setListOpenState, searchIcon, setSelectedIcon } = useIconPicker(props);\n // TODO figure out a better way to type this ref, without using `as unknown as`\n const inputRef = useRef<HTMLInputElement>(null as unknown as HTMLInputElement);\n\n useEffect(() => {\n setTimeout(() => {\n if (vm.open && inputRef.current) {\n inputRef.current.focus();\n }\n }, 50);\n }, [vm.open]);\n\n return (\n <PopoverPrimitive open={vm.open} onOpenChange={setListOpenState}>\n <PopoverPrimitive.Trigger asChild>\n <button\n data-disabled={props.disabled}\n className={cn(\n inputVariants({\n size: props.size,\n variant: props.variant,\n invalid: props.invalid\n }),\n iconPickerVariants({ size: props.size, disabled: props.disabled })\n )}\n >\n <IconPickerTrigger value={props.value} size={props.size} />\n </button>\n </PopoverPrimitive.Trigger>\n <PopoverPrimitive.Content\n align={\"start\"}\n className={\"min-w-96\"}\n onWheel={e => e.stopPropagation()} // Wheel event should not propagate to the parent: this fixes scrolling issues when the IconPicker is placed inside a Dialog.\n >\n <IconPickerInput value={vm.searchQuery} onChange={searchIcon} inputRef={inputRef} />\n <IconPickerGrid\n icons={vm.icons}\n iconsLength={vm.iconsLength}\n onIconSelect={setSelectedIcon}\n />\n </PopoverPrimitive.Content>\n </PopoverPrimitive>\n );\n};\n\nexport { IconPickerPrimitive, type IconPickerPrimitiveProps };\n"],"names":["iconPickerVariants","cva","IconPickerPrimitive","props","vm","setListOpenState","searchIcon","setSelectedIcon","useIconPicker","inputRef","useRef","useEffect","setTimeout","PopoverPrimitive","cn","inputVariants","IconPickerTrigger","e","IconPickerInput","IconPickerGrid"],"mappings":";;;;;;AASA,MAAMA,qBAAqBC,IAAI,sCAAsC;IACjE,UAAU;QACN,MAAM;YACF,IAAI;YACJ,IAAI;YACJ,IAAI;QACR;QACA,UAAU;YACN,MAAM;QACV;IACJ;IACA,iBAAiB;QACb,MAAM;IACV;AACJ;AA+BA,MAAMC,sBAAsB,CAACC;IACzB,MAAM,EAAEC,EAAE,EAAEC,gBAAgB,EAAEC,UAAU,EAAEC,eAAe,EAAE,GAAGC,cAAcL;IAE5E,MAAMM,WAAWC,OAAyB;IAE1CC,UAAU;QACNC,WAAW;YACP,IAAIR,GAAG,IAAI,IAAIK,SAAS,OAAO,EAC3BA,SAAS,OAAO,CAAC,KAAK;QAE9B,GAAG;IACP,GAAG;QAACL,GAAG,IAAI;KAAC;IAEZ,OAAO,WAAP,GACI,oBAACS,kBAAgBA;QAAC,MAAMT,GAAG,IAAI;QAAE,cAAcC;qBAC3C,oBAACQ,iBAAiB,OAAO;QAAC;qBACtB,oBAAC;QACG,iBAAeV,MAAM,QAAQ;QAC7B,WAAWW,GACPC,cAAc;YACV,MAAMZ,MAAM,IAAI;YAChB,SAASA,MAAM,OAAO;YACtB,SAASA,MAAM,OAAO;QAC1B,IACAH,mBAAmB;YAAE,MAAMG,MAAM,IAAI;YAAE,UAAUA,MAAM,QAAQ;QAAC;qBAGpE,oBAACa,mBAAiBA;QAAC,OAAOb,MAAM,KAAK;QAAE,MAAMA,MAAM,IAAI;wBAG/D,oBAACU,iBAAiB,OAAO;QACrB,OAAO;QACP,WAAW;QACX,SAASI,CAAAA,IAAKA,EAAE,eAAe;qBAE/B,oBAACC,iBAAeA;QAAC,OAAOd,GAAG,WAAW;QAAE,UAAUE;QAAY,UAAUG;sBACxE,oBAACU,gBAAcA;QACX,OAAOf,GAAG,KAAK;QACf,aAAaA,GAAG,WAAW;QAC3B,cAAcG;;AAKlC"}
1
+ {"version":3,"file":"IconPicker/primitives/IconPickerPrimitive.js","sources":["../../../src/IconPicker/primitives/IconPickerPrimitive.tsx"],"sourcesContent":["import React, { useEffect, useRef } from \"react\";\nimport type { InputPrimitiveProps } from \"~/Input/index.js\";\nimport { inputVariants } from \"~/Input/index.js\";\nimport { PopoverPrimitive } from \"~/Popover/index.js\";\nimport { cn, cva, type VariantProps } from \"~/utils.js\";\nimport { IconPickerGrid, IconPickerInput, IconPickerTrigger } from \"./components/index.js\";\nimport type { IconPickerIconDto } from \"../domains/index.js\";\nimport { useIconPicker } from \"./useIconPicker.js\";\n\nconst iconPickerVariants = cva(\"cursor-pointer text-neutral-strong\", {\n variants: {\n size: {\n md: \"w-16\",\n lg: \"w-16\",\n xl: \"w-20\"\n },\n disabled: {\n true: \"pointer-events-none\"\n }\n },\n defaultVariants: {\n size: \"lg\"\n }\n});\n\ninterface IconPickerPrimitiveProps extends VariantProps<typeof iconPickerVariants> {\n /**\n * Indicates if the field is disabled.\n */\n disabled?: boolean;\n /**\n * Callback triggered when the value changes.\n */\n onChange?: (value: string) => void;\n /**\n * List of icons to be displayed in the icon picker.\n */\n icons: IconPickerIconDto[];\n /**\n * Indicates if the input field is invalid.\n * Refer to `InputPrimitiveProps[\"invalid\"]` for possible values.\n */\n invalid?: InputPrimitiveProps[\"invalid\"];\n /**\n * Optional selected icon.\n */\n value?: string;\n /**\n * Variant of the input field.\n * Refer to `InputPrimitiveProps[\"variant\"]` for possible values.\n */\n variant?: InputPrimitiveProps[\"variant\"];\n}\n\nconst IconPickerPrimitive = (props: IconPickerPrimitiveProps) => {\n const { vm, setListOpenState, searchIcon, setSelectedIcon } = useIconPicker(props);\n // TODO figure out a better way to type this ref, without using `as unknown as`\n const inputRef = useRef<HTMLInputElement>(null as unknown as HTMLInputElement);\n\n useEffect(() => {\n setTimeout(() => {\n if (vm.open && inputRef.current) {\n inputRef.current.focus();\n }\n }, 50);\n }, [vm.open]);\n\n return (\n <PopoverPrimitive open={vm.open} onOpenChange={setListOpenState}>\n <PopoverPrimitive.Trigger asChild>\n <button\n data-disabled={props.disabled}\n className={cn(\n inputVariants({\n size: props.size,\n variant: props.variant,\n invalid: props.invalid\n }),\n iconPickerVariants({ size: props.size, disabled: props.disabled })\n )}\n >\n <IconPickerTrigger value={props.value} size={props.size} />\n </button>\n </PopoverPrimitive.Trigger>\n <PopoverPrimitive.Content align={\"start\"} className={\"min-w-96\"}>\n <IconPickerInput value={vm.searchQuery} onChange={searchIcon} inputRef={inputRef} />\n <IconPickerGrid\n icons={vm.icons}\n iconsLength={vm.iconsLength}\n onIconSelect={setSelectedIcon}\n />\n </PopoverPrimitive.Content>\n </PopoverPrimitive>\n );\n};\n\nexport { IconPickerPrimitive, type IconPickerPrimitiveProps };\n"],"names":["iconPickerVariants","cva","IconPickerPrimitive","props","vm","setListOpenState","searchIcon","setSelectedIcon","useIconPicker","inputRef","useRef","useEffect","setTimeout","PopoverPrimitive","cn","inputVariants","IconPickerTrigger","IconPickerInput","IconPickerGrid"],"mappings":";;;;;;AASA,MAAMA,qBAAqBC,IAAI,sCAAsC;IACjE,UAAU;QACN,MAAM;YACF,IAAI;YACJ,IAAI;YACJ,IAAI;QACR;QACA,UAAU;YACN,MAAM;QACV;IACJ;IACA,iBAAiB;QACb,MAAM;IACV;AACJ;AA+BA,MAAMC,sBAAsB,CAACC;IACzB,MAAM,EAAEC,EAAE,EAAEC,gBAAgB,EAAEC,UAAU,EAAEC,eAAe,EAAE,GAAGC,cAAcL;IAE5E,MAAMM,WAAWC,OAAyB;IAE1CC,UAAU;QACNC,WAAW;YACP,IAAIR,GAAG,IAAI,IAAIK,SAAS,OAAO,EAC3BA,SAAS,OAAO,CAAC,KAAK;QAE9B,GAAG;IACP,GAAG;QAACL,GAAG,IAAI;KAAC;IAEZ,OAAO,WAAP,GACI,oBAACS,kBAAgBA;QAAC,MAAMT,GAAG,IAAI;QAAE,cAAcC;qBAC3C,oBAACQ,iBAAiB,OAAO;QAAC;qBACtB,oBAAC;QACG,iBAAeV,MAAM,QAAQ;QAC7B,WAAWW,GACPC,cAAc;YACV,MAAMZ,MAAM,IAAI;YAChB,SAASA,MAAM,OAAO;YACtB,SAASA,MAAM,OAAO;QAC1B,IACAH,mBAAmB;YAAE,MAAMG,MAAM,IAAI;YAAE,UAAUA,MAAM,QAAQ;QAAC;qBAGpE,oBAACa,mBAAiBA;QAAC,OAAOb,MAAM,KAAK;QAAE,MAAMA,MAAM,IAAI;wBAG/D,oBAACU,iBAAiB,OAAO;QAAC,OAAO;QAAS,WAAW;qBACjD,oBAACI,iBAAeA;QAAC,OAAOb,GAAG,WAAW;QAAE,UAAUE;QAAY,UAAUG;sBACxE,oBAACS,gBAAcA;QACX,OAAOd,GAAG,KAAK;QACf,aAAaA,GAAG,WAAW;QAC3B,cAAcG;;AAKlC"}
@@ -7,6 +7,8 @@ import { CheckboxPrimitiveRenderer } from "../../Checkbox/index.js";
7
7
  import { Icon } from "../../Icon/index.js";
8
8
  import { IconButton } from "../../Button/index.js";
9
9
  import { selectTriggerVariants } from "../../Select/primitives/components/index.js";
10
+ import { ScrollArea } from "../../ScrollArea/index.js";
11
+ import { useEscapeScrollLock } from "../../hooks/index.js";
10
12
  const MultiSelectTrigger = ({ displayValue, hasValue, placeholder, displayResetAction, disabled, invalid, size, variant, onValueReset })=>{
11
13
  const resetButton = useMemo(()=>{
12
14
  if (!hasValue || !displayResetAction) return;
@@ -49,14 +51,18 @@ const MultiSelectTrigger = ({ displayValue, hasValue, placeholder, displayResetA
49
51
  className: "h-md w-md"
50
52
  })));
51
53
  };
52
- const MultiSelectContent = ({ options, value, onToggle })=>/*#__PURE__*/ react.createElement(Popover.Portal, null, /*#__PURE__*/ react.createElement(Popover.Content, {
53
- className: cn("relative z-popover shadow-lg py-sm overflow-y-auto rounded-sm border-sm border-neutral-muted bg-neutral-base text-neutral-strong", "data-[state=open]:animate-in data-[state=closed]:animate-out", "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0", "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95", "data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2", "data-[side=bottom]:translate-y-1 data-[side=top]:-translate-y-1"),
54
+ const MultiSelectContent = ({ options, value, onToggle })=>{
55
+ const contentRef = useEscapeScrollLock();
56
+ return /*#__PURE__*/ react.createElement(Popover.Portal, null, /*#__PURE__*/ react.createElement(Popover.Content, {
57
+ ref: contentRef,
58
+ className: cn("relative z-popover shadow-lg overflow-hidden rounded-sm border-sm border-neutral-muted bg-neutral-base text-neutral-strong", "data-[state=open]:animate-in data-[state=closed]:animate-out", "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0", "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95", "data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2", "data-[side=bottom]:translate-y-1 data-[side=top]:-translate-y-1"),
54
59
  style: {
55
- width: "var(--radix-popover-trigger-width)",
56
- maxHeight: "min(250px, var(--radix-popover-content-available-height, 250px))"
60
+ width: "var(--radix-popover-trigger-width)"
57
61
  },
58
62
  align: "start",
59
63
  sideOffset: 4
64
+ }, /*#__PURE__*/ react.createElement(ScrollArea, {
65
+ viewportClassName: cn("py-sm", "max-h-[calc(min(250px,var(--radix-popover-content-available-height,250px))_-_2*var(--border-width-sm))]")
60
66
  }, options.map((option)=>/*#__PURE__*/ react.createElement("div", {
61
67
  key: option.value,
62
68
  className: cn("rounded-sm p-sm mx-sm cursor-pointer", "hover:bg-neutral-dimmed", option.disabled && "opacity-50 pointer-events-none"),
@@ -72,7 +78,8 @@ const MultiSelectContent = ({ options, value, onToggle })=>/*#__PURE__*/ react.c
72
78
  indeterminate: false,
73
79
  hasLabel: true,
74
80
  changeChecked: ()=>{}
75
- }))))));
81
+ })))))));
82
+ };
76
83
  const DecoratableMultiSelectPrimitive = ({ options = [], value = [], onChange, onValueReset, placeholder = "Select options", disabled, invalid, displayResetAction = true, showSelectionCount, size, variant })=>{
77
84
  const displayValue = useMemo(()=>{
78
85
  if (0 === value.length) return "";
@@ -1 +1 @@
1
- {"version":3,"file":"MultiSelect/primitives/MultiSelectPrimitive.js","sources":["../../../src/MultiSelect/primitives/MultiSelectPrimitive.tsx"],"sourcesContent":["import React, { useCallback, useMemo } from \"react\";\nimport { Popover } from \"radix-ui\";\nimport { ReactComponent as ChevronDown } from \"@webiny/icons/keyboard_arrow_down.svg\";\nimport { ReactComponent as Close } from \"@webiny/icons/close.svg\";\nimport { cn, makeDecoratable, type VariantProps } from \"~/utils.js\";\nimport { CheckboxPrimitiveRenderer } from \"~/Checkbox/index.js\";\nimport { Icon } from \"~/Icon/index.js\";\nimport { IconButton } from \"~/Button/index.js\";\nimport { selectTriggerVariants } from \"~/Select/primitives/components/index.js\";\n\ninterface MultiSelectOptionDto {\n label: string;\n value: string;\n disabled?: boolean;\n}\n\ninterface MultiSelectPrimitiveProps {\n options?: MultiSelectOptionDto[];\n value?: string[];\n onChange?: (values: string[]) => void;\n onValueReset?: () => void;\n placeholder?: string;\n disabled?: boolean;\n invalid?: boolean;\n displayResetAction?: boolean;\n /**\n * When `true`, shows \"{count} items selected\" in the trigger instead of the full\n * comma-separated label list.\n */\n showSelectionCount?: boolean;\n size?: VariantProps<typeof selectTriggerVariants>[\"size\"];\n variant?: VariantProps<typeof selectTriggerVariants>[\"variant\"];\n}\n\n/**\n * MultiSelect Trigger\n */\ninterface MultiSelectTriggerProps {\n displayValue: string;\n hasValue: boolean;\n placeholder: string;\n displayResetAction: boolean;\n disabled?: boolean;\n invalid?: VariantProps<typeof selectTriggerVariants>[\"invalid\"];\n size?: VariantProps<typeof selectTriggerVariants>[\"size\"];\n variant?: VariantProps<typeof selectTriggerVariants>[\"variant\"];\n onValueReset: () => void;\n}\n\nconst MultiSelectTrigger = ({\n displayValue,\n hasValue,\n placeholder,\n displayResetAction,\n disabled,\n invalid,\n size,\n variant,\n onValueReset\n}: MultiSelectTriggerProps) => {\n const resetButton = useMemo(() => {\n if (!hasValue || !displayResetAction) {\n return undefined;\n }\n return (\n <IconButton\n onPointerDown={event => {\n event.stopPropagation();\n onValueReset();\n }}\n icon={\n <span>\n <Icon\n icon={<Close />}\n label={\"Reset\"}\n color={variant === \"ghost-negative\" ? \"neutral-negative\" : \"inherit\"}\n />\n </span>\n }\n size={\"xs\"}\n variant={variant === \"ghost-negative\" ? \"ghost-negative\" : \"secondary\"}\n disabled={disabled}\n asChild\n />\n );\n }, [hasValue, displayResetAction, onValueReset, variant, disabled]);\n\n return (\n <Popover.Trigger\n className={cn(selectTriggerVariants({ variant, size, invalid }))}\n disabled={disabled}\n >\n <div className={\"flex-1 text-left truncate\"}>\n {hasValue ? (\n displayValue\n ) : (\n <span className={\"text-neutral-disabled\"}>{placeholder}</span>\n )}\n </div>\n {resetButton}\n <span className={\"h-md w-md shrink-0 fill-neutral-xstrong\"}>\n <ChevronDown className={\"h-md w-md\"} />\n </span>\n </Popover.Trigger>\n );\n};\n\n/**\n * MultiSelect Content\n */\ninterface MultiSelectContentProps {\n options: MultiSelectOptionDto[];\n value: string[];\n onToggle: (value: string) => void;\n}\n\nconst MultiSelectContent = ({ options, value, onToggle }: MultiSelectContentProps) => {\n return (\n <Popover.Portal>\n <Popover.Content\n className={cn(\n \"relative z-popover shadow-lg py-sm overflow-y-auto rounded-sm border-sm border-neutral-muted bg-neutral-base text-neutral-strong\",\n \"data-[state=open]:animate-in data-[state=closed]:animate-out\",\n \"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n \"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95\",\n \"data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2\",\n \"data-[side=bottom]:translate-y-1 data-[side=top]:-translate-y-1\"\n )}\n style={{\n width: \"var(--radix-popover-trigger-width)\",\n maxHeight: \"min(250px, var(--radix-popover-content-available-height, 250px))\"\n }}\n align={\"start\"}\n sideOffset={4}\n >\n {options.map(option => (\n <div\n key={option.value}\n className={cn(\n \"rounded-sm p-sm mx-sm cursor-pointer\",\n \"hover:bg-neutral-dimmed\",\n option.disabled && \"opacity-50 pointer-events-none\"\n )}\n onClick={() => onToggle(option.value)}\n >\n <div className={\"pointer-events-none\"}>\n <CheckboxPrimitiveRenderer\n id={option.value}\n label={option.label}\n value={option.value}\n checked={value.includes(option.value)}\n disabled={option.disabled ?? false}\n indeterminate={false}\n hasLabel={true}\n changeChecked={() => {}}\n />\n </div>\n </div>\n ))}\n </Popover.Content>\n </Popover.Portal>\n );\n};\n\n/**\n * MultiSelect Primitive\n */\nconst DecoratableMultiSelectPrimitive = ({\n options = [],\n value = [],\n onChange,\n onValueReset,\n placeholder = \"Select options\",\n disabled,\n invalid,\n displayResetAction = true,\n showSelectionCount,\n size,\n variant\n}: MultiSelectPrimitiveProps) => {\n const displayValue = useMemo(() => {\n if (value.length === 0) {\n return \"\";\n }\n if (showSelectionCount) {\n return `${value.length} items selected`;\n }\n const labelMap = new Map(options.map(o => [o.value, o.label]));\n return value.map(v => labelMap.get(v) ?? v).join(\", \");\n }, [value, options, showSelectionCount]);\n\n const toggle = useCallback(\n (optionValue: string) => {\n const next = value.includes(optionValue)\n ? value.filter(v => v !== optionValue)\n : [...value, optionValue];\n onChange?.(next);\n },\n [value, onChange]\n );\n\n const reset = useCallback(() => {\n onChange?.([]);\n onValueReset?.();\n }, [onChange, onValueReset]);\n\n return (\n <Popover.Root>\n <MultiSelectTrigger\n displayValue={displayValue}\n hasValue={value.length > 0}\n placeholder={placeholder}\n displayResetAction={displayResetAction}\n disabled={disabled}\n invalid={invalid}\n size={size}\n variant={variant}\n onValueReset={reset}\n />\n <MultiSelectContent options={options} value={value} onToggle={toggle} />\n </Popover.Root>\n );\n};\nconst MultiSelectPrimitive = makeDecoratable(\n \"MultiSelectPrimitive\",\n DecoratableMultiSelectPrimitive\n);\n\nexport { MultiSelectPrimitive, type MultiSelectPrimitiveProps, type MultiSelectOptionDto };\n"],"names":["MultiSelectTrigger","displayValue","hasValue","placeholder","displayResetAction","disabled","invalid","size","variant","onValueReset","resetButton","useMemo","IconButton","event","Icon","Close","Popover","cn","selectTriggerVariants","ChevronDown","MultiSelectContent","options","value","onToggle","option","CheckboxPrimitiveRenderer","DecoratableMultiSelectPrimitive","onChange","showSelectionCount","labelMap","Map","o","v","toggle","useCallback","optionValue","next","reset","MultiSelectPrimitive","makeDecoratable"],"mappings":";;;;;;;;;AAiDA,MAAMA,qBAAqB,CAAC,EACxBC,YAAY,EACZC,QAAQ,EACRC,WAAW,EACXC,kBAAkB,EAClBC,QAAQ,EACRC,OAAO,EACPC,IAAI,EACJC,OAAO,EACPC,YAAY,EACU;IACtB,MAAMC,cAAcC,QAAQ;QACxB,IAAI,CAACT,YAAY,CAACE,oBACd;QAEJ,OAAO,WAAP,GACI,oBAACQ,YAAUA;YACP,eAAeC,CAAAA;gBACXA,MAAM,eAAe;gBACrBJ;YACJ;YACA,oBACI,oBAAC,4BACG,oBAACK,MAAIA;gBACD,oBAAM,oBAACC,0BAAKA;gBACZ,OAAO;gBACP,OAAOP,AAAY,qBAAZA,UAA+B,qBAAqB;;YAIvE,MAAM;YACN,SAASA,AAAY,qBAAZA,UAA+B,mBAAmB;YAC3D,UAAUH;YACV;;IAGZ,GAAG;QAACH;QAAUE;QAAoBK;QAAcD;QAASH;KAAS;IAElE,OAAO,WAAP,GACI,oBAACW,QAAQ,OAAO;QACZ,WAAWC,GAAGC,sBAAsB;YAAEV;YAASD;YAAMD;QAAQ;QAC7D,UAAUD;qBAEV,oBAAC;QAAI,WAAW;OACXH,WACGD,eAAAA,WAAAA,GAEA,oBAAC;QAAK,WAAW;OAA0BE,eAGlDO,aAAAA,WAAAA,GACD,oBAAC;QAAK,WAAW;qBACb,oBAACS,gBAAWA;QAAC,WAAW;;AAIxC;AAWA,MAAMC,qBAAqB,CAAC,EAAEC,OAAO,EAAEC,KAAK,EAAEC,QAAQ,EAA2B,GACtE,WAAP,GACI,oBAACP,QAAQ,MAAM,sBACX,oBAACA,QAAQ,OAAO;QACZ,WAAWC,GACP,oIACA,gEACA,8DACA,gEACA,iFACA;QAEJ,OAAO;YACH,OAAO;YACP,WAAW;QACf;QACA,OAAO;QACP,YAAY;OAEXI,QAAQ,GAAG,CAACG,CAAAA,SAAAA,WAAAA,GACT,oBAAC;YACG,KAAKA,OAAO,KAAK;YACjB,WAAWP,GACP,wCACA,2BACAO,OAAO,QAAQ,IAAI;YAEvB,SAAS,IAAMD,SAASC,OAAO,KAAK;yBAEpC,oBAAC;YAAI,WAAW;yBACZ,oBAACC,2BAAyBA;YACtB,IAAID,OAAO,KAAK;YAChB,OAAOA,OAAO,KAAK;YACnB,OAAOA,OAAO,KAAK;YACnB,SAASF,MAAM,QAAQ,CAACE,OAAO,KAAK;YACpC,UAAUA,OAAO,QAAQ,IAAI;YAC7B,eAAe;YACf,UAAU;YACV,eAAe,KAAO;;AAatD,MAAME,kCAAkC,CAAC,EACrCL,UAAU,EAAE,EACZC,QAAQ,EAAE,EACVK,QAAQ,EACRlB,YAAY,EACZN,cAAc,gBAAgB,EAC9BE,QAAQ,EACRC,OAAO,EACPF,qBAAqB,IAAI,EACzBwB,kBAAkB,EAClBrB,IAAI,EACJC,OAAO,EACiB;IACxB,MAAMP,eAAeU,QAAQ;QACzB,IAAIW,AAAiB,MAAjBA,MAAM,MAAM,EACZ,OAAO;QAEX,IAAIM,oBACA,OAAO,GAAGN,MAAM,MAAM,CAAC,eAAe,CAAC;QAE3C,MAAMO,WAAW,IAAIC,IAAIT,QAAQ,GAAG,CAACU,CAAAA,IAAK;gBAACA,EAAE,KAAK;gBAAEA,EAAE,KAAK;aAAC;QAC5D,OAAOT,MAAM,GAAG,CAACU,CAAAA,IAAKH,SAAS,GAAG,CAACG,MAAMA,GAAG,IAAI,CAAC;IACrD,GAAG;QAACV;QAAOD;QAASO;KAAmB;IAEvC,MAAMK,SAASC,YACX,CAACC;QACG,MAAMC,OAAOd,MAAM,QAAQ,CAACa,eACtBb,MAAM,MAAM,CAACU,CAAAA,IAAKA,MAAMG,eACxB;eAAIb;YAAOa;SAAY;QAC7BR,WAAWS;IACf,GACA;QAACd;QAAOK;KAAS;IAGrB,MAAMU,QAAQH,YAAY;QACtBP,WAAW,EAAE;QACblB;IACJ,GAAG;QAACkB;QAAUlB;KAAa;IAE3B,OAAO,WAAP,GACI,oBAACO,QAAQ,IAAI,sBACT,oBAAChB,oBAAkBA;QACf,cAAcC;QACd,UAAUqB,MAAM,MAAM,GAAG;QACzB,aAAanB;QACb,oBAAoBC;QACpB,UAAUC;QACV,SAASC;QACT,MAAMC;QACN,SAASC;QACT,cAAc6B;sBAElB,oBAACjB,oBAAkBA;QAAC,SAASC;QAAS,OAAOC;QAAO,UAAUW;;AAG1E;AACA,MAAMK,uBAAuBC,gBACzB,wBACAb"}
1
+ {"version":3,"file":"MultiSelect/primitives/MultiSelectPrimitive.js","sources":["../../../src/MultiSelect/primitives/MultiSelectPrimitive.tsx"],"sourcesContent":["import React, { useCallback, useMemo } from \"react\";\nimport { Popover } from \"radix-ui\";\nimport { ReactComponent as ChevronDown } from \"@webiny/icons/keyboard_arrow_down.svg\";\nimport { ReactComponent as Close } from \"@webiny/icons/close.svg\";\nimport { cn, makeDecoratable, type VariantProps } from \"~/utils.js\";\nimport { CheckboxPrimitiveRenderer } from \"~/Checkbox/index.js\";\nimport { Icon } from \"~/Icon/index.js\";\nimport { IconButton } from \"~/Button/index.js\";\nimport { selectTriggerVariants } from \"~/Select/primitives/components/index.js\";\nimport { ScrollArea } from \"~/ScrollArea/index.js\";\nimport { useEscapeScrollLock } from \"~/hooks/index.js\";\n\ninterface MultiSelectOptionDto {\n label: string;\n value: string;\n disabled?: boolean;\n}\n\ninterface MultiSelectPrimitiveProps {\n options?: MultiSelectOptionDto[];\n value?: string[];\n onChange?: (values: string[]) => void;\n onValueReset?: () => void;\n placeholder?: string;\n disabled?: boolean;\n invalid?: boolean;\n displayResetAction?: boolean;\n /**\n * When `true`, shows \"{count} items selected\" in the trigger instead of the full\n * comma-separated label list.\n */\n showSelectionCount?: boolean;\n size?: VariantProps<typeof selectTriggerVariants>[\"size\"];\n variant?: VariantProps<typeof selectTriggerVariants>[\"variant\"];\n}\n\n/**\n * MultiSelect Trigger\n */\ninterface MultiSelectTriggerProps {\n displayValue: string;\n hasValue: boolean;\n placeholder: string;\n displayResetAction: boolean;\n disabled?: boolean;\n invalid?: VariantProps<typeof selectTriggerVariants>[\"invalid\"];\n size?: VariantProps<typeof selectTriggerVariants>[\"size\"];\n variant?: VariantProps<typeof selectTriggerVariants>[\"variant\"];\n onValueReset: () => void;\n}\n\nconst MultiSelectTrigger = ({\n displayValue,\n hasValue,\n placeholder,\n displayResetAction,\n disabled,\n invalid,\n size,\n variant,\n onValueReset\n}: MultiSelectTriggerProps) => {\n const resetButton = useMemo(() => {\n if (!hasValue || !displayResetAction) {\n return undefined;\n }\n return (\n <IconButton\n onPointerDown={event => {\n event.stopPropagation();\n onValueReset();\n }}\n icon={\n <span>\n <Icon\n icon={<Close />}\n label={\"Reset\"}\n color={variant === \"ghost-negative\" ? \"neutral-negative\" : \"inherit\"}\n />\n </span>\n }\n size={\"xs\"}\n variant={variant === \"ghost-negative\" ? \"ghost-negative\" : \"secondary\"}\n disabled={disabled}\n asChild\n />\n );\n }, [hasValue, displayResetAction, onValueReset, variant, disabled]);\n\n return (\n <Popover.Trigger\n className={cn(selectTriggerVariants({ variant, size, invalid }))}\n disabled={disabled}\n >\n <div className={\"flex-1 text-left truncate\"}>\n {hasValue ? (\n displayValue\n ) : (\n <span className={\"text-neutral-disabled\"}>{placeholder}</span>\n )}\n </div>\n {resetButton}\n <span className={\"h-md w-md shrink-0 fill-neutral-xstrong\"}>\n <ChevronDown className={\"h-md w-md\"} />\n </span>\n </Popover.Trigger>\n );\n};\n\n/**\n * MultiSelect Content\n */\ninterface MultiSelectContentProps {\n options: MultiSelectOptionDto[];\n value: string[];\n onToggle: (value: string) => void;\n}\n\nconst MultiSelectContent = ({ options, value, onToggle }: MultiSelectContentProps) => {\n /*\n * This popover is built on the Radix primitive directly, so it needs the same scroll-lock\n * escape hatch that `PopoverPrimitive.Content` applies.\n */\n const contentRef = useEscapeScrollLock<HTMLDivElement>();\n\n return (\n <Popover.Portal>\n <Popover.Content\n ref={contentRef}\n className={cn(\n \"relative z-popover shadow-lg overflow-hidden rounded-sm border-sm border-neutral-muted bg-neutral-base text-neutral-strong\",\n \"data-[state=open]:animate-in data-[state=closed]:animate-out\",\n \"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n \"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95\",\n \"data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2\",\n \"data-[side=bottom]:translate-y-1 data-[side=top]:-translate-y-1\"\n )}\n style={{ width: \"var(--radix-popover-trigger-width)\" }}\n align={\"start\"}\n sideOffset={4}\n >\n {/*\n * The padding sits inside the scroller so the scrollbar runs the full height, and\n * the cap leaves room for the popover's border, so the whole dropdown fits in the\n * space Radix says is available.\n */}\n <ScrollArea\n viewportClassName={cn(\n \"py-sm\",\n \"max-h-[calc(min(250px,var(--radix-popover-content-available-height,250px))_-_2*var(--border-width-sm))]\"\n )}\n >\n {options.map(option => (\n <div\n key={option.value}\n className={cn(\n \"rounded-sm p-sm mx-sm cursor-pointer\",\n \"hover:bg-neutral-dimmed\",\n option.disabled && \"opacity-50 pointer-events-none\"\n )}\n onClick={() => onToggle(option.value)}\n >\n <div className={\"pointer-events-none\"}>\n <CheckboxPrimitiveRenderer\n id={option.value}\n label={option.label}\n value={option.value}\n checked={value.includes(option.value)}\n disabled={option.disabled ?? false}\n indeterminate={false}\n hasLabel={true}\n changeChecked={() => {}}\n />\n </div>\n </div>\n ))}\n </ScrollArea>\n </Popover.Content>\n </Popover.Portal>\n );\n};\n\n/**\n * MultiSelect Primitive\n */\nconst DecoratableMultiSelectPrimitive = ({\n options = [],\n value = [],\n onChange,\n onValueReset,\n placeholder = \"Select options\",\n disabled,\n invalid,\n displayResetAction = true,\n showSelectionCount,\n size,\n variant\n}: MultiSelectPrimitiveProps) => {\n const displayValue = useMemo(() => {\n if (value.length === 0) {\n return \"\";\n }\n if (showSelectionCount) {\n return `${value.length} items selected`;\n }\n const labelMap = new Map(options.map(o => [o.value, o.label]));\n return value.map(v => labelMap.get(v) ?? v).join(\", \");\n }, [value, options, showSelectionCount]);\n\n const toggle = useCallback(\n (optionValue: string) => {\n const next = value.includes(optionValue)\n ? value.filter(v => v !== optionValue)\n : [...value, optionValue];\n onChange?.(next);\n },\n [value, onChange]\n );\n\n const reset = useCallback(() => {\n onChange?.([]);\n onValueReset?.();\n }, [onChange, onValueReset]);\n\n return (\n <Popover.Root>\n <MultiSelectTrigger\n displayValue={displayValue}\n hasValue={value.length > 0}\n placeholder={placeholder}\n displayResetAction={displayResetAction}\n disabled={disabled}\n invalid={invalid}\n size={size}\n variant={variant}\n onValueReset={reset}\n />\n <MultiSelectContent options={options} value={value} onToggle={toggle} />\n </Popover.Root>\n );\n};\nconst MultiSelectPrimitive = makeDecoratable(\n \"MultiSelectPrimitive\",\n DecoratableMultiSelectPrimitive\n);\n\nexport { MultiSelectPrimitive, type MultiSelectPrimitiveProps, type MultiSelectOptionDto };\n"],"names":["MultiSelectTrigger","displayValue","hasValue","placeholder","displayResetAction","disabled","invalid","size","variant","onValueReset","resetButton","useMemo","IconButton","event","Icon","Close","Popover","cn","selectTriggerVariants","ChevronDown","MultiSelectContent","options","value","onToggle","contentRef","useEscapeScrollLock","ScrollArea","option","CheckboxPrimitiveRenderer","DecoratableMultiSelectPrimitive","onChange","showSelectionCount","labelMap","Map","o","v","toggle","useCallback","optionValue","next","reset","MultiSelectPrimitive","makeDecoratable"],"mappings":"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"}
@@ -9,3 +9,10 @@ export declare const WithArrowAccentVariant: Story;
9
9
  export declare const SubtleVariant: Story;
10
10
  export declare const WithArrowSubtleVariant: Story;
11
11
  export declare const Documentation: Story;
12
+ /**
13
+ * A dialog locks scrolling outside of its own content, and the popover is portaled out of it, so
14
+ * the lock covers the popover too. What that costs is the wheel and the trackpad: the list below
15
+ * still moved by its scrollbar and by the arrow keys, but a wheel event over it did nothing at all.
16
+ * It has to scroll by wheel while the dialog is open.
17
+ */
18
+ export declare const InsideDialog: Story;
@@ -1,5 +1,7 @@
1
1
  import react from "react";
2
2
  import { Popover } from "./Popover.js";
3
+ import { Button } from "../Button/index.js";
4
+ import { Dialog } from "../Dialog/index.js";
3
5
  const meta = {
4
6
  title: "Components/Popover",
5
7
  component: Popover,
@@ -130,7 +132,28 @@ const Documentation = {
130
132
  }
131
133
  }
132
134
  };
135
+ const InsideDialog = {
136
+ render: ()=>/*#__PURE__*/ react.createElement(Dialog, {
137
+ trigger: /*#__PURE__*/ react.createElement(Button, {
138
+ variant: "primary",
139
+ text: "Open dialog"
140
+ }),
141
+ title: "Popover inside a dialog"
142
+ }, /*#__PURE__*/ react.createElement(Popover, {
143
+ trigger: /*#__PURE__*/ react.createElement("span", null, /*#__PURE__*/ react.createElement(Button, {
144
+ variant: "secondary",
145
+ text: "Open popover"
146
+ })),
147
+ content: /*#__PURE__*/ react.createElement("ul", {
148
+ className: "max-h-48 w-[220px] overflow-y-auto"
149
+ }, Array.from({
150
+ length: 40
151
+ }, (_, index)=>/*#__PURE__*/ react.createElement("li", {
152
+ key: index
153
+ }, "Option ", index + 1)))
154
+ }))
155
+ };
133
156
  export default Popover_stories;
134
- export { AccentVariant, Default, Documentation, SubtleVariant, WithArrowAccentVariant, WithArrowSubtleVariant };
157
+ export { AccentVariant, Default, Documentation, InsideDialog, SubtleVariant, WithArrowAccentVariant, WithArrowSubtleVariant };
135
158
 
136
159
  //# sourceMappingURL=Popover.stories.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Popover/Popover.stories.js","sources":["../../src/Popover/Popover.stories.tsx"],"sourcesContent":["import React from \"react\";\nimport type { Meta, StoryObj } from \"@storybook/react\";\nimport { Popover } from \"./Popover.js\";\n\nconst meta: Meta<typeof Popover> = {\n title: \"Components/Popover\",\n component: Popover,\n parameters: {\n layout: \"padded\"\n },\n argTypes: {\n align: {\n control: \"select\",\n options: [\"start\", \"center\", \"end\"]\n },\n side: {\n control: \"select\",\n options: [\"top\", \"bottom\", \"left\", \"right\"]\n }\n },\n decorators: [\n Story => (\n <div className=\"bg-[#f4f4f4] flex items-center justify-center w-full h-[300px]\">\n <Story />\n </div>\n )\n ]\n};\n\nexport default meta;\n\ntype Story = StoryObj<typeof Popover>;\n\nexport const Default: Story = {\n args: {\n trigger: <p>Popover trigger</p>,\n content: (\n <div className={\"w-[260px]\"}>\n <strong>Lorem ipsum dolor sit amet</strong>, consectetur adipiscing elit. Morbi\n lectus leo, dapibus vitae mollis dictum, vulputate eget lorem. Aliquam rutrum auctor\n tempus.\n </div>\n )\n }\n};\n\nexport const AccentVariant: Story = {\n args: {\n ...Default.args,\n variant: \"accent\"\n }\n};\n\nexport const WithArrowAccentVariant: Story = {\n args: {\n ...AccentVariant.args,\n arrow: true\n }\n};\n\nexport const SubtleVariant: Story = {\n args: {\n ...Default.args,\n variant: \"subtle\"\n },\n decorators: [\n Story => (\n <div className=\"flex items-center justify-center bg-neutral-dark text-neutral-light w-full h-[300px]\">\n <Story />\n </div>\n )\n ]\n};\n\nexport const WithArrowSubtleVariant: Story = {\n args: {\n variant: \"subtle\",\n trigger: <p>Popover trigger</p>,\n arrow: true,\n content: (\n <div className={\"w-[260px]\"}>\n <strong>Lorem ipsum dolor sit amet</strong>, consectetur adipiscing elit. Morbi\n lectus leo, dapibus vitae mollis dictum, vulputate eget lorem. Aliquam rutrum auctor\n tempus.\n </div>\n )\n },\n decorators: SubtleVariant.decorators\n};\n\nexport const Documentation: Story = {\n args: {\n align: \"center\",\n side: \"bottom\",\n variant: \"subtle\",\n arrow: false,\n close: false,\n trigger: <p>Popover trigger</p>,\n content: (\n <div className={\"w-[260px]\"}>\n <strong>Lorem ipsum dolor sit amet</strong>, consectetur adipiscing elit. Morbi\n lectus leo, dapibus vitae mollis dictum, vulputate eget lorem. Aliquam rutrum auctor\n tempus.\n </div>\n )\n },\n argTypes: {\n trigger: {\n description:\n \"The element that triggers the popover when clicked. Please refer to the example code for details.\"\n },\n content: {\n description:\n \"The content to display inside the popover. Please refer to the example code for details.\"\n },\n side: {\n description: \"The side of the trigger where the popover appears.\",\n control: \"select\",\n options: [\"top\", \"right\", \"bottom\", \"left\"]\n },\n align: {\n description: \"The alignment of the popover relative to the trigger.\",\n control: \"select\",\n options: [\"start\", \"center\", \"end\"]\n },\n variant: {\n description: \"The visual style variant of the popover.\",\n control: \"select\",\n options: [\"accent\", \"subtle\"]\n },\n arrow: {\n description: \"Whether to show an arrow pointing to the trigger.\",\n control: \"boolean\"\n },\n close: {\n description: \"Whether to show a close button inside the popover.\",\n control: \"boolean\"\n }\n }\n};\n"],"names":["meta","Popover","Story","Default","AccentVariant","WithArrowAccentVariant","SubtleVariant","WithArrowSubtleVariant","Documentation"],"mappings":";;AAIA,MAAMA,OAA6B;IAC/B,OAAO;IACP,WAAWC;IACX,YAAY;QACR,QAAQ;IACZ;IACA,UAAU;QACN,OAAO;YACH,SAAS;YACT,SAAS;gBAAC;gBAAS;gBAAU;aAAM;QACvC;QACA,MAAM;YACF,SAAS;YACT,SAAS;gBAAC;gBAAO;gBAAU;gBAAQ;aAAQ;QAC/C;IACJ;IACA,YAAY;QACRC,CAAAA,QAAAA,WAAAA,GACI,oBAAC;gBAAI,WAAU;6BACX,oBAACA,OAAAA;KAGZ;AACL;AAEA,wBAAeF;AAIR,MAAMG,UAAiB;IAC1B,MAAM;QACF,SAAS,WAAT,GAAS,oBAAC,WAAE;QACZ,SAAS,WAAT,GACI,oBAAC;YAAI,WAAW;yBACZ,oBAAC,gBAAO,+BAAmC;IAKvD;AACJ;AAEO,MAAMC,gBAAuB;IAChC,MAAM;QACF,GAAGD,QAAQ,IAAI;QACf,SAAS;IACb;AACJ;AAEO,MAAME,yBAAgC;IACzC,MAAM;QACF,GAAGD,cAAc,IAAI;QACrB,OAAO;IACX;AACJ;AAEO,MAAME,gBAAuB;IAChC,MAAM;QACF,GAAGH,QAAQ,IAAI;QACf,SAAS;IACb;IACA,YAAY;QACRD,CAAAA,QAAAA,WAAAA,GACI,oBAAC;gBAAI,WAAU;6BACX,oBAACA,OAAAA;KAGZ;AACL;AAEO,MAAMK,yBAAgC;IACzC,MAAM;QACF,SAAS;QACT,SAAS,WAAT,GAAS,oBAAC,WAAE;QACZ,OAAO;QACP,SAAS,WAAT,GACI,oBAAC;YAAI,WAAW;yBACZ,oBAAC,gBAAO,+BAAmC;IAKvD;IACA,YAAYD,cAAc,UAAU;AACxC;AAEO,MAAME,gBAAuB;IAChC,MAAM;QACF,OAAO;QACP,MAAM;QACN,SAAS;QACT,OAAO;QACP,OAAO;QACP,SAAS,WAAT,GAAS,oBAAC,WAAE;QACZ,SAAS,WAAT,GACI,oBAAC;YAAI,WAAW;yBACZ,oBAAC,gBAAO,+BAAmC;IAKvD;IACA,UAAU;QACN,SAAS;YACL,aACI;QACR;QACA,SAAS;YACL,aACI;QACR;QACA,MAAM;YACF,aAAa;YACb,SAAS;YACT,SAAS;gBAAC;gBAAO;gBAAS;gBAAU;aAAO;QAC/C;QACA,OAAO;YACH,aAAa;YACb,SAAS;YACT,SAAS;gBAAC;gBAAS;gBAAU;aAAM;QACvC;QACA,SAAS;YACL,aAAa;YACb,SAAS;YACT,SAAS;gBAAC;gBAAU;aAAS;QACjC;QACA,OAAO;YACH,aAAa;YACb,SAAS;QACb;QACA,OAAO;YACH,aAAa;YACb,SAAS;QACb;IACJ;AACJ"}
1
+ {"version":3,"file":"Popover/Popover.stories.js","sources":["../../src/Popover/Popover.stories.tsx"],"sourcesContent":["import React from \"react\";\nimport type { Meta, StoryObj } from \"@storybook/react\";\nimport { Popover } from \"./Popover.js\";\nimport { Button } from \"~/Button/index.js\";\nimport { Dialog } from \"~/Dialog/index.js\";\n\nconst meta: Meta<typeof Popover> = {\n title: \"Components/Popover\",\n component: Popover,\n parameters: {\n layout: \"padded\"\n },\n argTypes: {\n align: {\n control: \"select\",\n options: [\"start\", \"center\", \"end\"]\n },\n side: {\n control: \"select\",\n options: [\"top\", \"bottom\", \"left\", \"right\"]\n }\n },\n decorators: [\n Story => (\n <div className=\"bg-[#f4f4f4] flex items-center justify-center w-full h-[300px]\">\n <Story />\n </div>\n )\n ]\n};\n\nexport default meta;\n\ntype Story = StoryObj<typeof Popover>;\n\nexport const Default: Story = {\n args: {\n trigger: <p>Popover trigger</p>,\n content: (\n <div className={\"w-[260px]\"}>\n <strong>Lorem ipsum dolor sit amet</strong>, consectetur adipiscing elit. Morbi\n lectus leo, dapibus vitae mollis dictum, vulputate eget lorem. Aliquam rutrum auctor\n tempus.\n </div>\n )\n }\n};\n\nexport const AccentVariant: Story = {\n args: {\n ...Default.args,\n variant: \"accent\"\n }\n};\n\nexport const WithArrowAccentVariant: Story = {\n args: {\n ...AccentVariant.args,\n arrow: true\n }\n};\n\nexport const SubtleVariant: Story = {\n args: {\n ...Default.args,\n variant: \"subtle\"\n },\n decorators: [\n Story => (\n <div className=\"flex items-center justify-center bg-neutral-dark text-neutral-light w-full h-[300px]\">\n <Story />\n </div>\n )\n ]\n};\n\nexport const WithArrowSubtleVariant: Story = {\n args: {\n variant: \"subtle\",\n trigger: <p>Popover trigger</p>,\n arrow: true,\n content: (\n <div className={\"w-[260px]\"}>\n <strong>Lorem ipsum dolor sit amet</strong>, consectetur adipiscing elit. Morbi\n lectus leo, dapibus vitae mollis dictum, vulputate eget lorem. Aliquam rutrum auctor\n tempus.\n </div>\n )\n },\n decorators: SubtleVariant.decorators\n};\n\nexport const Documentation: Story = {\n args: {\n align: \"center\",\n side: \"bottom\",\n variant: \"subtle\",\n arrow: false,\n close: false,\n trigger: <p>Popover trigger</p>,\n content: (\n <div className={\"w-[260px]\"}>\n <strong>Lorem ipsum dolor sit amet</strong>, consectetur adipiscing elit. Morbi\n lectus leo, dapibus vitae mollis dictum, vulputate eget lorem. Aliquam rutrum auctor\n tempus.\n </div>\n )\n },\n argTypes: {\n trigger: {\n description:\n \"The element that triggers the popover when clicked. Please refer to the example code for details.\"\n },\n content: {\n description:\n \"The content to display inside the popover. Please refer to the example code for details.\"\n },\n side: {\n description: \"The side of the trigger where the popover appears.\",\n control: \"select\",\n options: [\"top\", \"right\", \"bottom\", \"left\"]\n },\n align: {\n description: \"The alignment of the popover relative to the trigger.\",\n control: \"select\",\n options: [\"start\", \"center\", \"end\"]\n },\n variant: {\n description: \"The visual style variant of the popover.\",\n control: \"select\",\n options: [\"accent\", \"subtle\"]\n },\n arrow: {\n description: \"Whether to show an arrow pointing to the trigger.\",\n control: \"boolean\"\n },\n close: {\n description: \"Whether to show a close button inside the popover.\",\n control: \"boolean\"\n }\n }\n};\n\n/**\n * A dialog locks scrolling outside of its own content, and the popover is portaled out of it, so\n * the lock covers the popover too. What that costs is the wheel and the trackpad: the list below\n * still moved by its scrollbar and by the arrow keys, but a wheel event over it did nothing at all.\n * It has to scroll by wheel while the dialog is open.\n */\nexport const InsideDialog: Story = {\n render: () => (\n <Dialog\n trigger={<Button variant={\"primary\"} text={\"Open dialog\"} />}\n title={\"Popover inside a dialog\"}\n >\n <Popover\n trigger={\n <span>\n <Button variant={\"secondary\"} text={\"Open popover\"} />\n </span>\n }\n content={\n <ul className={\"max-h-48 w-[220px] overflow-y-auto\"}>\n {Array.from({ length: 40 }, (_, index) => (\n <li key={index}>Option {index + 1}</li>\n ))}\n </ul>\n }\n />\n </Dialog>\n )\n};\n"],"names":["meta","Popover","Story","Default","AccentVariant","WithArrowAccentVariant","SubtleVariant","WithArrowSubtleVariant","Documentation","InsideDialog","Dialog","Button","Array","_","index"],"mappings":";;;;AAMA,MAAMA,OAA6B;IAC/B,OAAO;IACP,WAAWC;IACX,YAAY;QACR,QAAQ;IACZ;IACA,UAAU;QACN,OAAO;YACH,SAAS;YACT,SAAS;gBAAC;gBAAS;gBAAU;aAAM;QACvC;QACA,MAAM;YACF,SAAS;YACT,SAAS;gBAAC;gBAAO;gBAAU;gBAAQ;aAAQ;QAC/C;IACJ;IACA,YAAY;QACRC,CAAAA,QAAAA,WAAAA,GACI,oBAAC;gBAAI,WAAU;6BACX,oBAACA,OAAAA;KAGZ;AACL;AAEA,wBAAeF;AAIR,MAAMG,UAAiB;IAC1B,MAAM;QACF,SAAS,WAAT,GAAS,oBAAC,WAAE;QACZ,SAAS,WAAT,GACI,oBAAC;YAAI,WAAW;yBACZ,oBAAC,gBAAO,+BAAmC;IAKvD;AACJ;AAEO,MAAMC,gBAAuB;IAChC,MAAM;QACF,GAAGD,QAAQ,IAAI;QACf,SAAS;IACb;AACJ;AAEO,MAAME,yBAAgC;IACzC,MAAM;QACF,GAAGD,cAAc,IAAI;QACrB,OAAO;IACX;AACJ;AAEO,MAAME,gBAAuB;IAChC,MAAM;QACF,GAAGH,QAAQ,IAAI;QACf,SAAS;IACb;IACA,YAAY;QACRD,CAAAA,QAAAA,WAAAA,GACI,oBAAC;gBAAI,WAAU;6BACX,oBAACA,OAAAA;KAGZ;AACL;AAEO,MAAMK,yBAAgC;IACzC,MAAM;QACF,SAAS;QACT,SAAS,WAAT,GAAS,oBAAC,WAAE;QACZ,OAAO;QACP,SAAS,WAAT,GACI,oBAAC;YAAI,WAAW;yBACZ,oBAAC,gBAAO,+BAAmC;IAKvD;IACA,YAAYD,cAAc,UAAU;AACxC;AAEO,MAAME,gBAAuB;IAChC,MAAM;QACF,OAAO;QACP,MAAM;QACN,SAAS;QACT,OAAO;QACP,OAAO;QACP,SAAS,WAAT,GAAS,oBAAC,WAAE;QACZ,SAAS,WAAT,GACI,oBAAC;YAAI,WAAW;yBACZ,oBAAC,gBAAO,+BAAmC;IAKvD;IACA,UAAU;QACN,SAAS;YACL,aACI;QACR;QACA,SAAS;YACL,aACI;QACR;QACA,MAAM;YACF,aAAa;YACb,SAAS;YACT,SAAS;gBAAC;gBAAO;gBAAS;gBAAU;aAAO;QAC/C;QACA,OAAO;YACH,aAAa;YACb,SAAS;YACT,SAAS;gBAAC;gBAAS;gBAAU;aAAM;QACvC;QACA,SAAS;YACL,aAAa;YACb,SAAS;YACT,SAAS;gBAAC;gBAAU;aAAS;QACjC;QACA,OAAO;YACH,aAAa;YACb,SAAS;QACb;QACA,OAAO;YACH,aAAa;YACb,SAAS;QACb;IACJ;AACJ;AAQO,MAAMC,eAAsB;IAC/B,QAAQ,kBACJ,oBAACC,QAAMA;YACH,uBAAS,oBAACC,QAAMA;gBAAC,SAAS;gBAAW,MAAM;;YAC3C,OAAO;yBAEP,oBAACV,SAAOA;YACJ,uBACI,oBAAC,4BACG,oBAACU,QAAMA;gBAAC,SAAS;gBAAa,MAAM;;YAG5C,uBACI,oBAAC;gBAAG,WAAW;eACVC,MAAM,IAAI,CAAC;gBAAE,QAAQ;YAAG,GAAG,CAACC,GAAGC,QAAAA,WAAAA,GAC5B,oBAAC;oBAAG,KAAKA;mBAAO,WAAQA,QAAQ;;AAO5D"}
@@ -1,5 +1,6 @@
1
1
  import { Popover } from "radix-ui";
2
2
  import { cn, cva } from "../../../utils.js";
3
+ import { useEscapeScrollLock } from "../../../hooks/index.js";
3
4
  import * as __rspack_external_react from "react";
4
5
  const popoverContentVariants = cva([
5
6
  "bg-neutral-base rounded-sm shadow-md overflow-hidden outline-none z-popover",
@@ -27,7 +28,10 @@ const popoverContentVariants = cva([
27
28
  variant: "subtle"
28
29
  }
29
30
  });
30
- const PopoverContent = ({ className, variant, arrow = false, align = "center", sideOffset = 6, collisionPadding = 8, ...props })=>/*#__PURE__*/ __rspack_external_react.createElement(Popover.Portal, null, /*#__PURE__*/ __rspack_external_react.createElement(Popover.Content, {
31
+ const PopoverContent = ({ className, variant, arrow = false, align = "center", sideOffset = 6, collisionPadding = 8, ...props })=>{
32
+ const contentRef = useEscapeScrollLock();
33
+ return /*#__PURE__*/ __rspack_external_react.createElement(Popover.Portal, null, /*#__PURE__*/ __rspack_external_react.createElement(Popover.Content, {
34
+ ref: contentRef,
31
35
  "data-slot": "popover-content",
32
36
  align: align,
33
37
  sideOffset: sideOffset,
@@ -38,6 +42,7 @@ const PopoverContent = ({ className, variant, arrow = false, align = "center", s
38
42
  }), className),
39
43
  ...props
40
44
  }));
45
+ };
41
46
  export { PopoverContent };
42
47
 
43
48
  //# sourceMappingURL=PopoverContent.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Popover/primitives/components/PopoverContent.js","sources":["../../../../src/Popover/primitives/components/PopoverContent.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { Popover as PopoverPrimitive } from \"radix-ui\";\nimport { cn, cva, type VariantProps } from \"~/utils.js\";\n\nconst popoverContentVariants = cva(\n [\n \"bg-neutral-base rounded-sm shadow-md overflow-hidden outline-none z-popover\",\n \"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 origin-(--radix-popover-content-transform-origin)\",\n \"data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\"\n ],\n {\n variants: {\n variant: {\n accent: \"bg-neutral-dark text-neutral-light border-neutral-black\",\n subtle: \"bg-neutral-base text-neutral-primary border-neutral-muted\"\n },\n arrow: {\n true: [\n \"data-[side=top]:pb-xs-plus\",\n \"data-[side=bottom]:pt-xs-plus\",\n \"data-[side=left]:pr-xs-plus\",\n \"data-[side=right]:pl-xs-plus\"\n ],\n false: [\"border-sm\"]\n }\n },\n defaultVariants: {\n variant: \"subtle\"\n }\n }\n);\n\ntype PopoverContentProps = PopoverPrimitive.PopoverContentProps &\n VariantProps<typeof popoverContentVariants>;\n\nconst PopoverContent = ({\n className,\n variant,\n arrow = false,\n align = \"center\",\n sideOffset = 6,\n collisionPadding = 8,\n ...props\n}: PopoverContentProps) => (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n data-slot=\"popover-content\"\n align={align}\n sideOffset={sideOffset}\n collisionPadding={collisionPadding}\n className={cn(popoverContentVariants({ variant, arrow }), className)}\n {...props}\n />\n </PopoverPrimitive.Portal>\n);\n\nexport { PopoverContent, type PopoverContentProps };\n"],"names":["popoverContentVariants","cva","PopoverContent","className","variant","arrow","align","sideOffset","collisionPadding","props","PopoverPrimitive","cn"],"mappings":";;;AAIA,MAAMA,yBAAyBC,IAC3B;IACI;IACA;IACA;CACH,EACD;IACI,UAAU;QACN,SAAS;YACL,QAAQ;YACR,QAAQ;QACZ;QACA,OAAO;YACH,MAAM;gBACF;gBACA;gBACA;gBACA;aACH;YACD,OAAO;gBAAC;aAAY;QACxB;IACJ;IACA,iBAAiB;QACb,SAAS;IACb;AACJ;AAMJ,MAAMC,iBAAiB,CAAC,EACpBC,SAAS,EACTC,OAAO,EACPC,QAAQ,KAAK,EACbC,QAAQ,QAAQ,EAChBC,aAAa,CAAC,EACdC,mBAAmB,CAAC,EACpB,GAAGC,OACe,iBAClB,sCAACC,QAAAA,MAAuB,sBACpB,sCAACA,QAAAA,OAAwB;QACrB,aAAU;QACV,OAAOJ;QACP,YAAYC;QACZ,kBAAkBC;QAClB,WAAWG,GAAGX,uBAAuB;YAAEI;YAASC;QAAM,IAAIF;QACzD,GAAGM,KAAK"}
1
+ {"version":3,"file":"Popover/primitives/components/PopoverContent.js","sources":["../../../../src/Popover/primitives/components/PopoverContent.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { Popover as PopoverPrimitive } from \"radix-ui\";\nimport { cn, cva, type VariantProps } from \"~/utils.js\";\nimport { useEscapeScrollLock } from \"~/hooks/index.js\";\n\nconst popoverContentVariants = cva(\n [\n \"bg-neutral-base rounded-sm shadow-md overflow-hidden outline-none z-popover\",\n \"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 origin-(--radix-popover-content-transform-origin)\",\n \"data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\"\n ],\n {\n variants: {\n variant: {\n accent: \"bg-neutral-dark text-neutral-light border-neutral-black\",\n subtle: \"bg-neutral-base text-neutral-primary border-neutral-muted\"\n },\n arrow: {\n true: [\n \"data-[side=top]:pb-xs-plus\",\n \"data-[side=bottom]:pt-xs-plus\",\n \"data-[side=left]:pr-xs-plus\",\n \"data-[side=right]:pl-xs-plus\"\n ],\n false: [\"border-sm\"]\n }\n },\n defaultVariants: {\n variant: \"subtle\"\n }\n }\n);\n\ntype PopoverContentProps = PopoverPrimitive.PopoverContentProps &\n VariantProps<typeof popoverContentVariants>;\n\nconst PopoverContent = ({\n className,\n variant,\n arrow = false,\n align = \"center\",\n sideOffset = 6,\n collisionPadding = 8,\n ...props\n}: PopoverContentProps) => {\n /*\n * The popover is portaled to `document.body`, which puts it outside of a modal dialog's scroll\n * lock. Without this, anything scrollable within the popover freezes while a dialog is open.\n */\n const contentRef = useEscapeScrollLock<HTMLDivElement>();\n\n return (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n ref={contentRef}\n data-slot=\"popover-content\"\n align={align}\n sideOffset={sideOffset}\n collisionPadding={collisionPadding}\n className={cn(popoverContentVariants({ variant, arrow }), className)}\n {...props}\n />\n </PopoverPrimitive.Portal>\n );\n};\n\nexport { PopoverContent, type PopoverContentProps };\n"],"names":["popoverContentVariants","cva","PopoverContent","className","variant","arrow","align","sideOffset","collisionPadding","props","contentRef","useEscapeScrollLock","PopoverPrimitive","cn"],"mappings":";;;;AAKA,MAAMA,yBAAyBC,IAC3B;IACI;IACA;IACA;CACH,EACD;IACI,UAAU;QACN,SAAS;YACL,QAAQ;YACR,QAAQ;QACZ;QACA,OAAO;YACH,MAAM;gBACF;gBACA;gBACA;gBACA;aACH;YACD,OAAO;gBAAC;aAAY;QACxB;IACJ;IACA,iBAAiB;QACb,SAAS;IACb;AACJ;AAMJ,MAAMC,iBAAiB,CAAC,EACpBC,SAAS,EACTC,OAAO,EACPC,QAAQ,KAAK,EACbC,QAAQ,QAAQ,EAChBC,aAAa,CAAC,EACdC,mBAAmB,CAAC,EACpB,GAAGC,OACe;IAKlB,MAAMC,aAAaC;IAEnB,OAAO,WAAP,GACI,sCAACC,QAAAA,MAAuB,sBACpB,sCAACA,QAAAA,OAAwB;QACrB,KAAKF;QACL,aAAU;QACV,OAAOJ;QACP,YAAYC;QACZ,kBAAkBC;QAClB,WAAWK,GAAGb,uBAAuB;YAAEI;YAASC;QAAM,IAAIF;QACzD,GAAGM,KAAK;;AAIzB"}
@@ -13,7 +13,17 @@ export interface ScrollPosition {
13
13
  interface ScrollAreaProps extends Omit<React.ComponentProps<typeof ScrollAreaPrimitive.Root>, "onScroll"> {
14
14
  onScrollPositionChange?: (position: ScrollPosition) => void;
15
15
  onScroll?: (position: ScrollPosition) => void;
16
+ /**
17
+ * Classes for the scrolling element itself. Put the height limit here when the area has to grow
18
+ * with its content up to a maximum, instead of filling a parent of a known height.
19
+ */
20
+ viewportClassName?: string;
21
+ /**
22
+ * Native scroll handler for the scrolling element, for callers that need the event itself.
23
+ * `onScroll` reports positions instead.
24
+ */
25
+ onViewportScroll?: React.UIEventHandler<HTMLDivElement>;
16
26
  }
17
- declare function ScrollArea({ className, children, onScrollPositionChange, onScroll, ...props }: ScrollAreaProps): React.JSX.Element;
18
- declare function ScrollBar({ className, orientation, ...props }: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>): React.JSX.Element;
27
+ declare function ScrollArea({ className, children, onScrollPositionChange, onScroll, viewportClassName, onViewportScroll, type, ...props }: ScrollAreaProps): React.JSX.Element;
28
+ declare function ScrollBar({ className, orientation, onMouseDown, ...props }: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>): React.JSX.Element;
19
29
  export { ScrollArea, ScrollBar };
@@ -1,7 +1,7 @@
1
1
  import { cn } from "../utils.js";
2
2
  import * as __rspack_external_react from "react";
3
3
  import * as __rspack_external__radix_ui_react_scroll_area_bdec1136 from "@radix-ui/react-scroll-area";
4
- function ScrollArea({ className, children, onScrollPositionChange, onScroll, ...props }) {
4
+ function ScrollArea({ className, children, onScrollPositionChange, onScroll, viewportClassName, onViewportScroll, type = "auto", ...props }) {
5
5
  const viewportRef = __rspack_external_react.useRef(null);
6
6
  __rspack_external_react.useEffect(()=>{
7
7
  const viewport = viewportRef.current;
@@ -30,19 +30,26 @@ function ScrollArea({ className, children, onScrollPositionChange, onScroll, ...
30
30
  ]);
31
31
  return /*#__PURE__*/ __rspack_external_react.createElement(__rspack_external__radix_ui_react_scroll_area_bdec1136.Root, {
32
32
  "data-slot": "scroll-area",
33
+ type: type,
33
34
  className: cn("relative", className),
34
35
  ...props
35
36
  }, /*#__PURE__*/ __rspack_external_react.createElement(__rspack_external__radix_ui_react_scroll_area_bdec1136.Viewport, {
36
37
  ref: viewportRef,
37
38
  "data-slot": "scroll-area-viewport",
38
- className: "focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1"
39
+ onScroll: onViewportScroll,
40
+ className: cn("focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1", viewportClassName)
39
41
  }, children), /*#__PURE__*/ __rspack_external_react.createElement(ScrollBar, null), /*#__PURE__*/ __rspack_external_react.createElement(__rspack_external__radix_ui_react_scroll_area_bdec1136.Corner, null));
40
42
  }
41
- function ScrollBar({ className, orientation = "vertical", ...props }) {
43
+ function ScrollBar({ className, orientation = "vertical", onMouseDown, ...props }) {
44
+ const handleMouseDown = (event)=>{
45
+ onMouseDown?.(event);
46
+ event.preventDefault();
47
+ };
42
48
  return /*#__PURE__*/ __rspack_external_react.createElement(__rspack_external__radix_ui_react_scroll_area_bdec1136.ScrollAreaScrollbar, {
43
49
  "data-slot": "scroll-area-scrollbar",
44
50
  orientation: orientation,
45
- className: cn("flex touch-none transition-colors select-none", "vertical" === orientation && "h-full w-[8px] border-l border-l-transparent", "horizontal" === orientation && "h-[8px] flex-col border-t border-t-transparent", className),
51
+ onMouseDown: handleMouseDown,
52
+ className: cn("flex touch-none transition-colors select-none", "vertical" === orientation && "h-full w-[10px] p-[2px]", "horizontal" === orientation && "h-[10px] flex-col p-[2px]", className),
46
53
  ...props
47
54
  }, /*#__PURE__*/ __rspack_external_react.createElement(__rspack_external__radix_ui_react_scroll_area_bdec1136.ScrollAreaThumb, {
48
55
  "data-slot": "scroll-area-thumb",
@@ -1 +1 @@
1
- {"version":3,"file":"ScrollArea/ScrollArea.js","sources":["../../src/ScrollArea/ScrollArea.tsx"],"sourcesContent":["import * as React from \"react\";\nimport * as ScrollAreaPrimitive from \"@radix-ui/react-scroll-area\";\nimport { cn } from \"~/utils.js\";\n\nexport interface ScrollPosition {\n top: number;\n left: number;\n scrollTop: number;\n scrollLeft: number;\n scrollHeight: number;\n scrollWidth: number;\n clientHeight: number;\n clientWidth: number;\n}\n\ninterface ScrollAreaProps extends Omit<\n React.ComponentProps<typeof ScrollAreaPrimitive.Root>,\n \"onScroll\"\n> {\n onScrollPositionChange?: (position: ScrollPosition) => void;\n onScroll?: (position: ScrollPosition) => void;\n}\n\nfunction ScrollArea({\n className,\n children,\n onScrollPositionChange,\n onScroll,\n ...props\n}: ScrollAreaProps) {\n const viewportRef = React.useRef<HTMLDivElement>(null);\n\n React.useEffect(() => {\n const viewport = viewportRef.current;\n if (!viewport || (!onScrollPositionChange && !onScroll)) {\n return;\n }\n\n // The Viewport component itself is the scrollable element.\n const handleScroll = () => {\n const { scrollTop, scrollLeft, scrollHeight, scrollWidth, clientHeight, clientWidth } =\n viewport;\n\n const position: ScrollPosition = {\n top: scrollHeight > clientHeight ? scrollTop / (scrollHeight - clientHeight) : 0,\n left: scrollWidth > clientWidth ? scrollLeft / (scrollWidth - clientWidth) : 0,\n scrollTop,\n scrollLeft,\n scrollHeight,\n scrollWidth,\n clientHeight,\n clientWidth\n };\n\n onScrollPositionChange?.(position);\n onScroll?.(position);\n };\n\n // Call handleScroll initially to provide initial position.\n handleScroll();\n\n viewport.addEventListener(\"scroll\", handleScroll);\n return () => viewport.removeEventListener(\"scroll\", handleScroll);\n }, [onScrollPositionChange, onScroll]);\n\n return (\n <ScrollAreaPrimitive.Root\n data-slot=\"scroll-area\"\n className={cn(\"relative\", className)}\n {...props}\n >\n <ScrollAreaPrimitive.Viewport\n ref={viewportRef}\n data-slot=\"scroll-area-viewport\"\n className=\"focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1\"\n >\n {children}\n </ScrollAreaPrimitive.Viewport>\n <ScrollBar />\n <ScrollAreaPrimitive.Corner />\n </ScrollAreaPrimitive.Root>\n );\n}\n\nfunction ScrollBar({\n className,\n orientation = \"vertical\",\n ...props\n}: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {\n return (\n <ScrollAreaPrimitive.ScrollAreaScrollbar\n data-slot=\"scroll-area-scrollbar\"\n orientation={orientation}\n className={cn(\n \"flex touch-none transition-colors select-none\",\n orientation === \"vertical\" && \"h-full w-[8px] border-l border-l-transparent\",\n orientation === \"horizontal\" && \"h-[8px] flex-col border-t border-t-transparent\",\n className\n )}\n {...props}\n >\n <ScrollAreaPrimitive.ScrollAreaThumb\n data-slot=\"scroll-area-thumb\"\n className=\"bg-neutral-strong/70 relative flex-1 rounded-full\"\n />\n </ScrollAreaPrimitive.ScrollAreaScrollbar>\n );\n}\n\nexport { ScrollArea, ScrollBar };\n"],"names":["ScrollArea","className","children","onScrollPositionChange","onScroll","props","viewportRef","React","viewport","handleScroll","scrollTop","scrollLeft","scrollHeight","scrollWidth","clientHeight","clientWidth","position","ScrollAreaPrimitive","cn","ScrollBar","orientation"],"mappings":";;;AAuBA,SAASA,WAAW,EAChBC,SAAS,EACTC,QAAQ,EACRC,sBAAsB,EACtBC,QAAQ,EACR,GAAGC,OACW;IACd,MAAMC,cAAcC,wBAAAA,MAAY,CAAiB;IAEjDA,wBAAAA,SAAe,CAAC;QACZ,MAAMC,WAAWF,YAAY,OAAO;QACpC,IAAI,CAACE,YAAa,CAACL,0BAA0B,CAACC,UAC1C;QAIJ,MAAMK,eAAe;YACjB,MAAM,EAAEC,SAAS,EAAEC,UAAU,EAAEC,YAAY,EAAEC,WAAW,EAAEC,YAAY,EAAEC,WAAW,EAAE,GACjFP;YAEJ,MAAMQ,WAA2B;gBAC7B,KAAKJ,eAAeE,eAAeJ,YAAaE,CAAAA,eAAeE,YAAW,IAAK;gBAC/E,MAAMD,cAAcE,cAAcJ,aAAcE,CAAAA,cAAcE,WAAU,IAAK;gBAC7EL;gBACAC;gBACAC;gBACAC;gBACAC;gBACAC;YACJ;YAEAZ,yBAAyBa;YACzBZ,WAAWY;QACf;QAGAP;QAEAD,SAAS,gBAAgB,CAAC,UAAUC;QACpC,OAAO,IAAMD,SAAS,mBAAmB,CAAC,UAAUC;IACxD,GAAG;QAACN;QAAwBC;KAAS;IAErC,OAAO,WAAP,GACI,sCAACa,uDAAAA,IAAwB;QACrB,aAAU;QACV,WAAWC,GAAG,YAAYjB;QACzB,GAAGI,KAAK;qBAET,sCAACY,uDAAAA,QAA4B;QACzB,KAAKX;QACL,aAAU;QACV,WAAU;OAETJ,WAAAA,WAAAA,GAEL,sCAACiB,WAASA,OAAAA,WAAAA,GACV,sCAACF,uDAAAA,MAA0B;AAGvC;AAEA,SAASE,UAAU,EACflB,SAAS,EACTmB,cAAc,UAAU,EACxB,GAAGf,OACgE;IACnE,OAAO,WAAP,GACI,sCAACY,uDAAAA,mBAAuC;QACpC,aAAU;QACV,aAAaG;QACb,WAAWF,GACP,iDACAE,AAAgB,eAAhBA,eAA8B,gDAC9BA,AAAgB,iBAAhBA,eAAgC,kDAChCnB;QAEH,GAAGI,KAAK;qBAET,sCAACY,uDAAAA,eAAmC;QAChC,aAAU;QACV,WAAU;;AAI1B"}
1
+ {"version":3,"file":"ScrollArea/ScrollArea.js","sources":["../../src/ScrollArea/ScrollArea.tsx"],"sourcesContent":["import * as React from \"react\";\nimport * as ScrollAreaPrimitive from \"@radix-ui/react-scroll-area\";\nimport { cn } from \"~/utils.js\";\n\nexport interface ScrollPosition {\n top: number;\n left: number;\n scrollTop: number;\n scrollLeft: number;\n scrollHeight: number;\n scrollWidth: number;\n clientHeight: number;\n clientWidth: number;\n}\n\ninterface ScrollAreaProps extends Omit<\n React.ComponentProps<typeof ScrollAreaPrimitive.Root>,\n \"onScroll\"\n> {\n onScrollPositionChange?: (position: ScrollPosition) => void;\n onScroll?: (position: ScrollPosition) => void;\n /**\n * Classes for the scrolling element itself. Put the height limit here when the area has to grow\n * with its content up to a maximum, instead of filling a parent of a known height.\n */\n viewportClassName?: string;\n /**\n * Native scroll handler for the scrolling element, for callers that need the event itself.\n * `onScroll` reports positions instead.\n */\n onViewportScroll?: React.UIEventHandler<HTMLDivElement>;\n}\n\nfunction ScrollArea({\n className,\n children,\n onScrollPositionChange,\n onScroll,\n viewportClassName,\n onViewportScroll,\n /*\n * Radix would only show the scrollbar once the pointer is inside. Showing it whenever there is\n * more content is the same rule the rest of the admin follows, a Select included.\n */\n type = \"auto\",\n ...props\n}: ScrollAreaProps) {\n const viewportRef = React.useRef<HTMLDivElement>(null);\n\n React.useEffect(() => {\n const viewport = viewportRef.current;\n if (!viewport || (!onScrollPositionChange && !onScroll)) {\n return;\n }\n\n // The Viewport component itself is the scrollable element.\n const handleScroll = () => {\n const { scrollTop, scrollLeft, scrollHeight, scrollWidth, clientHeight, clientWidth } =\n viewport;\n\n const position: ScrollPosition = {\n top: scrollHeight > clientHeight ? scrollTop / (scrollHeight - clientHeight) : 0,\n left: scrollWidth > clientWidth ? scrollLeft / (scrollWidth - clientWidth) : 0,\n scrollTop,\n scrollLeft,\n scrollHeight,\n scrollWidth,\n clientHeight,\n clientWidth\n };\n\n onScrollPositionChange?.(position);\n onScroll?.(position);\n };\n\n // Call handleScroll initially to provide initial position.\n handleScroll();\n\n viewport.addEventListener(\"scroll\", handleScroll);\n return () => viewport.removeEventListener(\"scroll\", handleScroll);\n }, [onScrollPositionChange, onScroll]);\n\n return (\n <ScrollAreaPrimitive.Root\n data-slot=\"scroll-area\"\n type={type}\n className={cn(\"relative\", className)}\n {...props}\n >\n <ScrollAreaPrimitive.Viewport\n ref={viewportRef}\n data-slot=\"scroll-area-viewport\"\n onScroll={onViewportScroll}\n className={cn(\n \"focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1\",\n viewportClassName\n )}\n >\n {children}\n </ScrollAreaPrimitive.Viewport>\n <ScrollBar />\n <ScrollAreaPrimitive.Corner />\n </ScrollAreaPrimitive.Root>\n );\n}\n\nfunction ScrollBar({\n className,\n orientation = \"vertical\",\n onMouseDown,\n ...props\n}: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {\n const handleMouseDown = (event: React.MouseEvent<HTMLDivElement>) => {\n onMouseDown?.(event);\n\n /*\n * Grabbing a scrollbar must not move focus. An autocomplete closes its list the moment its\n * input blurs, so without this, dragging the thumb dismisses the list under the pointer.\n */\n event.preventDefault();\n };\n\n return (\n <ScrollAreaPrimitive.ScrollAreaScrollbar\n data-slot=\"scroll-area-scrollbar\"\n orientation={orientation}\n onMouseDown={handleMouseDown}\n className={cn(\n \"flex touch-none transition-colors select-none\",\n orientation === \"vertical\" && \"h-full w-[10px] p-[2px]\",\n orientation === \"horizontal\" && \"h-[10px] flex-col p-[2px]\",\n className\n )}\n {...props}\n >\n <ScrollAreaPrimitive.ScrollAreaThumb\n data-slot=\"scroll-area-thumb\"\n className=\"bg-neutral-strong/70 relative flex-1 rounded-full\"\n />\n </ScrollAreaPrimitive.ScrollAreaScrollbar>\n );\n}\n\nexport { ScrollArea, ScrollBar };\n"],"names":["ScrollArea","className","children","onScrollPositionChange","onScroll","viewportClassName","onViewportScroll","type","props","viewportRef","React","viewport","handleScroll","scrollTop","scrollLeft","scrollHeight","scrollWidth","clientHeight","clientWidth","position","ScrollAreaPrimitive","cn","ScrollBar","orientation","onMouseDown","handleMouseDown","event"],"mappings":";;;AAiCA,SAASA,WAAW,EAChBC,SAAS,EACTC,QAAQ,EACRC,sBAAsB,EACtBC,QAAQ,EACRC,iBAAiB,EACjBC,gBAAgB,EAKhBC,OAAO,MAAM,EACb,GAAGC,OACW;IACd,MAAMC,cAAcC,wBAAAA,MAAY,CAAiB;IAEjDA,wBAAAA,SAAe,CAAC;QACZ,MAAMC,WAAWF,YAAY,OAAO;QACpC,IAAI,CAACE,YAAa,CAACR,0BAA0B,CAACC,UAC1C;QAIJ,MAAMQ,eAAe;YACjB,MAAM,EAAEC,SAAS,EAAEC,UAAU,EAAEC,YAAY,EAAEC,WAAW,EAAEC,YAAY,EAAEC,WAAW,EAAE,GACjFP;YAEJ,MAAMQ,WAA2B;gBAC7B,KAAKJ,eAAeE,eAAeJ,YAAaE,CAAAA,eAAeE,YAAW,IAAK;gBAC/E,MAAMD,cAAcE,cAAcJ,aAAcE,CAAAA,cAAcE,WAAU,IAAK;gBAC7EL;gBACAC;gBACAC;gBACAC;gBACAC;gBACAC;YACJ;YAEAf,yBAAyBgB;YACzBf,WAAWe;QACf;QAGAP;QAEAD,SAAS,gBAAgB,CAAC,UAAUC;QACpC,OAAO,IAAMD,SAAS,mBAAmB,CAAC,UAAUC;IACxD,GAAG;QAACT;QAAwBC;KAAS;IAErC,OAAO,WAAP,GACI,sCAACgB,uDAAAA,IAAwB;QACrB,aAAU;QACV,MAAMb;QACN,WAAWc,GAAG,YAAYpB;QACzB,GAAGO,KAAK;qBAET,sCAACY,uDAAAA,QAA4B;QACzB,KAAKX;QACL,aAAU;QACV,UAAUH;QACV,WAAWe,GACP,sJACAhB;OAGHH,WAAAA,WAAAA,GAEL,sCAACoB,WAASA,OAAAA,WAAAA,GACV,sCAACF,uDAAAA,MAA0B;AAGvC;AAEA,SAASE,UAAU,EACfrB,SAAS,EACTsB,cAAc,UAAU,EACxBC,WAAW,EACX,GAAGhB,OACgE;IACnE,MAAMiB,kBAAkB,CAACC;QACrBF,cAAcE;QAMdA,MAAM,cAAc;IACxB;IAEA,OAAO,WAAP,GACI,sCAACN,uDAAAA,mBAAuC;QACpC,aAAU;QACV,aAAaG;QACb,aAAaE;QACb,WAAWJ,GACP,iDACAE,AAAgB,eAAhBA,eAA8B,2BAC9BA,AAAgB,iBAAhBA,eAAgC,6BAChCtB;QAEH,GAAGO,KAAK;qBAET,sCAACY,uDAAAA,eAAmC;QAChC,aAAU;QACV,WAAU;;AAI1B"}
@@ -1,22 +1,20 @@
1
1
  import { Select } from "radix-ui";
2
2
  import { cn } from "../../../utils.js";
3
- import { SelectScrollUpButton } from "./SelectScrollUpButton.js";
4
- import { SelectScrollDownButton } from "./SelectScrollDownButton.js";
5
3
  import * as __rspack_external_react from "react";
6
4
  const SelectContent = ({ className, children, ...props })=>/*#__PURE__*/ __rspack_external_react.createElement(Select.Portal, null, /*#__PURE__*/ __rspack_external_react.createElement(Select.Content, {
7
5
  className: cn([
8
- "relative z-popover max-h-[250px] min-w-56 shadow-lg py-sm overflow-hidden rounded-sm border-sm border-neutral-muted bg-neutral-base text-neutral-strong",
6
+ "relative z-popover max-h-[250px] min-w-56 shadow-lg overflow-hidden rounded-sm border-sm border-neutral-muted bg-neutral-base text-neutral-strong",
9
7
  "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
10
8
  "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1"
11
9
  ], className),
12
10
  position: "popper",
13
11
  ...props
14
- }, /*#__PURE__*/ __rspack_external_react.createElement(SelectScrollUpButton, null), /*#__PURE__*/ __rspack_external_react.createElement(Select.Viewport, {
12
+ }, /*#__PURE__*/ __rspack_external_react.createElement(Select.Viewport, {
15
13
  className: cn([
16
- "py-xs",
14
+ "py-sm",
17
15
  "h-(--radix-select-trigger-height) w-full min-w-(--radix-select-trigger-width)"
18
16
  ])
19
- }, children), /*#__PURE__*/ __rspack_external_react.createElement(SelectScrollDownButton, null)));
17
+ }, children)));
20
18
  export { SelectContent };
21
19
 
22
20
  //# sourceMappingURL=SelectContent.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Select/primitives/components/SelectContent.js","sources":["../../../../src/Select/primitives/components/SelectContent.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { Select as SelectPrimitives } from \"radix-ui\";\nimport { cn } from \"~/utils.js\";\nimport { SelectScrollUpButton } from \"./SelectScrollUpButton.js\";\nimport { SelectScrollDownButton } from \"./SelectScrollDownButton.js\";\n\ntype SelectContentProps = SelectPrimitives.SelectContentProps;\n\nconst SelectContent = ({ className, children, ...props }: SelectContentProps) => (\n <SelectPrimitives.Portal>\n <SelectPrimitives.Content\n className={cn(\n [\n \"relative z-popover max-h-[250px] min-w-56 shadow-lg py-sm overflow-hidden rounded-sm border-sm border-neutral-muted bg-neutral-base text-neutral-strong\",\n \"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\"\n ],\n className\n )}\n position={\"popper\"}\n {...props}\n >\n <SelectScrollUpButton />\n <SelectPrimitives.Viewport\n className={cn([\n \"py-xs\",\n \"h-(--radix-select-trigger-height) w-full min-w-(--radix-select-trigger-width)\"\n ])}\n >\n {children}\n </SelectPrimitives.Viewport>\n <SelectScrollDownButton />\n </SelectPrimitives.Content>\n </SelectPrimitives.Portal>\n);\n\nexport { SelectContent, type SelectContentProps };\n"],"names":["SelectContent","className","children","props","SelectPrimitives","cn","SelectScrollUpButton","SelectScrollDownButton"],"mappings":";;;;;AAQA,MAAMA,gBAAgB,CAAC,EAAEC,SAAS,EAAEC,QAAQ,EAAE,GAAGC,OAA2B,iBACxE,sCAACC,OAAAA,MAAuB,sBACpB,sCAACA,OAAAA,OAAwB;QACrB,WAAWC,GACP;YACI;YACA;YACA;SACH,EACDJ;QAEJ,UAAU;QACT,GAAGE,KAAK;qBAET,sCAACG,sBAAoBA,OAAAA,WAAAA,GACrB,sCAACF,OAAAA,QAAyB;QACtB,WAAWC,GAAG;YACV;YACA;SACH;OAEAH,WAAAA,WAAAA,GAEL,sCAACK,wBAAsBA"}
1
+ {"version":3,"file":"Select/primitives/components/SelectContent.js","sources":["../../../../src/Select/primitives/components/SelectContent.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { Select as SelectPrimitives } from \"radix-ui\";\nimport { cn } from \"~/utils.js\";\n\ntype SelectContentProps = SelectPrimitives.SelectContentProps;\n\nconst SelectContent = ({ className, children, ...props }: SelectContentProps) => (\n <SelectPrimitives.Portal>\n <SelectPrimitives.Content\n className={cn(\n [\n \"relative z-popover max-h-[250px] min-w-56 shadow-lg overflow-hidden rounded-sm border-sm border-neutral-muted bg-neutral-base text-neutral-strong\",\n \"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\"\n ],\n className\n )}\n position={\"popper\"}\n {...props}\n >\n {/* Two things keep this scrollbar in line with the one in the autocomplete popovers.\n No scroll buttons, because they come and go with the scroll position, taking the\n viewport height and the size of the thumb with them. And the padding on the\n viewport rather than around it, so the scrollbar runs the full height of the list. */}\n <SelectPrimitives.Viewport\n className={cn([\n \"py-sm\",\n \"h-(--radix-select-trigger-height) w-full min-w-(--radix-select-trigger-width)\"\n ])}\n >\n {children}\n </SelectPrimitives.Viewport>\n </SelectPrimitives.Content>\n </SelectPrimitives.Portal>\n);\n\nexport { SelectContent, type SelectContentProps };\n"],"names":["SelectContent","className","children","props","SelectPrimitives","cn"],"mappings":";;;AAMA,MAAMA,gBAAgB,CAAC,EAAEC,SAAS,EAAEC,QAAQ,EAAE,GAAGC,OAA2B,iBACxE,sCAACC,OAAAA,MAAuB,sBACpB,sCAACA,OAAAA,OAAwB;QACrB,WAAWC,GACP;YACI;YACA;YACA;SACH,EACDJ;QAEJ,UAAU;QACT,GAAGE,KAAK;qBAMT,sCAACC,OAAAA,QAAyB;QACtB,WAAWC,GAAG;YACV;YACA;SACH;OAEAH"}
package/hooks/index.d.ts CHANGED
@@ -1 +1,2 @@
1
1
  export * from "./useDisclosure.js";
2
+ export * from "./useEscapeScrollLock.js";
package/hooks/index.js CHANGED
@@ -1 +1,2 @@
1
1
  export * from "./useDisclosure.js";
2
+ export * from "./useEscapeScrollLock.js";
@@ -0,0 +1,13 @@
1
+ /**
2
+ * A modal `Dialog` locks scrolling by preventing every `wheel` and `touchmove` event that lands
3
+ * outside of its content. The listener sits on `document`, so layers that are portaled to
4
+ * `document.body` - popovers and the lists they render - count as "outside" and stop scrolling
5
+ * while the dialog is open.
6
+ *
7
+ * Stopping those events on the layer itself keeps them away from the `document` listener: the
8
+ * browser scrolls the layer as it normally would, and the lock still holds everywhere else.
9
+ *
10
+ * Attach the returned callback ref to the element whose subtree must remain scrollable. It has to
11
+ * be a callback ref, because layers like the popover mount their element after the first render.
12
+ */
13
+ export declare const useEscapeScrollLock: <T extends HTMLElement>() => (element: T | null) => void;
@@ -0,0 +1,21 @@
1
+ import { useCallback, useRef } from "react";
2
+ const useEscapeScrollLock = ()=>{
3
+ const detach = useRef(null);
4
+ return useCallback((element)=>{
5
+ if (detach.current) {
6
+ detach.current();
7
+ detach.current = null;
8
+ }
9
+ if (!element) return;
10
+ const stopPropagation = (event)=>event.stopPropagation();
11
+ element.addEventListener("wheel", stopPropagation);
12
+ element.addEventListener("touchmove", stopPropagation);
13
+ detach.current = ()=>{
14
+ element.removeEventListener("wheel", stopPropagation);
15
+ element.removeEventListener("touchmove", stopPropagation);
16
+ };
17
+ }, []);
18
+ };
19
+ export { useEscapeScrollLock };
20
+
21
+ //# sourceMappingURL=useEscapeScrollLock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks/useEscapeScrollLock.js","sources":["../../src/hooks/useEscapeScrollLock.ts"],"sourcesContent":["import { useCallback, useRef } from \"react\";\n\n/**\n * A modal `Dialog` locks scrolling by preventing every `wheel` and `touchmove` event that lands\n * outside of its content. The listener sits on `document`, so layers that are portaled to\n * `document.body` - popovers and the lists they render - count as \"outside\" and stop scrolling\n * while the dialog is open.\n *\n * Stopping those events on the layer itself keeps them away from the `document` listener: the\n * browser scrolls the layer as it normally would, and the lock still holds everywhere else.\n *\n * Attach the returned callback ref to the element whose subtree must remain scrollable. It has to\n * be a callback ref, because layers like the popover mount their element after the first render.\n */\nexport const useEscapeScrollLock = <T extends HTMLElement>() => {\n const detach = useRef<(() => void) | null>(null);\n\n return useCallback((element: T | null) => {\n if (detach.current) {\n detach.current();\n detach.current = null;\n }\n\n if (!element) {\n return;\n }\n\n const stopPropagation = (event: Event) => event.stopPropagation();\n\n element.addEventListener(\"wheel\", stopPropagation);\n element.addEventListener(\"touchmove\", stopPropagation);\n\n detach.current = () => {\n element.removeEventListener(\"wheel\", stopPropagation);\n element.removeEventListener(\"touchmove\", stopPropagation);\n };\n }, []);\n};\n"],"names":["useEscapeScrollLock","detach","useRef","useCallback","element","stopPropagation","event"],"mappings":";AAcO,MAAMA,sBAAsB;IAC/B,MAAMC,SAASC,OAA4B;IAE3C,OAAOC,YAAY,CAACC;QAChB,IAAIH,OAAO,OAAO,EAAE;YAChBA,OAAO,OAAO;YACdA,OAAO,OAAO,GAAG;QACrB;QAEA,IAAI,CAACG,SACD;QAGJ,MAAMC,kBAAkB,CAACC,QAAiBA,MAAM,eAAe;QAE/DF,QAAQ,gBAAgB,CAAC,SAASC;QAClCD,QAAQ,gBAAgB,CAAC,aAAaC;QAEtCJ,OAAO,OAAO,GAAG;YACbG,QAAQ,mBAAmB,CAAC,SAASC;YACrCD,QAAQ,mBAAmB,CAAC,aAAaC;QAC7C;IACJ,GAAG,EAAE;AACT"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webiny/admin-ui",
3
- "version": "6.5.0-beta.0",
3
+ "version": "6.5.0-beta.2",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./index.js",
@@ -19,9 +19,9 @@
19
19
  "@monaco-editor/react": "4.7.0",
20
20
  "@radix-ui/react-scroll-area": "1.2.15",
21
21
  "@tanstack/react-table": "8.21.3",
22
- "@webiny/icons": "6.5.0-beta.0",
23
- "@webiny/react-composition": "6.5.0-beta.0",
24
- "@webiny/utils": "6.5.0-beta.0",
22
+ "@webiny/icons": "6.5.0-beta.2",
23
+ "@webiny/react-composition": "6.5.0-beta.2",
24
+ "@webiny/utils": "6.5.0-beta.2",
25
25
  "bytes": "3.1.2",
26
26
  "class-variance-authority": "0.7.1",
27
27
  "clsx": "2.1.1",
@@ -56,8 +56,8 @@
56
56
  "@types/react-color": "3.0.13",
57
57
  "@types/react-custom-scrollbars": "4.0.13",
58
58
  "@types/react-virtualized": "9.22.3",
59
- "@webiny/build-tools": "6.5.0-beta.0",
60
- "@webiny/project": "6.5.0-beta.0",
59
+ "@webiny/build-tools": "6.5.0-beta.2",
60
+ "@webiny/project": "6.5.0-beta.2",
61
61
  "chalk": "5.6.2",
62
62
  "oxfmt": "0.59.0",
63
63
  "rimraf": "6.1.3",
package/theme.css CHANGED
@@ -366,6 +366,34 @@
366
366
  @apply bg-neutral-light;
367
367
  }
368
368
 
369
+ /*
370
+ * A Select hides its scrollbar and offers scroll buttons instead, which leaves a long list looking
371
+ * like it ends where it is cut off. These rules bring the scrollbar back, shaped like the thumb
372
+ * `ScrollArea` draws, so the two kinds of dropdown read the same. Radix injects the rules that hide
373
+ * it when the list opens, hence `!important`.
374
+ */
375
+ [data-radix-select-viewport] {
376
+ /* Back to the initial value, both to undo Radix and because Chrome drops the rules below when
377
+ `scrollbar-width` or `scrollbar-color` say anything else. */
378
+ scrollbar-width: auto !important;
379
+ }
380
+
381
+ [data-radix-select-viewport]::-webkit-scrollbar {
382
+ display: block !important;
383
+ width: 10px;
384
+ }
385
+
386
+ [data-radix-select-viewport]::-webkit-scrollbar-track {
387
+ background: transparent;
388
+ }
389
+
390
+ [data-radix-select-viewport]::-webkit-scrollbar-thumb {
391
+ background-color: color-mix(in oklab, var(--color-neutral-strong) 70%, transparent);
392
+ background-clip: content-box;
393
+ border: 2px solid transparent;
394
+ border-radius: calc(infinity * 1px);
395
+ }
396
+
369
397
  @layer base {
370
398
  a {
371
399
  @apply text-accent-primary hover:underline focus-visible:outline-none focus-visible:ring-lg focus-visible:ring-primary-dimmed rounded-xs;