Explorar o código

feat: artifacts style

Dogtiti hai 1 ano
pai
achega
21ef9a4567

+ 2 - 0
.gitignore

@@ -44,3 +44,5 @@ dev
 
 *.key
 *.key.pub
+
+masks.json

+ 12 - 0
app/components/artifact.module.scss

@@ -0,0 +1,12 @@
+.artifact {
+  display: block;
+  width: 100%;
+  height: 100%;
+  position: relative;
+}
+
+.artifact-iframe {
+  width: 100%;
+  border: var(--border-in-light);
+  border-radius: 6px;
+}

+ 12 - 13
app/components/artifact.tsx

@@ -13,6 +13,7 @@ import { Modal, showToast } from "./ui-lib";
 import { copyToClipboard, downloadAs } from "../utils";
 import { Path, ApiPath, REPO_URL } from "@/app/constant";
 import { Loading } from "./home";
+import styles from "./artifact.module.scss";
 
 export function HTMLPreview(props: {
   code: string;
@@ -61,17 +62,22 @@ export function HTMLPreview(props: {
     return props.code + script;
   }, [props.code]);
 
+  const handleOnLoad = () => {
+    if (props?.onLoad) {
+      props.onLoad(title);
+    }
+  };
+
   return (
     <iframe
+      className={styles["artifact-iframe"]}
       id={frameId.current}
       ref={ref}
-      frameBorder={0}
       sandbox="allow-forms allow-modals allow-scripts"
-      style={{ width: "100%", height }}
-      // src={`data:text/html,${encodeURIComponent(srcDoc)}`}
+      style={{ height }}
       srcDoc={srcDoc}
-      onLoad={(e) => props?.onLoad && props?.onLoad(title)}
-    ></iframe>
+      onLoad={handleOnLoad}
+    />
   );
 }
 
@@ -186,14 +192,7 @@ export function Artifact() {
   }, [id]);
 
   return (
-    <div
-      style={{
-        display: "block",
-        width: "100%",
-        height: "100%",
-        position: "relative",
-      }}
-    >
+    <div className={styles.artifact}>
       <div
         style={{
           height: 36,

+ 2 - 2
app/components/markdown.tsx

@@ -105,9 +105,9 @@ export function PreCode(props: { children: any }) {
         <Mermaid code={mermaidCode} key={mermaidCode} />
       )}
       {htmlCode.length > 0 && (
-        <FullScreen className="no-dark html" right={60}>
+        <FullScreen className="no-dark html" right={70}>
           <ArtifactShareButton
-            style={{ position: "absolute", right: 10, top: 10 }}
+            style={{ position: "absolute", right: 20, top: 10 }}
             getCode={() => htmlCode}
           />
           <HTMLPreview

+ 1 - 0
app/components/ui-lib.module.scss

@@ -292,6 +292,7 @@
   z-index: 999;
 
   &-content {
+    min-width: 300px;
     .list {
       max-height: 90vh;
       overflow-x: hidden;

+ 29 - 10
app/components/ui-lib.tsx

@@ -53,7 +53,7 @@ export function ListItem(props: {
   children?: JSX.Element | JSX.Element[];
   icon?: JSX.Element;
   className?: string;
-  onClick?: () => void;
+  onClick?: (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
 }) {
   return (
     <div
@@ -454,25 +454,45 @@ export function Selector<T>(props: {
   onClose?: () => void;
   multiple?: boolean;
 }) {
+  const [selectedValues, setSelectedValues] = useState<T[]>(
+    Array.isArray(props.defaultSelectedValue)
+      ? props.defaultSelectedValue
+      : props.defaultSelectedValue !== undefined
+      ? [props.defaultSelectedValue]
+      : [],
+  );
+
+  const handleSelection = (
+    e: React.MouseEvent<HTMLDivElement, MouseEvent>,
+    value: T,
+  ) => {
+    if (props.multiple) {
+      e.stopPropagation();
+      const newSelectedValues = selectedValues.includes(value)
+        ? selectedValues.filter((v) => v !== value)
+        : [...selectedValues, value];
+      setSelectedValues(newSelectedValues);
+      props.onSelection?.(newSelectedValues);
+    } else {
+      setSelectedValues([value]);
+      props.onSelection?.([value]);
+      props.onClose?.();
+    }
+  };
+
   return (
     <div className={styles["selector"]} onClick={() => props.onClose?.()}>
       <div className={styles["selector-content"]}>
         <List>
           {props.items.map((item, i) => {
-            const selected = props.multiple
-              ? // @ts-ignore
-                props.defaultSelectedValue?.includes(item.value)
-              : props.defaultSelectedValue === item.value;
+            const selected = selectedValues.includes(item.value);
             return (
               <ListItem
                 className={styles["selector-item"]}
                 key={i}
                 title={item.title}
                 subTitle={item.subTitle}
-                onClick={() => {
-                  props.onSelection?.([item.value]);
-                  props.onClose?.();
-                }}
+                onClick={(e) => handleSelection(e, item.value)}
               >
                 {selected ? (
                   <div
@@ -494,7 +514,6 @@ export function Selector<T>(props: {
     </div>
   );
 }
-
 export function FullScreen(props: any) {
   const { children, right = 10, top = 10, ...rest } = props;
   const ref = useRef<HTMLDivElement>();