= (props) => {
return (
- setQuery(ev.target.value)} value={query}>
+ props.onChange(query)}
+ aria-labelledby={comboId}
+ placeholder="Search.."
+ onChange={(ev) => setQuery(ev.target.value)}
+ value={query}
+ >
{children}
diff --git a/packages/dev/sharedUiComponents/src/fluent/primitives/uploadButton.tsx b/packages/dev/sharedUiComponents/src/fluent/primitives/uploadButton.tsx
new file mode 100644
index 00000000000..ad819e90899
--- /dev/null
+++ b/packages/dev/sharedUiComponents/src/fluent/primitives/uploadButton.tsx
@@ -0,0 +1,51 @@
+import type { FunctionComponent } from "react";
+import { useRef } from "react";
+import { ArrowUploadRegular } from "@fluentui/react-icons";
+import { Button } from "./button";
+import type { ButtonProps } from "./button";
+
+type UploadButtonProps = Omit & {
+ /**
+ * Callback when files are selected
+ */
+ onUpload: (files: FileList) => void;
+ /**
+ * File types to accept (e.g., ".jpg, .png, .dds")
+ */
+ accept?: string;
+ /**
+ * Text label to display on the button (optional)
+ */
+ label?: string;
+};
+
+/**
+ * A button that triggers a file upload dialog.
+ * Combines a Button with a hidden file input.
+ * @param props UploadButtonProps
+ * @returns UploadButton component
+ */
+export const UploadButton: FunctionComponent = (props) => {
+ const { onUpload, accept, label, ...buttonProps } = props;
+ UploadButton.displayName = "UploadButton";
+ const inputRef = useRef(null);
+
+ const handleClick = () => {
+ inputRef.current?.click();
+ };
+
+ const handleChange = (evt: React.ChangeEvent) => {
+ const files = evt.target.files;
+ if (files && files.length) {
+ onUpload(files);
+ }
+ evt.target.value = "";
+ };
+
+ return (
+ <>
+
+
+ >
+ );
+};