@simplysm/angular 14.0.51 → 14.0.53
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/data/sheet/sd-sheet.d.ts +9 -12
- package/dist/data/sheet/sd-sheet.d.ts.map +1 -1
- package/dist/data/sheet/sd-sheet.js +150 -168
- package/dist/data/sheet/types.d.ts +1 -0
- package/dist/data/sheet/types.d.ts.map +1 -1
- package/dist/data/sheet/useSheetCellStyling.d.ts +2 -2
- package/dist/data/sheet/useSheetCellStyling.d.ts.map +1 -1
- package/dist/data/sheet/useSheetCellStyling.js +20 -12
- package/dist/data/sheet/useSheetColumnFixing.d.ts +3 -8
- package/dist/data/sheet/useSheetColumnFixing.d.ts.map +1 -1
- package/dist/data/sheet/useSheetColumnFixing.js +19 -27
- package/dist/data/sheet/useSheetLayoutEngine.d.ts.map +1 -1
- package/dist/data/sheet/useSheetLayoutEngine.js +4 -1
- package/dist/layout/dock/sd-dock-container.d.ts.map +1 -1
- package/dist/layout/dock/sd-dock-container.js +3 -3
- package/package.json +7 -8
- package/src/data/sheet/sd-sheet.ts +39 -60
- package/src/data/sheet/types.ts +1 -0
- package/src/data/sheet/useSheetCellStyling.ts +19 -11
- package/src/data/sheet/useSheetColumnFixing.ts +21 -28
- package/src/data/sheet/useSheetLayoutEngine.ts +4 -1
- package/src/layout/dock/sd-dock-container.ts +1 -0
- package/README.md +0 -476
- package/docs/bootstrap/provide-sd-angular.md +0 -37
- package/docs/bootstrap/sd-angular-config-provider.md +0 -16
- package/docs/directives/sd-command-directive.md +0 -30
- package/docs/directives/sd-events.md +0 -25
- package/docs/directives/sd-intersection-directive.md +0 -36
- package/docs/directives/sd-invalid.md +0 -24
- package/docs/directives/sd-resize-directive.md +0 -42
- package/docs/directives/sd-ripple.md +0 -23
- package/docs/directives/sd-router-link.md +0 -38
- package/docs/directives/sd-show-effect.md +0 -18
- package/docs/directives/sd-typed-template.md +0 -69
- package/docs/features/sd-address-search-modal.md +0 -50
- package/docs/features/sd-permission-table.md +0 -20
- package/docs/features/sd-shared-data-components.md +0 -158
- package/docs/features/sd-tiptap-editor.md +0 -26
- package/docs/pipes/format-pipe.md +0 -41
- package/docs/plugins/sd-global-error-handler.md +0 -23
- package/docs/plugins/sd-option-event-plugin.md +0 -34
- package/docs/provider-types/sd-menu.md +0 -65
- package/docs/provider-types/sd-modal-content-def.md +0 -148
- package/docs/provider-types/sd-toast-content-def.md +0 -73
- package/docs/provider-types/shared-data-base.md +0 -59
- package/docs/providers/sd-activated-modal-provider.md +0 -34
- package/docs/providers/sd-app-structure-provider.md +0 -81
- package/docs/providers/sd-busy-provider.md +0 -18
- package/docs/providers/sd-file-dialog-provider.md +0 -40
- package/docs/providers/sd-local-storage-provider.md +0 -20
- package/docs/providers/sd-modal-provider.md +0 -67
- package/docs/providers/sd-navigate-window-provider.md +0 -18
- package/docs/providers/sd-print-provider.md +0 -25
- package/docs/providers/sd-service-client-factory-provider.md +0 -43
- package/docs/providers/sd-shared-data-provider.md +0 -64
- package/docs/providers/sd-system-config-provider.md +0 -46
- package/docs/providers/sd-system-log-provider.md +0 -18
- package/docs/providers/sd-theme-provider.md +0 -38
- package/docs/providers/sd-toast-provider.md +0 -65
- package/docs/recipes/_common-rules.md +0 -244
- package/docs/recipes/crud-detail/extension-a-edit-save.md +0 -230
- package/docs/recipes/crud-detail/extension-b-delete-restore.md +0 -142
- package/docs/recipes/crud-detail/extension-c-modal-view.md +0 -214
- package/docs/recipes/crud-detail/extension-d-control-view.md +0 -103
- package/docs/recipes/crud-detail/extension-e-auxiliary.md +0 -87
- package/docs/recipes/crud-detail/extension-f-complex-detail.md +0 -234
- package/docs/recipes/crud-detail.md +0 -353
- package/docs/recipes/crud-list/extension-a-inline-edit.md +0 -410
- package/docs/recipes/crud-list/extension-b-selection.md +0 -226
- package/docs/recipes/crud-list/extension-c-inline-delete.md +0 -87
- package/docs/recipes/crud-list/extension-d-select-modal.md +0 -207
- package/docs/recipes/crud-list/extension-e-readonly-modal.md +0 -165
- package/docs/recipes/crud-list/extension-f-modal-edit.md +0 -177
- package/docs/recipes/crud-list/extension-g-excel.md +0 -157
- package/docs/recipes/crud-list.md +0 -446
- package/docs/recipes/data-select-button.md +0 -412
- package/docs/recipes/page-modal-container.md +0 -260
- package/docs/styling/classes.md +0 -149
- package/docs/styling/mixins.md +0 -100
- package/docs/styling/themes.md +0 -35
- package/docs/styling/variables.md +0 -147
- package/docs/type-utilities/directive-input-signals.md +0 -232
- package/docs/ui-data/sd-list.md +0 -37
- package/docs/ui-data/sd-sheet.md +0 -227
- package/docs/ui-form/sd-additional-button.md +0 -26
- package/docs/ui-form/sd-anchor.md +0 -31
- package/docs/ui-form/sd-button.md +0 -105
- package/docs/ui-form/sd-checkbox-group.md +0 -39
- package/docs/ui-form/sd-checkbox.md +0 -81
- package/docs/ui-form/sd-date-range-picker.md +0 -27
- package/docs/ui-form/sd-form.md +0 -89
- package/docs/ui-form/sd-modal-select-button.md +0 -54
- package/docs/ui-form/sd-numpad.md +0 -26
- package/docs/ui-form/sd-range.md +0 -26
- package/docs/ui-form/sd-select.md +0 -68
- package/docs/ui-form/sd-shared-data-select.md +0 -52
- package/docs/ui-form/sd-state-preset.md +0 -37
- package/docs/ui-form/sd-switch.md +0 -27
- package/docs/ui-form/sd-textarea.md +0 -33
- package/docs/ui-form/sd-textfield.md +0 -145
- package/docs/ui-layout/sd-dock-container.md +0 -64
- package/docs/ui-layout/sd-dock.md +0 -37
- package/docs/ui-layout/sd-gap.md +0 -26
- package/docs/ui-layout/sd-kanban-board.md +0 -96
- package/docs/ui-layout/sd-kanban-lane.md +0 -34
- package/docs/ui-layout/sd-kanban.md +0 -29
- package/docs/ui-navigation/sd-collapse.md +0 -35
- package/docs/ui-navigation/sd-pagination.md +0 -26
- package/docs/ui-navigation/sd-sidebar-container.md +0 -49
- package/docs/ui-navigation/sd-sidebar-menu.md +0 -22
- package/docs/ui-navigation/sd-sidebar-user.md +0 -43
- package/docs/ui-navigation/sd-tab.md +0 -51
- package/docs/ui-navigation/sd-topbar-container.md +0 -97
- package/docs/ui-navigation/sd-topbar-menu.md +0 -23
- package/docs/ui-navigation/sd-topbar-user.md +0 -38
- package/docs/ui-navigation/sd-topbar.md +0 -30
- package/docs/ui-overlay/sd-busy-container.md +0 -69
- package/docs/ui-overlay/sd-confirm-modal.md +0 -30
- package/docs/ui-overlay/sd-dropdown.md +0 -40
- package/docs/ui-overlay/sd-modal.md +0 -34
- package/docs/ui-overlay/sd-prompt-modal.md +0 -30
- package/docs/ui-overlay/sd-toast.md +0 -35
- package/docs/ui-visual/sd-barcode.md +0 -36
- package/docs/ui-visual/sd-calendar.md +0 -34
- package/docs/ui-visual/sd-echarts.md +0 -32
- package/docs/ui-visual/sd-label.md +0 -24
- package/docs/ui-visual/sd-note.md +0 -23
- package/docs/ui-visual/sd-progress.md +0 -23
- package/docs/utils/inject-routing-signals.md +0 -161
- package/docs/utils/inject-sd-system-config-resource.md +0 -35
- package/docs/utils/mark.md +0 -43
- package/docs/utils/selection-managers.md +0 -96
- package/docs/utils/set-safe-style.md +0 -19
- package/docs/utils/setup-functions.md +0 -93
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
# `SdCommandDirective`
|
|
2
|
-
|
|
3
|
-
키보드 단축키를 output 이벤트로 제공하는 디렉티브. `document` keydown을 감지하며, `shouldProcessCommandEvent()`로 최상위 모달만 이벤트 처리한다.
|
|
4
|
-
|
|
5
|
-
```typescript
|
|
6
|
-
@Directive({ selector: "[sdRefreshCommand],[sdSaveCommand],[sdInsertCommand]" })
|
|
7
|
-
class SdCommandDirective {
|
|
8
|
-
sdRefreshCommand = output<KeyboardEvent>(); // Ctrl+Alt+L
|
|
9
|
-
sdSaveCommand = output<KeyboardEvent>(); // Ctrl+S
|
|
10
|
-
sdInsertCommand = output<KeyboardEvent>(); // Ctrl+Insert
|
|
11
|
-
}
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
## Members
|
|
15
|
-
|
|
16
|
-
| Member | Kind | Type | Description |
|
|
17
|
-
|--------|------|------|-------------|
|
|
18
|
-
| `sdRefreshCommand` | output | `KeyboardEvent` | Ctrl+Alt+L 단축키 이벤트 |
|
|
19
|
-
| `sdSaveCommand` | output | `KeyboardEvent` | Ctrl+S 단축키 이벤트 |
|
|
20
|
-
| `sdInsertCommand` | output | `KeyboardEvent` | Ctrl+Insert 단축키 이벤트 |
|
|
21
|
-
|
|
22
|
-
## Usage
|
|
23
|
-
|
|
24
|
-
```html
|
|
25
|
-
<div
|
|
26
|
-
(sdSaveCommand)="onSave($event)"
|
|
27
|
-
(sdRefreshCommand)="onRefresh($event)"
|
|
28
|
-
(sdInsertCommand)="onInsert($event)"
|
|
29
|
-
></div>
|
|
30
|
-
```
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
# `SdEvents`
|
|
2
|
-
|
|
3
|
-
`.capture`, `.passive`, `.once` 수식어 및 커스텀 이벤트 바인딩을 지원하는 디렉티브. Angular 템플릿에서 해당 이벤트를 사용할 때 자동 매칭된다.
|
|
4
|
-
|
|
5
|
-
```typescript
|
|
6
|
-
@Directive({
|
|
7
|
-
selector: `[click.capture], [scroll.passive], ...`,
|
|
8
|
-
})
|
|
9
|
-
class SdEvents {}
|
|
10
|
-
```
|
|
11
|
-
|
|
12
|
-
## 지원 이벤트
|
|
13
|
-
|
|
14
|
-
- 클릭: `click.capture`, `click.once`, `click.capture.once`
|
|
15
|
-
- 마우스: `mousedown.capture`, `mouseup.capture`, `mouseover.capture`, `mouseout.capture`
|
|
16
|
-
- 키보드: `keydown.capture`, `keyup.capture`
|
|
17
|
-
- 포커스: `focus.capture`, `blur.capture`
|
|
18
|
-
- 폼: `invalid.capture`
|
|
19
|
-
- 스크롤: `scroll.capture`, `scroll.passive`, `scroll.capture.passive`
|
|
20
|
-
- 휠: `wheel.passive`, `wheel.capture.passive`
|
|
21
|
-
- 터치: `touchstart.passive`, `touchstart.capture.passive`, `touchmove.passive`, `touchmove.capture.passive`, `touchend.passive`
|
|
22
|
-
- 드래그: `dragover.capture`, `dragenter.capture`, `dragleave.capture`, `drop.capture`
|
|
23
|
-
- 애니메이션: `transitionend.once`, `animationend.once`
|
|
24
|
-
|
|
25
|
-
> **NOTE:** `sdResize`, `sdSaveCommand`, `sdRefreshCommand`, `sdInsertCommand`는 `SdEvents`에서 분리되어 각각 [`SdResizeDirective`](./sd-resize-directive.md), [`SdIntersectionDirective`](./sd-intersection-directive.md), [`SdCommandDirective`](./sd-command-directive.md)로 독립 디렉티브로 제공된다.
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
# `SdIntersectionDirective`
|
|
2
|
-
|
|
3
|
-
IntersectionObserver 기반 intersection output 이벤트 디렉티브.
|
|
4
|
-
|
|
5
|
-
```typescript
|
|
6
|
-
@Directive({ selector: "[sdIntersection]" })
|
|
7
|
-
class SdIntersectionDirective {
|
|
8
|
-
sdIntersection = output<SdIntersectionEvent>();
|
|
9
|
-
}
|
|
10
|
-
```
|
|
11
|
-
|
|
12
|
-
## Members
|
|
13
|
-
|
|
14
|
-
| Member | Kind | Type | Description |
|
|
15
|
-
|--------|------|------|-------------|
|
|
16
|
-
| `sdIntersection` | output | `SdIntersectionEvent` | 뷰포트와의 교차 변경 시 발생 |
|
|
17
|
-
|
|
18
|
-
## Related Types
|
|
19
|
-
|
|
20
|
-
### `SdIntersectionEvent`
|
|
21
|
-
|
|
22
|
-
```typescript
|
|
23
|
-
interface SdIntersectionEvent {
|
|
24
|
-
entry: IntersectionObserverEntry;
|
|
25
|
-
}
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
| Field | Type | Description |
|
|
29
|
-
|-------|------|-------------|
|
|
30
|
-
| `entry` | `IntersectionObserverEntry` | 마지막 IntersectionObserver 엔트리 |
|
|
31
|
-
|
|
32
|
-
## Usage
|
|
33
|
-
|
|
34
|
-
```html
|
|
35
|
-
<div (sdIntersection)="onIntersect($event)"></div>
|
|
36
|
-
```
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
# `SdInvalid`
|
|
2
|
-
|
|
3
|
-
호스트 요소에 유효성 검증 표시기를 추가하는 디렉티브. 빨간 점 표시기와 숨겨진 input으로 구성.
|
|
4
|
-
|
|
5
|
-
```typescript
|
|
6
|
-
@Directive({ selector: "[sdInvalid]" })
|
|
7
|
-
class SdInvalid {
|
|
8
|
-
invalidMessage = input.required<string>({ alias: "sdInvalid" });
|
|
9
|
-
}
|
|
10
|
-
```
|
|
11
|
-
|
|
12
|
-
## Members
|
|
13
|
-
|
|
14
|
-
| Member | Kind | Type | Description |
|
|
15
|
-
|--------|------|------|-------------|
|
|
16
|
-
| `invalidMessage` (`sdInvalid`) | input (required) | `string` | 유효성 오류 메시지. 빈 문자열이면 유효, 비어있지 않으면 무효 |
|
|
17
|
-
|
|
18
|
-
## Usage
|
|
19
|
-
|
|
20
|
-
```html
|
|
21
|
-
<div [sdInvalid]="name이 비어있습니다">
|
|
22
|
-
<!-- 메시지가 있으면 빨간 점 표시기 노출 -->
|
|
23
|
-
</div>
|
|
24
|
-
```
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
# `SdResizeDirective`
|
|
2
|
-
|
|
3
|
-
ResizeObserver 기반 resize output 이벤트 디렉티브. `requestAnimationFrame`으로 디바운스.
|
|
4
|
-
|
|
5
|
-
```typescript
|
|
6
|
-
@Directive({ selector: "[sdResize]" })
|
|
7
|
-
class SdResizeDirective {
|
|
8
|
-
sdResize = output<SdResizeEvent>();
|
|
9
|
-
}
|
|
10
|
-
```
|
|
11
|
-
|
|
12
|
-
## Members
|
|
13
|
-
|
|
14
|
-
| Member | Kind | Type | Description |
|
|
15
|
-
|--------|------|------|-------------|
|
|
16
|
-
| `sdResize` | output | `SdResizeEvent` | 요소 크기 변경 시 발생 |
|
|
17
|
-
|
|
18
|
-
## Related Types
|
|
19
|
-
|
|
20
|
-
### `SdResizeEvent`
|
|
21
|
-
|
|
22
|
-
```typescript
|
|
23
|
-
interface SdResizeEvent {
|
|
24
|
-
heightChanged: boolean;
|
|
25
|
-
widthChanged: boolean;
|
|
26
|
-
target: HTMLElement;
|
|
27
|
-
contentRect: DOMRectReadOnly;
|
|
28
|
-
}
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
| Field | Type | Description |
|
|
32
|
-
|-------|------|-------------|
|
|
33
|
-
| `heightChanged` | `boolean` | 높이 변경 여부 |
|
|
34
|
-
| `widthChanged` | `boolean` | 너비 변경 여부 |
|
|
35
|
-
| `target` | `HTMLElement` | 대상 요소 |
|
|
36
|
-
| `contentRect` | `DOMRectReadOnly` | 컨텐츠 영역 크기 |
|
|
37
|
-
|
|
38
|
-
## Usage
|
|
39
|
-
|
|
40
|
-
```html
|
|
41
|
-
<div (sdResize)="onResize($event)"></div>
|
|
42
|
-
```
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# `SdRipple`
|
|
2
|
-
|
|
3
|
-
호스트 요소에 리플 효과를 추가하는 디렉티브.
|
|
4
|
-
|
|
5
|
-
```typescript
|
|
6
|
-
@Directive({ selector: "[sdRipple]" })
|
|
7
|
-
class SdRipple {
|
|
8
|
-
enabled = input.required({ alias: "sdRipple", transform: booleanAttribute });
|
|
9
|
-
}
|
|
10
|
-
```
|
|
11
|
-
|
|
12
|
-
## Members
|
|
13
|
-
|
|
14
|
-
| Member | Kind | Type | Description |
|
|
15
|
-
|--------|------|------|-------------|
|
|
16
|
-
| `enabled` (`sdRipple`) | input (required) | `boolean` | 리플 효과 활성화 여부 |
|
|
17
|
-
|
|
18
|
-
## Usage
|
|
19
|
-
|
|
20
|
-
```html
|
|
21
|
-
<div [sdRipple]="true">리플 효과 있음</div>
|
|
22
|
-
<div sdRipple>리플 효과 있음 (boolean attribute)</div>
|
|
23
|
-
```
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
# `SdRouterLink`
|
|
2
|
-
|
|
3
|
-
라우터 네비게이션 디렉티브. 일반 클릭은 라우터 네비게이션, Ctrl/Shift+클릭은 새 창, 팝업 윈도우에서는 팝업 형태로 열린다.
|
|
4
|
-
|
|
5
|
-
```typescript
|
|
6
|
-
@Directive({
|
|
7
|
-
selector: "[sdRouterLink]",
|
|
8
|
-
host: {
|
|
9
|
-
"[style.cursor]": "option() ? 'pointer' : ''",
|
|
10
|
-
"(click)": "onClick($event)",
|
|
11
|
-
},
|
|
12
|
-
})
|
|
13
|
-
class SdRouterLink {
|
|
14
|
-
option = input<{
|
|
15
|
-
link: string;
|
|
16
|
-
params?: Record<string, string>;
|
|
17
|
-
window?: { width?: number; height?: number };
|
|
18
|
-
outletName?: string;
|
|
19
|
-
queryParams?: Record<string, string>;
|
|
20
|
-
} | undefined>(undefined, { alias: "sdRouterLink" });
|
|
21
|
-
}
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
## Members
|
|
25
|
-
|
|
26
|
-
| Member | Kind | Type | Description |
|
|
27
|
-
|--------|------|------|-------------|
|
|
28
|
-
| `option` (`sdRouterLink`) | input | `{ link, params?, window?, outletName?, queryParams? } \| undefined` | 라우터 링크 옵션 |
|
|
29
|
-
|
|
30
|
-
## Option Fields
|
|
31
|
-
|
|
32
|
-
| Field | Type | Description |
|
|
33
|
-
|-------|------|-------------|
|
|
34
|
-
| `link` | `string` | 네비게이션 경로 |
|
|
35
|
-
| `params` | `Record<string, string> \| undefined` | 라우터 파라미터 |
|
|
36
|
-
| `window` | `{ width?, height? } \| undefined` | 팝업 윈도우 크기 (설정 시 팝업으로 열림) |
|
|
37
|
-
| `outletName` | `string \| undefined` | named outlet |
|
|
38
|
-
| `queryParams` | `Record<string, string> \| undefined` | 쿼리 파라미터 |
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
# `SdShowEffect`
|
|
2
|
-
|
|
3
|
-
뷰포트에 진입할 때 reveal 애니메이션을 적용하는 디렉티브. IntersectionObserver 사용.
|
|
4
|
-
|
|
5
|
-
```typescript
|
|
6
|
-
@Directive({ selector: "[sdShowEffect]" })
|
|
7
|
-
class SdShowEffect {
|
|
8
|
-
enabled = input.required({ alias: "sdShowEffect", transform: booleanAttribute });
|
|
9
|
-
sdShowEffectType = input<"l2r" | "t2b">("t2b");
|
|
10
|
-
}
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
## Members
|
|
14
|
-
|
|
15
|
-
| Member | Kind | Type | Default | Description |
|
|
16
|
-
|--------|------|------|---------|-------------|
|
|
17
|
-
| `enabled` (`sdShowEffect`) | input (required) | `boolean` | - | 효과 활성화 여부 |
|
|
18
|
-
| `sdShowEffectType` | input | `"l2r" \| "t2b"` | `"t2b"` | 애니메이션 방향 (좌→우 / 위→아래) |
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
# `SdTypedTemplate`
|
|
2
|
-
|
|
3
|
-
`ng-template`의 컨텍스트 타입을 지정하는 디렉티브. 타입 가드를 통해 템플릿 내부에서 정확한 타입을 사용할 수 있다.
|
|
4
|
-
|
|
5
|
-
```typescript
|
|
6
|
-
@Directive({ selector: "ng-template[typed]" })
|
|
7
|
-
class SdTypedTemplate<T> {
|
|
8
|
-
typed = input.required<T>();
|
|
9
|
-
|
|
10
|
-
static ngTemplateContextGuard<TypeToken>(
|
|
11
|
-
_dir: SdTypedTemplate<TypeToken>,
|
|
12
|
-
_ctx: unknown,
|
|
13
|
-
): _ctx is TypeToken;
|
|
14
|
-
}
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
## Members
|
|
18
|
-
|
|
19
|
-
| Member | Kind | Type | Description |
|
|
20
|
-
|--------|------|------|-------------|
|
|
21
|
-
| `typed` | input (required) | `T` | 컨텍스트 타입 토큰 |
|
|
22
|
-
|
|
23
|
-
## Related Types
|
|
24
|
-
|
|
25
|
-
### `SdItemOfTemplate`
|
|
26
|
-
|
|
27
|
-
항목 반복 템플릿의 컨텍스트 타입을 지정하는 디렉티브.
|
|
28
|
-
|
|
29
|
-
```typescript
|
|
30
|
-
@Directive({ selector: "ng-template[itemOf]" })
|
|
31
|
-
class SdItemOfTemplate<TItem> {
|
|
32
|
-
itemOf = input.required<TItem[]>();
|
|
33
|
-
|
|
34
|
-
static ngTemplateContextGuard<TContextItem>(
|
|
35
|
-
_dir: SdItemOfTemplate<TContextItem>,
|
|
36
|
-
_ctx: unknown,
|
|
37
|
-
): _ctx is SdItemOfTemplateContext<TContextItem>;
|
|
38
|
-
}
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
### `SdItemOfTemplateContext`
|
|
42
|
-
|
|
43
|
-
```typescript
|
|
44
|
-
interface SdItemOfTemplateContext<TItem> {
|
|
45
|
-
$implicit: TItem;
|
|
46
|
-
item: TItem;
|
|
47
|
-
index: number;
|
|
48
|
-
depth: number;
|
|
49
|
-
}
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
| Field | Type | Description |
|
|
53
|
-
|-------|------|-------------|
|
|
54
|
-
| `$implicit` | `TItem` | 현재 항목 (let-item으로 접근) |
|
|
55
|
-
| `item` | `TItem` | 현재 항목 (명시적 접근) |
|
|
56
|
-
| `index` | `number` | 인덱스 |
|
|
57
|
-
| `depth` | `number` | 깊이 (트리 구조에서 사용) |
|
|
58
|
-
|
|
59
|
-
## Usage
|
|
60
|
-
|
|
61
|
-
```html
|
|
62
|
-
<ng-template [typed]="typedVar" let-item>
|
|
63
|
-
<!-- item의 타입이 typeof typedVar -->
|
|
64
|
-
</ng-template>
|
|
65
|
-
|
|
66
|
-
<ng-template [itemOf]="items()" let-item let-index="index">
|
|
67
|
-
{{ item.name }}
|
|
68
|
-
</ng-template>
|
|
69
|
-
```
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
# `SdAddressSearchModal`
|
|
2
|
-
|
|
3
|
-
Daum Postcode API를 사용한 주소 검색 모달. `SdModalContentDef<Address>`를 구현한다.
|
|
4
|
-
|
|
5
|
-
```typescript
|
|
6
|
-
@Component({ selector: "sd-address-search-modal" })
|
|
7
|
-
class SdAddressSearchModal implements SdModalContentDef<Address>, OnInit {
|
|
8
|
-
close = output<Address>();
|
|
9
|
-
initialized = signal(false);
|
|
10
|
-
}
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
## Members
|
|
14
|
-
|
|
15
|
-
| Member | Kind | Type | Description |
|
|
16
|
-
|--------|------|------|-------------|
|
|
17
|
-
| `close` | output | `Address` | 주소 선택 완료 시 발생 |
|
|
18
|
-
| `initialized` | signal | `boolean` | 초기화 완료 여부 |
|
|
19
|
-
|
|
20
|
-
## Related Types
|
|
21
|
-
|
|
22
|
-
### `Address`
|
|
23
|
-
|
|
24
|
-
```typescript
|
|
25
|
-
interface Address {
|
|
26
|
-
postNumber: string | undefined;
|
|
27
|
-
address: string | undefined;
|
|
28
|
-
buildingName: string | undefined;
|
|
29
|
-
}
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
| Field | Type | Description |
|
|
33
|
-
|-------|------|-------------|
|
|
34
|
-
| `postNumber` | `string \| undefined` | 우편번호 |
|
|
35
|
-
| `address` | `string \| undefined` | 주소 |
|
|
36
|
-
| `buildingName` | `string \| undefined` | 건물명 |
|
|
37
|
-
|
|
38
|
-
## Usage
|
|
39
|
-
|
|
40
|
-
```typescript
|
|
41
|
-
const result = await this._sdModal.showAsync({
|
|
42
|
-
title: "주소 검색",
|
|
43
|
-
type: SdAddressSearchModal,
|
|
44
|
-
inputs: {},
|
|
45
|
-
});
|
|
46
|
-
if (result != null) {
|
|
47
|
-
this.data().address = result.address;
|
|
48
|
-
mark(this.data);
|
|
49
|
-
}
|
|
50
|
-
```
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
# `SdPermissionTable`
|
|
2
|
-
|
|
3
|
-
권한 매트릭스 테이블. `SdPermission` 트리를 테이블로 렌더링하여 use/edit 체크박스를 표시한다.
|
|
4
|
-
|
|
5
|
-
```typescript
|
|
6
|
-
@Component({ selector: "sd-permission-table" })
|
|
7
|
-
class SdPermissionTable<TModule = unknown> {
|
|
8
|
-
value = model<Record<string, boolean>>({});
|
|
9
|
-
items = input<SdPermission<TModule>[]>([]);
|
|
10
|
-
disabled = input(false, { transform: booleanAttribute });
|
|
11
|
-
}
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
## Members
|
|
15
|
-
|
|
16
|
-
| Member | Kind | Type | Default | Description |
|
|
17
|
-
|--------|------|------|---------|-------------|
|
|
18
|
-
| `value` | model | `Record<string, boolean>` | `{}` | 권한 레코드 (two-way). 키는 `codeChain.join(".") + ".use"` 또는 `".edit"` 형태 |
|
|
19
|
-
| `items` | input | `SdPermission<TModule>[]` | `[]` | 권한 트리 |
|
|
20
|
-
| `disabled` | input | `boolean` | `false` | 비활성화 |
|
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
# Shared Data Components
|
|
2
|
-
|
|
3
|
-
공유 데이터(`SdSharedDataProvider`)와 연동하는 UI 컴포넌트 모음.
|
|
4
|
-
|
|
5
|
-
## `SdSharedDataSelect`
|
|
6
|
-
|
|
7
|
-
공유 데이터 드롭다운 선택 컴포넌트. 검색 기능 포함.
|
|
8
|
-
|
|
9
|
-
```typescript
|
|
10
|
-
@Component({ selector: "sd-shared-data-select" })
|
|
11
|
-
class SdSharedDataSelect<
|
|
12
|
-
TItem extends SharedDataBase<string | number>,
|
|
13
|
-
TMode extends keyof SelectModeValue<...>,
|
|
14
|
-
TModal extends SdSelectModal<any>
|
|
15
|
-
> {
|
|
16
|
-
value = model<SelectModeValue<TItem["__valueKey"] | undefined>[TMode]>();
|
|
17
|
-
items = input.required<TItem[]>();
|
|
18
|
-
disabled = input(false, { transform: booleanAttribute });
|
|
19
|
-
required = input(false, { transform: booleanAttribute });
|
|
20
|
-
useUndefined = input(false, { transform: booleanAttribute });
|
|
21
|
-
inset = input(false, { transform: booleanAttribute });
|
|
22
|
-
inline = input(false, { transform: booleanAttribute });
|
|
23
|
-
size = input<"sm" | "lg">();
|
|
24
|
-
selectMode = input("single" as TMode);
|
|
25
|
-
filterFn = input<(item: TItem, index: number, ...params: any[]) => boolean>();
|
|
26
|
-
filterFnParams = input<any[]>();
|
|
27
|
-
modal = input<SdSelectModalInfo<TModal>>();
|
|
28
|
-
editModal = input<SdModalInfo<SdModalContentDef<boolean>>>();
|
|
29
|
-
selectClass = input<string>();
|
|
30
|
-
multiSelectionDisplayDirection = input<"vertical">();
|
|
31
|
-
getIsHiddenFn = input<(item: TItem, index: number) => boolean>();
|
|
32
|
-
getSearchTextFn = input<(item: TItem, index: number) => string>();
|
|
33
|
-
displayOrderKeyProp = input<string>();
|
|
34
|
-
}
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
### Members
|
|
38
|
-
|
|
39
|
-
| Member | Kind | Type | Default | Description |
|
|
40
|
-
|--------|------|------|---------|-------------|
|
|
41
|
-
| `value` | model | `SelectModeValue<TItem["__valueKey"] \| undefined>[TMode]` | - | 선택된 값 (two-way) |
|
|
42
|
-
| `items` | input (required) | `TItem[]` | - | 공유 데이터 항목 |
|
|
43
|
-
| `disabled` | input | `boolean` | `false` | 비활성화 |
|
|
44
|
-
| `required` | input | `boolean` | `false` | 필수 |
|
|
45
|
-
| `useUndefined` | input | `boolean` | `false` | undefined 항목 포함 |
|
|
46
|
-
| `inset` | input | `boolean` | `false` | 삽입 스타일 |
|
|
47
|
-
| `inline` | input | `boolean` | `false` | 인라인 표시 |
|
|
48
|
-
| `size` | input | `"sm" \| "lg" \| undefined` | `undefined` | 크기 |
|
|
49
|
-
| `selectMode` | input | `TMode` | `"single"` | 선택 모드 |
|
|
50
|
-
| `filterFn` | input | `((item, index, ...params) => boolean) \| undefined` | `undefined` | 필터 함수 |
|
|
51
|
-
| `modal` | input | `SdSelectModalInfo<TModal> \| undefined` | `undefined` | 모달 선택 정보 |
|
|
52
|
-
|
|
53
|
-
### 시트 셀 내 사용 패턴
|
|
54
|
-
|
|
55
|
-
```html
|
|
56
|
-
<sd-sheet-column [header]="'거래처'" [key]="'vendorId'">
|
|
57
|
-
<ng-template [cell]="items()" let-item let-edit="edit">
|
|
58
|
-
<sd-shared-data-select
|
|
59
|
-
[items]="sharedVendors()"
|
|
60
|
-
[inset]="true"
|
|
61
|
-
[size]="'sm'"
|
|
62
|
-
[disabled]="!canEdit()"
|
|
63
|
-
[readonly]="!edit"
|
|
64
|
-
[(value)]="item.vendorId"
|
|
65
|
-
(valueChange)="mark(items)"
|
|
66
|
-
>
|
|
67
|
-
<ng-template [itemOf]="sharedVendors()">
|
|
68
|
-
<div class="flex-row gap-sm">
|
|
69
|
-
<div>{{ item.__searchText }}</div>
|
|
70
|
-
</div>
|
|
71
|
-
</ng-template>
|
|
72
|
-
</sd-shared-data-select>
|
|
73
|
-
</ng-template>
|
|
74
|
-
</sd-sheet-column>
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
시트 셀 내 사용 시 `[inset]="true" [size]="'sm'"`을 반드시 지정한다.
|
|
78
|
-
|
|
79
|
-
## `SdSharedDataSelectButton`
|
|
80
|
-
|
|
81
|
-
공유 데이터 모달 선택 버튼. `<sd-modal-select-button>`을 컴포지션하여 공유 데이터 항목을 표시한다.
|
|
82
|
-
|
|
83
|
-
```typescript
|
|
84
|
-
@Component({ selector: "sd-shared-data-select-button" })
|
|
85
|
-
class SdSharedDataSelectButton<
|
|
86
|
-
TItem extends SharedDataBase<string | number>,
|
|
87
|
-
TMode extends keyof SelectModeValue<string | number>,
|
|
88
|
-
TModal extends SdSelectModal<any>
|
|
89
|
-
> {
|
|
90
|
-
value = model<SelectModeValue<string | number>[TMode]>();
|
|
91
|
-
items = input<TItem[]>([]);
|
|
92
|
-
modal = input.required<SdSelectModalInfo<TModal>>();
|
|
93
|
-
selectMode = input<TMode>("single" as TMode);
|
|
94
|
-
disabled = input(false, { transform: booleanAttribute });
|
|
95
|
-
required = input(false, { transform: booleanAttribute });
|
|
96
|
-
inset = input(false, { transform: booleanAttribute });
|
|
97
|
-
size = input<"sm" | "lg">();
|
|
98
|
-
}
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
### Members
|
|
102
|
-
|
|
103
|
-
| Member | Kind | Type | Default | Description |
|
|
104
|
-
|--------|------|------|---------|-------------|
|
|
105
|
-
| `value` | model | `SelectModeValue<string \| number>[TMode]` | - | 선택된 값 (two-way) |
|
|
106
|
-
| `items` | input | `TItem[]` | `[]` | 공유 데이터 항목 |
|
|
107
|
-
| `modal` | input (required) | `SdSelectModalInfo<TModal>` | - | 모달 정보 |
|
|
108
|
-
| `selectMode` | input | `TMode` | `"single"` | 선택 모드 |
|
|
109
|
-
| `disabled` | input | `boolean` | `false` | 비활성화 |
|
|
110
|
-
| `required` | input | `boolean` | `false` | 필수 |
|
|
111
|
-
|
|
112
|
-
## `SdSharedDataSelectList`
|
|
113
|
-
|
|
114
|
-
공유 데이터 목록형 선택 컴포넌트. 검색, 페이지네이션, 외부 링크 기능을 포함한다.
|
|
115
|
-
|
|
116
|
-
```typescript
|
|
117
|
-
@Component({ selector: "sd-shared-data-select-list" })
|
|
118
|
-
class SdSharedDataSelectList<
|
|
119
|
-
TItem extends SharedDataBase<string | number>,
|
|
120
|
-
TModal extends SdSelectModal<any>
|
|
121
|
-
> {
|
|
122
|
-
selectedItem = model<TItem>();
|
|
123
|
-
canChangeFn = input<(item: TItem | undefined) => boolean | Promise<boolean>>(() => true);
|
|
124
|
-
items = input.required<TItem[]>();
|
|
125
|
-
selectedIcon = input<string>();
|
|
126
|
-
useUndefined = input(false, { transform: booleanAttribute });
|
|
127
|
-
filterFn = input<(item: TItem, index: number) => boolean>();
|
|
128
|
-
modal = input<SdSelectModalInfo<TModal>>();
|
|
129
|
-
header = input<string>();
|
|
130
|
-
pageItemCount = input<number>();
|
|
131
|
-
}
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
### Members
|
|
135
|
-
|
|
136
|
-
| Member | Kind | Type | Default | Description |
|
|
137
|
-
|--------|------|------|---------|-------------|
|
|
138
|
-
| `selectedItem` | model | `TItem \| undefined` | - | 선택된 항목 (two-way) |
|
|
139
|
-
| `canChangeFn` | input | `(item) => boolean \| Promise<boolean>` | `() => true` | 선택 변경 가능 여부 함수 |
|
|
140
|
-
| `items` | input (required) | `TItem[]` | - | 공유 데이터 항목 |
|
|
141
|
-
| `selectedIcon` | input | `string \| undefined` | `undefined` | 선택됨 아이콘 |
|
|
142
|
-
| `useUndefined` | input | `boolean` | `false` | undefined 항목 포함 |
|
|
143
|
-
| `filterFn` | input | `((item, index) => boolean) \| undefined` | `undefined` | 필터 함수 |
|
|
144
|
-
| `modal` | input | `SdSelectModalInfo<TModal> \| undefined` | `undefined` | 모달 선택 정보 |
|
|
145
|
-
| `header` | input | `string \| undefined` | `undefined` | 헤더 텍스트 |
|
|
146
|
-
| `pageItemCount` | input | `number \| undefined` | `undefined` | 페이지당 항목 수 |
|
|
147
|
-
|
|
148
|
-
Content children: `#headerTpl`, `#filterTpl`, `SdItemOfTemplate`, `#undefinedTpl`
|
|
149
|
-
|
|
150
|
-
## `matchesSearchText`
|
|
151
|
-
|
|
152
|
-
공백 구분 AND 조건 텍스트 검색 매칭 함수.
|
|
153
|
-
|
|
154
|
-
```typescript
|
|
155
|
-
function matchesSearchText(itemText: string, searchQuery: string | undefined): boolean
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
모든 검색어(공백으로 분할)가 `itemText`에 포함되면 `true`. `searchQuery`가 undefined이거나 빈 문자열이면 항상 `true`.
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# `SdTiptapEditor`
|
|
2
|
-
|
|
3
|
-
TipTap 기반 리치 텍스트 에디터 컴포넌트. 툴바를 통해 텍스트 서식(제목, 굵게, 기울임, 색상, 정렬 등)을 제어한다.
|
|
4
|
-
|
|
5
|
-
```typescript
|
|
6
|
-
@Component({ selector: "sd-tiptap-editor", ... })
|
|
7
|
-
export class SdTiptapEditor
|
|
8
|
-
```
|
|
9
|
-
|
|
10
|
-
## Members
|
|
11
|
-
|
|
12
|
-
| Member | Kind | Type | Description |
|
|
13
|
-
|--------|------|------|-------------|
|
|
14
|
-
| `value` | model | `string \| undefined` | HTML 콘텐츠 |
|
|
15
|
-
| `disabled` | input | `boolean` | 비활성화 — 툴바 숨김, 편집 불가 (기본값: `false`) |
|
|
16
|
-
| `readonly` | input | `boolean` | 읽기 전용 — 편집 불가, 툴바 표시 (기본값: `false`) |
|
|
17
|
-
| `required` | input | `boolean` | 필수 여부 (기본값: `false`) |
|
|
18
|
-
| `placeholder` | input | `string \| undefined` | 플레이스홀더 텍스트 |
|
|
19
|
-
| `validatorFn` | input | `(value: string \| undefined) => string \| undefined` | 커스텀 유효성 검사 함수 |
|
|
20
|
-
| `extensions` | input | `AnyExtension[] \| undefined` | 추가 TipTap 확장 (기본 확장: StarterKit, TextStyle, Color, Highlight, TextAlign, Image, Underline, Placeholder) |
|
|
21
|
-
|
|
22
|
-
## Usage
|
|
23
|
-
|
|
24
|
-
```html
|
|
25
|
-
<sd-tiptap-editor [(value)]="content" [placeholder]="'내용을 입력하세요'" />
|
|
26
|
-
```
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
# `FormatPipe`
|
|
2
|
-
|
|
3
|
-
DateTime, DateOnly, string 값을 포맷팅하는 파이프. 파이프명: `format`
|
|
4
|
-
|
|
5
|
-
```typescript
|
|
6
|
-
@Pipe({ name: "format" })
|
|
7
|
-
class FormatPipe implements PipeTransform {
|
|
8
|
-
transform(value: string | DateTime | DateOnly | undefined, format: string): string;
|
|
9
|
-
}
|
|
10
|
-
```
|
|
11
|
-
|
|
12
|
-
## Parameters
|
|
13
|
-
|
|
14
|
-
| Param | Type | Description |
|
|
15
|
-
|-------|------|-------------|
|
|
16
|
-
| `value` | `string \| DateTime \| DateOnly \| undefined` | 포맷팅할 값 |
|
|
17
|
-
| `format` | `string` | 포맷 문자열 |
|
|
18
|
-
|
|
19
|
-
## Returns
|
|
20
|
-
|
|
21
|
-
`string` — 포맷팅된 문자열. `undefined` 또는 `null` 입력 시 빈 문자열 반환.
|
|
22
|
-
|
|
23
|
-
## Usage
|
|
24
|
-
|
|
25
|
-
### DateTime / DateOnly
|
|
26
|
-
|
|
27
|
-
`value.toFormatString(format)`을 호출한다.
|
|
28
|
-
|
|
29
|
-
```html
|
|
30
|
-
{{ someDateTime | format: "yyyy-MM-dd HH:mm" }}
|
|
31
|
-
{{ someDateOnly | format: "yyyy년 MM월 dd일" }}
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
### String
|
|
35
|
-
|
|
36
|
-
format 문자열에서 `X` 문자를 값의 문자로 치환한다. `|`로 구분된 여러 포맷 중 길이가 일치하는 것을 사용한다.
|
|
37
|
-
|
|
38
|
-
```html
|
|
39
|
-
<!-- "01012345678" → "010-1234-5678" -->
|
|
40
|
-
{{ phone | format: "XXX-XXXX-XXXX|XX-XXX-XXXX|XX-XXXX-XXXX" }}
|
|
41
|
-
```
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# `SdGlobalErrorHandlerPlugin`
|
|
2
|
-
|
|
3
|
-
글로벌 에러 핸들러. Angular `ErrorHandler`를 구현하여 처리되지 않은 에러를 포착하고 화면에 표시한다.
|
|
4
|
-
|
|
5
|
-
```typescript
|
|
6
|
-
@Injectable({ providedIn: null })
|
|
7
|
-
export class SdGlobalErrorHandlerPlugin implements ErrorHandler
|
|
8
|
-
```
|
|
9
|
-
|
|
10
|
-
`provideSdAngular()`에 의해 자동 등록된다. 직접 등록할 필요 없다.
|
|
11
|
-
|
|
12
|
-
## Members
|
|
13
|
-
|
|
14
|
-
| Member | Kind | Type | Description |
|
|
15
|
-
|--------|------|------|-------------|
|
|
16
|
-
| `handleError(event)` | method | `(any) => void` | 에러 처리. `PromiseRejectionEvent`, `ErrorEvent`, `Error` 등을 구분하여 처리 |
|
|
17
|
-
|
|
18
|
-
## 동작
|
|
19
|
-
|
|
20
|
-
- `PromiseRejectionEvent` → reason이 `Error`면 메시지+스택, 객체면 JSON 표시
|
|
21
|
-
- `ErrorEvent` → error가 `Error`면 메시지+스택, string이면 그대로 표시
|
|
22
|
-
- `Error` → 메시지+스택 표시
|
|
23
|
-
- devMode에서는 toast로, prodMode에서는 alert로 표시 (중복 표시 방지)
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
# `SdOptionEventPlugin`
|
|
2
|
-
|
|
3
|
-
`.capture`, `.passive`, `.once` 이벤트 수식어 플러그인. 네이티브 DOM 이벤트에 addEventListener options를 적용한다. [`provideSdAngular`](../bootstrap/provide-sd-angular.md)에서 자동 등록된다.
|
|
4
|
-
|
|
5
|
-
```typescript
|
|
6
|
-
class SdOptionEventPlugin extends EventManagerPlugin {
|
|
7
|
-
supports(eventName: string): boolean; // /\.(capture|passive|once)/ 매칭
|
|
8
|
-
}
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Usage
|
|
12
|
-
|
|
13
|
-
```html
|
|
14
|
-
<div (scroll.passive)="onScroll($event)">...</div>
|
|
15
|
-
<div (click.capture.once)="onClick($event)">...</div>
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
## Related Types
|
|
19
|
-
|
|
20
|
-
### `SdGlobalErrorHandlerPlugin`
|
|
21
|
-
|
|
22
|
-
글로벌 에러 핸들러. Angular의 `ErrorHandler`를 구현하여 PromiseRejectionEvent, ErrorEvent, Error 등을 처리한다.
|
|
23
|
-
|
|
24
|
-
```typescript
|
|
25
|
-
class SdGlobalErrorHandlerPlugin implements ErrorHandler {
|
|
26
|
-
handleError(event: any): false;
|
|
27
|
-
}
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
에러 발생 시:
|
|
31
|
-
1. `SdSystemLogProvider.writeAsync()`로 로그 기록
|
|
32
|
-
2. 전체 화면 에러 메시지 표시 (검은 배경 + 흰 텍스트)
|
|
33
|
-
3. `ApplicationRef.destroy()` 호출하여 앱 정지
|
|
34
|
-
4. 클릭 시 페이지 리로드 (프로덕션에서는 `location.hash = "/"` 후 리로드)
|