@simplysm/sd-claude 14.0.88 → 14.0.90

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 (135) hide show
  1. package/claude/references/sd-simplysm14/README.md +16 -17
  2. package/claude/references/sd-simplysm14/apis/angular/README.md +39 -43
  3. package/claude/references/sd-simplysm14/apis/angular/controls.md +174 -80
  4. package/claude/references/sd-simplysm14/apis/angular/crud.md +41 -50
  5. package/claude/references/sd-simplysm14/apis/angular/directives.md +60 -26
  6. package/claude/references/sd-simplysm14/apis/angular/features.md +109 -37
  7. package/claude/references/sd-simplysm14/apis/angular/infra.md +61 -44
  8. package/claude/references/sd-simplysm14/apis/angular/layout.md +39 -31
  9. package/claude/references/sd-simplysm14/apis/angular/overlay.md +73 -85
  10. package/claude/references/sd-simplysm14/apis/angular/routing-appstructure.md +54 -39
  11. package/claude/references/sd-simplysm14/apis/angular/selection-managers.md +55 -30
  12. package/claude/references/sd-simplysm14/apis/angular/shared-data.md +71 -67
  13. package/claude/references/sd-simplysm14/apis/angular/sheet.md +82 -72
  14. package/claude/references/sd-simplysm14/apis/capacitor-plugin-auto-update/README.md +35 -36
  15. package/claude/references/sd-simplysm14/apis/capacitor-plugin-file-system/README.md +71 -43
  16. package/claude/references/sd-simplysm14/apis/capacitor-plugin-intent/README.md +38 -30
  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 +39 -38
  21. package/claude/references/sd-simplysm14/apis/core-common/README.md +95 -103
  22. package/claude/references/sd-simplysm14/apis/core-common/array-ext.md +59 -54
  23. package/claude/references/sd-simplysm14/apis/core-common/async-runtime.md +86 -0
  24. package/claude/references/sd-simplysm14/apis/core-common/datetime.md +57 -66
  25. package/claude/references/sd-simplysm14/apis/core-common/errors.md +86 -0
  26. package/claude/references/sd-simplysm14/apis/core-common/obj.md +60 -42
  27. package/claude/references/sd-simplysm14/apis/core-common/serialization.md +55 -0
  28. package/claude/references/sd-simplysm14/apis/core-node/README.md +10 -8
  29. package/claude/references/sd-simplysm14/apis/core-node/consola.md +29 -32
  30. package/claude/references/sd-simplysm14/apis/core-node/cpx.md +34 -22
  31. package/claude/references/sd-simplysm14/apis/core-node/fs-watcher.md +29 -25
  32. package/claude/references/sd-simplysm14/apis/core-node/fsx.md +40 -53
  33. package/claude/references/sd-simplysm14/apis/core-node/pathx.md +22 -29
  34. package/claude/references/sd-simplysm14/apis/core-node/worker.md +31 -31
  35. package/claude/references/sd-simplysm14/apis/excel/README.md +26 -26
  36. package/claude/references/sd-simplysm14/apis/excel/cell.md +37 -29
  37. package/claude/references/sd-simplysm14/apis/excel/conditional-format.md +29 -15
  38. package/claude/references/sd-simplysm14/apis/excel/style.md +33 -27
  39. package/claude/references/sd-simplysm14/apis/excel/utils.md +29 -19
  40. package/claude/references/sd-simplysm14/apis/excel/workbook-worksheet.md +78 -55
  41. package/claude/references/sd-simplysm14/apis/excel/wrapper.md +42 -45
  42. package/claude/references/sd-simplysm14/apis/lint/README.md +27 -21
  43. package/claude/references/sd-simplysm14/apis/lint/rules.md +89 -49
  44. package/claude/references/sd-simplysm14/apis/orm-common/README.md +6 -62
  45. package/claude/references/sd-simplysm14/apis/orm-common/db-context.md +149 -67
  46. package/claude/references/sd-simplysm14/apis/orm-common/expr.md +111 -99
  47. package/claude/references/sd-simplysm14/apis/orm-common/queryable.md +115 -72
  48. package/claude/references/sd-simplysm14/apis/orm-common/schema.md +134 -92
  49. package/claude/references/sd-simplysm14/apis/orm-common/types.md +67 -52
  50. package/claude/references/sd-simplysm14/apis/orm-node/README.md +63 -26
  51. package/claude/references/sd-simplysm14/apis/orm-node/db-conn.md +51 -40
  52. package/claude/references/sd-simplysm14/apis/sd-cli/README.md +10 -12
  53. package/claude/references/sd-simplysm14/apis/sd-cli/SdTsCompiler.md +92 -45
  54. package/claude/references/sd-simplysm14/apis/sd-cli/sd-config-types.md +226 -108
  55. package/claude/references/sd-simplysm14/apis/service-client/README.md +90 -88
  56. package/claude/references/sd-simplysm14/apis/service-client/orm.md +37 -29
  57. package/claude/references/sd-simplysm14/apis/service-client/transport.md +45 -20
  58. package/claude/references/sd-simplysm14/apis/service-common/README.md +89 -40
  59. package/claude/references/sd-simplysm14/apis/service-common/app-structure.md +126 -34
  60. package/claude/references/sd-simplysm14/apis/service-common/protocol.md +109 -54
  61. package/claude/references/sd-simplysm14/apis/service-server/README.md +70 -66
  62. package/claude/references/sd-simplysm14/apis/service-server/service-authoring.md +47 -47
  63. package/claude/references/sd-simplysm14/apis/service-server/transport-internals.md +71 -34
  64. package/claude/references/sd-simplysm14/apis/service-server/v1-legacy.md +31 -32
  65. package/claude/references/sd-simplysm14/apis/storage/README.md +34 -28
  66. package/claude/references/sd-simplysm14/manuals/client-app-structure.md +142 -140
  67. package/claude/references/sd-simplysm14/manuals/client-orm.md +1 -1
  68. package/claude/references/sd-simplysm14/manuals/client-service.md +19 -7
  69. package/claude/references/sd-simplysm14/manuals/client-shared-data.md +2 -2
  70. package/claude/references/sd-simplysm14/manuals/client-system-log.md +11 -3
  71. package/claude/references/sd-simplysm14/manuals/data-log.md +0 -1
  72. package/claude/references/sd-simplysm14/manuals/orm.md +16 -0
  73. package/claude/rules/sd-design-rules.md +10 -0
  74. package/claude/skills/sd-docs/SKILL.md +58 -46
  75. package/claude/skills/sd-docs/references/{doc-rules.md → subagent-prompt.md} +103 -103
  76. package/claude/skills/sd-impl/SKILL.md +1 -1
  77. package/claude/skills/sd-spec/SKILL.md +858 -858
  78. package/claude/skills/sd-spec/references/example-spec.md +26 -36
  79. package/package.json +1 -1
  80. package/claude/references/sd-simplysm14/apis/core-common/json-transfer.md +0 -47
  81. package/claude/references/sd-simplysm14/apis/orm-common/query-builder.md +0 -29
  82. package/claude/skills/sd-demo/evals/fixtures/inventory-list/.specs/inventory/spec.md +0 -99
  83. package/claude/skills/sd-demo/evals/fixtures/inventory-list/packages/demo-client/package.json +0 -12
  84. package/claude/skills/sd-demo/evals/fixtures/inventory-list/packages/demo-client/src/index.ts +0 -3
  85. package/claude/skills/sd-demo/evals/fixtures/inventory-list/packages/demo-client/src/screens/inbound/inbound.list.ts +0 -150
  86. package/claude/skills/sd-demo/evals/fixtures/inventory-list/packages/demo-client/src/screens/inventory/inventory-master.list.ts +0 -143
  87. package/claude/skills/sd-demo/evals/fixtures/inventory-list/packages/demo-client/src/screens/outbound/outbound.list.ts +0 -150
  88. package/claude/skills/sd-demo/evals/fixtures/inventory-list/pnpm-workspace.yaml +0 -2
  89. package/claude/skills/sd-demo/evals/fixtures/inventory-list/sd.config.ts +0 -12
  90. package/claude/skills/sd-demo/evals/golden.jsonl +0 -1
  91. package/claude/skills/sd-dev/evals/fixtures/minimal-ts-pkg/package.json +0 -8
  92. package/claude/skills/sd-dev/evals/fixtures/minimal-ts-pkg/src/.gitkeep +0 -0
  93. package/claude/skills/sd-dev/evals/fixtures/minimal-ts-pkg/tests/.gitkeep +0 -0
  94. package/claude/skills/sd-dev/evals/fixtures/minimal-ts-pkg/tsconfig.json +0 -10
  95. package/claude/skills/sd-dev/evals/golden.jsonl +0 -1
  96. package/claude/skills/sd-docs/evals/fixtures/new-write/.claude/references/sd-simplysm14/README.md +0 -7
  97. package/claude/skills/sd-docs/evals/fixtures/new-write/packages/bar/package.json +0 -5
  98. package/claude/skills/sd-docs/evals/fixtures/new-write/packages/bar/src/index.ts +0 -3
  99. package/claude/skills/sd-docs/evals/fixtures/new-write/packages/baz/package.json +0 -6
  100. package/claude/skills/sd-docs/evals/fixtures/new-write/packages/baz/src/index.ts +0 -1
  101. package/claude/skills/sd-docs/evals/fixtures/new-write/packages/foo/package.json +0 -5
  102. package/claude/skills/sd-docs/evals/fixtures/new-write/packages/foo/src/index.ts +0 -8
  103. package/claude/skills/sd-docs/evals/fixtures/update-mixed/.claude/references/sd-simplysm14/README.md +0 -7
  104. package/claude/skills/sd-docs/evals/fixtures/update-mixed/.claude/references/sd-simplysm14/apis/foo/README.md +0 -3
  105. package/claude/skills/sd-docs/evals/fixtures/update-mixed/packages/bar/package.json +0 -5
  106. package/claude/skills/sd-docs/evals/fixtures/update-mixed/packages/bar/src/index.ts +0 -3
  107. package/claude/skills/sd-docs/evals/fixtures/update-mixed/packages/baz/package.json +0 -6
  108. package/claude/skills/sd-docs/evals/fixtures/update-mixed/packages/baz/src/index.ts +0 -1
  109. package/claude/skills/sd-docs/evals/fixtures/update-mixed/packages/foo/package.json +0 -5
  110. package/claude/skills/sd-docs/evals/fixtures/update-mixed/packages/foo/src/index.ts +0 -8
  111. package/claude/skills/sd-docs/evals/golden.jsonl +0 -2
  112. package/claude/skills/sd-impl/evals/fixtures/case-a-new-screen/.specs/260513120000_warehouse/spec.md +0 -101
  113. package/claude/skills/sd-impl/evals/fixtures/case-b-update-with-demo/.specs/260513120000_warehouse/spec.md +0 -101
  114. package/claude/skills/sd-impl/evals/fixtures/case-b-update-with-demo/packages/app/src/screens/box-register/box-register.view.ts +0 -46
  115. package/claude/skills/sd-impl/evals/fixtures/case-c-new-cross/.specs/260513120000_warehouse/spec.md +0 -89
  116. package/claude/skills/sd-impl/evals/fixtures/case-d-spec-modify/.specs/260513120000_warehouse/spec.md +0 -101
  117. package/claude/skills/sd-impl/evals/golden.jsonl +0 -4
  118. package/claude/skills/sd-manual/evals/fixtures/new-manual/src/notification.ts +0 -25
  119. package/claude/skills/sd-manual/evals/fixtures/update-manual/.claude/references/sd-simplysm14/manuals/notification.md +0 -14
  120. package/claude/skills/sd-manual/evals/fixtures/update-manual/src/notification.ts +0 -37
  121. package/claude/skills/sd-manual/evals/golden.jsonl +0 -2
  122. package/claude/skills/sd-review/evals/fixtures/code-review/src/foo.ts +0 -7
  123. package/claude/skills/sd-review/evals/fixtures/doc-review/docs/foo.md +0 -4
  124. package/claude/skills/sd-review/evals/golden.jsonl +0 -2
  125. package/claude/skills/sd-skill/evals/fixtures/existing-skill/.claude/skills/todo-format/SKILL.md +0 -14
  126. package/claude/skills/sd-skill/evals/fixtures/new-skill/.gitkeep +0 -0
  127. package/claude/skills/sd-skill/evals/golden.jsonl +0 -2
  128. package/claude/skills/sd-spec/evals/fixtures/case-a-split//355/232/214/354/235/230/353/241/235.md +0 -20
  129. package/claude/skills/sd-spec/evals/fixtures/case-b-detail/.specs/260513120000_warehouse/spec.md +0 -95
  130. package/claude/skills/sd-spec/evals/golden.jsonl +0 -2
  131. package/claude/skills/sd-unpack/evals/fixtures/eml-with-text-attachment/meeting.eml +0 -21
  132. package/claude/skills/sd-unpack/evals/fixtures/simple-eml/meeting.eml +0 -10
  133. package/claude/skills/sd-unpack/evals/golden.jsonl +0 -2
  134. package/claude/skills/sd-use/evals/fixtures/empty/.gitkeep +0 -0
  135. package/claude/skills/sd-use/evals/golden.jsonl +0 -6
@@ -44,20 +44,19 @@ 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) 기반 SI/업무 클라이언트용 UI 컴포넌트·디렉티브·전역 프로바이더·signal 헬퍼 — 부트스트랩(provideSdAngular)·모달/토스트/busy/인쇄·라우팅/메뉴/권한·폼 입력 컨트롤·시트(sd-sheet)·공유 마스터 데이터·CRUD 화면 골격·사이드바/탑바 레이아웃·칸반/권한표/에디터/시각화를 쓸 때. 자세히: [apis/angular/README.md](./apis/angular/README.md)
48
+ - **capacitor-plugin-auto-update** — Android APK 자동 업데이트 Capacitor 플러그인 부팅 서버/외부저장소의 최신 APK 받아 설치하는 오케스트레이터(AutoUpdate)와 저수준 설치·권한·버전 조회 정적 클래스(ApkInstaller). 자세히: [apis/capacitor-plugin-auto-update/README.md](./apis/capacitor-plugin-auto-update/README.md)
49
+ - **capacitor-plugin-file-system** — Capacitor 네이티브 파일 시스템 접근(Android OS 파일 시스템 / 웹 IndexedDB 에뮬레이션). FileSystem 정적 메서드로 권한 확인·요청, 디렉토리 읽기/생성, 파일 읽기/쓰기/삭제, 저장소 경로·파일 URI 조회 시. 자세히: [apis/capacitor-plugin-file-system/README.md](./apis/capacitor-plugin-file-system/README.md)
50
+ - **capacitor-plugin-intent** — Android 인텐트 송수신 Capacitor 플러그인(Intent 정적 클래스) — 브로드캐스트 구독/전송, 실행 인텐트 조회, newIntent 리스닝, startActivityForResult 외부 Activity 실행·결과 수신. 바코드 스캐너·PDA 등 산업용 디바이스 연동 시 사용. 자세히: [apis/capacitor-plugin-intent/README.md](./apis/capacitor-plugin-intent/README.md)
51
+ - **capacitor-plugin-usb-storage** — 연결된 USB Mass Storage 장치를 열거·권한확인 디렉토리/파일을 읽는 Capacitor 플러그인. 정적 클래스 UsbStorage 입출력 타입(UsbDeviceInfo/UsbDeviceFilter/UsbFileInfo/UsbStoragePlugin) 제공. 자세히: [apis/capacitor-plugin-usb-storage/README.md](./apis/capacitor-plugin-usb-storage/README.md)
52
+ - **core-browser** — 브라우저 전용 유틸리티DOM 요소 탐색·위치 계산·가시성 확장, IndexedDB 영속화 가상 파일시스템, Blob 다운로드·URL 바이너리 수신·파일 선택 대화상자가 필요할 때. 자세히: [apis/core-browser/README.md](./apis/core-browser/README.md)
53
+ - **core-common** — 브라우저·Node 공용 기반 유틸 날짜/시간 값 타입(DateTime/DateOnly/Time), 에러 클래스(SdError 등), 배열/객체 조작, 직렬화(json/xml/bytes/transfer), 비동기 큐·이벤트·대기, 로거·환경변수가 필요할 때. 자세히: [apis/core-common/README.md](./apis/core-common/README.md)
54
+ - **core-node** — Node 전용 유틸: 파일시스템 IO(fsx)·경로 가공(pathx)·자식 프로세스 실행(cpx)·glob 감시(FsWatcher)·consola 로깅 셋업(setupConsola)·worker_threads 타입 안전 래퍼(Worker/createWorker)가 필요할 때. 자세히: [apis/core-node/README.md](./apis/core-node/README.md)
55
+ - **excel** — OOXML(.xlsx) 워크북을 ZIP 단위 lazy-load 로 읽고 쓰는 라이브러리. ExcelWorkbook/ExcelWorksheet 시트·셀 값/수식·스타일·조건부 서식·이미지·행 복사·뷰를, ExcelWrapper 로 Zod 스키마 기반 레코드 엑셀 변환을, ExcelUtils 로 주소·날짜 시리얼·숫자형식 변환을 다룰 때. 자세히: [apis/excel/README.md](./apis/excel/README.md)
56
+ - **orm-common** — Dialect 독립 ORM 코어 DbContext 상속·연결/트랜잭션/DDL/마이그레이션, Table/View/Procedure 스키마 빌더, Queryable 체이닝·CRUD·검색·UNION, expr 표현식 빌더, QueryDef/Expr AST·QueryBuilder·결과 파싱을 다룰 참조. 자세히: [apis/orm-common/README.md](./apis/orm-common/README.md)
57
+ - **orm-node** — Node.js 환경에서 DbContext MySQL/MSSQL/PostgreSQL연결·실행하는 ORM 런타임 고수준 createOrm(트랜잭션 경계) 저수준 createDbConn/DbConn(raw SQL·파라미터 쿼리·bulk insert·수동 트랜잭션) 제공. 자세히: [apis/orm-node/README.md](./apis/orm-node/README.md)
58
+ - **sd-cli** — sd.config.ts 설정 타입(SdConfigFn·타겟별 패키지 설정·배포/Capacitor/Electron/PWA), 패키지 단위 TS/Angular AOT 증분 컴파일러 SdTsCompiler, Vitest용 Angular Vite 플러그인 sdAngularPlugin 다룰 때. 자세히: [apis/sd-cli/README.md](./apis/sd-cli/README.md)
59
+ - **service-client** — WebSocket 으로 서비스 서버에 접속해 서비스 RPC 호출·서버 푸시 이벤트 구독/발행·파일 업다운로드·서버측 ORM 원격 실행을 수행하는 클라이언트(브라우저/Node 양용) 필요할 때. 자세히: [apis/service-client/README.md](./apis/service-client/README.md)
60
+ - **service-common** — 서버·클라이언트 공유 서비스 통신 계약defineEvent 이벤트 정의, 내장 RPC 서비스(OrmService·AutoUpdateService) 시그니처, 메뉴·권한·모듈 구조(AppStructure), WebSocket 바이너리 프로토콜·메시지 타입. 자세히: [apis/service-common/README.md](./apis/service-common/README.md)
61
+ - **service-server** — Fastify 기반 RPC 서비스 서버(WebSocket/HTTP 전송, JWT 인증, 정적 파일·업로드, 서버측 이벤트 브로드캐스트, 내장 ORM/자동업데이트 서비스) 띄우거나 defineService/auth 서비스 메서드를 작성할 때. 자세히: [apis/service-server/README.md](./apis/service-server/README.md)
62
+ - **storage** — FTP/FTPS/SFTP 원격 스토리지에 접속해 파일·디렉토리를 업로드·다운로드·조회·삭제할 때(StorageFactory.connect 연결/종료 자동 관리). 자세히: [apis/storage/README.md](./apis/storage/README.md)
@@ -1,61 +1,57 @@
1
1
  # @simplysm/angular
2
2
 
3
- Angular 기반 업무 화면 UI 컴포넌트·디렉티브·프로바이더 묶음. `provideSdAngular()` 부트스트랩하고, 컨트롤·시트·모달/토스트/Busy 오버레이·CRUD 화면 골격·권한/공유데이터 인프라를 standalone 컴포넌트로 제공. zoneless(Signal 기반) 전제이며 모든 입력은 Angular `input()`/`model()` 시그널.
3
+ Angular(zoneless) 기반 SI/업무 클라이언트용 UI 컴포넌트·디렉티브·프로바이더·signal 헬퍼 라이브러리. `import "@simplysm/core-browser"` side-effect 로드하며, 모든 컴포넌트는 standalone + OnPush + `ViewEncapsulation.None`, selector `sd-` prefix.
4
4
 
5
- ## 사용 트리거 인덱스
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
- ## 유틸 타입·헬퍼 (인라인)
5
+ > 사용 패턴 근거: `manuals/client-component.md`, `client-shared-data.md`, `client-system-log.md`, `client-demo.md`, `client-rules.md`. 화면 작성 시 provider 경유 호출·표준 시그널(ready/initialized/busyCount/viewType)·`mark` 사용·`$any` 금지 등은 매뉴얼을 따름.
20
6
 
21
- 군에 속하지 않는 소형 유틸. 모두 `@simplysm/angular` 루트에서 직접 import.
22
-
23
- ### mark
24
-
25
- `mark(sig: WritableSignal<any>): void` — 시그널 값을 in-place mutation 한 뒤 소비자에게 변경을 알림.
7
+ ## 사용 트리거 인덱스
26
8
 
27
- - `sig` 대상 WritableSignal. 값이 배열이면 `[...v]`, 객체면 `{...v}` 얕은 복사해 참조로 set → OnPush/computed 재평가 트리거. push·속성변경 후 한 줄로 갱신 신호를 줄 때.
9
+ - **앱 부트스트랩·전역 프로바이더** `provideSdAngular`, 테마/로컬스토리지/시스템설정/시스템로그/서비스클라이언트 provider 배선할 때. 자세히: [infra.md](./infra.md)
10
+ - **모달·토스트·busy·인쇄 (오버레이/전역 피드백)** — 화면에서 모달을 띄우거나, 토스트로 알림·진행률을 표시하거나, busy 인디케이터·인쇄/PDF 를 호출할 때. 자세히: [overlay.md](./overlay.md)
11
+ - **라우팅·앱 구조(메뉴·권한)** — 라우터 링크, 현재 페이지 코드·뷰 타입·뷰 제목 signal, 메뉴·권한 트리(`injectPermsSignal`) 를 다룰 때. 자세히: [routing-appstructure.md](./routing-appstructure.md)
12
+ - **디렉티브·signal setup 헬퍼** — 리사이즈/교차/캡처 이벤트, 커맨드 단축키, ripple, 노출 애니메이션, invalid 표시, 타입드 템플릿을 붙일 때. 자세히: [directives.md](./directives.md)
13
+ - **폼·기본 입력 컨트롤** — 버튼/앵커, textfield/textarea/numpad/range/날짜범위, checkbox/switch/group, select/dropdown, form/collapse/tab/list/pagination 을 배치할 때. 자세히: [controls.md](./controls.md)
14
+ - **레이아웃 셸 (사이드바·탑바)** — 앱 좌측 사이드바/상단바 + 메뉴/사용자 메뉴를 구성할 때. 자세히: [layout.md](./layout.md)
15
+ - **시트(그리드)** — `sd-sheet` + 컬럼/셀 템플릿으로 다건 목록·편집 표를 그릴 때. 자세히: [sheet.md](./sheet.md)
16
+ - **공유 마스터 데이터 + 선택 컨트롤** — `SdSharedDataProvider` 등록·조회, `sd-shared-data-select`(드롭다운/버튼/리스트) 로 마스터 데이터를 선택할 때. 자세히: [shared-data.md](./shared-data.md)
17
+ - **selection/sorting/expanding 매니저** — 커스텀 목록 컴포넌트에서 선택·정렬·트리 펼침 상태 로직을 signal 로 합성할 때. 자세히: [selection-managers.md](./selection-managers.md)
18
+ - **CRUD 화면 표준 골격** — `sd-base-container` / `sd-crud-list` / `sd-crud-detail` 로 목록/단건 화면을 만들 때. 자세히: [crud.md](./crud.md)
19
+ - **기능 컴포넌트 (칸반·권한표·상태프리셋·테마선택·주소검색·에디터·시각화)** — 위 군에 안 드는 도메인성 컴포넌트를 쓸 때. 자세히: [features.md](./features.md)
28
20
 
29
- ```typescript
30
- items().push(x); // 참조 동일 → 안 알려짐
31
- mark(items); // 얕은 복사로 새 참조 → 변경 전파
32
- ```
21
+ 아래는 군을 별도로 둘 만큼 크지 않은 유틸·타입·표시용 심볼의 인라인 섹션이다.
33
22
 
34
- ### setSafeStyle
23
+ ## signal·DOM 유틸
35
24
 
36
- `setSafeStyle(renderer: Renderer2, el: HTMLElement, style: Partial<CSSStyleDeclaration>): void` — Renderer2여러 인라인 스타일을 번에 적용.
25
+ - `mark(sig: WritableSignal<any>): void` — WritableSignal 의 값을 in-place 변경한 뒤 변경 알림만 발행. 내부적으로 배열이면 `[...v]`, 객체면 `{...v}` shallow copy 참조를 set. effect 강제 재발화나 객체/배열 필드 변경 알림에 사용. 매뉴얼 권장 패턴: `doRefresh(){ mark(this.lastFilter); }`, 양방향 바인딩 자식 변경 시 `(valueChange)="mark(filter)"`.
26
+ - `setSafeStyle(renderer: Renderer2, el: HTMLElement, style: Partial<CSSStyleDeclaration>): void` — `style` 객체의 각 키를 `renderer.setStyle` 로 적용. Angular Renderer 경유로 DOM 스타일을 안전하게 일괄 세팅할 때(직접 `el.style` 대입을 피해야 하는 디렉티브/setup 내부).
37
27
 
38
- - `renderer` — Angular `Renderer2` 인스턴스. 키별로 `renderer.setStyle` 호출.
39
- - `el` — 대상 엘리먼트.
40
- - `style` — CSS 속성 부분 객체. 동작 셋업 함수(setupInvalid 등)가 내부적으로 사용.
28
+ ## FormatPipe (`format` 파이프)
41
29
 
42
- ### FormatPipe (`| format`)
30
+ - `transform(value: string | DateTime | DateOnly | undefined, format: string): string` — 값 표시 포매팅 파이프(`name: "format"`).
31
+ - `value` 가 `null`/`undefined` → `""` 반환(결측 보존).
32
+ - `DateTime`/`DateOnly` → `value.toFormatString(format)`.
33
+ - `string` → `format` 을 `|` 로 끊어 각 후보에서 `X` 개수가 문자열 길이와 같은 것을 찾아 `X` 자리에 한 글자씩 끼워 마스킹(예: 전화번호 `"XXX-XXXX-XXXX"`). 매칭 후보가 없으면 원문 그대로.
34
+ - 사용: `{{ phone | format: 'XXX-XXXX-XXXX' }}`, `{{ date | format: 'yyyy-MM-dd' }}`.
43
35
 
44
- `transform(value: string | DateTime | DateOnly | undefined, format: string): string` — 값을 포맷 문자열로 변환하는 standalone 파이프(name `format`).
36
+ ## 디렉티브 입력 추론 타입
45
37
 
46
- - `value` 대상. `null`/`undefined` `""`. `DateTime`/`DateOnly` `value.toFormatString(format)`. 문자열이면 `X` 자리표시자 마스킹 적용(길이 일치 시).
47
- - `format` — 포맷 문자열. 문자열 입력 시 `|` 로 분리한 후보 중 `X` 개수가 값 길이와 같은 패턴을 골라 `X` 를 한 글자씩 치환(예: `"XXX-XXXX"`).
38
+ 모달/토스트/인쇄 provider `inputs` 타입 계산에 쓰이는 유틸 타입. 직접 일은 드물지만 시그니처 해석용으로 노출됨.
48
39
 
49
- ### DirectiveInputSignals / UndefToOptional / WithOptional (타입)
40
+ - `DirectiveInputSignals<T>` 컴포넌트/디렉티브 클래스 `T` 의 `InputSignal` 프로퍼티만 골라 `{ 키: 값타입 }` 으로 추출. `InputSignal` 아닌 멤버는 제외, `undefined` 포함 필드는 optional 로 변환.
41
+ - `UndefToOptional<T>` — `undefined` 를 포함하는 프로퍼티를 optional(`?`)로 바꾸는 매핑 타입. `DirectiveInputSignals` 내부에서 사용.
42
+ - `WithOptional<T, K extends keyof T>` — 특정 키 `K` 만 optional 로 만든 타입(`Omit<T,K> & Partial<Pick<T,K>>`). provider 의 `inputs` 에서 "기본값 있는 입력은 생략 가능" 을 표현.
50
43
 
51
- 컴포넌트의 `input()` 시그널 집합에서 값 타입을 추출하는 유틸 타입. 모달/토스트/인쇄 콘텐츠 컴포넌트의 `inputs` 타입 추론에 쓰임.
44
+ ## SelectModalOutputResult
52
45
 
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 로 변환.
46
+ - `interface SelectModalOutputResult<TKey = any> { selectedKeys: TKey[] }` 선택 전용 모달이 close 시 emit 하는 페이로드 규약. `SdSelectModal` / `SdModalSelectButton` / `sd-shared-data-select` 모달 연동의 반환 타입. 선택 모달 컴포넌트는 타입을 `close.emit` 으로 돌려줌.
56
47
 
57
- ### SelectModalOutputResult (타입)
48
+ ## SdGap (`sd-gap`)
58
49
 
59
- `interface SelectModalOutputResult<TKey = any> { selectedKeys: TKey[] }` 선택 모달이 close 로 반환하는 결과 형태.
50
+ 여백 전용 컴포넌트. flex 레이아웃 사이 간격을 토큰/픽셀로 삽입.
60
51
 
61
- - `selectedKeys` — 선택된 배열. 단일 선택이어도 배열. `SdSelectModal` 구현 모달이 확정 emit.
52
+ - `height: "xxs"|"xs"|"sm"|"default"|"lg"|"xl"|"xxl"` — 세로 간격 토큰(`--gap-*`). 세로 스택 사이 간격에 사용. 지정display=block.
53
+ - `heightPx: number` — 세로 간격 px. `0` 이면 display=none(간격 제거).
54
+ - `width: "xxs"|...|"xxl"` — 가로 간격 토큰. 가로 나열 사이 간격에 사용. 지정 시 display=inline-block.
55
+ - `widthPx: number` — 가로 간격 px. `0` 이면 display=none.
56
+ - `widthEm: number` — 가로 간격 em. `0` 이면 display=none.
57
+ - 사용: `<sd-gap [width]="'sm'" />`.
@@ -1,119 +1,213 @@
1
- # @simplysm/angular — 컨트롤·버튼·선택 컨트롤
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
+ 버튼·앵커, 텍스트/숫자/날짜 입력, 체크박스/스위치, 셀렉트/드롭다운, 폼/접기/탭/리스트/페이지네이션 폼·UI 기본 컨트롤 군. 화면 폼·필터·시트 셀에서 함께 쓰임. 공통: 거의 모든 컨트롤이 `size: "sm"|"lg"`(미지정=기본), `inline`, `inset`(테두리 제거·셀 내장용), `disabled`, `theme` 가짐. 매뉴얼(client-component.md "표준 입력 컨트롤"·"버튼 스타일")의 역할별 theme/size 규약을 따름.
4
4
 
5
- ## SdButton / SdAnchor / SdAdditionalButton
5
+ ## 버튼·앵커
6
6
 
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`.
7
+ ### SdButton (`sd-button`)
10
8
 
11
- ## SdModalSelectButton
9
+ - `type: "button"|"submit"` — 버튼 타입. `"submit"` 이면 부모 `sd-form` submit 트리거. 기본 `"button"`.
10
+ - `theme` — 색 테마. 일반 시리즈 `"primary"|"secondary"|"info"|"success"|"warning"|"danger"|"gray"|"blue-gray"`(채움 버튼), link 시리즈 `"link"|"link-primary"|...|"link-blue-gray"|"link-rev"`(테두리·배경 없는 텍스트 버튼). 저장/삭제 등 데이터 변경 최상위 액션은 일반 시리즈, 유틸/시트 위 버튼은 link 시리즈(client-component.md).
11
+ - `size: "sm"|"lg"` — 패딩 크기. 시트 위/셀 버튼은 `"sm"`.
12
+ - `inline: boolean` — true 면 width auto(인라인 배치). 기본은 width 100%.
13
+ - `inset: boolean` — true 면 테두리·radius 제거(컨테이너 내장 버튼).
14
+ - `disabled: boolean` — 비활성.
15
+ - `buttonStyle: string` / `buttonClass: string` — 내부 `<button>` 에 직접 줄 스타일/클래스.
16
+ - 사용: `<sd-button [theme]="'primary'" (click)="onSave()">저장</sd-button>`.
12
17
 
13
- `<sd-modal-select-button>` 모달로 선택하는 값 입력 버튼(검색 아이콘 → 선택모달, 지우개 → 초기화).
18
+ ### SdAnchor (`sd-anchor`)
14
19
 
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).
20
+ 인라인 텍스트 링크/아이콘 버튼.
21
21
 
22
- 타입: `SdSelectModal<TKey>`(선택모달 인터페이스, `selectMode`/`selectedKeys` input 추가), `SdSelectModalInfo<T>`(`SdModalInfo` 에서 `selectMode`/`selectedKeys` 제외).
22
+ - `theme: "primary"|...|"blue-gray"` 텍스트 (기본 `"primary"`). hover underline.
23
+ - `disabled: boolean` — true 면 흐려지고 포인터·tabindex 제거.
24
+ - 사용: 시트 셀 안 액션 아이콘 `<sd-anchor [theme]="'danger'" (click)="onDelete()"><ng-icon [svg]="tablerEraser" /></sd-anchor>`.
23
25
 
24
- ## SdTextfield
26
+ ### SdAdditionalButton (`sd-additional-button`)
25
27
 
26
- `<sd-textfield>` 타입별 단일값 입력. 제네릭 `K extends keyof SdTextfieldTypes` 타입이 결정됨.
28
+ 콘텐츠 + 우측 버튼을 테두리로 묶는 컨테이너. `<ng-content>` 본문 + 투영된 `sd-anchor`/`sd-button`.
27
29
 
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` — 공통 레이아웃.
30
+ - `size: "sm"|"lg"` — 패딩.
31
+ - `inset: boolean` — 테두리·radius 제거.
37
32
 
38
- `SdTextfieldTypes`(타입 → 값 타입): `number`→number, `text`/`password`/`color`/`email`/`format`→string, `date`/`month`/`year`→DateOnly, `datetime`/`datetime-sec`→DateTime, `time`/`time-sec`→Time. `sdTextfieldTypes` 는 이 키들의 배열.
33
+ ### SdModalSelectButton (`sd-modal-select-button`)
39
34
 
40
- ```html
41
- <sd-textfield [type]="'number'" [(value)]="qty" [min]="0" [required]="true" />
42
- <sd-textfield [type]="'date'" [(value)]="orderDate" />
43
- ```
35
+ 값 표시 + 검색 버튼으로 선택 모달을 띄우는 입력. 선택 결과(`SelectModalOutputResult`)를 `value` 에 반영.
44
36
 
45
- ## SdTextarea
37
+ - `modal: input.required<SdSelectModalInfo<SdSelectModal<K>>>` — 띄울 선택 모달 정보(`selectMode`/`selectedKeys` 는 자동 주입되므로 inputs 에서 제외).
38
+ - `value: model<...>` — 선택 값. `selectMode="single"` 이면 단일 키, `"multi"` 면 키 배열.
39
+ - `selectMode: "single"|"multi"` — 선택 모드(기본 `"single"`).
40
+ - `modalOptions: SdModalOptions` — 모달 표시 옵션.
41
+ - `required: boolean` — true 면 값 없을 때 invalid(빨간 점) + 지우개 버튼 숨김.
42
+ - `disabled` / `inset` / `size` — 공통.
43
+ - `searchIcon: input` — 검색 버튼 아이콘(기본 `tablerSearch`).
44
+ - 동작: 검색 버튼 클릭 → 현재 값으로 `selectedKeys` 채워 모달 표시 → 결과로 `value` 갱신. required 가 아니고 값 있으면 지우개로 비움.
45
+ - `SdSelectModal<TKey>` = `SdModalContentDef<SelectModalOutputResult<TKey>>` + `selectMode`/`selectedKeys` input. 선택 모달 컴포넌트가 구현(보통 `sd-crud-list` 를 모달로).
46
+ - `SdSelectModalInfo<T>` = `SdModalInfo<T, "selectMode"|"selectedKeys">`.
46
47
 
47
- `<sd-textarea>` 여러 줄 문자열 입력. `value = model<string>()`, `minRows`(최소 줄수, 내용 따라 자동 확장), `placeholder`/`title`/`disabled`/`readonly`/`required`/`inline`/`inset`/`size`/`theme`/`validatorFn`/`inputStyle`/`inputClass`.
48
+ ## 텍스트·숫자·날짜 입력
48
49
 
49
- ## SdNumpad
50
+ ### SdTextfield<K> (`sd-textfield`)
50
51
 
51
- `<sd-numpad>` 터치 숫자패드. `value = model<number>()`, `placeholder`, `required`, `inputDisabled`(상단 입력칸 비활성), `useEnterButton`(ENT 버튼 표시), `useMinusButton`(부호 토글), `enterButtonClick = output()`(ENT 클릭).
52
+ 타입별 핸들러로 파싱·포맷·검증하는 만능 입력. `value` 타입이 `type` 따라 결정됨.
52
53
 
53
- ## SdRange
54
+ - `type: input.required<K extends keyof SdTextfieldTypes>` — 입력 타입. 값 타입 매핑(`SdTextfieldTypes`):
55
+ - `"text"|"password"|"email"|"color"|"format"` → `string`.
56
+ - `"number"` → `number`(콤마 표시, 우정렬).
57
+ - `"date"|"month"|"year"` → `DateOnly`.
58
+ - `"datetime"|"datetime-sec"` → `DateTime`(sec 는 초 포함).
59
+ - `"time"|"time-sec"` → `Time`.
60
+ - (`sdTextfieldTypes` 는 이 키들의 런타임 배열.)
61
+ - `value: model<SdTextfieldTypes[K]>` — 값. 빈 입력은 `undefined`(결측 보존). 파싱 실패 시 표시값 롤백.
62
+ - `placeholder` / `title` — 안내/툴팁.
63
+ - `disabled` / `readonly` — readonly 는 값 표시만(input 미렌더).
64
+ - `required: boolean` — 빈 값이면 invalid.
65
+ - `min` / `max: SdTextfieldTypes[K]` — 숫자/날짜/시간 범위 검증.
66
+ - `minlength` / `maxlength: number` / `pattern: string` — 문자열 길이·정규식 검증(text 계열).
67
+ - `format: string` — `"format"` 타입의 마스킹 패턴(예: `"XXX-XXXX"`, `|` 로 여러 길이 후보).
68
+ - `validatorFn: (value) => string | undefined` — 커스텀 검증. 메시지 반환 시 invalid.
69
+ - `step: number` — 숫자/날짜 스텝.
70
+ - `autocomplete: string` — 자동완성 속성.
71
+ - `useNumberComma: boolean` — `"number"` 표시 시 천단위 콤마(기본 true). false 면 콤마 없이.
72
+ - `minDigits: number` — 숫자 표시 최소 소수 자릿수.
73
+ - `inline` / `inset` / `size` / `theme` / `inputStyle` / `inputClass` — 공통/스타일.
74
+ - 사용: `<sd-textfield [type]="'number'" [(value)]="data().qty" (valueChange)="mark(data)" />`.
54
75
 
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`.
76
+ ### SdTextarea (`sd-textarea`)
56
77
 
57
- ## SdDateRangePicker
78
+ 여러 줄 텍스트. 내용 줄 수에 따라 자동 높이(`minRows` 이상).
58
79
 
59
- `<sd-date-range-picker>` — 일/월/범위 기간 선택. `periodType = model<"일"|"월"|"범위">()`(기본 `"범위"`), `from`/`to = model<DateOnly>()`, `required`. 월 선택 시 from/to 를 해당 월 1일~말일로 동기화, 일 선택 시 to=from.
80
+ - `value: model<string>` 값은 `undefined`.
81
+ - `minRows: number` — 최소 줄 수(기본 1).
82
+ - `placeholder` / `title` / `disabled` / `readonly` / `required` / `validatorFn` / `inline` / `inset` / `size` / `theme` / `inputStyle` / `inputClass` — `sd-textfield` 와 동일 의미.
60
83
 
61
- ## SdCheckbox / SdSwitch / SdCheckboxGroup(Item)
84
+ ### SdNumpad (`sd-numpad`)
62
85
 
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 의 배열에 포함되면 체크.
86
+ 터치 숫자 입력 패드 + 표시 필드.
67
87
 
68
- ## SdSelect / SdSelectItem / SdSelectButton
88
+ - `value: model<number>` 입력된 숫자.
89
+ - `placeholder: string` — 표시 필드 placeholder.
90
+ - `required: boolean` — true 면 빈 값에서 ENT 비활성.
91
+ - `inputDisabled: boolean` — true 면 상단 텍스트 직접 입력 막고 패드만.
92
+ - `useEnterButton: boolean` — true 면 ENT 버튼 표시.
93
+ - `useMinusButton: boolean` — true 면 부호(-) 버튼 표시.
94
+ - `enterButtonClick: output()` — ENT 클릭 시 발화(확정 처리 트리거).
69
95
 
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).
96
+ ### SdRange<K> (`sd-range`)
81
97
 
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
- ```
98
+ `from ~ to` 두 입력. `to` 의 min 을 `from` 으로 자동 제한.
88
99
 
89
- ## SdDropdown / SdDropdownPopup
100
+ - `type: input.required<K>` — `sd-textfield` 와 동일 타입 키.
101
+ - `from: model<SdTextfieldTypes[K]>` / `to: model<SdTextfieldTypes[K]>` — 범위 양끝.
102
+ - `required` / `disabled` / `inputStyle` — 공통.
90
103
 
91
- - `<sd-dropdown>` — 트리거 + 팝업 래퍼. `open = model(false)`, `disabled`. 팝업은 body 로 이동·위치 자동 계산(상/하·좌/우), 모바일은 하단 시트 + 백드롭. ArrowDown/Up/Space/ESC 키 처리.
92
- - `<sd-dropdown-popup>` — 팝업 콘텐츠. content 투영, 높이 300px 초과 시 스크롤 캡.
104
+ ### SdDateRangePicker (`sd-date-range-picker`)
93
105
 
94
- ## SdForm
106
+ 기간 종류(일/월/범위) 선택 + 그에 맞는 날짜 입력. 종류·시작일 변경 시 `to` 자동 동기화(일=from과 동일, 월=그 달 1일~말일, 범위=from>to면 보정).
95
107
 
96
- `<sd-form>` — 네이티브 검증 연동 폼 래퍼. `formSubmit = output<SubmitEvent>()`(검증 통과 시), `formInvalid = output()`(실패 `reportValidity`). `requestSubmit()` 메서드로 외부 제출. 내부 컨트롤의 `setupInvalid` 검증과 함께 동작.
108
+ - `periodType: model<"일"|"월"|"범위">` 기간 종류(기본 `"범위"`).
109
+ - `from: model<DateOnly>` / `to: model<DateOnly>` — 기간 양끝.
110
+ - `required: boolean` — 필수 여부.
111
+ - 사용: `<sd-date-range-picker [(from)]="filter().from" [(to)]="filter().to" (fromChange)="mark(filter)" />`.
97
112
 
98
- ## SdCollapse / SdCollapseIcon
113
+ ## 체크박스·스위치
99
114
 
100
- - `<sd-collapse>` — 높이 애니메이션 접기. `open = input(false)`. 콘텐츠 높이 측정해 margin-top 으로 접음.
101
- - `<sd-collapse-icon>` — 회전 화살표 아이콘. `icon`(기본 chevronDown), `open = input(false)`, `openRotate = input(90)`(열림 시 회전각).
115
+ ### SdCheckbox (`sd-checkbox`)
102
116
 
103
- ## SdTab / SdTabItem
117
+ 체크박스 또는 라디오. `canChangeFn` 으로 변경 가드.
104
118
 
105
- - `<sd-tab>` — 탭 바. `value = model<any>()`선택된 탭 값.
106
- - `<sd-tab-item>` — 항목. `value = input<any>()`. 부모 value 같으면 선택 표시, 클릭 시 부모 value set.
119
+ - `value: model<boolean>`체크 상태.
120
+ - `canChangeFn: (next: boolean) => boolean | Promise<boolean>` — 변경 시도 false(또는 Promise<false>) 변경 차단. 비동기 확인 변경에 사용.
121
+ - `radio: boolean` — true 면 라디오 모양(클릭 시 항상 true, 토글 안 함).
122
+ - `icon: input` — 체크 아이콘(기본 `tablerCheck`).
123
+ - `disabled` / `size` / `inline` / `inset` / `theme`(+`"white"`) / `contentStyle` — 공통/스타일.
124
+ - 사용: 라디오 그룹은 같은 모델을 `[radio]="true"` 체크박스 여러 개로.
107
125
 
108
- ## SdList / SdListItem
126
+ ### SdSwitch (`sd-switch`)
109
127
 
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` 로 우측 도구 영역.
128
+ on/off 토글 스위치.
112
129
 
113
- ## SdGap
130
+ - `value: model<boolean>` / `canChangeFn` — `sd-checkbox` 와 동일.
131
+ - `disabled` / `inline` / `inset` / `size` / `theme` — 공통.
114
132
 
115
- `<sd-gap>` 간격. `height`/`width: "xxs"|"xs"|"sm"|"default"|"lg"|"xl"|"xxl"`(CSS 변수 기반), `heightPx`/`widthPx`/`widthEm`(수치). 0 이면 `display:none`, width 계열이면 inline-block, height 면 block.
133
+ ### SdCheckboxGroup<T> / SdCheckboxGroupItem<T> (`sd-checkbox-group` / `-item`)
116
134
 
117
- ## SdPagination
135
+ 배열 값을 항목 체크로 토글하는 그룹.
118
136
 
119
- `<sd-pagination>` — 페이지 네비. `currentPage = model(0)`(0-base 현재 페이지), `totalPageCount = input(0)`(전체 페이지 수), `visiblePageCount = input(10)`(한 그룹에 보일 페이지 버튼 수). 처음/이전그룹/페이지번호/다음그룹/마지막 버튼.
137
+ - `SdCheckboxGroup.value: model<T[]>` 선택된 항목 배열.
138
+ - `SdCheckboxGroup.disabled: boolean` — 그룹 전체 비활성.
139
+ - `SdCheckboxGroupItem.value: input.required<T>` — 이 항목의 값. 체크 시 그룹 배열에 추가/제거.
140
+ - `SdCheckboxGroupItem.inline: boolean` — 인라인 표시.
141
+ - 사용: `<sd-checkbox-group [(value)]="selected"><sd-checkbox-group-item [value]="'a'">A</sd-checkbox-group-item>...</sd-checkbox-group>`.
142
+
143
+ ## 셀렉트·드롭다운
144
+
145
+ ### SdSelect<M,T> (`sd-select`) + SdSelectItem<T> / SdSelectButton
146
+
147
+ 드롭다운 셀렉트. 정적 항목(`sd-select-item` 투영) 또는 `items`+`itemOf` 템플릿, single/multi.
148
+
149
+ - `selectMode: "single"|"multi"` — 선택 모드(기본 single). multi 면 헤더에 전체선택/해제 + 체크박스.
150
+ - `value: model<SelectModeValue<any>[M]>` — single 이면 단일 값, multi 면 배열. `SelectModeValue<T> = { single: T; multi: T[] }`.
151
+ - `placeholder: string` — 미선택 표시.
152
+ - `required: boolean` — 빈 값이면 invalid.
153
+ - `items: T[]` + `getChildrenFn: (item) => T[]|undefined` — 데이터 기반 항목(트리 가능). `trackByFn: (item, index) => unknown`.
154
+ - `hideSelectAll: boolean` — multi 의 전체선택/해제 바 숨김.
155
+ - `multiSelectionDisplayDirection: "vertical"` — multi 선택 표시를 세로 나열.
156
+ - `disabled` / `inline` / `inset` / `size` / `contentClass` / `contentStyle` — 공통/스타일.
157
+ - `dropdownOpen: model<boolean>` — 드롭다운 열림 상태.
158
+ - 내부 메서드 `selectItem`/`toggleItem`/`openDropdown`/`closeDropdown` 은 자식 `sd-select-item` 이 호출.
159
+ - `SdSelectItem.value: input<T>` — 항목 값. `disabled` / `hidden` 으로 개별 제어. 클릭 시 부모 select 토글(single 은 닫힘).
160
+ - `SdSelectButton` (`sd-select-button`) — 드롭다운 우측에 끼우는 액션 버튼(검색/편집 등). `<sd-select-button>` 으로 투영.
161
+ - 사용: `<sd-select [(value)]="data().state" [required]="true"><sd-select-item [value]="'작성'">작성</sd-select-item></sd-select>`.
162
+
163
+ ### SdDropdown / SdDropdownPopup (`sd-dropdown` / `sd-dropdown-popup`)
164
+
165
+ 범용 드롭다운 토글 + 팝업. 위치 자동 배치, 모바일에선 하단 시트, 외부 클릭/blur/ESC 로 닫힘.
166
+
167
+ - `SdDropdown.open: model<boolean>` — 열림 상태.
168
+ - `SdDropdown.disabled: boolean` — true 면 토글 막음.
169
+ - 본문 콘텐츠와 `<sd-dropdown-popup>` 을 자식으로 둠. `sd-select`·`sd-topbar-menu`·`sd-theme-selector` 등이 내부에서 사용.
170
+
171
+ ## 폼·접기·탭·리스트·페이지네이션
172
+
173
+ ### SdForm (`sd-form`)
174
+
175
+ native form 래퍼. Enter/submit 버튼으로 submit, 검증 실패 시 네이티브 메시지·포커싱.
176
+
177
+ - `formSubmit: output<SubmitEvent>` — 검증 통과 후 submit. `(formSubmit)="onSubmit()"`.
178
+ - `formInvalid: output()` — 검증 실패 시.
179
+ - `requestSubmit(): void` — 코드에서 submit 트리거. `formEl` getter 로 native form 접근.
180
+ - `sd-crud-list`/`sd-crud-detail` 는 내부에 form 을 보유하므로 별도 래핑 불필요.
181
+
182
+ ### SdCollapse / SdCollapseIcon (`sd-collapse` / `sd-collapse-icon`)
183
+
184
+ - `SdCollapse.open: boolean` — true 면 펼침, false 면 높이 0 으로 접힘(높이 트랜지션). 콘텐츠 높이 변화 자동 재측정.
185
+ - `SdCollapseIcon.open: boolean` — 열림이면 회전. `openRotate: number`(기본 90도) 만큼 회전. `icon`(기본 `tablerChevronDown`). 접기 토글 표시용.
186
+
187
+ ### SdTab / SdTabItem (`sd-tab` / `sd-tab-item`)
188
+
189
+ - `SdTab.value: model<any>` — 선택된 탭 값.
190
+ - `SdTabItem.value: input<any>` — 이 탭의 값. 클릭 시 부모 `value` 로 set, 일치하면 선택 표시.
191
+ - 사용: `<sd-tab [(value)]="tab"><sd-tab-item [value]="'a'">A</sd-tab-item></sd-tab>`.
192
+
193
+ ### SdList / SdListItem (`sd-list` / `sd-list-item`)
194
+
195
+ 세로 리스트(중첩 가능, accordion/flat).
196
+
197
+ - `SdList.inset: boolean` — 배경 투명(중첩 리스트용).
198
+ - `SdListItem.layout: "accordion"|"flat"` — 자식 리스트 동작. `"accordion"`(기본) = 클릭 토글로 펼침, `"flat"` = 항상 펼침(섹션 헤더처럼).
199
+ - `SdListItem.open: model<boolean>` — accordion 펼침 상태.
200
+ - `SdListItem.selected: boolean` — 선택 강조.
201
+ - `SdListItem.selectedIcon: string` — leaf 항목에 선택 아이콘 표시.
202
+ - `SdListItem.readonly: boolean` — 클릭 토글 비활성.
203
+ - `SdListItem.contentStyle` / `contentClass` — 콘텐츠 행 스타일.
204
+ - `#toolTpl` 템플릿으로 행 우측 도구 배치. 사이드바/탑바 메뉴가 이 위에 구성됨.
205
+
206
+ ### SdPagination (`sd-pagination`)
207
+
208
+ 페이지 번호 네비게이터(처음/이전그룹/번호/다음그룹/끝).
209
+
210
+ - `currentPage: model<number>` — 0-based 현재 페이지.
211
+ - `totalPageCount: number` — 전체 페이지 수(0 이면 비표시).
212
+ - `visiblePageCount: number` — 한 번에 보일 번호 개수(기본 10).
213
+ - 사용: `<sd-pagination [(currentPage)]="page" [totalPageCount]="pageLength()" />`. `sd-sheet`/`sd-crud-list` 가 내장.
@@ -1,50 +1,41 @@
1
- # @simplysm/angular — CRUD 화면 골격
2
-
3
- 목록·상세 화면의 표준 레이아웃(타이틀바·커맨드 영역·콘텐츠·하단 커맨드) busy·권한제한·뷰타입(page/modal/control)별 분기·모달 선택 모드를 제공하는 컨테이너. 콘텐츠는 `<ng-template #...>` 슬롯으로 주입. `viewType` `injectViewTypeSignal()`(routing 군) 결과를 넣는 것이 일반적.
4
-
5
- ## SdBaseContainer
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` 은 라우팅 군의 제목 신호 자동 사용.
15
-
16
- ## SdCrudDetail
17
-
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
- ```
1
+ # @simplysm/angular — CRUD 화면 표준 골격
2
+
3
+ 목록/단건 화면의 표준 컨테이너 골격. `sd-base-container`(공통 셸) 위에 `sd-crud-list`(목록), `sd-crud-detail`(단건)이 얹힘. 표준 시그널(ready/initialized/busyCount/viewType)·page/modal/control 컨텍스트별 탑바/하단바 자동 구성·CTRL+S 저장을 내장. 화면 데이터 흐름·시그널 전파 규약은 client-component.md / client-crud.md 따름.
4
+
5
+ ## SdBaseContainer (`sd-base-container`)
6
+
7
+ 모든 화면의 공통 셸. busy 오버레이 + 권한 제한 표시 + (page 모드) 탑바 + 슬롯(content/command/bottom) 구성. 공유 데이터 로드 완료까지 ready 를 지연.
8
+
9
+ - `ready: model<boolean>`데이터 로드 시작 허용 시점. 공유데이터 대기 후 자동 true(자식 effect 발화 트리거). 부모↔자식 전파.
10
+ - `initialized: input<boolean>` 로드 완료 여부. true 여야 콘텐츠 렌더(아니면 busy).
11
+ - `busyCount: model<number>`진행 작업 수(>0 이면 busy). 자식과 양방향.
12
+ - `restricted: input<boolean>`true 콘텐츠 대신 "사용권한 없음" 안내 표시. `[restricted]="!perms().includes('use')"`.
13
+ - `viewType: input.required<SdViewType>`page/modal/control. page 탑바 + 제목 표시. `injectViewTypeSignal()` 결과 전달.
14
+ - 슬롯: `#topbarTpl`(page 탑바 우측), `#commandTpl`(상단 명령줄), `#contentTpl`(본문), `#bottomCommandTpl`(하단 명령줄).
15
+ - 사용: view 합성의 루트(client-component.md). 직접 화면을 list/detail 없이 짤 때 사용.
16
+
17
+ ## SdCrudList<TItem, TKey> (`sd-crud-list`)
18
+
19
+ 목록 화면 골격. 내부에 `sd-sheet` + 검색 폼 + 등록/삭제/복구 버튼 + (모달 모드) 선택 확정 바를 내장. 투영한 `<sd-sheet-column>` 을 시트로 전달. CTRL+S 로 저장 트리거.
20
+
21
+ - 표준 시그널: `ready: model<boolean>`, `initialized: input<boolean>`, `busyCount: model<number>`, `restricted: input<boolean>`, `viewType: input.required<SdViewType>`.
22
+ - `readonly: input<boolean>`true 면 저장/등록/삭제 UI·편집 동작 제거(조회 전용).
23
+ - `selectMode: "single"|"multi"` — 선택 모드. modal 모드 + 지정 하단에 선택 해제/확인 바. single 은 행 클릭 자동 선택, 미지정+편집 가능이면 multi 기본.
24
+ - `key: input.required<string>` 시트 설정 저장 키(`<key>-sheet` 시트에 전달).
25
+ - `items: TItem[]` — 행 데이터. `selectedKeys: model<NonNullable<TKey>[]>` — 선택 키.
26
+ - `currDeletedItems: TItem[]` — 현재 삭제 상태 항목(취소선 표시 + 선택 시 복구 버튼 노출).
27
+ - 페이징/정렬: `currentPage: model<number>`, `totalPageCount: input<number>`(서버 페이징), `itemsPerPage: input<number>`(클라 페이징), `visiblePageCount: input<number>`(기본 10), `sorts: model<SortingDef[]>`. 서버/클라 페이징 택일은 client-component.md.
28
+ - `trackByFn: input.required<(item: TItem) => TKey>` 함수.
29
+ - 출력: `filterSubmit: output()`(검색 폼 submit), `submit: output()`(저장 폼 submit/CTRL+S), `create: output()`(등록), `delete: output<TItem[]>`(선택/행 삭제), `restore: output<TItem[]>`(복구).
30
+ - 슬롯: `#commandTpl`(상단 추가 버튼), `#filterTpl`(검색 폼 항목), `#toolTpl`(시트 도구 버튼), `#bottomCommandTpl`(하단), 그리고 직속 `<sd-sheet-column>`.
31
+ - 사용(client-crud.md): `<sd-crud-list [key]="'goods'" [items]="items()" [(selectedKeys)]="selectedKeys" [trackByFn]="trackByFn" [viewType]="viewType()" ... (create)="onCreate()" (delete)="onDelete($event)"><ng-template #filterTpl>...</ng-template><sd-sheet-column .../></sd-crud-list>`.
32
+
33
+ ## SdCrudDetail (`sd-crud-detail`)
34
+
35
+ 단건 보기/편집 화면 골격. 내부에 `sd-form`(편집 시) + page 탑바/modal 하단 확인 버튼을 컨텍스트별 자동 구성. CTRL+S 저장.
36
+
37
+ - 표준 시그널: `ready: model<boolean>`, `initialized: input<boolean>`, `busyCount: model<number>`, `restricted: input<boolean>`, `viewType: input.required<SdViewType>`.
38
+ - `readonly: input<boolean>` true form 없이 표시만(저장 버튼 제거).
39
+ - `submit: output()` 저장 submit/CTRL+S/확인 버튼 클릭 발화.
40
+ - 슬롯: `#commandTpl`(명령줄), `#contentTpl`(본문 폼), `#bottomCommandTpl`(하단 추가).
41
+ - 사용: `<sd-crud-detail [viewType]="viewType()" [initialized]="initialized()" [(busyCount)]="busyCount" (submit)="onSubmit()"><ng-template #contentTpl><div class="form-table">...</div></ng-template></sd-crud-detail>`. 식별자 로드·원본 스냅샷·이탈 가드 등 데이터 흐름은 client-component.md "detail 데이터 흐름".