@webiny/admin-ui 6.6.0-alpha.7 → 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.
- package/Command/components/List.d.ts +1 -1
- package/Command/components/List.js +9 -5
- package/Command/components/List.js.map +1 -1
- package/FilePicker/primitives/components/previews/ItemActions.js +1 -1
- package/FilePicker/primitives/components/previews/ItemActions.js.map +1 -1
- package/FilePicker/primitives/components/previews/RichItemPreview/FileType.d.ts +5 -0
- package/FilePicker/primitives/components/previews/RichItemPreview/FileType.js +45 -0
- package/FilePicker/primitives/components/previews/RichItemPreview/FileType.js.map +1 -0
- package/FilePicker/primitives/components/previews/RichItemPreview/Placeholder.d.ts +5 -0
- package/FilePicker/primitives/components/previews/RichItemPreview/Placeholder.js +14 -0
- package/FilePicker/primitives/components/previews/RichItemPreview/Placeholder.js.map +1 -0
- package/FilePicker/primitives/components/previews/RichItemPreview/RichItemPreview.js +52 -11
- package/FilePicker/primitives/components/previews/RichItemPreview/RichItemPreview.js.map +1 -1
- package/FilePicker/primitives/components/previews/RichItemPreview/RichItemThumbnail.d.ts +5 -4
- package/FilePicker/primitives/components/previews/RichItemPreview/RichItemThumbnail.js +9 -66
- package/FilePicker/primitives/components/previews/RichItemPreview/RichItemThumbnail.js.map +1 -1
- package/FilePicker/primitives/components/previews/RichItemPreview/Thumbnail.d.ts +11 -0
- package/FilePicker/primitives/components/previews/RichItemPreview/Thumbnail.js +24 -0
- package/FilePicker/primitives/components/previews/RichItemPreview/Thumbnail.js.map +1 -0
- package/FilePicker/primitives/components/previews/RichItemPreview/ThumbnailActions.d.ts +10 -0
- package/FilePicker/primitives/components/previews/RichItemPreview/ThumbnailActions.js +46 -0
- package/FilePicker/primitives/components/previews/RichItemPreview/ThumbnailActions.js.map +1 -0
- package/FilePicker/primitives/components/previews/TruncatedFileName.d.ts +7 -0
- package/FilePicker/primitives/components/previews/TruncatedFileName.js +20 -0
- package/FilePicker/primitives/components/previews/TruncatedFileName.js.map +1 -0
- package/FilePicker/primitives/components/previews/fileName.d.ts +4 -0
- package/FilePicker/primitives/components/previews/fileName.js +26 -0
- package/FilePicker/primitives/components/previews/fileName.js.map +1 -0
- package/FilePicker/primitives/components/previews/index.d.ts +1 -0
- package/FilePicker/primitives/components/previews/index.js +1 -0
- package/IconPicker/primitives/IconPickerPrimitive.js +1 -2
- package/IconPicker/primitives/IconPickerPrimitive.js.map +1 -1
- package/Link/Link.d.ts +1 -1
- package/Link/Link.js +1 -1
- package/Link/Link.js.map +1 -1
- package/MultiSelect/primitives/MultiSelectPrimitive.js +6 -1
- package/MultiSelect/primitives/MultiSelectPrimitive.js.map +1 -1
- package/Popover/Popover.stories.d.ts +7 -0
- package/Popover/Popover.stories.js +24 -1
- package/Popover/Popover.stories.js.map +1 -1
- package/Popover/primitives/components/PopoverContent.js +6 -1
- package/Popover/primitives/components/PopoverContent.js.map +1 -1
- package/ScrollArea/ScrollArea.d.ts +12 -2
- package/ScrollArea/ScrollArea.js +9 -3
- package/ScrollArea/ScrollArea.js.map +1 -1
- package/hooks/index.d.ts +1 -0
- package/hooks/index.js +1 -0
- package/hooks/useEscapeScrollLock.d.ts +13 -0
- package/hooks/useEscapeScrollLock.js +21 -0
- package/hooks/useEscapeScrollLock.js.map +1 -0
- 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(
|
|
5
|
-
className: cn(
|
|
6
|
-
|
|
7
|
-
|
|
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 <
|
|
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
|
-
},
|
|
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 {
|
|
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 })
|
|
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: "
|
|
35
|
+
className: "@min-[280px]:hidden"
|
|
17
36
|
}, /*#__PURE__*/ react.createElement("div", {
|
|
18
|
-
className: "flex
|
|
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
|
-
|
|
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\"
|
|
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
|
-
*
|
|
9
|
-
*
|
|
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
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
|
|
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("
|
|
69
|
-
}, "thumbnail" === preview || isImage ?
|
|
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
|
|
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,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"}
|
|
@@ -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
|
|
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
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\
|
|
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 })
|
|
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":"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"}
|
|
@@ -9,3 +9,10 @@ export declare const WithArrowAccentVariant: Story;
|
|
|
9
9
|
export declare const SubtleVariant: Story;
|
|
10
10
|
export declare const WithArrowSubtleVariant: Story;
|
|
11
11
|
export declare const Documentation: Story;
|
|
12
|
+
/**
|
|
13
|
+
* A dialog locks scrolling outside of its own content, and the popover is portaled out of it, so
|
|
14
|
+
* the lock covers the popover too. What that costs is the wheel and the trackpad: the list below
|
|
15
|
+
* still moved by its scrollbar and by the arrow keys, but a wheel event over it did nothing at all.
|
|
16
|
+
* It has to scroll by wheel while the dialog is open.
|
|
17
|
+
*/
|
|
18
|
+
export declare const InsideDialog: Story;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import react from "react";
|
|
2
2
|
import { Popover } from "./Popover.js";
|
|
3
|
+
import { Button } from "../Button/index.js";
|
|
4
|
+
import { Dialog } from "../Dialog/index.js";
|
|
3
5
|
const meta = {
|
|
4
6
|
title: "Components/Popover",
|
|
5
7
|
component: Popover,
|
|
@@ -130,7 +132,28 @@ const Documentation = {
|
|
|
130
132
|
}
|
|
131
133
|
}
|
|
132
134
|
};
|
|
135
|
+
const InsideDialog = {
|
|
136
|
+
render: ()=>/*#__PURE__*/ react.createElement(Dialog, {
|
|
137
|
+
trigger: /*#__PURE__*/ react.createElement(Button, {
|
|
138
|
+
variant: "primary",
|
|
139
|
+
text: "Open dialog"
|
|
140
|
+
}),
|
|
141
|
+
title: "Popover inside a dialog"
|
|
142
|
+
}, /*#__PURE__*/ react.createElement(Popover, {
|
|
143
|
+
trigger: /*#__PURE__*/ react.createElement("span", null, /*#__PURE__*/ react.createElement(Button, {
|
|
144
|
+
variant: "secondary",
|
|
145
|
+
text: "Open popover"
|
|
146
|
+
})),
|
|
147
|
+
content: /*#__PURE__*/ react.createElement("ul", {
|
|
148
|
+
className: "max-h-48 w-[220px] overflow-y-auto"
|
|
149
|
+
}, Array.from({
|
|
150
|
+
length: 40
|
|
151
|
+
}, (_, index)=>/*#__PURE__*/ react.createElement("li", {
|
|
152
|
+
key: index
|
|
153
|
+
}, "Option ", index + 1)))
|
|
154
|
+
}))
|
|
155
|
+
};
|
|
133
156
|
export default Popover_stories;
|
|
134
|
-
export { AccentVariant, Default, Documentation, SubtleVariant, WithArrowAccentVariant, WithArrowSubtleVariant };
|
|
157
|
+
export { AccentVariant, Default, Documentation, InsideDialog, SubtleVariant, WithArrowAccentVariant, WithArrowSubtleVariant };
|
|
135
158
|
|
|
136
159
|
//# sourceMappingURL=Popover.stories.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Popover/Popover.stories.js","sources":["../../src/Popover/Popover.stories.tsx"],"sourcesContent":["import React from \"react\";\nimport type { Meta, StoryObj } from \"@storybook/react\";\nimport { Popover } from \"./Popover.js\";\n\nconst meta: Meta<typeof Popover> = {\n title: \"Components/Popover\",\n component: Popover,\n parameters: {\n layout: \"padded\"\n },\n argTypes: {\n align: {\n control: \"select\",\n options: [\"start\", \"center\", \"end\"]\n },\n side: {\n control: \"select\",\n options: [\"top\", \"bottom\", \"left\", \"right\"]\n }\n },\n decorators: [\n Story => (\n <div className=\"bg-[#f4f4f4] flex items-center justify-center w-full h-[300px]\">\n <Story />\n </div>\n )\n ]\n};\n\nexport default meta;\n\ntype Story = StoryObj<typeof Popover>;\n\nexport const Default: Story = {\n args: {\n trigger: <p>Popover trigger</p>,\n content: (\n <div className={\"w-[260px]\"}>\n <strong>Lorem ipsum dolor sit amet</strong>, consectetur adipiscing elit. Morbi\n lectus leo, dapibus vitae mollis dictum, vulputate eget lorem. Aliquam rutrum auctor\n tempus.\n </div>\n )\n }\n};\n\nexport const AccentVariant: Story = {\n args: {\n ...Default.args,\n variant: \"accent\"\n }\n};\n\nexport const WithArrowAccentVariant: Story = {\n args: {\n ...AccentVariant.args,\n arrow: true\n }\n};\n\nexport const SubtleVariant: Story = {\n args: {\n ...Default.args,\n variant: \"subtle\"\n },\n decorators: [\n Story => (\n <div className=\"flex items-center justify-center bg-neutral-dark text-neutral-light w-full h-[300px]\">\n <Story />\n </div>\n )\n ]\n};\n\nexport const WithArrowSubtleVariant: Story = {\n args: {\n variant: \"subtle\",\n trigger: <p>Popover trigger</p>,\n arrow: true,\n content: (\n <div className={\"w-[260px]\"}>\n <strong>Lorem ipsum dolor sit amet</strong>, consectetur adipiscing elit. Morbi\n lectus leo, dapibus vitae mollis dictum, vulputate eget lorem. Aliquam rutrum auctor\n tempus.\n </div>\n )\n },\n decorators: SubtleVariant.decorators\n};\n\nexport const Documentation: Story = {\n args: {\n align: \"center\",\n side: \"bottom\",\n variant: \"subtle\",\n arrow: false,\n close: false,\n trigger: <p>Popover trigger</p>,\n content: (\n <div className={\"w-[260px]\"}>\n <strong>Lorem ipsum dolor sit amet</strong>, consectetur adipiscing elit. Morbi\n lectus leo, dapibus vitae mollis dictum, vulputate eget lorem. Aliquam rutrum auctor\n tempus.\n </div>\n )\n },\n argTypes: {\n trigger: {\n description:\n \"The element that triggers the popover when clicked. Please refer to the example code for details.\"\n },\n content: {\n description:\n \"The content to display inside the popover. Please refer to the example code for details.\"\n },\n side: {\n description: \"The side of the trigger where the popover appears.\",\n control: \"select\",\n options: [\"top\", \"right\", \"bottom\", \"left\"]\n },\n align: {\n description: \"The alignment of the popover relative to the trigger.\",\n control: \"select\",\n options: [\"start\", \"center\", \"end\"]\n },\n variant: {\n description: \"The visual style variant of the popover.\",\n control: \"select\",\n options: [\"accent\", \"subtle\"]\n },\n arrow: {\n description: \"Whether to show an arrow pointing to the trigger.\",\n control: \"boolean\"\n },\n close: {\n description: \"Whether to show a close button inside the popover.\",\n control: \"boolean\"\n }\n }\n};\n"],"names":["meta","Popover","Story","Default","AccentVariant","WithArrowAccentVariant","SubtleVariant","WithArrowSubtleVariant","Documentation"],"mappings":"
|
|
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 })
|
|
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
|
|
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 };
|
package/ScrollArea/ScrollArea.js
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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
package/hooks/index.js
CHANGED
|
@@ -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.
|
|
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.
|
|
23
|
-
"@webiny/react-composition": "6.6.0-alpha.
|
|
24
|
-
"@webiny/utils": "6.6.0-alpha.
|
|
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.
|
|
60
|
-
"@webiny/project": "6.6.0-alpha.
|
|
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",
|