i18n - docs translations (#23559)
Created by Github action Co-authored-by: github-actions <github-actions@twenty.com>
This commit is contained in:
committed by
GitHub
parent
c862a2a43d
commit
cdeebb1a18
@@ -703,69 +703,69 @@ const Card = () => {
|
||||
|
||||
## 현재 제한 사항
|
||||
|
||||
Front 컴포넌트는 활발히 개발 중입니다. 렌더링, 스타일링 및 이벤트 처리는 잘 작동합니다. 렌더링 *이후* 단계에 해당하는 작업(요소 측정, ref에서 DOM 메서드 호출, 트리 외부로의 포털링, 브라우저 스토리지 접근 등)은 현재 누락되어 있거나 불완전하며, 대부분은 조용히 실패합니다. 예외도 발생하지 않고, 스캐폴드가 전체 브라우저 DOM을 기준으로 타입이 지정되어 있기 때문에 TypeScript 오류도 발생하지 않습니다.
|
||||
Front 컴포넌트는 활발히 개발 중입니다. 렌더링, 스타일링 및 이벤트 처리는 잘 동작합니다. 렌더링을 *넘어서는* 작업(요소 측정, ref에 DOM 메서드 호출, 트리 바깥으로 포털링, 브라우저 스토리지 접근 등)은 현재 누락되었거나 불완전하며, 대부분 조용히 실패합니다. 예외도 발생하지 않고, 스캐폴드가 전체 브라우저 DOM을 기준으로 타입이 지정되어 있기 때문에 TypeScript 오류도 발생하지 않습니다.
|
||||
|
||||
이 중 하나가 작업을 막고 있다면, 우선순위를 높일 수 있도록 [issue를 생성](https://github.com/twentyhq/twenty/issues/new/choose)해 주세요.
|
||||
이 중 하나가 개발을 가로막는다면, 우선순위를 높일 수 있도록 [issue를 열어](https://github.com/twentyhq/twenty/issues/new/choose) 주세요.
|
||||
|
||||
### 레이아웃과 측정
|
||||
|
||||
아직 어떤 요소도 스스로를 측정할 수 없습니다.
|
||||
|
||||
| API | 무슨 일이 일어나는지 |
|
||||
| ------------------------------------------------------------- | ------------------------------------------------------------------------ |
|
||||
| `getBoundingClientRect()`, `getClientRects()` | 예외 발생(Throws) |
|
||||
| `offsetWidth`, `clientWidth`, `scrollWidth`, `offsetTop`, ... | 조용히 `undefined`가 되어 `width ?? 0`은 `0`을 반환하고, `width > 600`은 항상 false입니다. |
|
||||
| `ResizeObserver`, `IntersectionObserver` | `ReferenceError`가 발생합니다(`typeof` 가드는 동작함). |
|
||||
| `window.matchMedia()`, `window.getComputedStyle()` | 예외 발생(Throws) |
|
||||
| `window.innerWidth`, `innerHeight`, `devicePixelRatio` | 조용히 `undefined`가 됩니다. |
|
||||
| `new MutationObserver(fn)` | 생성은 되지만 이후 `.observe()`에서 예외가 발생합니다. |
|
||||
| API | 무슨 일이 일어나는지 |
|
||||
| ------------------------------------------------------------- | ------------------------------------------------------------------------- |
|
||||
| `getBoundingClientRect()`, `getClientRects()` | 예외 발생 |
|
||||
| `offsetWidth`, `clientWidth`, `scrollWidth`, `offsetTop`, ... | 조용히 `undefined`가 되어, `width ?? 0`은 `0`을 반환하고, `width > 600`은 항상 false입니다. |
|
||||
| `ResizeObserver`, `IntersectionObserver` | `ReferenceError` 발생(단, `typeof` 가드는 동작함) |
|
||||
| `window.matchMedia()`, `window.getComputedStyle()` | 예외 발생 |
|
||||
| `window.innerWidth`, `innerHeight`, `devicePixelRatio` | 조용히 `undefined`가 됨 |
|
||||
| `new MutationObserver(fn)` | 생성은 되지만 이후 `.observe()`에서 예외가 발생합니다. |
|
||||
|
||||
따라서 recharts의 `ResponsiveContainer`, Floating UI / Popper, 리스트 가상화, 드래그로 크기 조절 등은 아직 동작하지 않습니다. 대신 CSS로 레이아웃을 구성하세요. 스타일시트는 실제 페이지에 도달하므로 flexbox, grid, `aspect-ratio`, `clamp()`, `@container`는 모두 정상적으로 동작합니다.
|
||||
따라서 recharts의 `ResponsiveContainer`, Floating UI / Popper, 리스트 가상화, 드래그로 크기 조절 등은 아직 동작하지 않습니다. 대신 CSS에서 레이아웃을 구현하세요. 스타일시트는 실제 페이지에 도달하므로 flexbox, grid, `aspect-ratio`, `clamp()` 및 `@container`는 모두 정상적으로 동작합니다.
|
||||
|
||||
<Note>
|
||||
`requestAnimationFrame`, `fetch`, `setTimeout`, `queueMicrotask`는 `window.` 접두사 없이도 동작합니다. `window.requestAnimationFrame(...)` 등만 예외를 발생시킵니다.
|
||||
`requestAnimationFrame`, `fetch`, `setTimeout` 및 `queueMicrotask`는 `window.` 접두사 없이 동작합니다. `window.requestAnimationFrame(...)` 등만 예외를 발생시킵니다.
|
||||
</Note>
|
||||
|
||||
### DOM 액세스
|
||||
|
||||
`ref`는 `HTMLElement`가 아닌 샌드박스 요소를 제공합니다.
|
||||
`ref`는 `HTMLElement`가 아니라 샌드박스 요소를 반환합니다.
|
||||
|
||||
| 작성한 코드 | 무슨 일이 일어나는지 | 대신 사용할 것 |
|
||||
| ----------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | --------------------------------------------------------------------------- |
|
||||
| `ref.current.focus()`, `.click()`, `.select()`, `.setSelectionRange()`, `.scrollIntoView()`, `video.play()` | 예외 발생(Throws) | 제어 컴포넌트 사용; 값을 `event.target`에서 읽기 |
|
||||
| `element.classList.add(...)` | 예외 발생(`classList`가 `undefined`임) | `className` 문자열을 직접 구성하세요. |
|
||||
| `document.getElementById()`, `getElementsByClassName()`, `createTreeWalker()` | 예외 발생(Throws) | 정상 동작하는 `querySelector()` / `querySelectorAll()` 사용 |
|
||||
| `document.activeElement` | 항상 `undefined`입니다. | `onFocus` / `onBlur`로 포커스를 추적하세요. |
|
||||
| `\<canvas>` | 아무것도 렌더링되지 않으며, 오류도 없습니다. | SVG를 사용하거나, 오프스크린에서 그린 뒤 `<img src={dataUrl}>`로 표시하세요. |
|
||||
| `createPortal(node, document.body)` | `isConnected`는 성공을 보고하지만 실제로는 아무것도 렌더링되지 않습니다. | `position: absolute`를 사용해 인라인으로 오버레이를 배치하거나, 라이브러리에 직접 렌더링한 컨테이너 요소를 전달하세요. |
|
||||
| 작성한 코드 | 무슨 일이 일어나는지 | 대신 사용할 것 |
|
||||
| ----------------------------------------------------------------------------------------------------------- | ----------------------------------------- | ------------------------------------------------------------------- |
|
||||
| `ref.current.focus()`, `.click()`, `.select()`, `.setSelectionRange()`, `.scrollIntoView()`, `video.play()` | 예외 발생 | 제어 컴포넌트를 사용하고 값을 `event.target`에서 읽습니다 |
|
||||
| `element.classList.add(...)` | 예외 발생(`classList`는 `undefined`임) | `className` 문자열을 직접 구성하세요. |
|
||||
| `document.getElementById()`, `getElementsByClassName()`, `createTreeWalker()` | 예외 발생 | 정상 동작하는 `querySelector()` / `querySelectorAll()`을 사용 |
|
||||
| `document.activeElement` | 항상 `undefined` | `onFocus` / `onBlur`로 포커스를 추적하세요. |
|
||||
| `\<canvas>` | 아무것도 렌더링되지 않으며, 오류도 없습니다. | SVG를 사용하거나, 오프스크린에서 그린 뒤 `<img src={dataUrl}>`로 표시하세요. |
|
||||
| `createPortal(node, document.body)` | `isConnected`는 성공으로 보고하지만 아무것도 렌더링되지 않습니다 | `position: absolute`로 인라인 오버레이를 사용하거나 라이브러리에 직접 렌더링한 컨테이너 요소를 전달하세요 |
|
||||
|
||||
이 포털 간극 때문에 Radix, Headless UI, MUI, react-select의 팝오버는 기본적으로 아무것도 렌더링하지 않습니다. 대부분은 container prop을 받으므로, 여러분이 렌더링한 요소를 가리키도록 설정하면 됩니다.
|
||||
이 포털 간극 때문에 Radix, Headless UI, MUI, react-select의 팝오버는 기본적으로 아무것도 렌더링하지 않습니다. 대부분 컨테이너 prop을 받으므로, 직접 렌더링한 요소를 가리키도록 설정하세요.
|
||||
|
||||
### 이벤트
|
||||
|
||||
Mouse, pointer, touch, drag, keyboard, focus, `input`/`change`/`submit`, `scroll`/`wheel`/`contextmenu` and `animationend`/`transitionend` cross to the host, plus a few per element: `load`/`error` on `<img>`, clipboard and composition on `<input>`/`\<textarea>`, media on `\<video>`/`\<audio>`, `toggle` on `\<details>`/`\<dialog>`. Anything else (`onAuxClick`, `onSelect`, `onInvalid`, `onReset`, `onAnimationStart`, pointer capture, `onLoad` off `<img>`) is dropped without warning.
|
||||
마우스, 포인터, 터치, 드래그, 키보드, 포커스, `input`/`change`/`submit`, `scroll`/`wheel`/`contextmenu` 그리고 `animationend`/`transitionend` 이벤트는 호스트로 전달되며, 여기에 요소별로 몇 가지가 더해집니다: `<img>`의 `load`/`error`, `<input>`/`\<textarea>`의 클립보드 및 조합(composition), `\<video>`/`\<audio>`의 미디어, `\<details>`/`\<dialog>`의 `toggle` 등입니다. 그 밖의 것들(`onAuxClick`, `onSelect`, `onInvalid`, `onReset`, `onAnimationStart`, 포인터 캡처, `<img>`의 `onLoad` 등)은 경고 없이 모두 무시됩니다.
|
||||
|
||||
`document.addEventListener()` and `window.addEventListener()` register without error and never fire, which is why a drag stops as soon as the pointer leaves the element it started on. `event.preventDefault()` does not cross either; form submission, `dragover`/`drop` and link clicks are already guarded for you.
|
||||
`document.addEventListener()`와 `window.addEventListener()`는 오류 없이 등록되지만 절대 실행되지 않으며, 이 때문에 드래그는 시작한 요소를 벗어나는 순간 중지됩니다. `event.preventDefault()` 역시 전달되지 않습니다. 폼 제출, `dragover`/`drop` 및 링크 클릭은 이미 보호되어 있습니다.
|
||||
|
||||
### Attributes and styling
|
||||
### 속성과 스타일링
|
||||
|
||||
Each element forwards its own properties to the host DOM (`href` on `\<a>`, `src`/`alt` on `<img>`, `value`/`placeholder`/`disabled` on `<input>`, and so on), plus a common set on every element: `id`, `className`, `style`, `title`, `tabIndex`, `role`, `draggable` and any `aria-*` / `data-*` attribute (hyphenated, so `ariaLabel` is dropped). Anything outside that is silently discarded, so express custom state as `data-*`.
|
||||
각 요소는 자신의 속성을 호스트 DOM으로 전달합니다(`href`는 `\<a>`, `src`/`alt`는 `<img>`, `value`/`placeholder`/`disabled`는 `<input>` 등). 또한 모든 요소에 공통으로 `id`, `className`, `style`, `title`, `tabIndex`, `role`, `draggable`, 그리고 하이픈이 포함된 모든 `aria-*` / `data-*` 속성(따라서 `ariaLabel`은 무시됨)을 전달합니다. 그 외의 속성은 조용히 폐기되므로, 사용자 정의 상태는 `data-*`로 표현하세요.
|
||||
|
||||
Component CSS, whether from `import './styles.css'`, CSS-in-JS or a `\<style>` element, is injected into the host page's `\<head>` **unscoped**. So class names collide with Twenty's own (prefix them, and never write bare `div { ... }` selectors), and `@media` matches the browser window rather than your widget (use `@container` with your own `container-type`). Inline `style` props are unaffected.
|
||||
컴포넌트 CSS는 `import './styles.css'`, CSS-in-JS 또는 `\<style>` 요소에서 오든, 호스트 페이지의 `\<head>`에 **범위 없이(unscoped)** 주입됩니다. 따라서 클래스 이름이 Twenty 자체 것과 충돌합니다(접두사를 붙이고, `div { ... }` 선택자를 직접 작성하지 마세요). 그리고 `@media`는 위젯이 아니라 브라우저 창을 기준으로 매칭됩니다(직접 지정한 `container-type`과 함께 `@container`를 사용하세요). 인라인 `style` prop은 영향을 받지 않습니다.
|
||||
|
||||
### Storage and network
|
||||
### 스토리지와 네트워크
|
||||
|
||||
`localStorage`, `sessionStorage`, IndexedDB, cookies, the Cache API and `BroadcastChannel` are all unavailable, since the component runs in a worker at an opaque origin. To persist state, call a [logic function](/l/ko/developers/extend/apps/logic/logic-functions) and use its [key-value store](/l/ko/developers/extend/apps/logic/key-value-store).
|
||||
`localStorage`, `sessionStorage`, IndexedDB, 쿠키, Cache API 및 `BroadcastChannel`은 모두 사용할 수 없습니다. 컴포넌트가 불투명한 origin의 워커에서 실행되기 때문입니다. 상태를 영속화하려면 [logic function](/l/ko/developers/extend/apps/logic/logic-functions)을 호출하고, 해당 [key-value store](/l/ko/developers/extend/apps/logic/key-value-store)를 사용하세요.
|
||||
|
||||
`fetch` works, with caveats:
|
||||
`fetch`는 동작하지만, 몇 가지 주의사항이 있습니다:
|
||||
|
||||
* Calls to the Twenty API and your app's routes are proxied by the host, so prefer [`RestApiClient`](#calling-the-twenty-rest-api). On proxied calls, `AbortSignal` and the other `RequestInit` options are dropped, and only `string` and `URLSearchParams` bodies are supported.
|
||||
* Other origins leave the sandbox with `Origin: null`, so a third-party API answers only if it sends `Access-Control-Allow-Origin: *`. Call it from a logic function instead.
|
||||
* `fetch('/rest/people')` is never matched to the Twenty API, because the sandbox has no page URL to resolve a relative path against.
|
||||
* Twenty API와 앱의 라우트로 가는 호출은 호스트에서 프록시되므로, [`RestApiClient`](#calling-the-twenty-rest-api)를 사용하는 것이 좋습니다. 프록시되는 호출에서는 `AbortSignal` 및 기타 `RequestInit` 옵션이 제거되며, `string`과 `URLSearchParams` 타입의 body만 지원됩니다.
|
||||
* 다른 오리진으로 나가는 요청은 `Origin: null`을 가진 채 샌드박스를 벗어나므로, 서드파티 API는 `Access-Control-Allow-Origin: *`를 보내는 경우에만 응답합니다. 대신 logic function에서 호출하세요.
|
||||
* 샌드박스에는 상대 경로를 해석할 페이지 URL이 없으므로, `fetch('/rest/people')`은 Twenty API와 절대 매칭되지 않습니다.
|
||||
|
||||
### Other gaps
|
||||
### 기타 제약 사항
|
||||
|
||||
* **File contents.** `<input type="file">` gives your handler file metadata only, not the bytes, so `FileReader` and uploads are not possible yet.
|
||||
* **Drag-and-drop payloads.** Drag events fire, but `event.dataTransfer` is `undefined`.
|
||||
* **Node built-ins.** `fs`, `path` and `node:crypto` fail the build, so move that work into a [logic function](/l/ko/developers/extend/apps/logic/logic-functions). Web Crypto, `fetch`, `TextEncoder` and `URL` are available.
|
||||
* **`\<iframe>`** is always re-sandboxed without `allow-same-origin`, so an embed relying on its own session renders logged out. It has no `onLoad` either.
|
||||
* **파일 내용.** `<input type="file">`은 핸들러에 바이트가 아닌 파일 메타데이터만 제공하므로, 현재는 `FileReader` 사용과 업로드가 불가능합니다.
|
||||
* **드래그 앤 드롭 페이로드.** 드래그 이벤트는 발생하지만, `event.dataTransfer`는 `undefined`입니다.
|
||||
* **Node 내장 모듈.** `fs`, `path` 및 `node:crypto`는 빌드에 실패하므로, 해당 작업은 [logic function](/l/ko/developers/extend/apps/logic/logic-functions)으로 옮기세요. Web Crypto, `fetch`, `TextEncoder` 및 `URL`은 사용할 수 있습니다.
|
||||
* \*\*`\<iframe>`\*\*은 항상 `allow-same-origin` 없이 다시 샌드박싱되므로, 자체 세션에 의존하는 임베드는 로그아웃된 상태로 렌더링됩니다. 또한 `onLoad`도 지원되지 않습니다.
|
||||
|
||||
Reference in New Issue
Block a user