@webiny/admin-ui 6.6.0-alpha.8 → 6.6.0-alpha.9

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.
Files changed (51) hide show
  1. package/Command/components/List.d.ts +1 -1
  2. package/Command/components/List.js +9 -5
  3. package/Command/components/List.js.map +1 -1
  4. package/FilePicker/primitives/components/previews/ItemActions.js +1 -1
  5. package/FilePicker/primitives/components/previews/ItemActions.js.map +1 -1
  6. package/FilePicker/primitives/components/previews/RichItemPreview/FileType.d.ts +5 -0
  7. package/FilePicker/primitives/components/previews/RichItemPreview/FileType.js +45 -0
  8. package/FilePicker/primitives/components/previews/RichItemPreview/FileType.js.map +1 -0
  9. package/FilePicker/primitives/components/previews/RichItemPreview/Placeholder.d.ts +5 -0
  10. package/FilePicker/primitives/components/previews/RichItemPreview/Placeholder.js +14 -0
  11. package/FilePicker/primitives/components/previews/RichItemPreview/Placeholder.js.map +1 -0
  12. package/FilePicker/primitives/components/previews/RichItemPreview/RichItemPreview.js +52 -11
  13. package/FilePicker/primitives/components/previews/RichItemPreview/RichItemPreview.js.map +1 -1
  14. package/FilePicker/primitives/components/previews/RichItemPreview/RichItemThumbnail.d.ts +5 -4
  15. package/FilePicker/primitives/components/previews/RichItemPreview/RichItemThumbnail.js +9 -66
  16. package/FilePicker/primitives/components/previews/RichItemPreview/RichItemThumbnail.js.map +1 -1
  17. package/FilePicker/primitives/components/previews/RichItemPreview/Thumbnail.d.ts +11 -0
  18. package/FilePicker/primitives/components/previews/RichItemPreview/Thumbnail.js +24 -0
  19. package/FilePicker/primitives/components/previews/RichItemPreview/Thumbnail.js.map +1 -0
  20. package/FilePicker/primitives/components/previews/RichItemPreview/ThumbnailActions.d.ts +10 -0
  21. package/FilePicker/primitives/components/previews/RichItemPreview/ThumbnailActions.js +46 -0
  22. package/FilePicker/primitives/components/previews/RichItemPreview/ThumbnailActions.js.map +1 -0
  23. package/FilePicker/primitives/components/previews/TruncatedFileName.d.ts +7 -0
  24. package/FilePicker/primitives/components/previews/TruncatedFileName.js +20 -0
  25. package/FilePicker/primitives/components/previews/TruncatedFileName.js.map +1 -0
  26. package/FilePicker/primitives/components/previews/fileName.d.ts +4 -0
  27. package/FilePicker/primitives/components/previews/fileName.js +26 -0
  28. package/FilePicker/primitives/components/previews/fileName.js.map +1 -0
  29. package/FilePicker/primitives/components/previews/index.d.ts +1 -0
  30. package/FilePicker/primitives/components/previews/index.js +1 -0
  31. package/IconPicker/primitives/IconPickerPrimitive.js +1 -2
  32. package/IconPicker/primitives/IconPickerPrimitive.js.map +1 -1
  33. package/Link/Link.d.ts +1 -1
  34. package/Link/Link.js +1 -1
  35. package/Link/Link.js.map +1 -1
  36. package/MultiSelect/primitives/MultiSelectPrimitive.js +6 -1
  37. package/MultiSelect/primitives/MultiSelectPrimitive.js.map +1 -1
  38. package/Popover/Popover.stories.d.ts +7 -0
  39. package/Popover/Popover.stories.js +24 -1
  40. package/Popover/Popover.stories.js.map +1 -1
  41. package/Popover/primitives/components/PopoverContent.js +6 -1
  42. package/Popover/primitives/components/PopoverContent.js.map +1 -1
  43. package/ScrollArea/ScrollArea.d.ts +12 -2
  44. package/ScrollArea/ScrollArea.js +9 -3
  45. package/ScrollArea/ScrollArea.js.map +1 -1
  46. package/hooks/index.d.ts +1 -0
  47. package/hooks/index.js +1 -0
  48. package/hooks/useEscapeScrollLock.d.ts +13 -0
  49. package/hooks/useEscapeScrollLock.js +21 -0
  50. package/hooks/useEscapeScrollLock.js.map +1 -0
  51. package/package.json +6 -6
@@ -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"}
@@ -11,7 +11,7 @@ const ItemActions = ({ disabled, onRemoveItem, onEditItem, onReplaceItem, small,
11
11
  return /*#__PURE__*/ react.createElement("div", {
12
12
  ...props,
13
13
  className: cn("flex justify-center items-center gap-xs", className)
14
- }, small && onReplaceItem && /*#__PURE__*/ react.createElement(IconButton, {
14
+ }, onReplaceItem && /*#__PURE__*/ react.createElement(IconButton, {
15
15
  icon: /*#__PURE__*/ react.createElement(Icon, {
16
16
  icon: /*#__PURE__*/ react.createElement(ReactComponent, null),
17
17
  label: "Replace",
@@ -1 +1 @@
1
- {"version":3,"file":"FilePicker/primitives/components/previews/ItemActions.js","sources":["../../../../../src/FilePicker/primitives/components/previews/ItemActions.tsx"],"sourcesContent":["import React from \"react\";\nimport { ReactComponent as ReplaceIcon } from \"@webiny/icons/file_upload.svg\";\nimport { ReactComponent as EditIcon } from \"@webiny/icons/edit.svg\";\nimport { ReactComponent as TrashIcon } from \"@webiny/icons/delete.svg\";\nimport { IconButton } from \"~/Button/index.js\";\nimport { Icon } from \"~/Icon/index.js\";\nimport { cn } from \"~/utils.js\";\n\ninterface ItemActionsProps extends React.HTMLAttributes<HTMLDivElement> {\n onRemoveItem?: () => void;\n onEditItem?: () => void;\n onReplaceItem?: () => void;\n disabled?: boolean;\n small?: boolean;\n}\n\nconst ItemActions = ({\n disabled,\n onRemoveItem,\n onEditItem,\n onReplaceItem,\n small,\n className,\n ...props\n}: ItemActionsProps) => {\n const iconSize = small ? \"default\" : \"lg\";\n const buttonSize = small ? \"xs\" : \"sm\";\n\n return (\n <div {...props} className={cn(\"flex justify-center items-center gap-xs\", className)}>\n {small && onReplaceItem && (\n <IconButton\n icon={\n <Icon\n icon={<ReplaceIcon />}\n label={\"Replace\"}\n size={\"md\"}\n color={\"neutral-light\"}\n />\n }\n variant={\"ghost\"}\n size={buttonSize}\n iconSize={iconSize}\n onClick={onReplaceItem}\n disabled={disabled}\n />\n )}\n\n {onEditItem && (\n <IconButton\n icon={\n <Icon\n icon={<EditIcon />}\n label={\"Edit\"}\n size={\"md\"}\n color={\"neutral-light\"}\n />\n }\n variant={\"ghost\"}\n size={buttonSize}\n iconSize={iconSize}\n onClick={onEditItem}\n disabled={disabled}\n />\n )}\n\n {onRemoveItem && (\n <IconButton\n icon={\n <Icon\n icon={<TrashIcon />}\n label={\"Remove\"}\n size={\"md\"}\n color={\"neutral-light\"}\n />\n }\n variant={\"ghost\"}\n size={buttonSize}\n iconSize={iconSize}\n onClick={onRemoveItem}\n disabled={disabled}\n />\n )}\n </div>\n );\n};\n\nexport { ItemActions, type ItemActionsProps };\n"],"names":["ItemActions","disabled","onRemoveItem","onEditItem","onReplaceItem","small","className","props","iconSize","buttonSize","cn","IconButton","Icon","ReplaceIcon","EditIcon","TrashIcon"],"mappings":";;;;;;;AAgBA,MAAMA,cAAc,CAAC,EACjBC,QAAQ,EACRC,YAAY,EACZC,UAAU,EACVC,aAAa,EACbC,KAAK,EACLC,SAAS,EACT,GAAGC,OACY;IACf,MAAMC,WAAWH,QAAQ,YAAY;IACrC,MAAMI,aAAaJ,QAAQ,OAAO;IAElC,OAAO,WAAP,GACI,oBAAC;QAAK,GAAGE,KAAK;QAAE,WAAWG,GAAG,2CAA2CJ;OACpED,SAASD,iBAAiB,WAAjBA,GACN,oBAACO,YAAUA;QACP,oBACI,oBAACC,MAAIA;YACD,oBAAM,oBAACC,gBAAWA;YAClB,OAAO;YACP,MAAM;YACN,OAAO;;QAGf,SAAS;QACT,MAAMJ;QACN,UAAUD;QACV,SAASJ;QACT,UAAUH;QAIjBE,cAAc,WAAdA,GACG,oBAACQ,YAAUA;QACP,oBACI,oBAACC,MAAIA;YACD,oBAAM,oBAACE,yBAAQA;YACf,OAAO;YACP,MAAM;YACN,OAAO;;QAGf,SAAS;QACT,MAAML;QACN,UAAUD;QACV,SAASL;QACT,UAAUF;QAIjBC,gBAAgB,WAAhBA,GACG,oBAACS,YAAUA;QACP,oBACI,oBAACC,MAAIA;YACD,oBAAM,oBAACG,2BAASA;YAChB,OAAO;YACP,MAAM;YACN,OAAO;;QAGf,SAAS;QACT,MAAMN;QACN,UAAUD;QACV,SAASN;QACT,UAAUD;;AAK9B"}
1
+ {"version":3,"file":"FilePicker/primitives/components/previews/ItemActions.js","sources":["../../../../../src/FilePicker/primitives/components/previews/ItemActions.tsx"],"sourcesContent":["import React from \"react\";\nimport { ReactComponent as ReplaceIcon } from \"@webiny/icons/file_upload.svg\";\nimport { ReactComponent as EditIcon } from \"@webiny/icons/edit.svg\";\nimport { ReactComponent as TrashIcon } from \"@webiny/icons/delete.svg\";\nimport { IconButton } from \"~/Button/index.js\";\nimport { Icon } from \"~/Icon/index.js\";\nimport { cn } from \"~/utils.js\";\n\ninterface ItemActionsProps extends React.HTMLAttributes<HTMLDivElement> {\n onRemoveItem?: () => void;\n onEditItem?: () => void;\n onReplaceItem?: () => void;\n disabled?: boolean;\n small?: boolean;\n}\n\nconst ItemActions = ({\n disabled,\n onRemoveItem,\n onEditItem,\n onReplaceItem,\n small,\n className,\n ...props\n}: ItemActionsProps) => {\n const iconSize = small ? \"default\" : \"lg\";\n const buttonSize = small ? \"xs\" : \"sm\";\n\n return (\n <div {...props} className={cn(\"flex justify-center items-center gap-xs\", className)}>\n {onReplaceItem && (\n <IconButton\n icon={\n <Icon\n icon={<ReplaceIcon />}\n label={\"Replace\"}\n size={\"md\"}\n color={\"neutral-light\"}\n />\n }\n variant={\"ghost\"}\n size={buttonSize}\n iconSize={iconSize}\n onClick={onReplaceItem}\n disabled={disabled}\n />\n )}\n\n {onEditItem && (\n <IconButton\n icon={\n <Icon\n icon={<EditIcon />}\n label={\"Edit\"}\n size={\"md\"}\n color={\"neutral-light\"}\n />\n }\n variant={\"ghost\"}\n size={buttonSize}\n iconSize={iconSize}\n onClick={onEditItem}\n disabled={disabled}\n />\n )}\n\n {onRemoveItem && (\n <IconButton\n icon={\n <Icon\n icon={<TrashIcon />}\n label={\"Remove\"}\n size={\"md\"}\n color={\"neutral-light\"}\n />\n }\n variant={\"ghost\"}\n size={buttonSize}\n iconSize={iconSize}\n onClick={onRemoveItem}\n disabled={disabled}\n />\n )}\n </div>\n );\n};\n\nexport { ItemActions, type ItemActionsProps };\n"],"names":["ItemActions","disabled","onRemoveItem","onEditItem","onReplaceItem","small","className","props","iconSize","buttonSize","cn","IconButton","Icon","ReplaceIcon","EditIcon","TrashIcon"],"mappings":";;;;;;;AAgBA,MAAMA,cAAc,CAAC,EACjBC,QAAQ,EACRC,YAAY,EACZC,UAAU,EACVC,aAAa,EACbC,KAAK,EACLC,SAAS,EACT,GAAGC,OACY;IACf,MAAMC,WAAWH,QAAQ,YAAY;IACrC,MAAMI,aAAaJ,QAAQ,OAAO;IAElC,OAAO,WAAP,GACI,oBAAC;QAAK,GAAGE,KAAK;QAAE,WAAWG,GAAG,2CAA2CJ;OACpEF,iBAAiB,WAAjBA,GACG,oBAACO,YAAUA;QACP,oBACI,oBAACC,MAAIA;YACD,oBAAM,oBAACC,gBAAWA;YAClB,OAAO;YACP,MAAM;YACN,OAAO;;QAGf,SAAS;QACT,MAAMJ;QACN,UAAUD;QACV,SAASJ;QACT,UAAUH;QAIjBE,cAAc,WAAdA,GACG,oBAACQ,YAAUA;QACP,oBACI,oBAACC,MAAIA;YACD,oBAAM,oBAACE,yBAAQA;YACf,OAAO;YACP,MAAM;YACN,OAAO;;QAGf,SAAS;QACT,MAAML;QACN,UAAUD;QACV,SAASL;QACT,UAAUF;QAIjBC,gBAAgB,WAAhBA,GACG,oBAACS,YAAUA;QACP,oBACI,oBAACC,MAAIA;YACD,oBAAM,oBAACG,2BAASA;YAChB,OAAO;YACP,MAAM;YACN,OAAO;;QAGf,SAAS;QACT,MAAMN;QACN,UAAUD;QACV,SAASN;QACT,UAAUD;;AAK9B"}
@@ -0,0 +1,5 @@
1
+ import React from "react";
2
+ import type { FileItemFormatted } from "../../../../../FilePicker/index.js";
3
+ type FileTypeProps = Pick<FileItemFormatted, "mimeType" | "name">;
4
+ declare const FileType: ({ mimeType, name }: FileTypeProps) => React.JSX.Element;
5
+ export { FileType, type FileTypeProps };
@@ -0,0 +1,45 @@
1
+ import react from "react";
2
+ import csv from "../assets/csv.js";
3
+ import doc from "../assets/doc.js";
4
+ import docx from "../assets/docx.js";
5
+ import file from "../assets/file.js";
6
+ import pdf from "../assets/pdf.js";
7
+ import ppt from "../assets/ppt.js";
8
+ import pptx from "../assets/pptx.js";
9
+ import txt from "../assets/txt.js";
10
+ import xls from "../assets/xls.js";
11
+ import xlsx from "../assets/xlsx.js";
12
+ const FileType = ({ mimeType = "", name })=>{
13
+ const getMimeTypeSrc = (mimeType)=>{
14
+ switch(mimeType){
15
+ case "text/csv":
16
+ return csv;
17
+ case "application/msword":
18
+ return doc;
19
+ case "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
20
+ return docx;
21
+ case "application/pdf":
22
+ return pdf;
23
+ case "application/vnd.ms-powerpoint":
24
+ return ppt;
25
+ case "application/vnd.openxmlformats-officedocument.presentationml.presentation":
26
+ return pptx;
27
+ case "text/plain":
28
+ return txt;
29
+ case "application/vnd.ms-excel":
30
+ return xls;
31
+ case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":
32
+ return xlsx;
33
+ default:
34
+ return file;
35
+ }
36
+ };
37
+ return /*#__PURE__*/ react.createElement("img", {
38
+ src: getMimeTypeSrc(mimeType),
39
+ alt: name,
40
+ className: "size-full object-contain p-sm-extra"
41
+ });
42
+ };
43
+ export { FileType };
44
+
45
+ //# sourceMappingURL=FileType.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FilePicker/primitives/components/previews/RichItemPreview/FileType.js","sources":["../../../../../../src/FilePicker/primitives/components/previews/RichItemPreview/FileType.tsx"],"sourcesContent":["import React from \"react\";\nimport type { FileItemFormatted } from \"~/FilePicker/index.js\";\n\nimport csvThumb from \"../assets/csv.svg\";\nimport docThumb from \"../assets/doc.svg\";\nimport docxThumb from \"../assets/docx.svg\";\nimport fileThumb from \"../assets/file.svg\";\nimport pdfThumb from \"../assets/pdf.svg\";\nimport pptThumb from \"../assets/ppt.svg\";\nimport pptxThumb from \"../assets/pptx.svg\";\nimport txtThumb from \"../assets/txt.svg\";\nimport xlsThumb from \"../assets/xls.svg\";\nimport xlsxThumb from \"../assets/xlsx.svg\";\n\ntype FileTypeProps = Pick<FileItemFormatted, \"mimeType\" | \"name\">;\n\nconst FileType = ({ mimeType = \"\", name }: FileTypeProps) => {\n const getMimeTypeSrc = (mimeType: string) => {\n switch (mimeType) {\n case \"text/csv\": // .csv\n return csvThumb;\n case \"application/msword\": // .doc\n return docThumb;\n case \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\": // .docx\n return docxThumb;\n case \"application/pdf\": // .pdf\n return pdfThumb;\n case \"application/vnd.ms-powerpoint\": // .ppt\n return pptThumb;\n case \"application/vnd.openxmlformats-officedocument.presentationml.presentation\": // .pptx\n return pptxThumb;\n case \"text/plain\": // .txt\n return txtThumb;\n case \"application/vnd.ms-excel\": // .xls\n return xlsThumb;\n case \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\": // .xlsx\n return xlsxThumb;\n default:\n return fileThumb;\n }\n };\n\n return (\n <img\n src={getMimeTypeSrc(mimeType)}\n alt={name}\n className=\"size-full object-contain p-sm-extra\"\n />\n );\n};\n\nexport { FileType, type FileTypeProps };\n"],"names":["FileType","mimeType","name","getMimeTypeSrc","csvThumb","docThumb","docxThumb","pdfThumb","pptThumb","pptxThumb","txtThumb","xlsThumb","xlsxThumb","fileThumb"],"mappings":";;;;;;;;;;;AAgBA,MAAMA,WAAW,CAAC,EAAEC,WAAW,EAAE,EAAEC,IAAI,EAAiB;IACpD,MAAMC,iBAAiB,CAACF;QACpB,OAAQA;YACJ,KAAK;gBACD,OAAOG;YACX,KAAK;gBACD,OAAOC;YACX,KAAK;gBACD,OAAOC;YACX,KAAK;gBACD,OAAOC;YACX,KAAK;gBACD,OAAOC;YACX,KAAK;gBACD,OAAOC;YACX,KAAK;gBACD,OAAOC;YACX,KAAK;gBACD,OAAOC;YACX,KAAK;gBACD,OAAOC;YACX;gBACI,OAAOC;QACf;IACJ;IAEA,OAAO,WAAP,GACI,oBAAC;QACG,KAAKV,eAAeF;QACpB,KAAKC;QACL,WAAU;;AAGtB"}
@@ -0,0 +1,5 @@
1
+ import React from "react";
2
+ import type { FileItemFormatted } from "../../../../../FilePicker/index.js";
3
+ type PlaceholderProps = Pick<FileItemFormatted, "name">;
4
+ declare const Placeholder: ({ name }: PlaceholderProps) => React.JSX.Element;
5
+ export { Placeholder, type PlaceholderProps };
@@ -0,0 +1,14 @@
1
+ import react from "react";
2
+ import { ReactComponent } from "@webiny/icons/image.svg";
3
+ import { Icon } from "../../../../../Icon/index.js";
4
+ const Placeholder = ({ name })=>/*#__PURE__*/ react.createElement("div", {
5
+ className: "size-full flex justify-center items-center bg-transparent"
6
+ }, /*#__PURE__*/ react.createElement(Icon, {
7
+ icon: /*#__PURE__*/ react.createElement(ReactComponent, null),
8
+ label: name,
9
+ size: "lg",
10
+ color: "neutral-light"
11
+ }));
12
+ export { Placeholder };
13
+
14
+ //# sourceMappingURL=Placeholder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FilePicker/primitives/components/previews/RichItemPreview/Placeholder.js","sources":["../../../../../../src/FilePicker/primitives/components/previews/RichItemPreview/Placeholder.tsx"],"sourcesContent":["import React from \"react\";\nimport { ReactComponent as PlaceholderIcon } from \"@webiny/icons/image.svg\";\nimport type { FileItemFormatted } from \"~/FilePicker/index.js\";\nimport { Icon } from \"~/Icon/index.js\";\n\ntype PlaceholderProps = Pick<FileItemFormatted, \"name\">;\n\nconst Placeholder = ({ name }: PlaceholderProps) => {\n return (\n <div className={\"size-full flex justify-center items-center bg-transparent\"}>\n <Icon icon={<PlaceholderIcon />} label={name} size={\"lg\"} color={\"neutral-light\"} />\n </div>\n );\n};\n\nexport { Placeholder, type PlaceholderProps };\n"],"names":["Placeholder","name","Icon","PlaceholderIcon"],"mappings":";;;AAOA,MAAMA,cAAc,CAAC,EAAEC,IAAI,EAAoB,GACpC,WAAP,GACI,oBAAC;QAAI,WAAW;qBACZ,oBAACC,MAAIA;QAAC,oBAAM,oBAACC,gBAAeA;QAAK,OAAOF;QAAM,MAAM;QAAM,OAAO"}
@@ -1,37 +1,78 @@
1
1
  import react from "react";
2
+ import bytes from "bytes";
2
3
  import { cn, makeDecoratable } from "../../../../../utils.js";
4
+ import { Text } from "../../../../../Text/index.js";
3
5
  import { RichItemThumbnail } from "./RichItemThumbnail.js";
6
+ import { ThumbnailActions } from "./ThumbnailActions.js";
4
7
  import { ItemDescription } from "../ItemDescription.js";
5
8
  import { ItemActions } from "../ItemActions.js";
9
+ import { TruncatedFileName } from "../TruncatedFileName.js";
6
10
  import { previewVariants } from "../variants.js";
7
- const DecoratableRichItemPreview = ({ className, disabled, onRemoveItem, onReplaceItem, onEditItem, value, variant, preview, renderImage, ...props })=>/*#__PURE__*/ react.createElement("div", {
11
+ const DecoratableRichItemPreview = ({ className, disabled, onRemoveItem, onReplaceItem, onEditItem, value, variant, preview, renderImage, ...props })=>{
12
+ const actions = {
13
+ onRemoveItem,
14
+ onReplaceItem,
15
+ onEditItem,
16
+ disabled
17
+ };
18
+ const formattedSize = value.size ? bytes.format(value.size, {
19
+ unitSeparator: " ",
20
+ decimalPlaces: 0
21
+ }) : "";
22
+ const details = [
23
+ value.mimeType,
24
+ formattedSize
25
+ ].filter(Boolean).join(" - ");
26
+ return /*#__PURE__*/ react.createElement("div", {
8
27
  "data-testid": "image-preview",
9
- className: cn("w-full rounded-md", previewVariants({
28
+ className: cn("w-full rounded-md @container", previewVariants({
10
29
  variant,
11
30
  disabled
12
31
  }), className),
13
32
  ...props
14
33
  }, /*#__PURE__*/ react.createElement("div", {
15
34
  "data-role": "select-image",
16
- className: "flex items-center justify-between gap-sm-extra min-w-0"
35
+ className: "@min-[280px]:hidden"
17
36
  }, /*#__PURE__*/ react.createElement("div", {
18
- className: "flex items-center justify-between flex-1 cursor-pointer gap-sm-extra self-stretch min-w-0",
37
+ className: "flex flex-col gap-xs p-xs"
38
+ }, /*#__PURE__*/ react.createElement("div", {
39
+ className: "group relative cursor-pointer",
40
+ onClick: onReplaceItem
41
+ }, /*#__PURE__*/ react.createElement(RichItemThumbnail, {
42
+ ...value,
43
+ variant: "banner",
44
+ disabled: disabled,
45
+ preview: preview,
46
+ renderImage: renderImage
47
+ }), /*#__PURE__*/ react.createElement(ThumbnailActions, actions)), /*#__PURE__*/ react.createElement("div", {
48
+ className: "flex flex-col gap-xxs min-w-0 px-xxs pb-xxs"
49
+ }, /*#__PURE__*/ react.createElement(TruncatedFileName, {
50
+ name: value.name,
51
+ className: disabled ? "text-neutral-disabled" : "text-neutral-primary"
52
+ }), details ? /*#__PURE__*/ react.createElement(Text, {
53
+ size: "sm",
54
+ className: cn("truncate", disabled ? "text-neutral-disabled" : "text-neutral-muted")
55
+ }, details) : null))), /*#__PURE__*/ react.createElement("div", {
56
+ "data-role": "select-image",
57
+ className: "hidden @min-[280px]:flex items-center gap-sm-extra min-w-0"
58
+ }, /*#__PURE__*/ react.createElement("div", {
59
+ className: "shrink-0 cursor-pointer",
19
60
  onClick: onReplaceItem
20
61
  }, /*#__PURE__*/ react.createElement(RichItemThumbnail, {
21
62
  ...value,
22
63
  disabled: disabled,
23
64
  preview: preview,
24
65
  renderImage: renderImage
25
- }), /*#__PURE__*/ react.createElement(ItemDescription, {
66
+ })), /*#__PURE__*/ react.createElement(ItemDescription, {
26
67
  item: value,
27
- disabled: disabled
28
- })), /*#__PURE__*/ react.createElement(ItemActions, {
29
- onRemoveItem: onRemoveItem,
30
- onReplaceItem: onReplaceItem,
31
- onEditItem: onEditItem,
32
68
  disabled: disabled,
33
- className: "pr-sm-extra"
69
+ onClick: onReplaceItem,
70
+ className: "grow basis-0 cursor-pointer"
71
+ }), /*#__PURE__*/ react.createElement(ItemActions, {
72
+ ...actions,
73
+ className: "ml-auto pr-sm-extra"
34
74
  })));
75
+ };
35
76
  const RichItemPreview = makeDecoratable("RichItemPreview", DecoratableRichItemPreview);
36
77
  export { RichItemPreview };
37
78
 
@@ -1 +1 @@
1
- {"version":3,"file":"FilePicker/primitives/components/previews/RichItemPreview/RichItemPreview.js","sources":["../../../../../../src/FilePicker/primitives/components/previews/RichItemPreview/RichItemPreview.tsx"],"sourcesContent":["import React from \"react\";\nimport { cn, makeDecoratable } from \"~/utils.js\";\nimport { RichItemThumbnail } from \"./RichItemThumbnail.js\";\nimport { ItemDescription } from \"../ItemDescription.js\";\nimport { ItemActions } from \"~/FilePicker/primitives/components/previews/ItemActions.js\";\nimport { previewVariants } from \"../variants.js\";\nimport type { FilePreviewDefaultProps } from \"../../types.js\";\n\ntype RichItemPreviewProps = FilePreviewDefaultProps & {\n preview?: \"thumbnail\" | \"file-type\" | \"placeholder\";\n /** Optional custom image renderer for the thumbnail (e.g. a cropped preview). */\n renderImage?: (args: { url: string; name: string }) => React.ReactNode;\n};\n\nconst DecoratableRichItemPreview = ({\n className,\n disabled,\n onRemoveItem,\n onReplaceItem,\n onEditItem,\n value,\n variant,\n preview,\n renderImage,\n ...props\n}: RichItemPreviewProps) => {\n return (\n <div\n data-testid=\"image-preview\"\n className={cn(\"w-full rounded-md\", previewVariants({ variant, disabled }), className)}\n {...props}\n >\n <div\n data-role=\"select-image\"\n className=\"flex items-center justify-between gap-sm-extra min-w-0\"\n >\n <div\n className=\"flex items-center justify-between flex-1 cursor-pointer gap-sm-extra self-stretch min-w-0\"\n onClick={onReplaceItem}\n >\n <RichItemThumbnail\n {...value}\n disabled={disabled}\n preview={preview}\n renderImage={renderImage}\n />\n <ItemDescription item={value} disabled={disabled} />\n </div>\n\n <ItemActions\n onRemoveItem={onRemoveItem}\n onReplaceItem={onReplaceItem}\n onEditItem={onEditItem}\n disabled={disabled}\n className={\"pr-sm-extra\"}\n />\n </div>\n </div>\n );\n};\n\nconst RichItemPreview = makeDecoratable(\"RichItemPreview\", DecoratableRichItemPreview);\n\nexport { RichItemPreview, type RichItemPreviewProps };\n"],"names":["DecoratableRichItemPreview","className","disabled","onRemoveItem","onReplaceItem","onEditItem","value","variant","preview","renderImage","props","cn","previewVariants","RichItemThumbnail","ItemDescription","ItemActions","RichItemPreview","makeDecoratable"],"mappings":";;;;;;AAcA,MAAMA,6BAA6B,CAAC,EAChCC,SAAS,EACTC,QAAQ,EACRC,YAAY,EACZC,aAAa,EACbC,UAAU,EACVC,KAAK,EACLC,OAAO,EACPC,OAAO,EACPC,WAAW,EACX,GAAGC,OACgB,GACZ,WAAP,GACI,oBAAC;QACG,eAAY;QACZ,WAAWC,GAAG,qBAAqBC,gBAAgB;YAAEL;YAASL;QAAS,IAAID;QAC1E,GAAGS,KAAK;qBAET,oBAAC;QACG,aAAU;QACV,WAAU;qBAEV,oBAAC;QACG,WAAU;QACV,SAASN;qBAET,oBAACS,mBAAiBA;QACb,GAAGP,KAAK;QACT,UAAUJ;QACV,SAASM;QACT,aAAaC;sBAEjB,oBAACK,iBAAeA;QAAC,MAAMR;QAAO,UAAUJ;uBAG5C,oBAACa,aAAWA;QACR,cAAcZ;QACd,eAAeC;QACf,YAAYC;QACZ,UAAUH;QACV,WAAW;;AAO/B,MAAMc,kBAAkBC,gBAAgB,mBAAmBjB"}
1
+ {"version":3,"file":"FilePicker/primitives/components/previews/RichItemPreview/RichItemPreview.js","sources":["../../../../../../src/FilePicker/primitives/components/previews/RichItemPreview/RichItemPreview.tsx"],"sourcesContent":["import React from \"react\";\nimport bytes from \"bytes\";\nimport { cn, makeDecoratable } from \"~/utils.js\";\nimport { Text } from \"~/Text/index.js\";\nimport { RichItemThumbnail } from \"./RichItemThumbnail.js\";\nimport { ThumbnailActions } from \"./ThumbnailActions.js\";\nimport { ItemDescription } from \"../ItemDescription.js\";\nimport { ItemActions } from \"~/FilePicker/primitives/components/previews/ItemActions.js\";\nimport { TruncatedFileName } from \"../TruncatedFileName.js\";\nimport { previewVariants } from \"../variants.js\";\nimport type { FilePreviewDefaultProps } from \"../../types.js\";\n\ntype RichItemPreviewProps = FilePreviewDefaultProps & {\n preview?: \"thumbnail\" | \"file-type\" | \"placeholder\";\n /** Optional custom image renderer for the thumbnail (e.g. a cropped preview). */\n renderImage?: (args: { url: string; name: string }) => React.ReactNode;\n};\n\nconst DecoratableRichItemPreview = ({\n className,\n disabled,\n onRemoveItem,\n onReplaceItem,\n onEditItem,\n value,\n variant,\n preview,\n renderImage,\n ...props\n}: RichItemPreviewProps) => {\n const actions = { onRemoveItem, onReplaceItem, onEditItem, disabled };\n\n const formattedSize = value.size\n ? bytes.format(value.size, { unitSeparator: \" \", decimalPlaces: 0 })\n : \"\";\n const details = [value.mimeType, formattedSize].filter(Boolean).join(\" - \");\n\n return (\n <div\n data-testid=\"image-preview\"\n className={cn(\n \"w-full rounded-md @container\",\n previewVariants({ variant, disabled }),\n className\n )}\n {...props}\n >\n {/* Stacked layout for narrow containers (below 280px). */}\n <div data-role=\"select-image\" className={\"@min-[280px]:hidden\"}>\n <div className={\"flex flex-col gap-xs p-xs\"}>\n <div className={\"group relative cursor-pointer\"} onClick={onReplaceItem}>\n <RichItemThumbnail\n {...value}\n variant={\"banner\"}\n disabled={disabled}\n preview={preview}\n renderImage={renderImage}\n />\n <ThumbnailActions {...actions} />\n </div>\n\n <div className={\"flex flex-col gap-xxs min-w-0 px-xxs pb-xxs\"}>\n <TruncatedFileName\n name={value.name}\n className={disabled ? \"text-neutral-disabled\" : \"text-neutral-primary\"}\n />\n {details ? (\n <Text\n size=\"sm\"\n className={cn(\n \"truncate\",\n disabled ? \"text-neutral-disabled\" : \"text-neutral-muted\"\n )}\n >\n {details}\n </Text>\n ) : null}\n </div>\n </div>\n </div>\n\n {/* Side-by-side layout for wider containers (280px+). */}\n <div\n data-role=\"select-image\"\n className={\"hidden @min-[280px]:flex items-center gap-sm-extra min-w-0\"}\n >\n <div className={\"shrink-0 cursor-pointer\"} onClick={onReplaceItem}>\n <RichItemThumbnail\n {...value}\n disabled={disabled}\n preview={preview}\n renderImage={renderImage}\n />\n </div>\n\n <ItemDescription\n item={value}\n disabled={disabled}\n onClick={onReplaceItem}\n className={\"grow basis-0 cursor-pointer\"}\n />\n\n <ItemActions {...actions} className={\"ml-auto pr-sm-extra\"} />\n </div>\n </div>\n );\n};\n\nconst RichItemPreview = makeDecoratable(\"RichItemPreview\", DecoratableRichItemPreview);\n\nexport { RichItemPreview, type RichItemPreviewProps };\n"],"names":["DecoratableRichItemPreview","className","disabled","onRemoveItem","onReplaceItem","onEditItem","value","variant","preview","renderImage","props","actions","formattedSize","bytes","details","Boolean","cn","previewVariants","RichItemThumbnail","ThumbnailActions","TruncatedFileName","Text","ItemDescription","ItemActions","RichItemPreview","makeDecoratable"],"mappings":";;;;;;;;;;AAkBA,MAAMA,6BAA6B,CAAC,EAChCC,SAAS,EACTC,QAAQ,EACRC,YAAY,EACZC,aAAa,EACbC,UAAU,EACVC,KAAK,EACLC,OAAO,EACPC,OAAO,EACPC,WAAW,EACX,GAAGC,OACgB;IACnB,MAAMC,UAAU;QAAER;QAAcC;QAAeC;QAAYH;IAAS;IAEpE,MAAMU,gBAAgBN,MAAM,IAAI,GAC1BO,MAAM,MAAM,CAACP,MAAM,IAAI,EAAE;QAAE,eAAe;QAAK,eAAe;IAAE,KAChE;IACN,MAAMQ,UAAU;QAACR,MAAM,QAAQ;QAAEM;KAAc,CAAC,MAAM,CAACG,SAAS,IAAI,CAAC;IAErE,OAAO,WAAP,GACI,oBAAC;QACG,eAAY;QACZ,WAAWC,GACP,gCACAC,gBAAgB;YAAEV;YAASL;QAAS,IACpCD;QAEH,GAAGS,KAAK;qBAGT,oBAAC;QAAI,aAAU;QAAe,WAAW;qBACrC,oBAAC;QAAI,WAAW;qBACZ,oBAAC;QAAI,WAAW;QAAiC,SAASN;qBACtD,oBAACc,mBAAiBA;QACb,GAAGZ,KAAK;QACT,SAAS;QACT,UAAUJ;QACV,SAASM;QACT,aAAaC;sBAEjB,oBAACU,kBAAqBR,WAAAA,WAAAA,GAG1B,oBAAC;QAAI,WAAW;qBACZ,oBAACS,mBAAiBA;QACd,MAAMd,MAAM,IAAI;QAChB,WAAWJ,WAAW,0BAA0B;QAEnDY,UAAU,WAAVA,GACG,oBAACO,MAAIA;QACD,MAAK;QACL,WAAWL,GACP,YACAd,WAAW,0BAA0B;OAGxCY,WAEL,uBAMhB,oBAAC;QACG,aAAU;QACV,WAAW;qBAEX,oBAAC;QAAI,WAAW;QAA2B,SAASV;qBAChD,oBAACc,mBAAiBA;QACb,GAAGZ,KAAK;QACT,UAAUJ;QACV,SAASM;QACT,aAAaC;uBAIrB,oBAACa,iBAAeA;QACZ,MAAMhB;QACN,UAAUJ;QACV,SAASE;QACT,WAAW;sBAGf,oBAACmB,aAAWA;QAAE,GAAGZ,OAAO;QAAE,WAAW;;AAIrD;AAEA,MAAMa,kBAAkBC,gBAAgB,mBAAmBzB"}
@@ -5,14 +5,15 @@ type RichItemThumbnailProps = Omit<React.HTMLAttributes<HTMLDivElement>, "childr
5
5
  preview?: RichItemPreviewProps["preview"];
6
6
  disabled?: boolean;
7
7
  /**
8
- * Optional custom image renderer for image thumbnails (e.g. a cropped /
9
- * focal-point-aware image). Falls back to the default `<img>` when omitted
10
- * or when it returns a falsy value.
8
+ * `tile` is the fixed square that sits beside the file details; `banner` spans the full
9
+ * width of a stacked layout, where the panel is too narrow to afford a column for it.
11
10
  */
11
+ variant?: "tile" | "banner";
12
+ /** Optional custom image renderer for the thumbnail (e.g. a cropped preview). */
12
13
  renderImage?: (args: {
13
14
  url: string;
14
15
  name: string;
15
16
  }) => React.ReactNode;
16
17
  };
17
- declare const RichItemThumbnail: ({ url, name, className, mimeType, preview, disabled, renderImage }: RichItemThumbnailProps) => React.JSX.Element;
18
+ declare const RichItemThumbnail: ({ url, name, className, mimeType, preview, disabled, variant, renderImage }: RichItemThumbnailProps) => React.JSX.Element;
18
19
  export { RichItemThumbnail, type RichItemThumbnailProps };
@@ -1,74 +1,17 @@
1
1
  import react from "react";
2
- import { ReactComponent } from "@webiny/icons/image.svg";
3
- import { Icon } from "../../../../../Icon/index.js";
4
2
  import { cn } from "../../../../../utils.js";
5
- import csv from "../assets/csv.js";
6
- import doc from "../assets/doc.js";
7
- import docx from "../assets/docx.js";
8
- import file from "../assets/file.js";
9
- import pdf from "../assets/pdf.js";
10
- import ppt from "../assets/ppt.js";
11
- import pptx from "../assets/pptx.js";
12
- import txt from "../assets/txt.js";
13
- import xls from "../assets/xls.js";
14
- import xlsx from "../assets/xlsx.js";
15
- const Thumbnail = ({ url, name })=>/*#__PURE__*/ react.createElement("div", {
16
- className: "size-full bg-neutral-muted"
17
- }, /*#__PURE__*/ react.createElement("img", {
18
- src: url,
19
- alt: name,
20
- className: "size-full object-cover"
21
- }));
22
- const FileType = ({ mimeType = "", name })=>{
23
- const getMimeTypeSrc = (mimeType)=>{
24
- switch(mimeType){
25
- case "text/csv":
26
- return csv;
27
- case "application/msword":
28
- return doc;
29
- case "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
30
- return docx;
31
- case "application/pdf":
32
- return pdf;
33
- case "application/vnd.ms-powerpoint":
34
- return ppt;
35
- case "application/vnd.openxmlformats-officedocument.presentationml.presentation":
36
- return pptx;
37
- case "text/plain":
38
- return txt;
39
- case "application/vnd.ms-excel":
40
- return xls;
41
- case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":
42
- return xlsx;
43
- default:
44
- return file;
45
- }
46
- };
47
- return /*#__PURE__*/ react.createElement("img", {
48
- src: getMimeTypeSrc(mimeType),
49
- alt: name,
50
- className: "size-full p-sm-extra"
51
- });
52
- };
53
- const Placeholder = ({ name })=>/*#__PURE__*/ react.createElement("div", {
54
- className: "size-full flex justify-center items-center bg-transparent"
55
- }, /*#__PURE__*/ react.createElement(Icon, {
56
- icon: /*#__PURE__*/ react.createElement(ReactComponent, null),
57
- label: name,
58
- size: "lg",
59
- color: "neutral-light"
60
- }));
61
- const RichItemThumbnail = ({ url, name, className, mimeType, preview, disabled, renderImage })=>{
3
+ import { FileType } from "./FileType.js";
4
+ import { Placeholder } from "./Placeholder.js";
5
+ import { Thumbnail } from "./Thumbnail.js";
6
+ const RichItemThumbnail = ({ url, name, className, mimeType, preview, disabled, variant = "tile", renderImage })=>{
62
7
  const isImage = mimeType?.startsWith("image/");
63
- const customImage = "function" == typeof renderImage ? renderImage({
64
- url,
65
- name
66
- }) : false;
67
8
  return /*#__PURE__*/ react.createElement("div", {
68
- className: cn("size-[56px] m-xs rounded-sm overflow-hidden relative", disabled && "[&_img]:filter [&_img]:grayscale [&_img]:opacity-50", className)
69
- }, "thumbnail" === preview || isImage ? customImage || /*#__PURE__*/ react.createElement(Thumbnail, {
9
+ className: cn("rounded-sm overflow-hidden relative", "banner" === variant ? "w-full h-[96px]" : "size-[56px] m-xs", disabled && "[&_img]:filter [&_img]:grayscale [&_img]:opacity-50", className)
10
+ }, "thumbnail" === preview || isImage ? /*#__PURE__*/ react.createElement(Thumbnail, {
70
11
  url: url,
71
- name: name
12
+ name: name,
13
+ fit: "banner" === variant ? "contain" : "cover",
14
+ renderImage: renderImage
72
15
  }) : "placeholder" === preview ? /*#__PURE__*/ react.createElement(Placeholder, {
73
16
  name: name
74
17
  }) : /*#__PURE__*/ react.createElement(FileType, {
@@ -1 +1 @@
1
- {"version":3,"file":"FilePicker/primitives/components/previews/RichItemPreview/RichItemThumbnail.js","sources":["../../../../../../src/FilePicker/primitives/components/previews/RichItemPreview/RichItemThumbnail.tsx"],"sourcesContent":["import React from \"react\";\nimport { ReactComponent as PlaceholderIcon } from \"@webiny/icons/image.svg\";\nimport type { FileItemFormatted } from \"~/FilePicker/index.js\";\nimport { Icon } from \"~/Icon/index.js\";\nimport { cn } from \"~/utils.js\";\nimport type { RichItemPreviewProps } from \"~/FilePicker/primitives/components/index.js\";\n\nimport csvThumb from \"../assets/csv.svg\";\nimport docThumb from \"../assets/doc.svg\";\nimport docxThumb from \"../assets/docx.svg\";\nimport fileThumb from \"../assets/file.svg\";\nimport pdfThumb from \"../assets/pdf.svg\";\nimport pptThumb from \"../assets/ppt.svg\";\nimport pptxThumb from \"../assets/pptx.svg\";\nimport txtThumb from \"../assets/txt.svg\";\nimport xlsThumb from \"../assets/xls.svg\";\nimport xlsxThumb from \"../assets/xlsx.svg\";\n\ntype RichItemThumbnailProps = Omit<React.HTMLAttributes<HTMLDivElement>, \"children\"> &\n FileItemFormatted & {\n preview?: RichItemPreviewProps[\"preview\"];\n disabled?: boolean;\n /**\n * Optional custom image renderer for image thumbnails (e.g. a cropped /\n * focal-point-aware image). Falls back to the default `<img>` when omitted\n * or when it returns a falsy value.\n */\n renderImage?: (args: { url: string; name: string }) => React.ReactNode;\n };\n\ntype ThumbnailProps = Pick<FileItemFormatted, \"url\" | \"name\">;\n\nconst Thumbnail = ({ url, name }: ThumbnailProps) => {\n return (\n <div className={\"size-full bg-neutral-muted\"}>\n <img src={url} alt={name} className=\"size-full object-cover\" />\n </div>\n );\n};\n\ntype FileTypeProps = Pick<FileItemFormatted, \"mimeType\" | \"name\">;\n\nconst FileType = ({ mimeType = \"\", name }: FileTypeProps) => {\n const getMimeTypeSrc = (mimeType: string) => {\n switch (mimeType) {\n case \"text/csv\": // .csv\n return csvThumb;\n case \"application/msword\": // .doc\n return docThumb;\n case \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\": // .docx\n return docxThumb;\n case \"application/pdf\": // .pdf\n return pdfThumb;\n case \"application/vnd.ms-powerpoint\": // .ppt\n return pptThumb;\n case \"application/vnd.openxmlformats-officedocument.presentationml.presentation\": // .pptx\n return pptxThumb;\n case \"text/plain\": // .txt\n return txtThumb;\n case \"application/vnd.ms-excel\": // .xls\n return xlsThumb;\n case \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\": // .xlsx\n return xlsxThumb;\n default:\n return fileThumb;\n }\n };\n\n return <img src={getMimeTypeSrc(mimeType)} alt={name} className=\"size-full p-sm-extra\" />;\n};\n\ntype PlaceholderProps = Pick<FileItemFormatted, \"name\">;\n\nconst Placeholder = ({ name }: PlaceholderProps) => {\n return (\n <div className={\"size-full flex justify-center items-center bg-transparent\"}>\n <Icon icon={<PlaceholderIcon />} label={name} size={\"lg\"} color={\"neutral-light\"} />\n </div>\n );\n};\n\nconst RichItemThumbnail = ({\n url,\n name,\n className,\n mimeType,\n preview,\n disabled,\n renderImage\n}: RichItemThumbnailProps) => {\n const isImage = mimeType?.startsWith(\"image/\");\n const customImage = typeof renderImage === \"function\" ? renderImage({ url, name }) : false;\n\n return (\n <div\n className={cn(\n \"size-[56px] m-xs rounded-sm overflow-hidden relative\",\n disabled && \"[&_img]:filter [&_img]:grayscale [&_img]:opacity-50\",\n className\n )}\n >\n {preview === \"thumbnail\" || isImage ? (\n customImage || <Thumbnail url={url} name={name} />\n ) : preview === \"placeholder\" ? (\n <Placeholder name={name} />\n ) : (\n <FileType mimeType={mimeType} name={name} />\n )}\n </div>\n );\n};\n\nexport { RichItemThumbnail, type RichItemThumbnailProps };\n"],"names":["Thumbnail","url","name","FileType","mimeType","getMimeTypeSrc","csvThumb","docThumb","docxThumb","pdfThumb","pptThumb","pptxThumb","txtThumb","xlsThumb","xlsxThumb","fileThumb","Placeholder","Icon","PlaceholderIcon","RichItemThumbnail","className","preview","disabled","renderImage","isImage","customImage","cn"],"mappings":";;;;;;;;;;;;;;AAgCA,MAAMA,YAAY,CAAC,EAAEC,GAAG,EAAEC,IAAI,EAAkB,GACrC,WAAP,GACI,oBAAC;QAAI,WAAW;qBACZ,oBAAC;QAAI,KAAKD;QAAK,KAAKC;QAAM,WAAU;;AAOhD,MAAMC,WAAW,CAAC,EAAEC,WAAW,EAAE,EAAEF,IAAI,EAAiB;IACpD,MAAMG,iBAAiB,CAACD;QACpB,OAAQA;YACJ,KAAK;gBACD,OAAOE;YACX,KAAK;gBACD,OAAOC;YACX,KAAK;gBACD,OAAOC;YACX,KAAK;gBACD,OAAOC;YACX,KAAK;gBACD,OAAOC;YACX,KAAK;gBACD,OAAOC;YACX,KAAK;gBACD,OAAOC;YACX,KAAK;gBACD,OAAOC;YACX,KAAK;gBACD,OAAOC;YACX;gBACI,OAAOC;QACf;IACJ;IAEA,OAAO,WAAP,GAAO,oBAAC;QAAI,KAAKV,eAAeD;QAAW,KAAKF;QAAM,WAAU;;AACpE;AAIA,MAAMc,cAAc,CAAC,EAAEd,IAAI,EAAoB,GACpC,WAAP,GACI,oBAAC;QAAI,WAAW;qBACZ,oBAACe,MAAIA;QAAC,oBAAM,oBAACC,gBAAeA;QAAK,OAAOhB;QAAM,MAAM;QAAM,OAAO;;AAK7E,MAAMiB,oBAAoB,CAAC,EACvBlB,GAAG,EACHC,IAAI,EACJkB,SAAS,EACThB,QAAQ,EACRiB,OAAO,EACPC,QAAQ,EACRC,WAAW,EACU;IACrB,MAAMC,UAAUpB,UAAU,WAAW;IACrC,MAAMqB,cAAc,AAAuB,cAAvB,OAAOF,cAA6BA,YAAY;QAAEtB;QAAKC;IAAK,KAAK;IAErF,OAAO,WAAP,GACI,oBAAC;QACG,WAAWwB,GACP,wDACAJ,YAAY,uDACZF;OAGHC,AAAY,gBAAZA,WAA2BG,UACxBC,eAAe,WAAfA,GAAe,oBAACzB,WAASA;QAAC,KAAKC;QAAK,MAAMC;SAC1CmB,AAAY,kBAAZA,UAA4B,WAAhB,GACZ,oBAACL,aAAWA;QAAC,MAAMd;uBAEnB,oBAACC,UAAQA;QAAC,UAAUC;QAAU,MAAMF;;AAIpD"}
1
+ {"version":3,"file":"FilePicker/primitives/components/previews/RichItemPreview/RichItemThumbnail.js","sources":["../../../../../../src/FilePicker/primitives/components/previews/RichItemPreview/RichItemThumbnail.tsx"],"sourcesContent":["import React from \"react\";\nimport type { FileItemFormatted } from \"~/FilePicker/index.js\";\nimport { cn } from \"~/utils.js\";\nimport type { RichItemPreviewProps } from \"~/FilePicker/primitives/components/index.js\";\nimport { FileType } from \"./FileType.js\";\nimport { Placeholder } from \"./Placeholder.js\";\nimport { Thumbnail } from \"./Thumbnail.js\";\n\ntype RichItemThumbnailProps = Omit<React.HTMLAttributes<HTMLDivElement>, \"children\"> &\n FileItemFormatted & {\n preview?: RichItemPreviewProps[\"preview\"];\n disabled?: boolean;\n /**\n * `tile` is the fixed square that sits beside the file details; `banner` spans the full\n * width of a stacked layout, where the panel is too narrow to afford a column for it.\n */\n variant?: \"tile\" | \"banner\";\n /** Optional custom image renderer for the thumbnail (e.g. a cropped preview). */\n renderImage?: (args: { url: string; name: string }) => React.ReactNode;\n };\n\nconst RichItemThumbnail = ({\n url,\n name,\n className,\n mimeType,\n preview,\n disabled,\n variant = \"tile\",\n renderImage\n}: RichItemThumbnailProps) => {\n const isImage = mimeType?.startsWith(\"image/\");\n\n return (\n <div\n className={cn(\n \"rounded-sm overflow-hidden relative\",\n variant === \"banner\" ? \"w-full h-[96px]\" : \"size-[56px] m-xs\",\n disabled && \"[&_img]:filter [&_img]:grayscale [&_img]:opacity-50\",\n className\n )}\n >\n {preview === \"thumbnail\" || isImage ? (\n <Thumbnail\n url={url}\n name={name}\n fit={variant === \"banner\" ? \"contain\" : \"cover\"}\n renderImage={renderImage}\n />\n ) : preview === \"placeholder\" ? (\n <Placeholder name={name} />\n ) : (\n <FileType mimeType={mimeType} name={name} />\n )}\n </div>\n );\n};\n\nexport { RichItemThumbnail, type RichItemThumbnailProps };\n"],"names":["RichItemThumbnail","url","name","className","mimeType","preview","disabled","variant","renderImage","isImage","cn","Thumbnail","Placeholder","FileType"],"mappings":";;;;;AAqBA,MAAMA,oBAAoB,CAAC,EACvBC,GAAG,EACHC,IAAI,EACJC,SAAS,EACTC,QAAQ,EACRC,OAAO,EACPC,QAAQ,EACRC,UAAU,MAAM,EAChBC,WAAW,EACU;IACrB,MAAMC,UAAUL,UAAU,WAAW;IAErC,OAAO,WAAP,GACI,oBAAC;QACG,WAAWM,GACP,uCACAH,AAAY,aAAZA,UAAuB,oBAAoB,oBAC3CD,YAAY,uDACZH;OAGHE,AAAY,gBAAZA,WAA2BI,UAAU,WAAVA,GACxB,oBAACE,WAASA;QACN,KAAKV;QACL,MAAMC;QACN,KAAKK,AAAY,aAAZA,UAAuB,YAAY;QACxC,aAAaC;SAEjBH,AAAY,kBAAZA,UAA4B,WAAhB,GACZ,oBAACO,aAAWA;QAAC,MAAMV;uBAEnB,oBAACW,UAAQA;QAAC,UAAUT;QAAU,MAAMF;;AAIpD"}
@@ -0,0 +1,11 @@
1
+ import React from "react";
2
+ import type { FileItemFormatted } from "../../../../../FilePicker/index.js";
3
+ type ThumbnailProps = Pick<FileItemFormatted, "url" | "name"> & {
4
+ fit: "cover" | "contain";
5
+ renderImage?: (args: {
6
+ url: string;
7
+ name: string;
8
+ }) => React.ReactNode;
9
+ };
10
+ declare const Thumbnail: ({ url, name, fit, renderImage }: ThumbnailProps) => React.JSX.Element;
11
+ export { Thumbnail, type ThumbnailProps };
@@ -0,0 +1,24 @@
1
+ import react from "react";
2
+ const Thumbnail = ({ url, name, fit, renderImage })=>{
3
+ const customImage = "function" == typeof renderImage ? renderImage({
4
+ url,
5
+ name
6
+ }) : false;
7
+ if ("contain" === fit) return /*#__PURE__*/ react.createElement("div", {
8
+ className: "size-full p-xs bg-neutral-muted flex items-center justify-center"
9
+ }, customImage || /*#__PURE__*/ react.createElement("img", {
10
+ src: url,
11
+ alt: name,
12
+ className: "max-h-full max-w-full rounded-xs"
13
+ }));
14
+ return /*#__PURE__*/ react.createElement("div", {
15
+ className: "size-full bg-neutral-muted"
16
+ }, customImage || /*#__PURE__*/ react.createElement("img", {
17
+ src: url,
18
+ alt: name,
19
+ className: "size-full object-cover"
20
+ }));
21
+ };
22
+ export { Thumbnail };
23
+
24
+ //# sourceMappingURL=Thumbnail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FilePicker/primitives/components/previews/RichItemPreview/Thumbnail.js","sources":["../../../../../../src/FilePicker/primitives/components/previews/RichItemPreview/Thumbnail.tsx"],"sourcesContent":["import React from \"react\";\nimport type { FileItemFormatted } from \"~/FilePicker/index.js\";\n\ntype ThumbnailProps = Pick<FileItemFormatted, \"url\" | \"name\"> & {\n fit: \"cover\" | \"contain\";\n renderImage?: (args: { url: string; name: string }) => React.ReactNode;\n};\n\nconst Thumbnail = ({ url, name, fit, renderImage }: ThumbnailProps) => {\n const customImage = typeof renderImage === \"function\" ? renderImage({ url, name }) : false;\n\n if (fit === \"contain\") {\n return (\n <div className={\"size-full p-xs bg-neutral-muted flex items-center justify-center\"}>\n {customImage || (\n <img src={url} alt={name} className={\"max-h-full max-w-full rounded-xs\"} />\n )}\n </div>\n );\n }\n\n return (\n <div className={\"size-full bg-neutral-muted\"}>\n {customImage || <img src={url} alt={name} className={\"size-full object-cover\"} />}\n </div>\n );\n};\n\nexport { Thumbnail, type ThumbnailProps };\n"],"names":["Thumbnail","url","name","fit","renderImage","customImage"],"mappings":";AAQA,MAAMA,YAAY,CAAC,EAAEC,GAAG,EAAEC,IAAI,EAAEC,GAAG,EAAEC,WAAW,EAAkB;IAC9D,MAAMC,cAAc,AAAuB,cAAvB,OAAOD,cAA6BA,YAAY;QAAEH;QAAKC;IAAK,KAAK;IAErF,IAAIC,AAAQ,cAARA,KACA,OAAO,WAAP,GACI,oBAAC;QAAI,WAAW;OACXE,eAAe,WAAfA,GACG,oBAAC;QAAI,KAAKJ;QAAK,KAAKC;QAAM,WAAW;;IAMrD,OAAO,WAAP,GACI,oBAAC;QAAI,WAAW;OACXG,eAAe,WAAfA,GAAe,oBAAC;QAAI,KAAKJ;QAAK,KAAKC;QAAM,WAAW;;AAGjE"}
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ interface ThumbnailActionsProps {
3
+ onRemoveItem?: () => void;
4
+ onEditItem?: () => void;
5
+ onReplaceItem?: () => void;
6
+ disabled?: boolean;
7
+ className?: string;
8
+ }
9
+ declare const ThumbnailActions: ({ className, disabled, onEditItem, onRemoveItem, onReplaceItem }: ThumbnailActionsProps) => React.JSX.Element;
10
+ export { ThumbnailActions, type ThumbnailActionsProps };
@@ -0,0 +1,46 @@
1
+ import react, { useCallback } from "react";
2
+ import { ReactComponent } from "@webiny/icons/file_upload.svg";
3
+ import { ReactComponent as edit_svg_ReactComponent } from "@webiny/icons/edit.svg";
4
+ import { ReactComponent as delete_svg_ReactComponent } from "@webiny/icons/delete.svg";
5
+ import { IconButton } from "../../../../../Button/index.js";
6
+ import { Tooltip } from "../../../../../Tooltip/index.js";
7
+ import { cn } from "../../../../../utils.js";
8
+ const Action = ({ icon, label, onAction, disabled })=>{
9
+ const onClick = useCallback((event)=>{
10
+ event.stopPropagation();
11
+ onAction();
12
+ }, [
13
+ onAction
14
+ ]);
15
+ return /*#__PURE__*/ react.createElement(Tooltip, {
16
+ content: label,
17
+ trigger: /*#__PURE__*/ react.createElement(IconButton, {
18
+ variant: "tertiary",
19
+ size: "sm",
20
+ icon: icon,
21
+ onClick: onClick,
22
+ disabled: disabled
23
+ })
24
+ });
25
+ };
26
+ const ThumbnailActions = ({ className, disabled, onEditItem, onRemoveItem, onReplaceItem })=>/*#__PURE__*/ react.createElement("div", {
27
+ className: cn("invisible group-hover:visible", "flex items-center gap-xxs", "absolute top-xs-plus right-xs-plus", className)
28
+ }, onReplaceItem && /*#__PURE__*/ react.createElement(Action, {
29
+ icon: /*#__PURE__*/ react.createElement(ReactComponent, null),
30
+ label: "Replace",
31
+ onAction: onReplaceItem,
32
+ disabled: disabled
33
+ }), onEditItem && /*#__PURE__*/ react.createElement(Action, {
34
+ icon: /*#__PURE__*/ react.createElement(edit_svg_ReactComponent, null),
35
+ label: "Edit",
36
+ onAction: onEditItem,
37
+ disabled: disabled
38
+ }), onRemoveItem && /*#__PURE__*/ react.createElement(Action, {
39
+ icon: /*#__PURE__*/ react.createElement(delete_svg_ReactComponent, null),
40
+ label: "Remove",
41
+ onAction: onRemoveItem,
42
+ disabled: disabled
43
+ }));
44
+ export { ThumbnailActions };
45
+
46
+ //# sourceMappingURL=ThumbnailActions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FilePicker/primitives/components/previews/RichItemPreview/ThumbnailActions.js","sources":["../../../../../../src/FilePicker/primitives/components/previews/RichItemPreview/ThumbnailActions.tsx"],"sourcesContent":["import React, { useCallback } from \"react\";\nimport { ReactComponent as ReplaceIcon } from \"@webiny/icons/file_upload.svg\";\nimport { ReactComponent as EditIcon } from \"@webiny/icons/edit.svg\";\nimport { ReactComponent as TrashIcon } from \"@webiny/icons/delete.svg\";\nimport { IconButton } from \"~/Button/index.js\";\nimport { Tooltip } from \"~/Tooltip/index.js\";\nimport { cn } from \"~/utils.js\";\n\ninterface ActionProps {\n icon: React.JSX.Element;\n label: string;\n onAction: () => void;\n disabled?: boolean;\n}\n\nconst Action = ({ icon, label, onAction, disabled }: ActionProps) => {\n const onClick = useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n event.stopPropagation();\n onAction();\n },\n [onAction]\n );\n\n return (\n <Tooltip\n content={label}\n trigger={\n <IconButton\n variant={\"tertiary\"}\n size={\"sm\"}\n icon={icon}\n onClick={onClick}\n disabled={disabled}\n />\n }\n />\n );\n};\n\ninterface ThumbnailActionsProps {\n onRemoveItem?: () => void;\n onEditItem?: () => void;\n onReplaceItem?: () => void;\n disabled?: boolean;\n className?: string;\n}\n\nconst ThumbnailActions = ({\n className,\n disabled,\n onEditItem,\n onRemoveItem,\n onReplaceItem\n}: ThumbnailActionsProps) => {\n return (\n <div\n className={cn(\n \"invisible group-hover:visible\",\n \"flex items-center gap-xxs\",\n \"absolute top-xs-plus right-xs-plus\",\n className\n )}\n >\n {onReplaceItem && (\n <Action\n icon={<ReplaceIcon />}\n label={\"Replace\"}\n onAction={onReplaceItem}\n disabled={disabled}\n />\n )}\n {onEditItem && (\n <Action\n icon={<EditIcon />}\n label={\"Edit\"}\n onAction={onEditItem}\n disabled={disabled}\n />\n )}\n {onRemoveItem && (\n <Action\n icon={<TrashIcon />}\n label={\"Remove\"}\n onAction={onRemoveItem}\n disabled={disabled}\n />\n )}\n </div>\n );\n};\n\nexport { ThumbnailActions, type ThumbnailActionsProps };\n"],"names":["Action","icon","label","onAction","disabled","onClick","useCallback","event","Tooltip","IconButton","ThumbnailActions","className","onEditItem","onRemoveItem","onReplaceItem","cn","ReplaceIcon","EditIcon","TrashIcon"],"mappings":";;;;;;;AAeA,MAAMA,SAAS,CAAC,EAAEC,IAAI,EAAEC,KAAK,EAAEC,QAAQ,EAAEC,QAAQ,EAAe;IAC5D,MAAMC,UAAUC,YACZ,CAACC;QACGA,MAAM,eAAe;QACrBJ;IACJ,GACA;QAACA;KAAS;IAGd,OAAO,WAAP,GACI,oBAACK,SAAOA;QACJ,SAASN;QACT,uBACI,oBAACO,YAAUA;YACP,SAAS;YACT,MAAM;YACN,MAAMR;YACN,SAASI;YACT,UAAUD;;;AAK9B;AAUA,MAAMM,mBAAmB,CAAC,EACtBC,SAAS,EACTP,QAAQ,EACRQ,UAAU,EACVC,YAAY,EACZC,aAAa,EACO,GACb,WAAP,GACI,oBAAC;QACG,WAAWC,GACP,iCACA,6BACA,sCACAJ;OAGHG,iBAAiB,WAAjBA,GACG,oBAACd,QAAMA;QACH,oBAAM,oBAACgB,gBAAWA;QAClB,OAAO;QACP,UAAUF;QACV,UAAUV;QAGjBQ,cAAc,WAAdA,GACG,oBAACZ,QAAMA;QACH,oBAAM,oBAACiB,yBAAQA;QACf,OAAO;QACP,UAAUL;QACV,UAAUR;QAGjBS,gBAAgB,WAAhBA,GACG,oBAACb,QAAMA;QACH,oBAAM,oBAACkB,2BAASA;QAChB,OAAO;QACP,UAAUL;QACV,UAAUT"}
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+ interface TruncatedFileNameProps {
3
+ name: string;
4
+ className?: string;
5
+ }
6
+ declare const TruncatedFileName: ({ name, className }: TruncatedFileNameProps) => React.JSX.Element;
7
+ export { TruncatedFileName, type TruncatedFileNameProps };
@@ -0,0 +1,20 @@
1
+ import react from "react";
2
+ import { Text } from "../../../../Text/index.js";
3
+ import { cn } from "../../../../utils.js";
4
+ import { splitFileName } from "./fileName.js";
5
+ const TruncatedFileName = ({ name, className })=>{
6
+ const { head, tail } = splitFileName(name);
7
+ return /*#__PURE__*/ react.createElement(Text, {
8
+ size: "sm",
9
+ as: "div",
10
+ className: cn("flex min-w-0", className),
11
+ title: name
12
+ }, /*#__PURE__*/ react.createElement("span", {
13
+ className: "truncate"
14
+ }, head), tail ? /*#__PURE__*/ react.createElement("span", {
15
+ className: "shrink-0 whitespace-pre"
16
+ }, tail) : null);
17
+ };
18
+ export { TruncatedFileName };
19
+
20
+ //# sourceMappingURL=TruncatedFileName.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FilePicker/primitives/components/previews/TruncatedFileName.js","sources":["../../../../../src/FilePicker/primitives/components/previews/TruncatedFileName.tsx"],"sourcesContent":["import React from \"react\";\nimport { Text } from \"~/Text/index.js\";\nimport { cn } from \"~/utils.js\";\nimport { splitFileName } from \"./fileName.js\";\n\ninterface TruncatedFileNameProps {\n name: string;\n className?: string;\n}\n\nconst TruncatedFileName = ({ name, className }: TruncatedFileNameProps) => {\n const { head, tail } = splitFileName(name);\n\n return (\n <Text size=\"sm\" as=\"div\" className={cn(\"flex min-w-0\", className)} title={name}>\n <span className={\"truncate\"}>{head}</span>\n {tail ? <span className={\"shrink-0 whitespace-pre\"}>{tail}</span> : null}\n </Text>\n );\n};\n\nexport { TruncatedFileName, type TruncatedFileNameProps };\n"],"names":["TruncatedFileName","name","className","head","tail","splitFileName","Text","cn"],"mappings":";;;;AAUA,MAAMA,oBAAoB,CAAC,EAAEC,IAAI,EAAEC,SAAS,EAA0B;IAClE,MAAM,EAAEC,IAAI,EAAEC,IAAI,EAAE,GAAGC,cAAcJ;IAErC,OAAO,WAAP,GACI,oBAACK,MAAIA;QAAC,MAAK;QAAK,IAAG;QAAM,WAAWC,GAAG,gBAAgBL;QAAY,OAAOD;qBACtE,oBAAC;QAAK,WAAW;OAAaE,OAC7BC,OAAO,WAAPA,GAAO,oBAAC;QAAK,WAAW;OAA4BA,QAAe;AAGhF"}
@@ -0,0 +1,4 @@
1
+ export declare const splitFileName: (name: string) => {
2
+ head: string;
3
+ tail: string;
4
+ };
@@ -0,0 +1,26 @@
1
+ const TAIL_STEM_CHARS = 3;
2
+ const splitFileName = (name)=>{
3
+ const dot = name.lastIndexOf(".");
4
+ if (dot <= 0) return {
5
+ head: name,
6
+ tail: ""
7
+ };
8
+ const cut = dot - Math.min(TAIL_STEM_CHARS, dot);
9
+ if (cut <= 0) return {
10
+ head: name,
11
+ tail: ""
12
+ };
13
+ const head = name.slice(0, cut);
14
+ const tail = name.slice(cut);
15
+ if (head.length <= tail.length) return {
16
+ head: name,
17
+ tail: ""
18
+ };
19
+ return {
20
+ head,
21
+ tail
22
+ };
23
+ };
24
+ export { splitFileName };
25
+
26
+ //# sourceMappingURL=fileName.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FilePicker/primitives/components/previews/fileName.js","sources":["../../../../../src/FilePicker/primitives/components/previews/fileName.ts"],"sourcesContent":["const TAIL_STEM_CHARS = 3;\n\nexport const splitFileName = (name: string) => {\n const dot = name.lastIndexOf(\".\");\n\n if (dot <= 0) {\n return { head: name, tail: \"\" };\n }\n\n const cut = dot - Math.min(TAIL_STEM_CHARS, dot);\n\n if (cut <= 0) {\n return { head: name, tail: \"\" };\n }\n\n const head = name.slice(0, cut);\n const tail = name.slice(cut);\n\n if (head.length <= tail.length) {\n return { head: name, tail: \"\" };\n }\n\n return { head, tail };\n};\n"],"names":["TAIL_STEM_CHARS","splitFileName","name","dot","cut","Math","head","tail"],"mappings":"AAAA,MAAMA,kBAAkB;AAEjB,MAAMC,gBAAgB,CAACC;IAC1B,MAAMC,MAAMD,KAAK,WAAW,CAAC;IAE7B,IAAIC,OAAO,GACP,OAAO;QAAE,MAAMD;QAAM,MAAM;IAAG;IAGlC,MAAME,MAAMD,MAAME,KAAK,GAAG,CAACL,iBAAiBG;IAE5C,IAAIC,OAAO,GACP,OAAO;QAAE,MAAMF;QAAM,MAAM;IAAG;IAGlC,MAAMI,OAAOJ,KAAK,KAAK,CAAC,GAAGE;IAC3B,MAAMG,OAAOL,KAAK,KAAK,CAACE;IAExB,IAAIE,KAAK,MAAM,IAAIC,KAAK,MAAM,EAC1B,OAAO;QAAE,MAAML;QAAM,MAAM;IAAG;IAGlC,OAAO;QAAEI;QAAMC;IAAK;AACxB"}
@@ -2,3 +2,4 @@ export * from "./FilePreview.js";
2
2
  export * from "./ImagePreview/index.js";
3
3
  export * from "./RichItemPreview/index.js";
4
4
  export * from "./TextOnlyPreview/index.js";
5
+ export * from "./TruncatedFileName.js";
@@ -2,3 +2,4 @@ export * from "./FilePreview.js";
2
2
  export * from "./ImagePreview/index.js";
3
3
  export * from "./RichItemPreview/index.js";
4
4
  export * from "./TextOnlyPreview/index.js";
5
+ export * from "./TruncatedFileName.js";
@@ -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"}
package/Link/Link.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
2
  import { type VariantProps } from "../utils.js";
3
3
  import { LinkComponentProps } from "./LinkComponent.js";
4
- declare const linkVariants: (props?: ({
4
+ export declare const linkVariants: (props?: ({
5
5
  size?: "inherit" | "lg" | "md" | "sm" | "xl" | null | undefined;
6
6
  variant?: "primary" | "primary-negative" | "secondary" | "secondary-negative" | null | undefined;
7
7
  underline?: boolean | null | undefined;
package/Link/Link.js CHANGED
@@ -51,6 +51,6 @@ function LinkBase({ size, variant, underline, className, children, ...rest }) {
51
51
  }, children);
52
52
  }
53
53
  const Link = makeDecoratable("Link", LinkBase);
54
- export { Link };
54
+ export { Link, linkVariants };
55
55
 
56
56
  //# sourceMappingURL=Link.js.map
package/Link/Link.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Link/Link.js","sources":["../../src/Link/Link.tsx"],"sourcesContent":["import React from \"react\";\nimport { cva, type VariantProps, makeDecoratable, cn } from \"~/utils.js\";\nimport { useAdminUi } from \"~/index.js\";\nimport { LinkComponentProps } from \"./LinkComponent.js\";\n\nconst linkVariants = cva(\"font-sans rounded-xs\", {\n variants: {\n size: {\n inherit: \"[font-size:inherit]\",\n sm: \"text-sm\",\n md: \"text-md\",\n lg: \"text-lg\",\n xl: \"text-xl\"\n },\n variant: {\n primary: [\n \"text-accent-primary\",\n \"focus-visible:outline-none focus-visible:ring-[2px] focus-visible:ring-primary-dimmed\"\n ],\n secondary: [\n \"text-neutral-primary\",\n \"focus-visible:outline-none focus-visible:ring-[2px] focus-visible:ring-primary-dimmed\"\n ],\n \"primary-negative\": [\n \"text-accent-primary\",\n \"focus-visible:outline-none focus-visible:ring-[2px] focus-visible:ring-primary-strong\"\n ],\n \"secondary-negative\": [\n \"text-neutral-light\",\n \"focus-visible:outline-none focus-visible:ring-[2px] focus-visible:ring-primary-strong\"\n ]\n },\n underline: {\n true: \"underline hover:no-underline\",\n false: \"hover:underline\"\n }\n },\n defaultVariants: {\n size: \"inherit\",\n variant: \"primary\",\n underline: false\n }\n});\n\nexport type LinkProps = LinkComponentProps &\n VariantProps<typeof linkVariants> & {\n disabled?: boolean;\n };\n\nfunction LinkBase({ size, variant, underline, className, children, ...rest }: LinkProps) {\n const { linkComponent: LinkComponent } = useAdminUi();\n return (\n <LinkComponent\n {...rest}\n className={cn(linkVariants({ size, variant, underline }), className)}\n >\n {children}\n </LinkComponent>\n );\n}\n\nexport const Link = makeDecoratable(\"Link\", LinkBase);\n"],"names":["linkVariants","cva","LinkBase","size","variant","underline","className","children","rest","LinkComponent","useAdminUi","cn","Link","makeDecoratable"],"mappings":";;;AAKA,MAAMA,eAAeC,IAAI,wBAAwB;IAC7C,UAAU;QACN,MAAM;YACF,SAAS;YACT,IAAI;YACJ,IAAI;YACJ,IAAI;YACJ,IAAI;QACR;QACA,SAAS;YACL,SAAS;gBACL;gBACA;aACH;YACD,WAAW;gBACP;gBACA;aACH;YACD,oBAAoB;gBAChB;gBACA;aACH;YACD,sBAAsB;gBAClB;gBACA;aACH;QACL;QACA,WAAW;YACP,MAAM;YACN,OAAO;QACX;IACJ;IACA,iBAAiB;QACb,MAAM;QACN,SAAS;QACT,WAAW;IACf;AACJ;AAOA,SAASC,SAAS,EAAEC,IAAI,EAAEC,OAAO,EAAEC,SAAS,EAAEC,SAAS,EAAEC,QAAQ,EAAE,GAAGC,MAAiB;IACnF,MAAM,EAAE,eAAeC,aAAa,EAAE,GAAGC;IACzC,OAAO,WAAP,GACI,oBAACD,eAAAA;QACI,GAAGD,IAAI;QACR,WAAWG,GAAGX,aAAa;YAAEG;YAAMC;YAASC;QAAU,IAAIC;OAEzDC;AAGb;AAEO,MAAMK,OAAOC,gBAAgB,QAAQX"}
1
+ {"version":3,"file":"Link/Link.js","sources":["../../src/Link/Link.tsx"],"sourcesContent":["import React from \"react\";\nimport { cva, type VariantProps, makeDecoratable, cn } from \"~/utils.js\";\nimport { useAdminUi } from \"~/index.js\";\nimport { LinkComponentProps } from \"./LinkComponent.js\";\n\nexport const linkVariants = cva(\"font-sans rounded-xs\", {\n variants: {\n size: {\n inherit: \"[font-size:inherit]\",\n sm: \"text-sm\",\n md: \"text-md\",\n lg: \"text-lg\",\n xl: \"text-xl\"\n },\n variant: {\n primary: [\n \"text-accent-primary\",\n \"focus-visible:outline-none focus-visible:ring-[2px] focus-visible:ring-primary-dimmed\"\n ],\n secondary: [\n \"text-neutral-primary\",\n \"focus-visible:outline-none focus-visible:ring-[2px] focus-visible:ring-primary-dimmed\"\n ],\n \"primary-negative\": [\n \"text-accent-primary\",\n \"focus-visible:outline-none focus-visible:ring-[2px] focus-visible:ring-primary-strong\"\n ],\n \"secondary-negative\": [\n \"text-neutral-light\",\n \"focus-visible:outline-none focus-visible:ring-[2px] focus-visible:ring-primary-strong\"\n ]\n },\n underline: {\n true: \"underline hover:no-underline\",\n false: \"hover:underline\"\n }\n },\n defaultVariants: {\n size: \"inherit\",\n variant: \"primary\",\n underline: false\n }\n});\n\nexport type LinkProps = LinkComponentProps &\n VariantProps<typeof linkVariants> & {\n disabled?: boolean;\n };\n\nfunction LinkBase({ size, variant, underline, className, children, ...rest }: LinkProps) {\n const { linkComponent: LinkComponent } = useAdminUi();\n return (\n <LinkComponent\n {...rest}\n className={cn(linkVariants({ size, variant, underline }), className)}\n >\n {children}\n </LinkComponent>\n );\n}\n\nexport const Link = makeDecoratable(\"Link\", LinkBase);\n"],"names":["linkVariants","cva","LinkBase","size","variant","underline","className","children","rest","LinkComponent","useAdminUi","cn","Link","makeDecoratable"],"mappings":";;;AAKO,MAAMA,eAAeC,IAAI,wBAAwB;IACpD,UAAU;QACN,MAAM;YACF,SAAS;YACT,IAAI;YACJ,IAAI;YACJ,IAAI;YACJ,IAAI;QACR;QACA,SAAS;YACL,SAAS;gBACL;gBACA;aACH;YACD,WAAW;gBACP;gBACA;aACH;YACD,oBAAoB;gBAChB;gBACA;aACH;YACD,sBAAsB;gBAClB;gBACA;aACH;QACL;QACA,WAAW;YACP,MAAM;YACN,OAAO;QACX;IACJ;IACA,iBAAiB;QACb,MAAM;QACN,SAAS;QACT,WAAW;IACf;AACJ;AAOA,SAASC,SAAS,EAAEC,IAAI,EAAEC,OAAO,EAAEC,SAAS,EAAEC,SAAS,EAAEC,QAAQ,EAAE,GAAGC,MAAiB;IACnF,MAAM,EAAE,eAAeC,aAAa,EAAE,GAAGC;IACzC,OAAO,WAAP,GACI,oBAACD,eAAAA;QACI,GAAGD,IAAI;QACR,WAAWG,GAAGX,aAAa;YAAEG;YAAMC;YAASC;QAAU,IAAIC;OAEzDC;AAGb;AAEO,MAAMK,OAAOC,gBAAgB,QAAQX"}
@@ -7,6 +7,7 @@ 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 { useEscapeScrollLock } from "../../hooks/index.js";
10
11
  const MultiSelectTrigger = ({ displayValue, hasValue, placeholder, displayResetAction, disabled, invalid, size, variant, onValueReset })=>{
11
12
  const resetButton = useMemo(()=>{
12
13
  if (!hasValue || !displayResetAction) return;
@@ -49,7 +50,10 @@ const MultiSelectTrigger = ({ displayValue, hasValue, placeholder, displayResetA
49
50
  className: "h-md w-md"
50
51
  })));
51
52
  };
52
- const MultiSelectContent = ({ options, value, onToggle })=>/*#__PURE__*/ react.createElement(Popover.Portal, null, /*#__PURE__*/ react.createElement(Popover.Content, {
53
+ const MultiSelectContent = ({ options, value, onToggle })=>{
54
+ const contentRef = useEscapeScrollLock();
55
+ return /*#__PURE__*/ react.createElement(Popover.Portal, null, /*#__PURE__*/ react.createElement(Popover.Content, {
56
+ ref: contentRef,
53
57
  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
58
  style: {
55
59
  width: "var(--radix-popover-trigger-width)",
@@ -73,6 +77,7 @@ const MultiSelectContent = ({ options, value, onToggle })=>/*#__PURE__*/ react.c
73
77
  hasLabel: true,
74
78
  changeChecked: ()=>{}
75
79
  }))))));
80
+ };
76
81
  const DecoratableMultiSelectPrimitive = ({ options = [], value = [], onChange, onValueReset, placeholder = "Select options", disabled, invalid, displayResetAction = true, showSelectionCount, size, variant })=>{
77
82
  const displayValue = useMemo(()=>{
78
83
  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 { 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 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","contentRef","useEscapeScrollLock","option","CheckboxPrimitiveRenderer","DecoratableMultiSelectPrimitive","onChange","showSelectionCount","labelMap","Map","o","v","toggle","useCallback","optionValue","next","reset","MultiSelectPrimitive","makeDecoratable"],"mappings":";;;;;;;;;;AAkDA,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;IAK7E,MAAMC,aAAaC;IAEnB,OAAO,WAAP,GACI,oBAACT,QAAQ,MAAM,sBACX,oBAACA,QAAQ,OAAO;QACZ,KAAKQ;QACL,WAAWP,GACP,oIACA,gEACA,8DACA,gEACA,iFACA;QAEJ,OAAO;YACH,OAAO;YACP,WAAW;QACf;QACA,OAAO;QACP,YAAY;OAEXI,QAAQ,GAAG,CAACK,CAAAA,SAAAA,WAAAA,GACT,oBAAC;YACG,KAAKA,OAAO,KAAK;YACjB,WAAWT,GACP,wCACA,2BACAS,OAAO,QAAQ,IAAI;YAEvB,SAAS,IAAMH,SAASG,OAAO,KAAK;yBAEpC,oBAAC;YAAI,WAAW;yBACZ,oBAACC,2BAAyBA;YACtB,IAAID,OAAO,KAAK;YAChB,OAAOA,OAAO,KAAK;YACnB,OAAOA,OAAO,KAAK;YACnB,SAASJ,MAAM,QAAQ,CAACI,OAAO,KAAK;YACpC,UAAUA,OAAO,QAAQ,IAAI;YAC7B,eAAe;YACf,UAAU;YACV,eAAe,KAAO;;AAQtD;AAKA,MAAME,kCAAkC,CAAC,EACrCP,UAAU,EAAE,EACZC,QAAQ,EAAE,EACVO,QAAQ,EACRpB,YAAY,EACZN,cAAc,gBAAgB,EAC9BE,QAAQ,EACRC,OAAO,EACPF,qBAAqB,IAAI,EACzB0B,kBAAkB,EAClBvB,IAAI,EACJC,OAAO,EACiB;IACxB,MAAMP,eAAeU,QAAQ;QACzB,IAAIW,AAAiB,MAAjBA,MAAM,MAAM,EACZ,OAAO;QAEX,IAAIQ,oBACA,OAAO,GAAGR,MAAM,MAAM,CAAC,eAAe,CAAC;QAE3C,MAAMS,WAAW,IAAIC,IAAIX,QAAQ,GAAG,CAACY,CAAAA,IAAK;gBAACA,EAAE,KAAK;gBAAEA,EAAE,KAAK;aAAC;QAC5D,OAAOX,MAAM,GAAG,CAACY,CAAAA,IAAKH,SAAS,GAAG,CAACG,MAAMA,GAAG,IAAI,CAAC;IACrD,GAAG;QAACZ;QAAOD;QAASS;KAAmB;IAEvC,MAAMK,SAASC,YACX,CAACC;QACG,MAAMC,OAAOhB,MAAM,QAAQ,CAACe,eACtBf,MAAM,MAAM,CAACY,CAAAA,IAAKA,MAAMG,eACxB;eAAIf;YAAOe;SAAY;QAC7BR,WAAWS;IACf,GACA;QAAChB;QAAOO;KAAS;IAGrB,MAAMU,QAAQH,YAAY;QACtBP,WAAW,EAAE;QACbpB;IACJ,GAAG;QAACoB;QAAUpB;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,cAAc+B;sBAElB,oBAACnB,oBAAkBA;QAAC,SAASC;QAAS,OAAOC;QAAO,UAAUa;;AAG1E;AACA,MAAMK,uBAAuBC,gBACzB,wBACAb"}
@@ -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, ...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, ...props }) {
5
5
  const viewportRef = __rspack_external_react.useRef(null);
6
6
  __rspack_external_react.useEffect(()=>{
7
7
  const viewport = viewportRef.current;
@@ -35,13 +35,19 @@ function ScrollArea({ className, children, onScrollPositionChange, onScroll, ...
35
35
  }, /*#__PURE__*/ __rspack_external_react.createElement(__rspack_external__radix_ui_react_scroll_area_bdec1136.Viewport, {
36
36
  ref: viewportRef,
37
37
  "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"
38
+ onScroll: onViewportScroll,
39
+ 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
40
  }, children), /*#__PURE__*/ __rspack_external_react.createElement(ScrollBar, null), /*#__PURE__*/ __rspack_external_react.createElement(__rspack_external__radix_ui_react_scroll_area_bdec1136.Corner, null));
40
41
  }
41
- function ScrollBar({ className, orientation = "vertical", ...props }) {
42
+ function ScrollBar({ className, orientation = "vertical", onMouseDown, ...props }) {
43
+ const handleMouseDown = (event)=>{
44
+ onMouseDown?.(event);
45
+ event.preventDefault();
46
+ };
42
47
  return /*#__PURE__*/ __rspack_external_react.createElement(__rspack_external__radix_ui_react_scroll_area_bdec1136.ScrollAreaScrollbar, {
43
48
  "data-slot": "scroll-area-scrollbar",
44
49
  orientation: orientation,
50
+ onMouseDown: handleMouseDown,
45
51
  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),
46
52
  ...props
47
53
  }, /*#__PURE__*/ __rspack_external_react.createElement(__rspack_external__radix_ui_react_scroll_area_bdec1136.ScrollAreaThumb, {
@@ -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 ...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 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-[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","viewportClassName","onViewportScroll","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,EAChB,GAAGC,OACW;IACd,MAAMC,cAAcC,wBAAAA,MAAY,CAAiB;IAEjDA,wBAAAA,SAAe,CAAC;QACZ,MAAMC,WAAWF,YAAY,OAAO;QACpC,IAAI,CAACE,YAAa,CAACP,0BAA0B,CAACC,UAC1C;QAIJ,MAAMO,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;YAEAd,yBAAyBe;YACzBd,WAAWc;QACf;QAGAP;QAEAD,SAAS,gBAAgB,CAAC,UAAUC;QACpC,OAAO,IAAMD,SAAS,mBAAmB,CAAC,UAAUC;IACxD,GAAG;QAACR;QAAwBC;KAAS;IAErC,OAAO,WAAP,GACI,sCAACe,uDAAAA,IAAwB;QACrB,aAAU;QACV,WAAWC,GAAG,YAAYnB;QACzB,GAAGM,KAAK;qBAET,sCAACY,uDAAAA,QAA4B;QACzB,KAAKX;QACL,aAAU;QACV,UAAUF;QACV,WAAWc,GACP,sJACAf;OAGHH,WAAAA,WAAAA,GAEL,sCAACmB,WAASA,OAAAA,WAAAA,GACV,sCAACF,uDAAAA,MAA0B;AAGvC;AAEA,SAASE,UAAU,EACfpB,SAAS,EACTqB,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,gDAC9BA,AAAgB,iBAAhBA,eAAgC,kDAChCrB;QAEH,GAAGM,KAAK;qBAET,sCAACY,uDAAAA,eAAmC;QAChC,aAAU;QACV,WAAU;;AAI1B"}
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.6.0-alpha.8",
3
+ "version": "6.6.0-alpha.9",
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.18",
21
21
  "@tanstack/react-table": "9.1.2",
22
- "@webiny/icons": "6.6.0-alpha.8",
23
- "@webiny/react-composition": "6.6.0-alpha.8",
24
- "@webiny/utils": "6.6.0-alpha.8",
22
+ "@webiny/icons": "6.6.0-alpha.9",
23
+ "@webiny/react-composition": "6.6.0-alpha.9",
24
+ "@webiny/utils": "6.6.0-alpha.9",
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.6.0-alpha.8",
60
- "@webiny/project": "6.6.0-alpha.8",
59
+ "@webiny/build-tools": "6.6.0-alpha.9",
60
+ "@webiny/project": "6.6.0-alpha.9",
61
61
  "chalk": "6.0.0",
62
62
  "oxfmt": "0.64.0",
63
63
  "rimraf": "6.1.3",