@simplysm/sd-claude 14.0.88 → 14.0.89

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.
Files changed (122) hide show
  1. package/claude/references/sd-simplysm14/README.md +17 -17
  2. package/claude/references/sd-simplysm14/apis/angular/README.md +27 -53
  3. package/claude/references/sd-simplysm14/apis/angular/controls.md +37 -105
  4. package/claude/references/sd-simplysm14/apis/angular/crud.md +46 -43
  5. package/claude/references/sd-simplysm14/apis/angular/directives.md +22 -32
  6. package/claude/references/sd-simplysm14/apis/angular/features.md +40 -55
  7. package/claude/references/sd-simplysm14/apis/angular/infra.md +40 -40
  8. package/claude/references/sd-simplysm14/apis/angular/layout.md +25 -53
  9. package/claude/references/sd-simplysm14/apis/angular/overlay.md +70 -82
  10. package/claude/references/sd-simplysm14/apis/angular/routing-appstructure.md +44 -39
  11. package/claude/references/sd-simplysm14/apis/angular/selection-managers.md +21 -36
  12. package/claude/references/sd-simplysm14/apis/angular/shared-data.md +52 -65
  13. package/claude/references/sd-simplysm14/apis/angular/sheet.md +65 -70
  14. package/claude/references/sd-simplysm14/apis/capacitor-plugin-auto-update/README.md +33 -35
  15. package/claude/references/sd-simplysm14/apis/capacitor-plugin-file-system/README.md +7 -7
  16. package/claude/references/sd-simplysm14/apis/capacitor-plugin-intent/README.md +29 -29
  17. package/claude/references/sd-simplysm14/apis/capacitor-plugin-usb-storage/README.md +45 -50
  18. package/claude/references/sd-simplysm14/apis/core-browser/README.md +42 -55
  19. package/claude/references/sd-simplysm14/apis/core-browser/dom-element.md +62 -0
  20. package/claude/references/sd-simplysm14/apis/core-browser/indexed-db.md +13 -12
  21. package/claude/references/sd-simplysm14/apis/core-common/README.md +222 -98
  22. package/claude/references/sd-simplysm14/apis/core-common/array-ext.md +102 -53
  23. package/claude/references/sd-simplysm14/apis/core-common/async-runtime.md +128 -0
  24. package/claude/references/sd-simplysm14/apis/core-common/datetime.md +98 -64
  25. package/claude/references/sd-simplysm14/apis/core-common/errors.md +91 -0
  26. package/claude/references/sd-simplysm14/apis/core-common/json-transfer.md +34 -28
  27. package/claude/references/sd-simplysm14/apis/core-common/obj.md +104 -40
  28. package/claude/references/sd-simplysm14/apis/core-node/README.md +11 -8
  29. package/claude/references/sd-simplysm14/apis/core-node/consola.md +23 -31
  30. package/claude/references/sd-simplysm14/apis/core-node/cpx.md +33 -22
  31. package/claude/references/sd-simplysm14/apis/core-node/fs-watcher.md +28 -25
  32. package/claude/references/sd-simplysm14/apis/core-node/fsx.md +39 -53
  33. package/claude/references/sd-simplysm14/apis/core-node/pathx.md +26 -29
  34. package/claude/references/sd-simplysm14/apis/core-node/worker.md +27 -29
  35. package/claude/references/sd-simplysm14/apis/excel/README.md +14 -14
  36. package/claude/references/sd-simplysm14/apis/lint/README.md +27 -21
  37. package/claude/references/sd-simplysm14/apis/lint/rules.md +89 -49
  38. package/claude/references/sd-simplysm14/apis/orm-common/README.md +5 -59
  39. package/claude/references/sd-simplysm14/apis/orm-common/db-context.md +98 -67
  40. package/claude/references/sd-simplysm14/apis/orm-common/expr.md +107 -92
  41. package/claude/references/sd-simplysm14/apis/orm-common/queryable.md +99 -65
  42. package/claude/references/sd-simplysm14/apis/orm-common/schema.md +83 -98
  43. package/claude/references/sd-simplysm14/apis/orm-common/types.md +62 -52
  44. package/claude/references/sd-simplysm14/apis/orm-node/README.md +62 -25
  45. package/claude/references/sd-simplysm14/apis/orm-node/db-conn.md +27 -27
  46. package/claude/references/sd-simplysm14/apis/sd-cli/README.md +12 -15
  47. package/claude/references/sd-simplysm14/apis/sd-cli/SdTsCompiler.md +92 -45
  48. package/claude/references/sd-simplysm14/apis/sd-cli/sd-config-types.md +226 -108
  49. package/claude/references/sd-simplysm14/apis/service-client/README.md +84 -86
  50. package/claude/references/sd-simplysm14/apis/service-client/orm.md +14 -11
  51. package/claude/references/sd-simplysm14/apis/service-client/transport.md +33 -10
  52. package/claude/references/sd-simplysm14/apis/service-common/README.md +37 -23
  53. package/claude/references/sd-simplysm14/apis/service-common/app-structure.md +9 -9
  54. package/claude/references/sd-simplysm14/apis/service-common/protocol.md +13 -13
  55. package/claude/references/sd-simplysm14/apis/service-server/README.md +81 -65
  56. package/claude/references/sd-simplysm14/apis/service-server/service-authoring.md +32 -35
  57. package/claude/references/sd-simplysm14/apis/service-server/transport-internals.md +44 -33
  58. package/claude/references/sd-simplysm14/apis/service-server/v1-legacy.md +34 -45
  59. package/claude/references/sd-simplysm14/apis/storage/README.md +24 -18
  60. package/claude/skills/sd-demo/SKILL.md +6 -0
  61. package/claude/skills/sd-impl/SKILL.md +4 -7
  62. package/claude/skills/sd-spec/SKILL.md +31 -858
  63. package/claude/skills/sd-spec/references/spec-authoring.md +519 -0
  64. package/claude/workflows/sd-docs.js +84 -0
  65. package/package.json +1 -1
  66. package/claude/references/sd-simplysm14/apis/orm-common/query-builder.md +0 -29
  67. package/claude/skills/sd-demo/evals/fixtures/inventory-list/.specs/inventory/spec.md +0 -99
  68. package/claude/skills/sd-demo/evals/fixtures/inventory-list/packages/demo-client/package.json +0 -12
  69. package/claude/skills/sd-demo/evals/fixtures/inventory-list/packages/demo-client/src/index.ts +0 -3
  70. package/claude/skills/sd-demo/evals/fixtures/inventory-list/packages/demo-client/src/screens/inbound/inbound.list.ts +0 -150
  71. package/claude/skills/sd-demo/evals/fixtures/inventory-list/packages/demo-client/src/screens/inventory/inventory-master.list.ts +0 -143
  72. package/claude/skills/sd-demo/evals/fixtures/inventory-list/packages/demo-client/src/screens/outbound/outbound.list.ts +0 -150
  73. package/claude/skills/sd-demo/evals/fixtures/inventory-list/pnpm-workspace.yaml +0 -2
  74. package/claude/skills/sd-demo/evals/fixtures/inventory-list/sd.config.ts +0 -12
  75. package/claude/skills/sd-demo/evals/golden.jsonl +0 -1
  76. package/claude/skills/sd-dev/evals/fixtures/minimal-ts-pkg/package.json +0 -8
  77. package/claude/skills/sd-dev/evals/fixtures/minimal-ts-pkg/src/.gitkeep +0 -0
  78. package/claude/skills/sd-dev/evals/fixtures/minimal-ts-pkg/tests/.gitkeep +0 -0
  79. package/claude/skills/sd-dev/evals/fixtures/minimal-ts-pkg/tsconfig.json +0 -10
  80. package/claude/skills/sd-dev/evals/golden.jsonl +0 -1
  81. package/claude/skills/sd-docs/SKILL.md +0 -46
  82. package/claude/skills/sd-docs/evals/fixtures/new-write/.claude/references/sd-simplysm14/README.md +0 -7
  83. package/claude/skills/sd-docs/evals/fixtures/new-write/packages/bar/package.json +0 -5
  84. package/claude/skills/sd-docs/evals/fixtures/new-write/packages/bar/src/index.ts +0 -3
  85. package/claude/skills/sd-docs/evals/fixtures/new-write/packages/baz/package.json +0 -6
  86. package/claude/skills/sd-docs/evals/fixtures/new-write/packages/baz/src/index.ts +0 -1
  87. package/claude/skills/sd-docs/evals/fixtures/new-write/packages/foo/package.json +0 -5
  88. package/claude/skills/sd-docs/evals/fixtures/new-write/packages/foo/src/index.ts +0 -8
  89. package/claude/skills/sd-docs/evals/fixtures/update-mixed/.claude/references/sd-simplysm14/README.md +0 -7
  90. package/claude/skills/sd-docs/evals/fixtures/update-mixed/.claude/references/sd-simplysm14/apis/foo/README.md +0 -3
  91. package/claude/skills/sd-docs/evals/fixtures/update-mixed/packages/bar/package.json +0 -5
  92. package/claude/skills/sd-docs/evals/fixtures/update-mixed/packages/bar/src/index.ts +0 -3
  93. package/claude/skills/sd-docs/evals/fixtures/update-mixed/packages/baz/package.json +0 -6
  94. package/claude/skills/sd-docs/evals/fixtures/update-mixed/packages/baz/src/index.ts +0 -1
  95. package/claude/skills/sd-docs/evals/fixtures/update-mixed/packages/foo/package.json +0 -5
  96. package/claude/skills/sd-docs/evals/fixtures/update-mixed/packages/foo/src/index.ts +0 -8
  97. package/claude/skills/sd-docs/evals/golden.jsonl +0 -2
  98. package/claude/skills/sd-impl/evals/fixtures/case-a-new-screen/.specs/260513120000_warehouse/spec.md +0 -101
  99. package/claude/skills/sd-impl/evals/fixtures/case-b-update-with-demo/.specs/260513120000_warehouse/spec.md +0 -101
  100. package/claude/skills/sd-impl/evals/fixtures/case-b-update-with-demo/packages/app/src/screens/box-register/box-register.view.ts +0 -46
  101. package/claude/skills/sd-impl/evals/fixtures/case-c-new-cross/.specs/260513120000_warehouse/spec.md +0 -89
  102. package/claude/skills/sd-impl/evals/fixtures/case-d-spec-modify/.specs/260513120000_warehouse/spec.md +0 -101
  103. package/claude/skills/sd-impl/evals/golden.jsonl +0 -4
  104. package/claude/skills/sd-manual/evals/fixtures/new-manual/src/notification.ts +0 -25
  105. package/claude/skills/sd-manual/evals/fixtures/update-manual/.claude/references/sd-simplysm14/manuals/notification.md +0 -14
  106. package/claude/skills/sd-manual/evals/fixtures/update-manual/src/notification.ts +0 -37
  107. package/claude/skills/sd-manual/evals/golden.jsonl +0 -2
  108. package/claude/skills/sd-review/evals/fixtures/code-review/src/foo.ts +0 -7
  109. package/claude/skills/sd-review/evals/fixtures/doc-review/docs/foo.md +0 -4
  110. package/claude/skills/sd-review/evals/golden.jsonl +0 -2
  111. package/claude/skills/sd-skill/evals/fixtures/existing-skill/.claude/skills/todo-format/SKILL.md +0 -14
  112. package/claude/skills/sd-skill/evals/fixtures/new-skill/.gitkeep +0 -0
  113. package/claude/skills/sd-skill/evals/golden.jsonl +0 -2
  114. package/claude/skills/sd-spec/evals/fixtures/case-a-split//355/232/214/354/235/230/353/241/235.md +0 -20
  115. package/claude/skills/sd-spec/evals/fixtures/case-b-detail/.specs/260513120000_warehouse/spec.md +0 -95
  116. package/claude/skills/sd-spec/evals/golden.jsonl +0 -2
  117. package/claude/skills/sd-unpack/evals/fixtures/eml-with-text-attachment/meeting.eml +0 -21
  118. package/claude/skills/sd-unpack/evals/fixtures/simple-eml/meeting.eml +0 -10
  119. package/claude/skills/sd-unpack/evals/golden.jsonl +0 -2
  120. package/claude/skills/sd-use/evals/fixtures/empty/.gitkeep +0 -0
  121. package/claude/skills/sd-use/evals/golden.jsonl +0 -6
  122. /package/claude/{skills/sd-docs/references/doc-rules.md → workflows/sd-docs.rules.md} +0 -0
@@ -44,20 +44,20 @@ ORM 호출, 파일 변환, 비즈니스 로직 등은 위 두 경우에 해당
44
44
 
45
45
  ## 패키지 인덱스
46
46
 
47
- - **angular** — Angular 업무 화면 UI 키트(폼/시트/모달·토스트·Busy 오버레이/CRUD 골격/공유데이터/권한·메뉴/테마·에디터·시각화·칸반) 컴포넌트·디렉티브·프로바이더를 때. 자세히: [apis/angular/README.md](./apis/angular/README.md)
48
- - **capacitor-plugin-auto-update** — Android(Capacitor) 앱의 APK 자동 업데이트(서버/외부저장소 기반 버전 감지·다운로드·설치)와 하부 APK 설치 권한 관리·설치 인텐트 실행을 다룰 때. 자세히: [apis/capacitor-plugin-auto-update/README.md](./apis/capacitor-plugin-auto-update/README.md)
49
- - **capacitor-plugin-file-system** — Capacitor 기반 네이티브 파일 시스템(Android 외부/앱 저장소, Browser IndexedDB 에뮬레이션) 접근 — 파일 읽기/쓰기, 디렉토리 조회/생성, 삭제, 권한, 저장소 경로 조회가 필요할 때. 자세히: [apis/capacitor-plugin-file-system/README.md](./apis/capacitor-plugin-file-system/README.md)
50
- - **capacitor-plugin-intent** — Android 인텐트 송수신(브로드캐스트 구독/전송, 실행 인텐트 조회, newIntent 리스너, startActivityForResult 외부 Activity 실행) Capacitor 플러그인. 바코드 스캐너·PDA 산업용 디바이스 연동 시 사용, 웹은 미지원 스텁. 자세히: [apis/capacitor-plugin-intent/README.md](./apis/capacitor-plugin-intent/README.md)
51
- - **capacitor-plugin-usb-storage** — Capacitor USB Mass Storage 플러그인 정적 클래스 UsbStorage 로 USB 장치 목록 조회·권한 요청/확인·디렉토리 나열·파일(Bytes) 읽기. Android(libaums)/web(IndexedDB 에뮬레이션). 자세히: [apis/capacitor-plugin-usb-storage/README.md](./apis/capacitor-plugin-usb-storage/README.md)
52
- - **core-browser** — 브라우저 전용 유틸 — Element/HTMLElement 프로토타입 확장(탐색·가시성·상대좌표·스크롤), 클립보드 copy/paste 핸들러, getBounds 경계측정, Blob 다운로드·파일선택·진행률 fetch, IndexedDB KV 저장소·가상 파일시스템. 자세히: [apis/core-browser/README.md](./apis/core-browser/README.md)
53
- - **core-common** — 브라우저·Node 공용 유틸: 에러 계층(SdError류), 불변 날짜/시간(DateTime/DateOnly/Time), 큐·이벤트·로거, Array/Set/Map 프로토타입 확장, obj·str·num·bytes·path·json·xml·transfer·wait 네임스페이스, ZIP·코드 템플릿 태그·타입 유틸리티가 필요할 때. 자세히: [apis/core-common/README.md](./apis/core-common/README.md)
54
- - **core-node** — Node.js 전용 유틸 — 파일시스템 IO(fsx)·자식 프로세스 실행과 인코딩 디코딩(cpx)·경로 POSIX 정규화/판정(pathx)·파일 감시(FsWatcher)·consola 로깅 설정·worker_threads 타입 안전 래퍼(Worker) 필요할 때. 자세히: [apis/core-node/README.md](./apis/core-node/README.md)
55
- - **excel** — OOXML(.xlsx) 워크북을 lazy-load 로 읽고 시트·셀 값/수식/병합·스타일·조건부 서식·이미지 삽입, Zod 스키마 기반 레코드 매핑(ExcelWrapper), 주소/날짜/숫자형식 변환 유틸(ExcelUtils). 자세히: [apis/excel/README.md](./apis/excel/README.md)
56
- - **lint** — ESLint flat config 프리셋(eslint-recommended)과 커스텀 규칙 9종 플러그인(eslint-plugin)으로 simplysm 워크스페이스의 JS/TS/HTML lint 규칙을 강제할 때. 자세히: [apis/lint/README.md](./apis/lint/README.md)
57
- - **orm-common** — Dialect 독립 ORM 코어 — Table/View/Procedure 빌더로 스키마를 정의하고 DbContext 에 등록해 연결·트랜잭션·DDL·마이그레이션을 수행하며, Queryable 체이닝과 expr 표현식 빌더로 타입 안전 SELECT/CUD 쿼리를 QueryDef AST 로 조립할 때. 자세히: [apis/orm-common/README.md](./apis/orm-common/README.md)
58
- - **orm-node** — Node 환경에서 DbContext 를 MSSQL/MySQL/PostgreSQL 에 연결해 구동하는 ORM 실행 계층. createOrm 으로 트랜잭션 단위 쿼리를 돌리거나, createDbConn/DbConn 저수준 계층으로 원시 SQL·bulk insert·수동 트랜잭션을 직접 다룰 때. 자세히: [apis/orm-node/README.md](./apis/orm-node/README.md)
59
- - **sd-cli** — sd.config.ts 설정 타입(SdConfig/SdConfigFn/패키지·배포·Capacitor·Electron·PWA), 패키지 .ts 증분 컴파일 엔진(SdTsCompiler), Vitest용 Angular AOT Vite 플러그인(sdAngularPlugin)을 다룰 때. 자세히: [apis/sd-cli/README.md](./apis/sd-cli/README.md)
60
- - **service-client** — WebSocket 기반 simplysm 서비스 서버 클라이언트 서비스 메서드 RPC 호출(getService/ServiceProxy), 인증, 서버 푸시 이벤트 구독, 파일 업/다운로드, 진행률 추적, ORM 원격 트랜잭션 실행이 필요할 때. 자세히: [apis/service-client/README.md](./apis/service-client/README.md)
61
- - **service-common** — 서버·클라 공유 서비스 통신 계약 — 바이너리 프로토콜(인코딩/청킹/재조립), 서비스 인터페이스 타입(ORM·자동업데이트·업로드), 타입 안전 이벤트 정의(defineEvent), 앱 메뉴/권한 구조 모델. 자세히: [apis/service-common/README.md](./apis/service-common/README.md)
62
- - **service-server** — Fastify 기반 서비스 서버(WebSocket/HTTP RPC·JWT 인증·정적파일/업로드·서버→클라이언트 이벤트 푸시·ORM/자동업데이트 빌트인 서비스·V1 레거시 호환)를 부팅·서비스 정의·인증 처리할 때. 자세히: [apis/service-server/README.md](./apis/service-server/README.md)
63
- - **storage** — FTP/FTPS/SFTP 원격 스토리지에 접속해 파일·디렉토리를 업로드·다운로드·조회·삭제할 때(StorageFactory.connect 권장 진입점). 자세히: [apis/storage/README.md](./apis/storage/README.md)
47
+ - **angular** — Angular(zoneless·signal) 업무 프론트엔드 컴포넌트·디렉티브·프로바이더 — 앱 부트스트랩(provideSdAngular)·모달/토스트/busy/인쇄·라우팅/메뉴/권한·폼 컨트롤·레이아웃·sd-sheet·공유데이터·CRUD 화면 골격·주소검색/에디터/차트/칸반을 다룰 때. 자세히: [apis/angular/README.md](./apis/angular/README.md)
48
+ - **capacitor-plugin-auto-update** — Capacitor(Android) 앱에서 APK 설치 인텐트 실행·설치 권한 관리, 서버/외부 저장소 기반 최신 APK 자동 감지·다운로드·설치 흐름을 돌릴 때. 자세히: [apis/capacitor-plugin-auto-update/README.md](./apis/capacitor-plugin-auto-update/README.md)
49
+ - **capacitor-plugin-file-system** — Capacitor 파일 시스템 플러그인. 네이티브(Android 외부/앱 저장소)·브라우저(IndexedDB 에뮬레이션)에서 파일 읽기/쓰기, 디렉토리 조회/생성/삭제, 존재 확인, 권한 확인/요청, 저장소 경로·URI 조회를 static FileSystem 클래스로 제공. 자세히: [apis/capacitor-plugin-file-system/README.md](./apis/capacitor-plugin-file-system/README.md)
50
+ - **capacitor-plugin-intent** — Android 인텐트 송수신 Capacitor 플러그인 — 브로드캐스트 구독/전송·실행 인텐트 조회·newIntent 리스너·startActivityForResult 외부 Activity 실행을 정적 클래스 Intent 로 수행(바코드 스캐너·PDA 연동, 웹은 미지원 스텁). 자세히: [apis/capacitor-plugin-intent/README.md](./apis/capacitor-plugin-intent/README.md)
51
+ - **capacitor-plugin-usb-storage** — USB Mass Storage 장치(Android=libaums 실물, web=IndexedDB 가상)의 장치 목록 조회·권한 요청/확인·디렉토리/파일 읽기가 필요할 — 정적 클래스 UsbStorage. 자세히: [apis/capacitor-plugin-usb-storage/README.md](./apis/capacitor-plugin-usb-storage/README.md)
52
+ - **core-browser** — 브라우저 전용 유틸 — DOM 요소 확장 메서드(조회·탭이동·가시성·상대좌표·스크롤·클립보드·경계측정), Blob 다운로드/파일선택/진행률 fetch, IndexedDB KV 저장소 및 가상 파일시스템. 자세히: [apis/core-browser/README.md](./apis/core-browser/README.md)
53
+ - **core-common** — 런타임 무관 공통 유틸 날짜/시간 값 타입(DateTime/DateOnly/Time), 에러 트리(SdError 등), 비동기 큐/이벤트/캐시, Array/Set/Map 프로토타입 확장, obj/json/transfer/str/num/bytes/path/xml 유틸 네임스페이스가 필요할 때. 자세히: [apis/core-common/README.md](./apis/core-common/README.md)
54
+ - **core-node** — Node 런타임 전용 유틸 — 파일시스템 IO(fsx), 자식 프로세스 실행·인코딩(cpx), POSIX 경로 가공(pathx), 파일 변경 감시(FsWatcher), consola 로깅 셋업, worker_threads 타입 안전 래퍼(worker). 자세히: [apis/core-node/README.md](./apis/core-node/README.md)
55
+ - **excel** — OOXML(.xlsx) 워크북을 ZIP lazy-load 로 읽고 쓰기ExcelWorkbook/Worksheet 진입, 값·수식·스타일·병합, 조건부 서식, 이미지, Zod 기반 ExcelWrapper, 주소·날짜·숫자형식 변환 유틸이 필요할 때. 자세히: [apis/excel/README.md](./apis/excel/README.md)
56
+ - **lint** — ESLint 9 flat-config 프리셋(eslint-recommended)과 simplysm 커스텀 규칙 9종(eslint-plugin) subpath export 제공 — 프로젝트 lint 설정을 잡거나 커스텀 규칙 동작을 검토할 때. 자세히: [apis/lint/README.md](./apis/lint/README.md)
57
+ - **orm-common** — Dialect 독립 ORM 코어 — Table/View/Procedure fluent 빌더로 스키마를 정의하고 DbContext 에 등록해 connect/transaction/DDL 돌리며, Queryable 체이닝과 expr 표현식으로 SELECT/CUD/프로시저 쿼리를 JSON AST(QueryDef/Expr)로 조립할 때(실제 SQL 렌더링·결과 파싱은 mysql/mssql/postgresql 빌더·executor 가 담당). 자세히: [apis/orm-common/README.md](./apis/orm-common/README.md)
58
+ - **orm-node** — Node.js 환경에서 @simplysm/orm-common 의 DbContext 를 MSSQL/MySQL/PostgreSQL 실 DB 에 연결해 실행 createOrm 으로 트랜잭션 단위 ORM 실행을 하거나, 저수준 DbConn 으로 raw SQL·파라미터 쿼리·bulk insert·수동 트랜잭션을 직접 다룰 때. 자세히: [apis/orm-node/README.md](./apis/orm-node/README.md)
59
+ - **sd-cli** — sd.config.ts 설정 타입(빌드 타겟·배포·Capacitor/Electron/PWA), 프로그래밍 방식 TS/Angular AOT 증분 컴파일러(SdTsCompiler), Vitest용 Angular AOT Vite 플러그인(sdAngularPlugin)을 다룰 때. 자세히: [apis/sd-cli/README.md](./apis/sd-cli/README.md)
60
+ - **service-client** — WebSocket 서비스 서버에 접속해 서비스 메서드 RPC 호출·인증·서버 이벤트 구독·파일 업다운로드·ORM 원격 트랜잭션 실행이 필요할 (브라우저/Node 공용 클라이언트). 자세히: [apis/service-client/README.md](./apis/service-client/README.md)
61
+ - **service-common** — 서버·클라이언트 공유 통신 계약 — 바이너리 프로토콜(인코딩/청킹/재조립)·메시지 타입, ORM/자동업데이트/업로드 서비스 인터페이스, 타입 안전 이벤트 정의(defineEvent), 앱 메뉴·권한 트리 모델을 다룰 때. 자세히: [apis/service-common/README.md](./apis/service-common/README.md)
62
+ - **service-server** — Fastify 기반 WebSocket/HTTP RPC 서비스 서버 — defineService/auth 로 서비스 정의, JWT 인증, 정적 파일·업로드, 서버→클라이언트 이벤트 브로드캐스트, ORM/자동업데이트 내장 서비스, V1 레거시 호환을 다룰 때. 자세히: [apis/service-server/README.md](./apis/service-server/README.md)
63
+ - **storage** — FTP/FTPS/SFTP 원격 스토리지에 연결해 파일·디렉토리를 업로드·다운로드·조회·삭제할 때. 진입점은 StorageFactory.connect(프로토콜, 접속정보, 콜백) 연결·종료 자동 관리. 자세히: [apis/storage/README.md](./apis/storage/README.md)
@@ -1,61 +1,35 @@
1
1
  # @simplysm/angular
2
2
 
3
- Angular 기반 업무 화면 UI 컴포넌트·디렉티브·프로바이더 묶음. `provideSdAngular()` 부트스트랩하고, 컨트롤·시트·모달/토스트/Busy 오버레이·CRUD 화면 골격·권한/공유데이터 인프라를 standalone 컴포넌트로 제공. zoneless(Signal 기반) 전제이며 모든 입력은 Angular `input()`/`model()` 시그널.
3
+ Angular 19+ (zoneless, signal 기반) 업무 프론트엔드용 컴포넌트·디렉티브·프로바이더 모음. 모든 컴포넌트는 standalone, `OnPush`, signal input/model/output 사용. 부트스트랩은 `provideSdAngular` 1개로 시작.
4
4
 
5
5
  ## 사용 트리거 인덱스
6
6
 
7
- - **provideSdAngular / 설정·로깅·서비스 인프라** — 앱 부트스트랩, 클라이언트명 주입, 시스템 로그/로컬스토리지/시스템설정 저장, 서비스 클라이언트 연결, 전역 에러 처리. 자세히: [infra.md](./infra.md)
8
- - **모달 / 토스트 / Busy / 인쇄(오버레이)** — 프로그래밍 방식 모달·확인/프롬프트 모달, 토스트 알림, 로딩 표시, 인쇄·PDF 생성. 자세히: [overlay.md](./overlay.md)
9
- - **폼 컨트롤·버튼·선택 컨트롤** textfield/textarea/numpad/range/checkbox/switch/select/dropdown/form/collapse/tab/list/gap/pagination/button. 자세히: [controls.md](./controls.md)
10
- - **레이아웃(사이드바·탑바)**사이드바/탑바 컨테이너·메뉴·사용자 메뉴로 화면 구성. 자세히: [layout.md](./layout.md)
11
- - **시트(sd-sheet)**트리/페이징/정렬/고정열/셀편집/선택 그리드. 자세히: [sheet.md](./sheet.md)
12
- - **CRUD 화면 골격** 목록(sd-crud-list)·상세(sd-crud-detail)·기반 컨테이너(sd-base-container) 화면 템플릿. 자세히: [crud.md](./crud.md)
13
- - **공유 데이터(shared-data)** — 서버 공유 마스터데이터 등록·구독, 선택 컨트롤(select/select-button/select-list). 자세히: [shared-data.md](./shared-data.md)
14
- - **라우팅 / 앱 구조(메뉴·권한)** — 페이지 코드·뷰 타입·제목 시그널, 라우터링크, 구조→메뉴/권한 변환, 권한 테이블. 자세히: [routing-appstructure.md](./routing-appstructure.md)
15
- - **선택/정렬/확장 매니저**sd-sheet/공유선택 컨트롤이 공유하는 selection/sorting/expanding 로직 컴포저블. 자세히: [selection-managers.md](./selection-managers.md)
16
- - **부가 기능(테마·주소·에디터·시각화)** — 다크모드/폰트크기, 주소검색 모달, TipTap 리치에디터, 라벨/노트/진행률/달력/바코드/ECharts, 칸반, 상태 프리셋. 자세히: [features.md](./features.md)
17
- - **호스트 디렉티브·동작 셋업** resize/intersection/이벤트옵션/명령키 디렉티브, ripple/show-effect/invalid 셋업, 타입드 템플릿. 자세히: [directives.md](./directives.md)
18
-
19
- ## 유틸 타입·헬퍼 (인라인)
20
-
21
- 군에 속하지 않는 소형 유틸. 모두 `@simplysm/angular` 루트에서 직접 import.
22
-
23
- ### mark
24
-
25
- `mark(sig: WritableSignal<any>): void` — 시그널 값을 in-place mutation 한 뒤 소비자에게 변경을 알림.
26
-
27
- - `sig` 대상 WritableSignal. 값이 배열이면 `[...v]`, 객체면 `{...v}` 로 얕은 복사해 새 참조로 set → OnPush/computed 재평가 트리거. push·속성변경 후 한 줄로 갱신 신호를 줄 때.
28
-
29
- ```typescript
30
- items().push(x); // 참조 동일 → 안 알려짐
31
- mark(items); // 얕은 복사로 새 참조 → 변경 전파
7
+ - **앱 부트스트랩·전역 설정** — 앱 시작 `provideSdAngular` 호출, 전역 에러 처리·테마·로컬스토리지·서버연결·시스템설정 프로바이더 주입. 자세히: [infra.md](./infra.md)
8
+ - **모달·토스트·바쁨·인쇄(오버레이)** — 프로그래밍 방식으로 모달/토스트 띄우기, busy 표시, 화면 인쇄/PDF. 자세히: [overlay.md](./overlay.md)
9
+ - **라우팅·앱 구조·메뉴·권한**페이지 코드·뷰 타입·뷰 제목 signal, 라우터 링크, 사이드바/탑바 메뉴 트리, 권한 판정. 자세히: [routing-appstructure.md](./routing-appstructure.md)
10
+ - **호스트 디렉티브·setup 훅** 엘리먼트에 ripple/show-effect/invalid 표시 부착, 리사이즈/교차/명령(ctrl+s 등) 이벤트, 옵션 이벤트(`.capture`/`.passive`), 타입드 템플릿. 자세히: [directives.md](./directives.md)
11
+ - **입력·버튼 컨트롤** textfield/textarea/numpad/range/checkbox/switch/select/dropdown/form/button 폼 컨트롤. 자세히: [controls.md](./controls.md)
12
+ - **레이아웃(사이드바·탑바)** 화면 골격(사이드바 컨테이너/메뉴/유저, 탑바 컨테이너/메뉴/유저). 자세히: [layout.md](./layout.md)
13
+ - **시트(데이터 그리드)** — `sd-sheet` 컬럼 정의, 정렬/선택/페이징/고정/셀편집. 자세히: [sheet.md](./sheet.md)
14
+ - **공유 데이터(shared-data)** — 서버 마스터 데이터 캐시 프로바이더와 select/list/button UI. 자세히: [shared-data.md](./shared-data.md)
15
+ - **선택·정렬·확장 매니저(use* 컴포저블)** 커스텀 리스트에 선택/정렬/트리확장 로직 부착. 자세히: [selection-managers.md](./selection-managers.md)
16
+ - **CRUD 화면 골격·상태프리셋·권한표** 목록/상세 화면 컨테이너, 상태 프리셋 저장, 권한 편집 테이블. 자세히: [crud.md](./crud.md)
17
+ - **기능 컴포넌트(주소검색·에디터·시각화·칸반)**다음 주소검색 모달, tiptap 에디터, 바코드/달력/차트/라벨/노트/진행률, 칸반 보드. 자세히: [features.md](./features.md)
18
+ - **FormatPipe** — 템플릿에서 문자열/날짜 포맷 표시. 아래 인라인 참조.
19
+ - **SelectModalOutputResult / DirectiveInputSignals / UndefToOptional / WithOptional** — 모달 선택 결과·input signal 타입 유틸. 아래 인라인 참조.
20
+
21
+ ## FormatPipe
22
+
23
+ `{{ value | format: formatStr }}` — 파이프. value 가 `DateTime`/`DateOnly` 면 `toFormatString(formatStr)`, `string` 이면 `X` 마스크 포맷 적용(예: `format: 'XXX-XXXX'`, `|` 로 길이별 다중 패턴 분기 — `X` 개수가 value.length 와 일치하는 패턴 선택). value 가 null/undefined 면 `""` 반환(결측은 빈 문자열로 표시). standalone import 후 사용.
24
+
25
+ ```html
26
+ <span>{{ phone | format: 'XXX-XXXX-XXXX|XXX-XXX-XXXX' }}</span>
27
+ <span>{{ dateOnly | format: 'yyyy-MM-dd' }}</span>
32
28
  ```
33
29
 
34
- ### setSafeStyle
35
-
36
- `setSafeStyle(renderer: Renderer2, el: HTMLElement, style: Partial<CSSStyleDeclaration>): void` — Renderer2 로 여러 인라인 스타일을 한 번에 적용.
37
-
38
- - `renderer` — Angular `Renderer2` 인스턴스. 키별로 `renderer.setStyle` 호출.
39
- - `el` — 대상 엘리먼트.
40
- - `style` — CSS 속성 부분 객체. 동작 셋업 함수(setupInvalid 등)가 내부적으로 사용.
41
-
42
- ### FormatPipe (`| format`)
43
-
44
- `transform(value: string | DateTime | DateOnly | undefined, format: string): string` — 값을 포맷 문자열로 변환하는 standalone 파이프(name `format`).
45
-
46
- - `value` — 대상. `null`/`undefined` 면 `""`. `DateTime`/`DateOnly` 면 `value.toFormatString(format)`. 문자열이면 `X` 자리표시자 마스킹 적용(길이 일치 시).
47
- - `format` — 포맷 문자열. 문자열 입력 시 `|` 로 분리한 후보 중 `X` 개수가 값 길이와 같은 패턴을 골라 `X` 를 한 글자씩 치환(예: `"XXX-XXXX"`).
48
-
49
- ### DirectiveInputSignals / UndefToOptional / WithOptional (타입)
50
-
51
- 컴포넌트의 `input()` 시그널 집합에서 값 타입을 추출하는 유틸 타입. 모달/토스트/인쇄 콘텐츠 컴포넌트의 `inputs` 타입 추론에 쓰임.
52
-
53
- - `DirectiveInputSignals<T>` — `T` 의 `InputSignal` 프로퍼티만 골라 `{ key: 값타입 }` 로 변환. `InputSignal<V>` → `V`, undefined 포함 필드는 optional.
54
- - `UndefToOptional<T>` — `T` 의 필드 중 `undefined` 를 포함하는 키를 optional(`?`)로 바꾸고 값에서 `undefined` 제외.
55
- - `WithOptional<T, K>` — `T` 의 키 `K` 들만 optional 로 변환.
56
-
57
- ### SelectModalOutputResult (타입)
58
-
59
- `interface SelectModalOutputResult<TKey = any> { selectedKeys: TKey[] }` — 선택 모달이 close 로 반환하는 결과 형태.
30
+ ## 타입 유틸
60
31
 
61
- - `selectedKeys`선택된 배열. 단일 선택이어도 배열. `SdSelectModal` 구현 모달이 확정emit.
32
+ - **SelectModalOutputResult<TKey>**`{ selectedKeys: TKey[] }`. 선택 모달이 `close.emit` 으로 돌려주는 결과 형태. 선택 모달 컴포넌트 작성 close output 타입으로 사용.
33
+ - **DirectiveInputSignals<T>** — 컴포넌트/디렉티브 클래스 T 의 `InputSignal` prop 들만 골라 `{ prop: 값타입 }` 객체 타입으로 추출. `undefined` 포함 필드는 optional 로 변환. 모달/토스트/인쇄에 컴포넌트를 넘길 때 inputs 타입 산출에 내부적으로 쓰임.
34
+ - **UndefToOptional<T>** — `value: T | undefined` 필드를 `value?: T` 로 변환하는 매핑 타입. `DirectiveInputSignals` 가 내부에서 사용.
35
+ - **WithOptional<T, K>** — T 에서 키 K 들만 optional 로 만드는 타입. 모달/인쇄 inputs 에서 일부 input 을 선택 항목으로 표시할 때 사용.
@@ -1,119 +1,51 @@
1
1
  # @simplysm/angular — 폼 컨트롤·버튼·선택 컨트롤
2
2
 
3
- 폼·입력·선택·버튼·드롭다운·리스트류 standalone 컴포넌트. 공통 패턴: 값은 `model()` 양방향, `disabled`/`inset`/`size`(`"sm"|"lg"`)/`inline`/`required` 다수 공유. 공통 theme literal = `"primary"|"secondary"|"info"|"success"|"warning"|"danger"|"gray"|"blue-gray"`. `required` 컨트롤은 내부 `setupInvalid` 로 네이티브 폼 검증과 연동되어 `<sd-form>` 안에서 동작.
3
+ 화면을 구성하는 입력/버튼/선택 컴포넌트 묶음. 대부분 `value = model()` 양방향 바인딩과 `theme`/`size`/`inline`/`inset`/`disabled` 공통 input 가짐. 공통 enum:
4
+ - theme(기본 8색): `"primary"|"secondary"|"info"|"success"|"warning"|"danger"|"gray"|"blue-gray"` — 색상 테마.
5
+ - size: `"sm"|"lg"` — 작게/크게(미지정=기본).
6
+ - inline: boolean — inline-block 으로 배치(폭 자동).
7
+ - inset: boolean — 테두리·라운드 제거(셀/그룹 내부 삽입용).
8
+ - disabled: boolean — 비활성.
4
9
 
5
- ## SdButton / SdAnchor / SdAdditionalButton
10
+ ## 버튼류
6
11
 
7
- - `<sd-button>` — 버튼. `type: "button"|"submit"`(폼 제출 트리거 여부), `theme`(공통 8색 + `"link"`/`"link-{색}"`/`"link-rev"` 텍스트버튼), `inline`(인라인폭), `inset`(테두리 없는 삽입형), `size`, `disabled`, `buttonStyle`/`buttonClass`(내부 `<button>` 적용). 클릭 ripple 내장.
8
- - `<sd-anchor>` — 텍스트 링크형 클릭 요소. `disabled`, `theme`(공통 8색, 기본 `"primary"`). disabled tabindex 제거.
9
- - `<sd-additional-button>` — 콘텐츠 + 우측 버튼(`sd-anchor`/`sd-button` 투영) 결합 박스. `size`, `inset`.
12
+ - **SdButton** `<sd-button>` — 버튼. `type`("button"|"submit", 기본 button), `theme`(8색 + `"link"`/`"link-<색>"`/`"link-rev"` 텍스트형), `inline`/`inset`/`size`/`disabled`, `buttonStyle`/`buttonClass`(내부 button 엘리먼트 스타일/클래스). 제출 버튼이면 `type="submit"`.
13
+ - **SdAnchor** `<sd-anchor>` — 텍스트 링크. `theme`(8색, 기본 primary), `disabled`. 인라인 클릭 요소(아이콘 버튼 등)에.
14
+ - **SdAdditionalButton** `<sd-additional-button>` — 내용 + 우측 부속 버튼(`sd-anchor`/`sd-button` 투영) 컨테이너. `size`/`inset`.
15
+ - **SdModalSelectButton** `<sd-modal-select-button>` — 클릭 시 선택 모달을 띄워 값 선택. `modal = input.required<SdSelectModalInfo<...>>()`, `value = model()`, `selectMode`("single"|"multi", 기본 single — single 이면 단일 키, multi 면 키 배열), `required`(미선택 시 검증 오류 + 지우개 숨김), `disabled`/`inset`/`size`, `modalOptions`, `searchIcon`. required 아니고 값 있으면 지우개 표시. 타입: `SdSelectModal<TKey>`(선택모달이 구현, `SdModalContentDef<SelectModalOutputResult<TKey>>` + `selectMode`/`selectedKeys` input), `SdSelectModalInfo<T>`(selectMode/selectedKeys 제외한 모달 정보).
10
16
 
11
- ## SdModalSelectButton
17
+ ## 텍스트·숫자 입력
12
18
 
13
- `<sd-modal-select-button>` — 모달로 선택하는입력 버튼(검색 아이콘 선택모달, 지우개 초기화).
19
+ - **SdTextfield<K>** `<sd-textfield [type]="...">` — 타입별 단일 입력. `type = input.required<K>()`(K = `SdTextfieldTypes` 키), `value = model<SdTextfieldTypes[K]>()`. 추가 input: `placeholder`/`title`, `min`/`max`(타입에 맞는 ), `minlength`/`maxlength`/`pattern`(문자형 검증), `validatorFn`(커스텀 검증, 메시지 반환), `format`(format 타입의 X 마스크), `step`, `autocomplete`, `useNumberComma`(숫자 천단위 콤마, 기본 true), `minDigits`(숫자 소수 최소 자릿수), `required`, `readonly`, `inline`/`inset`/`size`/`theme`. 검증 실패 시 `setupInvalid` 로 폼 연동.
20
+ - **SdTextfieldTypes / sdTextfieldTypes** — 타입→값 매핑: `number`:number, `text`/`password`/`color`/`email`/`format`:string, `date`/`month`/`year`:DateOnly, `datetime`/`datetime-sec`:DateTime, `time`/`time-sec`:Time. `sdTextfieldTypes` 는 키 배열(예: select 옵션 생성).
21
+ - **SdTextarea** `<sd-textarea>` — 여러 줄 텍스트. `value = model<string>()`, `minRows`(기본 1, 내용 줄 수만큼 자동 확장), `placeholder`/`title`/`required`/`readonly`/`validatorFn`/`inline`/`inset`/`size`/`theme`/`inputStyle`/`inputClass`.
22
+ - **SdNumpad** `<sd-numpad>` — 화면 숫자 키패드. `value = model<number>()`, `placeholder`, `required`, `inputDisabled`(상단 입력칸 직접입력 막기), `useEnterButton`/`useMinusButton`(ENT/− 버튼 표시), `enterButtonClick = output()`.
23
+ - **SdRange<K>** `<sd-range [type]="...">` — 동일 타입 두 값의 범위(`from ~ to`). `type = input.required<K>()`, `from`/`to` = model<SdTextfieldTypes[K]>(), `required`/`disabled`/`inputStyle`. to 의 min 은 from 으로 자동 제한.
24
+ - **SdDateRangePicker** `<sd-date-range-picker>` — 일/월/범위 선택. `periodType = model<"일"|"월"|"범위">("범위")`(일=from=to 동기화, 월=해당 월 1일~말일 자동, 범위=from~to 자유), `from`/`to` = model<DateOnly>(), `required`.
14
25
 
15
- - `modal = input.required<SdSelectModalInfo<SdSelectModal<K>>>()` — 띄울 선택 모달 정보(`selectMode`/`selectedKeys` 제외 inputs).
16
- - `value = model<...>()` — 선택 결과 키(single=단일, multi=배열).
17
- - `selectMode: "single"|"multi"` — 선택 모드. 기본 `"single"`.
18
- - `disabled`/`required`(필수검증)/`inset`/`size` — 공통.
19
- - `modalOptions` — `SdModalOptions` 전달.
20
- - `searchIcon` — 검색 버튼 아이콘(기본 tablerSearch).
26
+ ## 체크·스위치
21
27
 
22
- 타입: `SdSelectModal<TKey>`(선택모달 인터페이스, `selectMode`/`selectedKeys` input 추가), `SdSelectModalInfo<T>`(`SdModalInfo` 에서 `selectMode`/`selectedKeys` 제외).
28
+ - **SdCheckbox** `<sd-checkbox>` 체크박스/라디오. `value = model(false)`, `canChangeFn`(변경 가드, boolean|Promise), `icon`(체크 아이콘), `radio`(라디오 모양·해제 불가), `disabled`/`size`/`inline`/`inset`, `theme`(8색 + `"white"`), `contentStyle`.
29
+ - **SdSwitch** `<sd-switch>` — 토글 스위치. `value = model(false)`, `canChangeFn`, `disabled`/`inline`/`inset`/`size`/`theme`(8색).
30
+ - **SdCheckboxGroup<T>** / **SdCheckboxGroupItem<T>** — 그룹 다중선택. group: `value = model<T[]>([])`, `disabled`. item: `value = input.required<T>()`, `inline`. 항목 클릭 시 그룹 value 배열에 추가/제거.
23
31
 
24
- ## SdTextfield
32
+ ## 선택(드롭다운)
25
33
 
26
- `<sd-textfield>` — 타입별 단일값 입력. 제네릭 `K extends keyof SdTextfieldTypes` 로 타입이 결정됨.
34
+ - **SdSelect<M, T>** `<sd-select>` — 드롭다운 선택. `selectMode = input("single" as M)`("single"|"multi" multi 면 value 가 배열·전체선택 바 표시), `value = model<...>()`, `placeholder`, `required`(미선택 시 검증오류), `disabled`/`inline`/`inset`/`size`, `hideSelectAll`(multi 전체선택 바 숨김), `multiSelectionDisplayDirection`("vertical" 이면 선택 항목 세로 표시), `items`/`trackByFn`/`getChildrenFn`(items 지정 시 `itemOf` 템플릿으로 렌더·트리 지원), `contentClass`/`contentStyle`, `dropdownOpen = model(false)`. 메서드: selectItem/toggleItem/openDropdown/closeDropdown/onSelectAll/onDeselectAll. 키보드 ↑↓ 항목 이동. 타입 `SelectModeValue<T> = { multi: T[]; single: T }`.
35
+ - **SdSelectItem<T>** `<sd-select-item [value]="...">` — 선택 항목. `value`, `disabled`, `hidden`(검색 필터 등으로 숨김). multi 모드면 좌측 체크박스 표시. Enter/Space 로 선택·토글.
36
+ - **SdSelectButton** `<sd-select-button>` — sd-select 우측에 붙는 부속 버튼(검색/편집 등 트리거). input 없음, 클릭 이벤트는 투영된 내용에서 처리.
27
37
 
28
- - `type = input.required<K>()` — 입력 타입(아래 `SdTextfieldTypes` 키). 값 타입·검증·표시 포맷을 결정.
29
- - `value = model<SdTextfieldTypes[K]>()` — 값(타입별 number/string/DateOnly/DateTime/Time).
30
- - `placeholder`/`title`/`inputStyle`/`inputClass` — 표시 부가.
31
- - `disabled`/`readonly` — 비활성/읽기전용(둘 다 input 숨기고 텍스트만).
32
- - `required`/`min`/`max`/`minlength`/`maxlength`/`pattern`/`validatorFn`/`format` — 검증 옵션. `validatorFn(value) => string | undefined` 는 커스텀 메시지, `format` 은 `type: "format"` 마스킹.
33
- - `step`/`autocomplete` — 네이티브 속성.
34
- - `useNumberComma` — number 타입 천단위 콤마. 기본 true.
35
- - `minDigits` — number 표시 시 최소 소수 자릿수.
36
- - `inline`/`inset`/`size`/`theme` — 공통 레이아웃.
38
+ ## 드롭다운(저수준)
37
39
 
38
- `SdTextfieldTypes`(타입 타입): `number`→number, `text`/`password`/`color`/`email`/`format`→string, `date`/`month`/`year`→DateOnly, `datetime`/`datetime-sec`→DateTime, `time`/`time-sec`→Time. `sdTextfieldTypes` 키들의 배열.
40
+ - **SdDropdown** `<sd-dropdown>` — 트리거 + `sd-dropdown-popup` 팝업. `open = model(false)`, `disabled`. 화면 위치 자동 배치, 모바일(≤520px)에선 하단 시트 + backdrop. 키보드 ↓ 로 열고 ↑/ESC 로 닫음. `popupElRef`(contentChild)로 팝업 엘리먼트 접근.
41
+ - **SdDropdownPopup** `<sd-dropdown-popup>` — 드롭다운 내용. input 없음. 내용 높이 300px 초과 시 자동 스크롤 캡.
39
42
 
40
- ```html
41
- <sd-textfield [type]="'number'" [(value)]="qty" [min]="0" [required]="true" />
42
- <sd-textfield [type]="'date'" [(value)]="orderDate" />
43
- ```
43
+ ## 폼·접기·탭·리스트·여백·페이지
44
44
 
45
- ## SdTextarea
46
-
47
- `<sd-textarea>` — 여러 문자열 입력. `value = model<string>()`, `minRows`(최소 줄수, 내용 따라 자동 확장), `placeholder`/`title`/`disabled`/`readonly`/`required`/`inline`/`inset`/`size`/`theme`/`validatorFn`/`inputStyle`/`inputClass`.
48
-
49
- ## SdNumpad
50
-
51
- `<sd-numpad>` — 터치 숫자패드. `value = model<number>()`, `placeholder`, `required`, `inputDisabled`(상단 입력칸 비활성), `useEnterButton`(ENT 버튼 표시), `useMinusButton`(부호 토글), `enterButtonClick = output()`(ENT 클릭).
52
-
53
- ## SdRange
54
-
55
- `<sd-range>` — from~to 범위 입력(textfield 2개). 제네릭 `K extends keyof SdTextfieldTypes`. `type = input.required<K>()`, `from`/`to = model<SdTextfieldTypes[K]>()`(to 의 min 은 from 자동), `inputStyle`, `required`, `disabled`.
56
-
57
- ## SdDateRangePicker
58
-
59
- `<sd-date-range-picker>` — 일/월/범위 기간 선택. `periodType = model<"일"|"월"|"범위">()`(기본 `"범위"`), `from`/`to = model<DateOnly>()`, `required`. 월 선택 시 from/to 를 해당 월 1일~말일로 동기화, 일 선택 시 to=from.
60
-
61
- ## SdCheckbox / SdSwitch / SdCheckboxGroup(Item)
62
-
63
- - `<sd-checkbox>` — 체크박스/라디오. `value = model(false)`, `canChangeFn`(변경 허용 함수, `(boolean) => boolean|Promise<boolean>`), `radio`(라디오 외형·체크만 가능), `icon`(체크 아이콘), `disabled`/`size`/`inline`/`inset`/`theme`(공통 8색 + `"white"`), `contentStyle`. Space 키 토글.
64
- - `<sd-switch>` — 토글 스위치. `value = model(false)`, `canChangeFn`, `disabled`/`inline`/`inset`/`size`/`theme`. on 시 success 색.
65
- - `<sd-checkbox-group>` — 다중선택 그룹. `value = model<T[]>([])`(선택값 배열), `disabled`.
66
- - `<sd-checkbox-group-item>` — 그룹 항목. `value = input.required<T>()`(항목 값), `inline`. 부모 group 의 배열에 포함되면 체크.
67
-
68
- ## SdSelect / SdSelectItem / SdSelectButton
69
-
70
- - `<sd-select>` — 드롭다운 선택. 제네릭 `<M, T>`.
71
- - `selectMode: M("single"|"multi")` — 선택 모드. 기본 `"single"`.
72
- - `value = model<SelectModeValue<any>[M]>()` — single=단일값, multi=배열.
73
- - `placeholder`/`disabled`/`inline`/`inset`/`size`/`required` — 공통.
74
- - `hideSelectAll` — multi 의 전체선택/해제 바 숨김.
75
- - `multiSelectionDisplayDirection: "vertical"` — multi 선택 표시 줄바꿈.
76
- - `items`/`trackByFn`/`getChildrenFn` — 데이터 바인딩 방식(템플릿 `[itemOf]` 와 병행). `getChildrenFn` 지정 시 트리.
77
- - `contentClass`/`contentStyle`, `dropdownOpen = model(false)`.
78
- - `SelectModeValue<T>` = `{ multi: T[]; single: T }`.
79
- - `<sd-select-item>` — 선택 항목. `value = input<T>()`, `disabled`, `hidden`. multi 면 체크박스 표시. 콘텐츠 HTML 이 선택 표시에 사용됨.
80
- - `<sd-select-button>` — select 내부 우측 액션 버튼(ripple).
81
-
82
- ```html
83
- <sd-select [(value)]="deptId" [required]="true">
84
- <sd-select-item [value]="undefined">미지정</sd-select-item>
85
- @for (d of depts) { <sd-select-item [value]="d.id">{{ d.name }}</sd-select-item> }
86
- </sd-select>
87
- ```
88
-
89
- ## SdDropdown / SdDropdownPopup
90
-
91
- - `<sd-dropdown>` — 트리거 + 팝업 래퍼. `open = model(false)`, `disabled`. 팝업은 body 로 이동·위치 자동 계산(상/하·좌/우), 모바일은 하단 시트 + 백드롭. ArrowDown/Up/Space/ESC 키 처리.
92
- - `<sd-dropdown-popup>` — 팝업 콘텐츠. content 투영, 높이 300px 초과 시 스크롤 캡.
93
-
94
- ## SdForm
95
-
96
- `<sd-form>` — 네이티브 검증 연동 폼 래퍼. `formSubmit = output<SubmitEvent>()`(검증 통과 시), `formInvalid = output()`(실패 시 `reportValidity` 후). `requestSubmit()` 메서드로 외부 제출. 내부 컨트롤의 `setupInvalid` 검증과 함께 동작.
97
-
98
- ## SdCollapse / SdCollapseIcon
99
-
100
- - `<sd-collapse>` — 높이 애니메이션 접기. `open = input(false)`. 콘텐츠 높이 측정해 margin-top 으로 접음.
101
- - `<sd-collapse-icon>` — 회전 화살표 아이콘. `icon`(기본 chevronDown), `open = input(false)`, `openRotate = input(90)`(열림 시 회전각).
102
-
103
- ## SdTab / SdTabItem
104
-
105
- - `<sd-tab>` — 탭 바. `value = model<any>()` — 선택된 탭 값.
106
- - `<sd-tab-item>` — 탭 항목. `value = input<any>()`. 부모 value 와 같으면 선택 표시, 클릭 시 부모 value set.
107
-
108
- ## SdList / SdListItem
109
-
110
- - `<sd-list>` — 리스트 컨테이너. `inset = input(false)`(배경 투명).
111
- - `<sd-list-item>` — 리스트 항목. `layout: "accordion"|"flat"`(기본 accordion; flat 은 그룹헤더+상시펼침), `open = model(false)`(아코디언 펼침), `selected`, `selectedIcon`(선택 표시 아이콘), `readonly`, `contentStyle`/`contentClass`. 자식 `<sd-list>` 투영 시 하위 트리. `#toolTpl` 로 우측 도구 영역.
112
-
113
- ## SdGap
114
-
115
- `<sd-gap>` — 빈 간격. `height`/`width: "xxs"|"xs"|"sm"|"default"|"lg"|"xl"|"xxl"`(CSS 변수 기반), `heightPx`/`widthPx`/`widthEm`(수치). 0 이면 `display:none`, width 계열이면 inline-block, height 면 block.
116
-
117
- ## SdPagination
118
-
119
- `<sd-pagination>` — 페이지 네비. `currentPage = model(0)`(0-base 현재 페이지), `totalPageCount = input(0)`(전체 페이지 수), `visiblePageCount = input(10)`(한 그룹에 보일 페이지 버튼 수). 처음/이전그룹/페이지번호/다음그룹/마지막 버튼.
45
+ - **SdForm** `<sd-form>` — `(formSubmit)`(검증 통과 시 SubmitEvent), `(formInvalid)`(검증 실패 시, 네이티브 메시지·포커스 자동). `requestSubmit()` 메서드, `formElRef`/`formEl`(폼 엘리먼트 접근). 내부 컨트롤들의 `setupInvalid` 검증을 모아 제출 제어.
46
+ - **SdCollapse** `<sd-collapse [open]="...">` — 높이 애니메이션 접기. `open`(boolean). 내용 높이 자동 측정.
47
+ - **SdCollapseIcon** `<sd-collapse-icon [open]="...">` — 펼침 상태 회전 아이콘. `icon`(기본 chevronDown), `open`, `openRotate`(펼칠 회전각도, 기본 90).
48
+ - **SdTab<any>** / **SdTabItem** — 탭. tab: `value = model<any>()`. item: `value = input<any>()`(클릭 시 부모 value 설정, 일치하면 선택 표시).
49
+ - **SdList** / **SdListItem** — 리스트(트리). list: `inset`. item: `layout`("accordion"|"flat", 기본 accordion — accordion 은 클릭 시 자식 접기/펼치기, flat 은 항상 펼침·헤더 비클릭), `open = model(false)`, `selected`(선택 강조), `selectedIcon`(선택 아이콘 표시), `readonly`(클릭 비활성), `contentStyle`/`contentClass`, `toolTpl`(우측 도구 템플릿). 자식 `sd-list` 투영 시 하위 트리.
50
+ - **SdGap** `<sd-gap>` — 여백 스페이서. `height`/`width`("xxs"|"xs"|"sm"|"default"|"lg"|"xl"|"xxl" CSS 변수 단위), `heightPx`/`widthPx`/`widthEm`(숫자, 0 이면 display:none). width 계열 지정 시 inline-block, height 계열이면 block.
51
+ - **SdPagination** `<sd-pagination>` — 페이지 네비게이션. `currentPage = model(0)`(0 기반), `totalPageCount`(전체 페이지 ), `visiblePageCount`( 그룹 표시 수, 기본 10). 처음/이전그룹/페이지번호/다음그룹/끝 버튼.
@@ -1,50 +1,53 @@
1
- # @simplysm/angular — CRUD 화면 골격
1
+ # @simplysm/angular — CRUD 화면 골격·상태프리셋·권한표
2
2
 
3
- 목록·상세 화면의 표준 레이아웃(타이틀바·커맨드 영역·콘텐츠·하단 커맨드)과 busy·권한제한·뷰타입(page/modal/control)별 분기·모달 선택 모드를 제공하는 컨테이너. 콘텐츠는 `<ng-template #...>` 슬롯으로 주입. `viewType` `injectViewTypeSignal()`(routing 군) 결과를 넣는 것이 일반적.
3
+ 업무 목록/상세 화면의 공통 골격(탑바·busy·권한 제한·도구바)과 보조 컴포넌트. 모두 `viewType = input.required<SdViewType>()` 로 page/modal/control 맥락을 받음(`injectViewTypeSignal()` 결과 전달). 화면 진입 공유 데이터 준비를 대기하고 `ready` 알림.
4
4
 
5
5
  ## SdBaseContainer
6
6
 
7
- `<sd-base-container>` — 모든 CRUD 컨테이너의 기반. busy·권한제한·뷰타입 분기·공유데이터 로드 대기 처리.
8
-
9
- - `viewType = input.required<SdViewType>()` `"page"|"modal"|"control"`. page 탑바+제목 표시, 그 외엔 콘텐츠만.
10
- - `initialized = input(false)`초기화 완료 여부. false busy 표시.
11
- - `restricted = input(false)` 권한 제한. true 면 콘텐츠 대신 "사용권한 없음" 안내.
12
- - `ready = model(false)` 준비 완료 신호(공유데이터 대기 set).
13
- - `busyCount = model(0)`busy 카운트(0 초과 busy).
14
- - 슬롯: `#topbarTpl`(탑바 액션), `#commandTpl`(상단 커맨드 바), `#contentTpl`(본문), `#bottomCommandTpl`(하단 커맨드). `viewTitle` 은 라우팅 군의 제목 신호 자동 사용.
7
+ `<sd-base-container [viewType]="...">` — 가장 단순한 화면 컨테이너(탑바 + busy + 권한제한 + 도구바).
8
+ - ready = model(false) — 공유 데이터 대기 완료 시 true. 화면 본문 표시 조건에.
9
+ - initialized: boolean데이터 로드 완료 여부(false busy).
10
+ - busyCount = model(0) — busy 카운트(>0오버레이).
11
+ - restricted: boolean — true 면 "사용권한 없음" 안내만 표시.
12
+ - viewType: input.required<SdViewType>page 탑바(제목+topbarTpl) 감싸고, 아니면 본문만.
13
+ - (contentChild) topbarTpl/commandTpl/contentTpl/bottomCommandTpl 탑바 우측/상단 명령/본문/하단 명령 영역.
15
14
 
16
15
  ## SdCrudDetail
17
16
 
18
- `<sd-crud-detail>` — 단일 레코드 상세/편집 화면. 저장 버튼·CTRL+S·폼 검증 연동.
19
-
20
- - `viewType = input.required<SdViewType>()` 타입. page=탑바 저장버튼, control=상단 저장버튼, modal=하단 확인버튼.
21
- - `initialized`/`restricted`/`busyCount`/`ready` `SdBaseContainer` 동일 의미.
22
- - `readonly = input(false)`읽기전용(폼·저장버튼 숨김).
23
- - `submit = output()` — 저장(폼 검증 통과) 시 emit. CTRL+S/저장버튼 → 폼 제출 → 이 이벤트.
24
- - 슬롯: `#commandTpl`/`#contentTpl`/`#bottomCommandTpl`. contentTpl 은 readonly 가 아니면 `<sd-form>` 으로 감싸짐.
25
-
26
- ## SdCrudList
27
-
28
- `<sd-crud-list>`목록 화면(필터 폼 + 시트 + 등록/삭제/복구/선택). 제네릭 `<TItem, TKey>`.
29
-
30
- - `viewType = input.required<SdViewType>()` / `initialized`/`restricted`/`busyCount`/`ready`/`readonly` 기반 동일.
31
- - `key = input.required<string>()` 시트 설정 키(`{key}-sheet`).
32
- - `selectMode: "single"|"multi"`모달 선택 모드. modal 뷰에서 single 선택 즉시 확정 close, multi 확인 버튼.
33
- - `items = input<TItem[]>([])` — 목록 데이터.
34
- - `selectedKeys = model<NonNullable<TKey>[]>([])` — 선택 키.
35
- - `trackByFn = input.required<(item) => TKey>()` 행 키 추출.
36
- - `currDeletedItems = input<TItem[]>([])` 삭제 표시(취소선) 항목 집합.
37
- - `currentPage = model(0)`/`totalPageCount`/`itemsPerPage`/`visiblePageCount`/`sorts = model<SortingDef[]>()`페이징·정렬(시트로 전달).
38
- - outputs: `filterSubmit`(조회 버튼), `submit`(저장/CTRL+S), `create`(등록 버튼), `delete = output<TItem[]>()`(선택/행 삭제), `restore = output<TItem[]>()`(선택/행 복구).
39
- - 슬롯: `#filterTpl`(필터 폼 필드), `#commandTpl`/`#toolTpl`/`#bottomCommandTpl`. `<sd-sheet-column>` 자식은 시트 컬럼으로 합쳐짐(삭제 컬럼은 자동 주입).
40
-
41
- ```html
42
- <sd-crud-list [viewType]="viewType()" key="user" [items]="users()"
43
- [(selectedKeys)]="sel" [trackByFn]="trackById"
44
- (create)="onCreate()" (delete)="onDelete($event)" (submit)="onSave()">
45
- <ng-template #filterTpl><sd-textfield [type]="'text'" [(value)]="filter.name" /></ng-template>
46
- <sd-sheet-column key="name" header="이름">
47
- <ng-template [cell]="users()" let-item="item">{{ item.name }}</ng-template>
48
- </sd-sheet-column>
49
- </sd-crud-list>
50
- ```
17
+ `<sd-crud-detail [viewType]="...">` — 단건 상세/편집 화면(폼 포함).
18
+ - ready/initialized/busyCount/restricted/viewType — 위와 동일.
19
+ - readonly: boolean읽기 전용.
20
+ - (viewChild) formCtrl: SdForm 내부 폼.
21
+ - (output) submit 폼 제출(검증 통과).
22
+ - (contentChild) commandTpl/contentTpl/bottomCommandTpl.
23
+
24
+ ## SdCrudList<TItem, TKey>
25
+
26
+ `<sd-crud-list [viewType]="...">` — 목록 화면(필터 폼 + 시트 + 페이징 + 선택/삭제/복원).
27
+ - ready/initialized/busyCount/restricted/viewType/readonly 위와 동일.
28
+ - selectMode?: "single"|"multi" — 행 선택 모드.
29
+ - key: input.required<string> 시트 설정 영속 키.
30
+ - (viewChild) formCtrl: SdForm.
31
+ - (output) filterSubmit필터 제출. submit 일반 제출. create 추가 버튼. delete: TItem[] 삭제 대상. restore: TItem[] — 복원 대상.
32
+ - items: TItem[] — 목록 데이터.
33
+ - selectedKeys = model<NonNullable<TKey>[]>([]) — 선택 키.
34
+ - currDeletedItems: TItem[] 현재 삭제표시된 항목(복원 대상 표시).
35
+ - currentPage = model(0) / totalPageCount / itemsPerPage / visiblePageCount(기본 10) 페이징(시트로 위임).
36
+ - sorts = model<SortingDef[]>([]) — 정렬 상태.
37
+ - trackByFn: input.required<(item) => TKey> 키.
38
+ - (contentChild) commandTpl/filterTpl/toolTpl/bottomCommandTpl, `sd-sheet-column` 명령/필터/도구/하단 명령 영역과 시트 컬럼.
39
+
40
+ ## SdStatePreset<TState>
41
+
42
+ `<sd-state-preset [key]="..." [(state)]="...">` — 화면 상태(필터 등) 프리셋 저장/적용 바.
43
+ - key: input.required<string> — 프리셋 영속 키(`SdSystemConfigProvider`).
44
+ - state = model.required<TState> — 현재 상태(저장·적용 대상).
45
+ - size?: "sm"|"lg".
46
+ - ★ 버튼으로 현재 상태를 이름 붙여 저장, 프리셋 클릭 시 상태 적용, 각 프리셋 저장(덮어쓰기)·삭제. 타입 `SdStatePresetDef<TState> = { name: string; state: TState }`.
47
+
48
+ ## SdPermissionTable<TModule>
49
+
50
+ `<sd-permission-table [items]="...">` — 권한(use/edit) 편집 테이블.
51
+ - value = model<Record<string, boolean>>({}) — `<코드>.<use|edit>` → 허용 맵.
52
+ - items: SdPermission<TModule>[] — 권한 트리(`SdAppStructureProvider.getPermissionsByStructure` 결과).
53
+ - disabled: boolean — 편집 비활성.
@@ -1,44 +1,34 @@
1
- # @simplysm/angular — 호스트 디렉티브·동작 셋업
1
+ # @simplysm/angular — 호스트 디렉티브·동작 셋업·템플릿
2
2
 
3
- 엘리먼트에 부착하는 동작 디렉티브와, 컴포넌트 생성자에서 호출해 호스트 엘리먼트에 동작을 주입하는 `setup*` 함수, 타입 안전 템플릿 디렉티브. 다른 컴포넌트들이 ripple/검증/리사이즈 감지 등에 내부적으로 사용하며 단독으로도 쓸 수 있음.
3
+ 엘리먼트/컴포넌트에 동작을 부착하는 디렉티브와, 컴포넌트 constructor 에서 호출하는 `setup*` 훅, 타입드 ng-template 묶음. 컴포넌트 동작을 직접 조립할 함께 읽힘.
4
4
 
5
- ## 이벤트 옵저버 디렉티브
5
+ ## 이벤트 디렉티브
6
6
 
7
- - `[sdResize]` (`SdResizeDirective`) `ResizeObserver` 크기 변화 감지. `sdResize = output<SdResizeEvent>()`. `SdResizeEvent = { heightChanged; widthChanged; target: HTMLElement; contentRect: DOMRectReadOnly }`. requestAnimationFrame 디바운스.
8
- - `[sdIntersection]` (`SdIntersectionDirective`) — `IntersectionObserver` 로 가시성 감지. `sdIntersection = output<SdIntersectionEvent>()`. `SdIntersectionEvent = { entry: IntersectionObserverEntry }`.
7
+ 옵션 이벤트(`.capture`/`.passive`/`.once`) `provideSdAngular` 등록한 `SdOptionEventPlugin` 으로 동작. 직접 inject 함.
9
8
 
10
- ## SdEvents
9
+ - **SdEvents** — 표준 이벤트의 옵션 변형을 output 으로 노출하는 디렉티브. `(click.capture)`, `(scroll.passive)`, `(touchstart.passive)`, `(wheel.capture.passive)`, `(transitionend.once)` 등(셀렉터에 열거된 조합만). 버블링 안 되는 focus/blur 를 capture 로 받거나 성능상 passive 스크롤이 필요할 때 사용.
10
+ - **SdResizeDirective** — `(sdResize)` 출력. ResizeObserver 기반, requestAnimationFrame 디바운스. 이벤트 `SdResizeEvent = { heightChanged; widthChanged; target: HTMLElement; contentRect: DOMRectReadOnly }`. 크기 변화에 반응할 때.
11
+ - **SdIntersectionDirective** — `(sdIntersection)` 출력. IntersectionObserver 기반. 이벤트 `SdIntersectionEvent = { entry: IntersectionObserverEntry }`. 화면 진입 감지(지연 로드 등)에.
12
+ - **SdCommandDirective** — `(sdRefreshCommand)`(Ctrl+Alt+L), `(sdSaveCommand)`(Ctrl+S), `(sdInsertCommand)`(Insert) 출력(`KeyboardEvent`). 최상위로 열린 모달 안에서만 동작(가려진 화면 단축키 차단). 새로고침/저장/추가 단축키 바인딩에.
11
13
 
12
- `SdEvents` 디렉티브 capture/passive/once 옵션 이벤트를 output 으로 노출(Angular 기본 바인딩이 지원 않는 리스너 옵션용). 셀렉터에 해당하는 속성을 호스트에 쓰면 동작. 예: `(click.capture)`, `(scroll.passive)`, `(wheel.capture.passive)`, `(touchstart.passive)`, `(transitionend.once)` 등. 각 output 은 대응 DOM 이벤트 타입(MouseEvent/WheelEvent/TouchEvent 등) emit.
14
+ ## 표시 효과 디렉티브 + 셋업
13
15
 
14
- `SdOptionEventPlugin` — `provideSdAngular` 등록하는 `EventManagerPlugin`. `.capture`/`.passive`/`.once` 접미사 이벤트 바인딩을 실제 리스너 옵션으로 변환. 직접 사용 불필요.
16
+ - **SdRipple** / **setupRipple** — `[sdRipple]="enabled"` 디렉티브 또는 `setupRipple(enableFn?: () => boolean)` 훅. 포인터 다운 위치에서 퍼지는 물결 효과. enabled/enableFn false 면 비활성. 버튼류에 부착.
17
+ - **SdShowEffect** / **setupRevealOnShow** — `[sdShowEffect]="enabled"` + `sdShowEffectType`("l2r"|"t2b", 기본 t2b) 디렉티브, 또는 `setupRevealOnShow(optFn?: () => { type?; enabled? })` 훅. 화면 진입 시 페이드+슬라이드로 나타남. type 은 슬라이드 방향(t2b=위→아래, l2r=왼→오). 진입 애니메이션에.
18
+ - **SdInvalid** / **setupInvalid** — `[sdInvalid]="message"` 디렉티브, 또는 `setupInvalid(getInvalidMessage: () => string)` 훅. 메시지가 빈 문자열이 아니면 호스트 좌상단에 빨간 점 표시 + 숨김 input 의 `setCustomValidity` 로 폼 검증 연동(폼 submit 시 메시지 노출). 커스텀 컨트롤의 유효성 표시에. (sd-textfield 등 내장 컨트롤이 이미 사용)
15
19
 
16
- ## SdCommandDirective
20
+ ## 기타 셋업 훅·유틸
17
21
 
18
- `[sdRefreshCommand],[sdSaveCommand],[sdInsertCommand]`전역 단축키를 명령 이벤트로 변환(최상위 모달 컨텍스트에서만 발동).
22
+ - **setupModelHook<T>(model, canFn: Signal<(item) => boolean | Promise<boolean>>)** model set/update 가로채 canFn 결과가 false 면 변경 차단(Promise 비동기 허용). 체크박스/스위치/리스트 선택의 변경 가드(`canChangeFn`)에 사용.
23
+ - **setupBgTheme(options?: { theme?; lightness? })** — body 배경색 CSS 변수를 테마색으로 설정(컴포넌트 파괴 시 복원). theme = `"primary"|...|"gray"|"blue-gray"`, lightness = `"lightest"|"lighter"`(기본 lightest). 화면 배경 톤 지정에.
24
+ - **setSafeStyle(renderer: Renderer2, el, style: Partial<CSSStyleDeclaration>)** — Renderer2 로 여러 스타일 일괄 적용. 디렉티브에서 DOM 스타일 직접 조작 시.
25
+ - **mark(sig: WritableSignal<any>)** — in-place 변경(배열 push 등) 후 shallow copy 새 참조로 set 하여 signal 소비자에게 변경 통지. 배열/객체를 직접 변형했을 때.
19
26
 
20
- - `sdRefreshCommand = output<KeyboardEvent>()` — Ctrl+Alt+L.
21
- - `sdSaveCommand = output<KeyboardEvent>()` — Ctrl+S.
22
- - `sdInsertCommand = output<KeyboardEvent>()` — Ctrl+Insert.
27
+ ## 타입드 템플릿 디렉티브
23
28
 
24
- CRUD 컨테이너가 `sdSaveCommand` 저장에 연결.
29
+ - **SdTypedTemplate<T>** `<ng-template [typed]="typeToken" let-x="...">`. ng-template 컨텍스트에 타입을 부여(타입 가드). 재귀 메뉴 템플릿 등에서 컨텍스트 타입 보장에 사용.
30
+ - **SdItemOfTemplate<TItem>** / **SdItemOfTemplateContext<TItem>** — `<ng-template [itemOf]="items" let-item="item" let-index="index" let-depth="depth">`. 컨텍스트 `{ $implicit; item; index; depth }`. select/shared-data/calendar 등이 항목 렌더 템플릿 규약으로 사용.
25
31
 
26
- ## ripple / show-effect / invalid 디렉티브·셋업
32
+ ## SdOptionEventPlugin
27
33
 
28
- 부착형 디렉티브와 동치 셋업 함수 쌍.
29
-
30
- - `[sdRipple]` (`SdRipple`) — 클릭 ripple 효과. `sdRipple = input.required(booleanAttribute)`(활성 여부). `setupRipple(enableFn?: () => boolean)` 는 컴포넌트 생성자에서 호스트에 ripple 주입(버튼/체크박스가 사용).
31
- - `[sdShowEffect]` (`SdShowEffect`) — 스크롤 진입 시 페이드/슬라이드 인. `sdShowEffect = input.required(booleanAttribute)`(활성), `sdShowEffectType: "l2r"|"t2b"`(슬라이드 방향, 기본 `"t2b"`). `setupRevealOnShow(optFn?)` 가 동치 셋업.
32
- - `[sdInvalid]` (`SdInvalid`) — 임의 엘리먼트에 폼 검증 메시지 부착. `sdInvalid = input.required<string>()`(메시지, 빈 문자열이면 유효). `setupInvalid(getInvalidMessage: () => string)` 가 동치 셋업(숨김 input + `setCustomValidity` 로 네이티브 검증 연동, `<sd-form>` 제출 시 표시). 모든 `required` 컨트롤이 내부 사용.
33
-
34
- ## setupModelHook
35
-
36
- `setupModelHook<T, S extends WritableSignal<T>>(model: S, canFn: Signal<(item: T) => boolean | Promise<boolean>>): void` — `model` 의 set/update 를 가로채 `canFn` 통과 시에만 값 적용. 체크박스/스위치/공유선택리스트의 `canChangeFn` 구현.
37
-
38
- - `model` — 가로챌 WritableSignal.
39
- - `canFn` — 변경 허용 판정 시그널. `false` 반환 시 무시, `true` 면 즉시 set, Promise 면 resolve 가 `false` 아닐 때 set(에러는 ErrorHandler 위임).
40
-
41
- ## 타입 안전 템플릿 디렉티브
42
-
43
- - `ng-template[typed]` (`SdTypedTemplate<T>`) — `typed = input.required<T>()` 로 템플릿 컨텍스트 타입을 명시(재귀 메뉴 등 `let-x` 타입 추론용). 값은 타입 토큰일 뿐.
44
- - `ng-template[itemOf]` (`SdItemOfTemplate<TItem>`) — `itemOf = input.required<TItem[]>()` 로 항목 반복 템플릿의 컨텍스트 타입 제공. select/calendar/공유선택이 항목 슬롯에 사용. 컨텍스트 `SdItemOfTemplateContext<TItem> = { $implicit; item; index; depth }`.
34
+ `provideSdAngular` 등록하는 `EventManagerPlugin`. `.capture`/`.passive`/`.once` 접미 이벤트를 해석. 직접 사용 안 함.