New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

rune-ts

Package Overview
Dependencies
Maintainers
1
Versions
46
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

rune-ts - npm Package Compare versions

Comparing version 0.0.3 to 0.0.4

190

docs/core/rune.View/튜토리얼.md

@@ -156,7 +156,6 @@ # 시작하기

onMount() {
this.element().addEventListener('click', () => this.onClick());
return this;
this.element().addEventListener('click', () => this.toggle());
}
onClick() {
toggle() {
this.data.checked = !this.data.checked;

@@ -174,7 +173,7 @@ this.element().classList.toggle('checked');

onMount() {
this.addEventListener('click', this.onClick);
return this;
this.addEventListener('click', this.toggle);
// or this.addEventListener('click', 'toggle');
}
onClick() {
toggle() {
this.data.checked = !this.data.checked;

@@ -186,10 +185,26 @@ this.element().classList.toggle('checked');

`view.addEventListener()`는 받은 함수를 등록해두었다가 이벤트가 실행되었을 때 `this`에 `view`를 바인딩하여 실행합니다. 위 코드에서 `ColorCheckboxView.prototype.onClick`은 하나의 함수이기 때문에 여러개의 ColorCheckboxView가 만들어지더라도 효율적입니다.
`view.addEventListener()`는 받은 함수를 등록해두었다가 이벤트가 실행되었을 때 `this`에 `view`를 바인딩하여 실행합니다. 위 코드에서 `ColorCheckboxView.prototype.toggle`은 하나의 함수이기 때문에 여러개의 ColorCheckboxView가 만들어지더라도 효율적입니다. 혹은 `'toggle'`과 같이 메서드명을 전달해도 됩니다.
### 커스텀 이벤트 디스패치
### 이벤트 등록 데코레이터
`@on` 데코레이터를 사용하면 보다 간결하게 코드를 작성할 수 있습니다. `@on('click')`은 `onMount` 내 작성했던 코드를 대체합니다.
```typescript
export class ColorCheckboxView extends View<Color> {
@on('click')
toggle() {
this.data.checked = !this.data.checked;
this.element().classList.toggle('checked');
}
}
```
### 커스텀 이벤트 디스패치와 이벤트 델리게이트
```typescript
export class ColorCheckboxView extends View<Color> {
...
onClick() {
@on('click')
toggle() {
this.data.checked = !this.data.checked;

@@ -221,6 +236,28 @@ this.element().classList.toggle('checked');

});
return this;
}
}
```
`@on` 데코레이터에 인자를 하나만 전달하면 `addEventListener`를 사용하고, `@on`에 두 번째 인자로 CSS 셀렉터를 함께 전달하면 `delegate`를 사용합니다. `delegate`도 데코레이터로 아래처럼 간결하게 작성할 수 있습니다.
```typescript
class MyView extends View<number> {
onMount() {
this.delegate('click', '.target', () => this.remove());
}
remove() {
this.element().remove();
}
}
class MyView extends View<number> {
@on('click', '.target')
remove() {
this.element().remove();
}
}
```
### ColorCheckBoxListView 마무리

@@ -239,3 +276,3 @@

onMount() {
return this.delegate('checkbox:change', '.ColorCheckboxView', this.onChange);
this.delegate('checkbox:change', '.ColorCheckboxView', this.onChange);
}

@@ -273,5 +310,5 @@

위의 `ColorCheckboxListView`와 `ColorCheckboxView`는 체크할 수 있다는 속성을 가지고 있습니다. 체크 기능을 추상화한 View를 준비하면 체크 기능이 적용된 더 많은 View를 보다 쉽게 만들 수 있습니다.
위의 `ColorCheckboxListView`와 `ColorCheckboxView`는 체크할 수 있다는 속성을 가지고 있습니다. 체크 기능을 추상화한 `View`를 준비하면 체크 기능이 적용된 더 많은 `View`를 보다 쉽게 만들 수 있습니다.
먼저 `ColorView`, `ColorCheckboxListView`, `ColorCheckboxView`가 구현된 코드를 다시보면 아래와 같습니다.
먼저 `ColorView`, `ColorCheckboxListView`, `ColorCheckboxView`의 코드를 다시보면 아래와 같습니다.

@@ -301,8 +338,4 @@ ```typescript

onMount() {
this.element().addEventListener('click', () => this.onClick());
return this;
}
onClick() {
@on('click')
toggle() {
this.data.checked = !this.data.checked;

@@ -326,3 +359,3 @@ this.element().classList.toggle('checked');

onMount() {
return this.delegate('checkbox:change', '.ColorCheckboxView', this.onChange);
this.delegate('checkbox:change', '.ColorCheckboxView', this.onChange);
}

@@ -350,3 +383,2 @@

checked?: boolean;
value?: string;
};

@@ -367,11 +399,7 @@

createSubView(): View<T> | string {
return this.SubView ? new this.SubView(this.data) : this.data.value || '';
return this.SubView ? new this.SubView(this.data) : '';
}
onMount() {
this.element().addEventListener('click', () => this.onClick());
return this;
}
onClick() {
@on('click')
toggle() {
this.data.checked = !this.data.checked;

@@ -403,6 +431,3 @@ this.element().classList.toggle('checked');

onMount() {
return this.delegate('checkbox:change', `> .${this.CheckboxView}`, this.onChange);
}
@on('checkbox:change', '> *')
onChange() {

@@ -420,4 +445,4 @@ this.element().dispatchEvent(

제네릭을 활용하여 `ColorCheckboxListView`, `ColorCheckboxView`를 확장한 `View`의 코드들에서 `data`의
타입을 추론할 수 있도록 하였습니다. `CheckboxView<T extends CheckboxData>`는 `CheckboxView`을 사용하거나 확장할 새로운 `View`의 `data`의 타입을 제약합니다. `tagName`, `CheckboxView` Constructor 등을 확장할 수 있도록 프로퍼티를 추가했습니다.
제네릭을 활용하여 `CheckboxListView`, `CheckboxView`를 확장할 코드들에서 `data`의
타입을 추론할 수 있도록 하였습니다. `CheckboxView<T extends CheckboxData>`는 `CheckboxView`을 확장할 새로운 `View`의 `data`의 타입을 제약합니다. 또한 `tagName`, `SubView`, `CheckboxView` 등을 확장할 수 있도록 프로퍼티를 추가했습니다.

@@ -518,2 +543,30 @@

### html을 활용하여 좀 더 쉽게 추상화하기
위에서 `CheckboxView`를 구현한 방식은 타입 정의를 잘해주어야하기 때문에 추상화가 약간 어렵습니다. rune의 템플릿 함수를 활용하면 아래처럼 좀 더 쉽게 추상화할 수 있습니다.
```typescript
export class CheckboxView<T extends CheckboxData> extends View<T> {
tagName: string = 'li';
template({ checked }: T) {
return html`
<${this.tagName} class="${checked ? 'checked' : ''}">
${this.createSubView()}
</${this.tagName}>
`;
}
createSubView() {
return html``;
}
}
export class ColorCheckboxView extends CheckboxView<Color> {
createSubView() {
return html`${new ColorView(this.data)}`;
}
}
```
## Enable

@@ -535,7 +588,4 @@

class Checkable<T extends CheckableData> extends Enable<T> {
onMount() {
this.addEventListener('click', this.onClick);
}
onClick() {
@on('click')
toggle() {
this.view.data.checked = !this.view.data.checked;

@@ -557,3 +607,3 @@ this.view.element().classList.toggle('checked');

override template(color: Color) {
template(color: Color) {
return html`

@@ -575,3 +625,3 @@ <div class="${color.checked ? 'checked' : ''}" style="background-color: ${color.code}">

```typescript
onClick() {
toggle() {
this.data.checked = !this.data.checked;

@@ -585,4 +635,21 @@ this.element().classList.toggle('checked');

`Enable`에서 `this.view.data === this.data` 이고 `this.view.element() === this.element()` 이기 때문에 onClick 영역을 위 코드처럼 변경할 수 있습니다. 이는 `View`를 작성할 때 만들었던 코드를 `Enable`로 옮겨 재사용가능한 코드로 만들고자 할 때 용이하게 합니다.
`Enable`에서 `this.view.data === this.data` 이고 `this.view.element() === this.element()` 이기 때문에 toggle 영역을 위 코드처럼 변경할 수 있습니다. 이는 `View`를 작성할 때 만들었던 코드를 `Enable`로 옮겨 재사용가능한 코드로 만들고자 할 때 용이하게 합니다.
### @enable 데코레이터
@enable 데코레이터를 활용하면 `CheckableColorView`를 간결하게 꾸며줄 수 있습니다.
```typescript
@enable(Checkable)
class CheckableColorView extends View<Color> {
template(color: Color) {
return html`
<div class="${color.checked ? 'checked' : ''}" style="background-color: ${color.code}">
</div>
`;
}
}
```
### 데이터 공유가 없는 View 확장

@@ -610,3 +677,3 @@

override template() {
template() {
return html`

@@ -636,3 +703,3 @@ <div style="

### ExtraViewInterface
### ViewExtraInterface

@@ -642,8 +709,8 @@ 위 코드에서는 `Deletable`의 삭제를 트리거하는 엘리먼트의 클래스명을 `remove-target`라는 문자열로 약속을 했습니다. `interface`를 활용하면 객체간 통신의 규약을 더 확장성이 있으면서도 안전하게 추상화할 수 있습니다.

```typescript
interface DeletableExtraViewInterface {
interface DeletableViewExtraInterface {
readonly targetClassName: string;
}
export class Deletable extends Enable<unknown, DeletableExtraViewInterface> {
override onMount() {
export class Deletable extends Enable<unknown, DeletableViewExtraInterface> {
onMount() {
this.delegate('mousedown', `.${this.view.targetClassName}`, this.remove);

@@ -659,5 +726,6 @@ }

deletable = new Deletable(this).init();
readonly targetClassName = 'target';
override template() {
template() {
return html`

@@ -681,3 +749,3 @@ <div style="

이제 `BallView`에서 `targetClassName`를 구현하지 않는다면 `Argument of type this is not assignable to parameter of type View<unknown> & DeletableExtraViewInterface`와 같은 에러메시지가 출력되어 개발자가 반드시 구현하도록 가이드를 줄 수 있습니다.
이제 `BallView`에서 `targetClassName`를 구현하지 않는다면 `Argument of type this is not assignable to parameter of type View<unknown> & DeletableViewExtraInterface`와 같은 에러메시지가 출력되어 개발자가 반드시 구현하도록 가이드를 줄 수 있습니다.

@@ -687,3 +755,3 @@ 다음은 객체간 통신의 예시로 `Deletable`이 `View`에게 `canRemove()`를 물어보고 삭제하도록 인터페이스와 구현을 추가했습니다.

```typescript
interface DeletableExtraViewInterface {
interface DeletableViewExtraInterface {
readonly targetClassName: string;

@@ -693,4 +761,4 @@ canRemove(): boolean;

export class Deletable extends Enable<unknown, DeletableExtraViewInterface> {
override onMount() {
export class Deletable extends Enable<unknown, DeletableViewExtraInterface> {
onMount() {
this.delegate('mousedown', `.${this.view.targetClassName}`, this.remove);

@@ -713,3 +781,5 @@ }

deletable = new Deletable(this).init();
readonly targetClassName = 'target';
canRemove() {

@@ -719,3 +789,3 @@ return confirm('삭제하시겠습니까?');

override template() {
template() {
return html`

@@ -756,5 +826,6 @@ ...

movable = new Movable(this).init();
deletable = new Deletable(this).init();
readonly targetClassName = 'target';
canRemove() {

@@ -764,3 +835,3 @@ return confirm('삭제하시겠습니까?');

override template() {
template() {
return html`

@@ -783,5 +854,6 @@ ...

movable = new Movable(this).init();
deletable = new Deletable(this).init();
readonly targetClassName = 'target';
canRemove() {

@@ -791,3 +863,3 @@ return --this.data.count === 0;

override template() {
template() {
return html`

@@ -794,0 +866,0 @@ ...

{
"name": "rune-ts",
"version": "0.0.3",
"version": "0.0.4",
"description": "Rune Core Library",

@@ -5,0 +5,0 @@ "engines": {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc