본문 바로가기
Canva

5. Canva에 앱 만들기. Button

by bryan.oh 2024. 6. 30.
반응형

Canva App Button

 

Canva 의 App 영역에 표시 될 수 있는 요소들은 아래의 Canva dev 의 storybook 에 나열되어 있습니다.

여기서 필요한 components 들을 사용할 수 있습니다.

https://www.canva.dev/docs/apps/app-ui-kit/storybook/?path=/docs/canva-app-ui-kit-action-button--docs

 

@storybook/cli - Storybook

 

www.canva.dev

 

우선 자주 쓰는것 위주로 사용 예제를 작성해보겠습니다.

Button

가장 기본적인 코드는

<Button
  alignment="center"
  onClick={() => {}}
  variant="primary"
>
  Click Me
</Button>
  • alignment : "center", "start", "end"
  • variant : "primary", ""secondary", "tertiary"
  • disabled : 버튼을 클릭할 수 없게 비활성화 합니다.
  • loading : 버튼에 로딩 표시를 합니다. 클릭할 수 없음.
  • stretch : 버튼의 가로 사이즈를 100% 로 합니다.

primary(보라색) / secondary(테두리있음) / tertiary(테두리없음)

<Button
  alignment="center"
  onClick={() => {}}
  disabled
  loading
  stretch
  variant="primary"
>
  Click Me
</Button>

왼쪽: disabled , 오른쪽 : loading

 

onClick

버튼을 클릭 했을 때, 메소드를 호출하는 방법은, onClick 에 메소드 명을 {} 사이에 넣으면 됩니다.

onClick={doSomething}

이렇게 하면, App = () => {} 에 정의한 메소드가 실행됩니다.

export const App = () => {
  const doSomething = () => {
    addNativeElement({
      type: "TEXT",
      children: ["Hello world!"],
    });
  };
  
  // 생략
  
};

 

loading

버튼을 누르고 어떤 작업이 처리되는 동안 loading 표시가 되게 하려면?

우선 useState 를 써야합니다.

import { useState } from "react";

그리고 이 useState 를 사용하는 변수를 생성합니다.

const [loading, setLoading] = useState(false);

loading 은 true/false 의 값이 저장될 것이고, setLoading 을 통해서 set을 할겁니다.

그리고 기본값은 false 입니다.

위치는 App() 안쪽에~

export const App = () => {
  const [loading, setLoading] = useState(false);
  
  const doSomething = () => {
    addNativeElement({
      type: "TEXT",
      children: ["Hello world!"],
    });
  };
  
  // 생략

Button 에는 loading 변수를 이용해서 loading 을 바꿀 수 있게 다음 코드를 추가합니다.

<Button
  alignment="center"
  onClick={doSomething}
  loading={loading}
  variant="primary"
>
  Click Me
</Button>

 

버튼을 클릭하면 loading 표시 -> 2초 대기 -> TEXT element 추가 후 loading 해제.

이러한 동작이 되도록 바꿔보겠습니다.

  const doSomething = () => {
    setLoading(true);
    setTimeout(function() {
      addNativeElement({
        type: "TEXT",
        children: ["Hello world!"],
      });
      setLoading(false);
    }, 2000);
  };

실행 해보면, 예상한 대로 동작 합니다.

그런데 setTimeout 을 쓰면, depth 가 자꾸 들어가게 되는데요.

아래와 같이 Promise 를 사용하면 코드가 더 가독성있게 됩니다. 

function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

async function demo() {
    console.log("시작");
    await sleep(2000);
    console.log("2초 후 실행");
}

 

전체 소스

import { Button, Rows, Text } from "@canva/app-ui-kit";
import { addNativeElement } from "@canva/design";
import * as React from "react";
import { useState } from "react";
import styles from "styles/components.css";

export const App = () => {
  const [loading, setLoading] = useState(false);

  function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }

  const doSomething = async () => {
    setLoading(true);
    await sleep(2000);
    addNativeElement({
      type: "TEXT",
      children: ["Hello world!"],
    });
    setLoading(false);
  };

  return (
    <div className={styles.scrollContainer}>
      <Rows spacing="2u">
        <Text>
          To make changes to this app, edit the <code>src/app.tsx</code> file,
          then close and reopen the app in the editor to preview the changes.
        </Text>
        <Button
          variant="primary"
          onClick={doSomething}
          loading={loading}
          stretch>
          Click Me
        </Button>
      </Rows>
    </div>
  );
};

 

 

마무리

버튼에 대한것은 이정도만 알아도 되지 않을까 합니다.

버튼에 대해서 뭔가를 더 해야한다면 canva storybook 을 참고해주세요~

다음은

button 으로 외부 api 를 (lambda url) 호출해서  데이터를 가져오는 예제를 작성해 보겠습니다.

 

 

728x90
반응형

댓글