@simplysm/sd-claude 14.0.89 โ†’ 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 (79) hide show
  1. package/claude/references/sd-simplysm14/README.md +16 -17
  2. package/claude/references/sd-simplysm14/apis/angular/README.md +52 -30
  3. package/claude/references/sd-simplysm14/apis/angular/controls.md +200 -38
  4. package/claude/references/sd-simplysm14/apis/angular/crud.md +41 -53
  5. package/claude/references/sd-simplysm14/apis/angular/directives.md +66 -22
  6. package/claude/references/sd-simplysm14/apis/angular/features.md +127 -40
  7. package/claude/references/sd-simplysm14/apis/angular/infra.md +60 -43
  8. package/claude/references/sd-simplysm14/apis/angular/layout.md +56 -20
  9. package/claude/references/sd-simplysm14/apis/angular/overlay.md +74 -74
  10. package/claude/references/sd-simplysm14/apis/angular/routing-appstructure.md +50 -40
  11. package/claude/references/sd-simplysm14/apis/angular/selection-managers.md +55 -15
  12. package/claude/references/sd-simplysm14/apis/angular/shared-data.md +59 -42
  13. package/claude/references/sd-simplysm14/apis/angular/sheet.md +77 -62
  14. package/claude/references/sd-simplysm14/apis/capacitor-plugin-auto-update/README.md +8 -7
  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 +22 -14
  17. package/claude/references/sd-simplysm14/apis/capacitor-plugin-usb-storage/README.md +19 -19
  18. package/claude/references/sd-simplysm14/apis/core-browser/README.md +17 -17
  19. package/claude/references/sd-simplysm14/apis/core-browser/dom-element.md +28 -28
  20. package/claude/references/sd-simplysm14/apis/core-browser/indexed-db.md +37 -37
  21. package/claude/references/sd-simplysm14/apis/core-common/README.md +87 -219
  22. package/claude/references/sd-simplysm14/apis/core-common/array-ext.md +54 -98
  23. package/claude/references/sd-simplysm14/apis/core-common/async-runtime.md +57 -99
  24. package/claude/references/sd-simplysm14/apis/core-common/datetime.md +60 -103
  25. package/claude/references/sd-simplysm14/apis/core-common/errors.md +42 -47
  26. package/claude/references/sd-simplysm14/apis/core-common/obj.md +42 -88
  27. package/claude/references/sd-simplysm14/apis/core-common/serialization.md +55 -0
  28. package/claude/references/sd-simplysm14/apis/core-node/README.md +6 -7
  29. package/claude/references/sd-simplysm14/apis/core-node/consola.md +17 -12
  30. package/claude/references/sd-simplysm14/apis/core-node/cpx.md +14 -13
  31. package/claude/references/sd-simplysm14/apis/core-node/fs-watcher.md +9 -8
  32. package/claude/references/sd-simplysm14/apis/core-node/fsx.md +14 -13
  33. package/claude/references/sd-simplysm14/apis/core-node/pathx.md +4 -8
  34. package/claude/references/sd-simplysm14/apis/core-node/worker.md +14 -12
  35. package/claude/references/sd-simplysm14/apis/excel/README.md +22 -22
  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/orm-common/README.md +6 -8
  43. package/claude/references/sd-simplysm14/apis/orm-common/db-context.md +118 -67
  44. package/claude/references/sd-simplysm14/apis/orm-common/expr.md +83 -86
  45. package/claude/references/sd-simplysm14/apis/orm-common/queryable.md +102 -93
  46. package/claude/references/sd-simplysm14/apis/orm-common/schema.md +138 -81
  47. package/claude/references/sd-simplysm14/apis/orm-common/types.md +49 -44
  48. package/claude/references/sd-simplysm14/apis/orm-node/README.md +42 -42
  49. package/claude/references/sd-simplysm14/apis/orm-node/db-conn.md +44 -33
  50. package/claude/references/sd-simplysm14/apis/sd-cli/README.md +11 -10
  51. package/claude/references/sd-simplysm14/apis/service-client/README.md +56 -52
  52. package/claude/references/sd-simplysm14/apis/service-client/orm.md +33 -28
  53. package/claude/references/sd-simplysm14/apis/service-client/transport.md +23 -21
  54. package/claude/references/sd-simplysm14/apis/service-common/README.md +83 -48
  55. package/claude/references/sd-simplysm14/apis/service-common/app-structure.md +126 -34
  56. package/claude/references/sd-simplysm14/apis/service-common/protocol.md +109 -54
  57. package/claude/references/sd-simplysm14/apis/service-server/README.md +69 -81
  58. package/claude/references/sd-simplysm14/apis/service-server/service-authoring.md +46 -43
  59. package/claude/references/sd-simplysm14/apis/service-server/transport-internals.md +63 -37
  60. package/claude/references/sd-simplysm14/apis/service-server/v1-legacy.md +40 -30
  61. package/claude/references/sd-simplysm14/apis/storage/README.md +17 -17
  62. package/claude/references/sd-simplysm14/manuals/client-app-structure.md +142 -140
  63. package/claude/references/sd-simplysm14/manuals/client-orm.md +1 -1
  64. package/claude/references/sd-simplysm14/manuals/client-service.md +19 -7
  65. package/claude/references/sd-simplysm14/manuals/client-shared-data.md +2 -2
  66. package/claude/references/sd-simplysm14/manuals/client-system-log.md +11 -3
  67. package/claude/references/sd-simplysm14/manuals/data-log.md +0 -1
  68. package/claude/references/sd-simplysm14/manuals/orm.md +16 -0
  69. package/claude/rules/sd-design-rules.md +10 -0
  70. package/claude/skills/sd-demo/SKILL.md +0 -6
  71. package/claude/skills/sd-docs/SKILL.md +58 -0
  72. package/claude/{workflows/sd-docs.rules.md โ†’ skills/sd-docs/references/subagent-prompt.md} +103 -103
  73. package/claude/skills/sd-impl/SKILL.md +7 -4
  74. package/claude/skills/sd-spec/SKILL.md +842 -15
  75. package/claude/skills/sd-spec/references/example-spec.md +26 -36
  76. package/package.json +1 -1
  77. package/claude/references/sd-simplysm14/apis/core-common/json-transfer.md +0 -53
  78. package/claude/skills/sd-spec/references/spec-authoring.md +0 -519
  79. package/claude/workflows/sd-docs.js +0 -84
@@ -44,20 +44,19 @@ ORM ํ˜ธ์ถœ, ํŒŒ์ผ ๋ณ€ํ™˜, ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ๋“ฑ์€ ์œ„ ๋‘ ๊ฒฝ์šฐ์— ํ•ด๋‹น
44
44
 
45
45
  ## ํŒจํ‚ค์ง€ ์ธ๋ฑ์Šค
46
46
 
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)
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,35 +1,57 @@
1
1
  # @simplysm/angular
2
2
 
3
- Angular 19+ (zoneless, signal ๊ธฐ๋ฐ˜) ์—…๋ฌด ํ”„๋ก ํŠธ์—”๋“œ์šฉ ์ปดํฌ๋„ŒํŠธยท๋””๋ ‰ํ‹ฐ๋ธŒยทํ”„๋กœ๋ฐ”์ด๋” ๋ชจ์Œ. ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๋Š” standalone, `OnPush`, signal input/model/output ์‚ฌ์šฉ. ๋ถ€ํŠธ์ŠคํŠธ๋žฉ์€ `provideSdAngular` 1๊ฐœ๋กœ ์‹œ์ž‘.
3
+ Angular(zoneless) ๊ธฐ๋ฐ˜ SI/์—…๋ฌด ํด๋ผ์ด์–ธํŠธ์šฉ UI ์ปดํฌ๋„ŒํŠธยท๋””๋ ‰ํ‹ฐ๋ธŒยทํ”„๋กœ๋ฐ”์ด๋”ยทsignal ํ—ฌํผ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ. `import "@simplysm/core-browser"` ๋ฅผ side-effect ๋กœ ๋กœ๋“œํ•˜๋ฉฐ, ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๋Š” standalone + OnPush + `ViewEncapsulation.None`, selector ๋Š” `sd-` prefix.
4
+
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` ๊ธˆ์ง€ ๋“ฑ์€ ๋งค๋‰ด์–ผ์„ ๋”ฐ๋ฆ„.
4
6
 
5
7
  ## ์‚ฌ์šฉ ํŠธ๋ฆฌ๊ฑฐ ์ธ๋ฑ์Šค
6
8
 
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>
28
- ```
29
-
30
- ## ํƒ€์ž… ์œ ํ‹ธ
31
-
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 ์„ ์„ ํƒ ํ•ญ๋ชฉ์œผ๋กœ ํ‘œ์‹œํ•  ๋•Œ ์‚ฌ์šฉ.
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)
20
+
21
+ ์•„๋ž˜๋Š” ๊ตฐ์„ ๋ณ„๋„๋กœ ๋‘˜ ๋งŒํผ ํฌ์ง€ ์•Š์€ ์œ ํ‹ธยทํƒ€์ž…ยทํ‘œ์‹œ์šฉ ์‹ฌ๋ณผ์˜ ์ธ๋ผ์ธ ์„น์…˜์ด๋‹ค.
22
+
23
+ ## signalยทDOM ์œ ํ‹ธ
24
+
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 ๋‚ด๋ถ€).
27
+
28
+ ## FormatPipe (`format` ํŒŒ์ดํ”„)
29
+
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' }}`.
35
+
36
+ ## ๋””๋ ‰ํ‹ฐ๋ธŒ ์ž…๋ ฅ ์ถ”๋ก  ํƒ€์ž…
37
+
38
+ ๋ชจ๋‹ฌ/ํ† ์ŠคํŠธ/์ธ์‡„ provider ์˜ `inputs` ํƒ€์ž… ๊ณ„์‚ฐ์— ์“ฐ์ด๋Š” ์œ ํ‹ธ ํƒ€์ž…. ์ง์ ‘ ์“ธ ์ผ์€ ๋“œ๋ฌผ์ง€๋งŒ ์‹œ๊ทธ๋‹ˆ์ฒ˜ ํ•ด์„์šฉ์œผ๋กœ ๋…ธ์ถœ๋จ.
39
+
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` ์—์„œ "๊ธฐ๋ณธ๊ฐ’ ์žˆ๋Š” ์ž…๋ ฅ์€ ์ƒ๋žต ๊ฐ€๋Šฅ" ์„ ํ‘œํ˜„.
43
+
44
+ ## SelectModalOutputResult
45
+
46
+ - `interface SelectModalOutputResult<TKey = any> { selectedKeys: TKey[] }` โ€” ์„ ํƒ ์ „์šฉ ๋ชจ๋‹ฌ์ด close ์‹œ emit ํ•˜๋Š” ํŽ˜์ด๋กœ๋“œ ๊ทœ์•ฝ. `SdSelectModal` / `SdModalSelectButton` / `sd-shared-data-select` ๋ชจ๋‹ฌ ์—ฐ๋™์˜ ๋ฐ˜ํ™˜ ํƒ€์ž…. ์„ ํƒ ๋ชจ๋‹ฌ ์ปดํฌ๋„ŒํŠธ๋Š” ์ด ํƒ€์ž…์„ `close.emit` ์œผ๋กœ ๋Œ๋ ค์คŒ.
47
+
48
+ ## SdGap (`sd-gap`)
49
+
50
+ ์—ฌ๋ฐฑ ์ „์šฉ ๋นˆ ์ปดํฌ๋„ŒํŠธ. flex ๋ ˆ์ด์•„์›ƒ ์‚ฌ์ด ๊ฐ„๊ฒฉ์„ ํ† ํฐ/ํ”ฝ์…€๋กœ ์‚ฝ์ž….
51
+
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,51 +1,213 @@
1
- # @simplysm/angular โ€” ํผ ์ปจํŠธ๋กคยท๋ฒ„ํŠผยท์„ ํƒ ์ปจํŠธ๋กค
1
+ # @simplysm/angular โ€” ํผยท๊ธฐ๋ณธ ์ž…๋ ฅ ์ปจํŠธ๋กค
2
2
 
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 โ€” ๋น„ํ™œ์„ฑ.
3
+ ๋ฒ„ํŠผยท์•ต์ปค, ํ…์ŠคํŠธ/์ˆซ์ž/๋‚ ์งœ ์ž…๋ ฅ, ์ฒดํฌ๋ฐ•์Šค/์Šค์œ„์น˜, ์…€๋ ‰ํŠธ/๋“œ๋กญ๋‹ค์šด, ํผ/์ ‘๊ธฐ/ํƒญ/๋ฆฌ์ŠคํŠธ/ํŽ˜์ด์ง€๋„ค์ด์…˜ ๋“ฑ ํผยทUI ๊ธฐ๋ณธ ์ปจํŠธ๋กค ๊ตฐ. ํ™”๋ฉด ํผยทํ•„ํ„ฐยท์‹œํŠธ ์…€์—์„œ ํ•จ๊ป˜ ์“ฐ์ž„. ๊ณตํ†ต: ๊ฑฐ์˜ ๋ชจ๋“  ์ปจํŠธ๋กค์ด `size: "sm"|"lg"`(๋ฏธ์ง€์ •=๊ธฐ๋ณธ), `inline`, `inset`(ํ…Œ๋‘๋ฆฌ ์ œ๊ฑฐยท์…€ ๋‚ด์žฅ์šฉ), `disabled`, `theme` ์„ ๊ฐ€์ง. ๋งค๋‰ด์–ผ(client-component.md "ํ‘œ์ค€ ์ž…๋ ฅ ์ปจํŠธ๋กค"ยท"๋ฒ„ํŠผ ์Šคํƒ€์ผ")์˜ ์—ญํ• ๋ณ„ theme/size ๊ทœ์•ฝ์„ ๋”ฐ๋ฆ„.
9
4
 
10
- ## ๋ฒ„ํŠผ๋ฅ˜
5
+ ## ๋ฒ„ํŠผยท์•ต์ปค
11
6
 
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 ์ œ์™ธํ•œ ๋ชจ๋‹ฌ ์ •๋ณด).
7
+ ### SdButton (`sd-button`)
16
8
 
17
- ## ํ…์ŠคํŠธยท์ˆซ์ž ์ž…๋ ฅ
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>`.
18
17
 
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`.
18
+ ### SdAnchor (`sd-anchor`)
25
19
 
26
- ## ์ฒดํฌยท์Šค์œ„์น˜
20
+ ์ธ๋ผ์ธ ํ…์ŠคํŠธ ๋งํฌ/์•„์ด์ฝ˜ ๋ฒ„ํŠผ.
27
21
 
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 ๋ฐฐ์—ด์— ์ถ”๊ฐ€/์ œ๊ฑฐ.
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>`.
31
25
 
32
- ## ์„ ํƒ(๋“œ๋กญ๋‹ค์šด)
26
+ ### SdAdditionalButton (`sd-additional-button`)
33
27
 
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 ์—†์Œ, ํด๋ฆญ ์ด๋ฒคํŠธ๋Š” ํˆฌ์˜๋œ ๋‚ด์šฉ์—์„œ ์ฒ˜๋ฆฌ.
28
+ ์ฝ˜ํ…์ธ  + ์šฐ์ธก ๋ฒ„ํŠผ์„ ํ•œ ํ…Œ๋‘๋ฆฌ๋กœ ๋ฌถ๋Š” ์ปจํ…Œ์ด๋„ˆ. `<ng-content>` ๋ณธ๋ฌธ + ํˆฌ์˜๋œ `sd-anchor`/`sd-button`.
37
29
 
38
- ## ๋“œ๋กญ๋‹ค์šด(์ €์ˆ˜์ค€)
30
+ - `size: "sm"|"lg"` โ€” ํŒจ๋”ฉ.
31
+ - `inset: boolean` โ€” ํ…Œ๋‘๋ฆฌยทradius ์ œ๊ฑฐ.
39
32
 
40
- - **SdDropdown** `<sd-dropdown>` โ€” ํŠธ๋ฆฌ๊ฑฐ + `sd-dropdown-popup` ํŒ์—…. `open = model(false)`, `disabled`. ํ™”๋ฉด ์œ„์น˜ ์ž๋™ ๋ฐฐ์น˜, ๋ชจ๋ฐ”์ผ(โ‰ค520px)์—์„  ํ•˜๋‹จ ์‹œํŠธ + backdrop. ํ‚ค๋ณด๋“œ โ†“ ๋กœ ์—ด๊ณ  โ†‘/ESC ๋กœ ๋‹ซ์Œ. `popupElRef`(contentChild)๋กœ ํŒ์—… ์—˜๋ฆฌ๋จผํŠธ ์ ‘๊ทผ.
41
- - **SdDropdownPopup** `<sd-dropdown-popup>` โ€” ๋“œ๋กญ๋‹ค์šด ๋‚ด์šฉ. input ์—†์Œ. ๋‚ด์šฉ ๋†’์ด 300px ์ดˆ๊ณผ ์‹œ ์ž๋™ ์Šคํฌ๋กค ์บก.
33
+ ### SdModalSelectButton (`sd-modal-select-button`)
42
34
 
43
- ## ํผยท์ ‘๊ธฐยทํƒญยท๋ฆฌ์ŠคํŠธยท์—ฌ๋ฐฑยทํŽ˜์ด์ง€
35
+ ๊ฐ’ ํ‘œ์‹œ + ๊ฒ€์ƒ‰ ๋ฒ„ํŠผ์œผ๋กœ ์„ ํƒ ๋ชจ๋‹ฌ์„ ๋„์šฐ๋Š” ์ž…๋ ฅ. ์„ ํƒ ๊ฒฐ๊ณผ(`SelectModalOutputResult`)๋ฅผ `value` ์— ๋ฐ˜์˜.
44
36
 
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). ์ฒ˜์Œ/์ด์ „๊ทธ๋ฃน/ํŽ˜์ด์ง€๋ฒˆํ˜ธ/๋‹ค์Œ๊ทธ๋ฃน/๋ ๋ฒ„ํŠผ.
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">`.
47
+
48
+ ## ํ…์ŠคํŠธยท์ˆซ์žยท๋‚ ์งœ ์ž…๋ ฅ
49
+
50
+ ### SdTextfield<K> (`sd-textfield`)
51
+
52
+ ํƒ€์ž…๋ณ„ ํ•ธ๋“ค๋Ÿฌ๋กœ ํŒŒ์‹ฑยทํฌ๋งทยท๊ฒ€์ฆํ•˜๋Š” ๋งŒ๋Šฅ ์ž…๋ ฅ. `value` ํƒ€์ž…์ด `type` ์— ๋”ฐ๋ผ ๊ฒฐ์ •๋จ.
53
+
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)" />`.
75
+
76
+ ### SdTextarea (`sd-textarea`)
77
+
78
+ ์—ฌ๋Ÿฌ ์ค„ ํ…์ŠคํŠธ. ๋‚ด์šฉ ์ค„ ์ˆ˜์— ๋”ฐ๋ผ ์ž๋™ ๋†’์ด(`minRows` ์ด์ƒ).
79
+
80
+ - `value: model<string>` โ€” ๋นˆ ๊ฐ’์€ `undefined`.
81
+ - `minRows: number` โ€” ์ตœ์†Œ ์ค„ ์ˆ˜(๊ธฐ๋ณธ 1).
82
+ - `placeholder` / `title` / `disabled` / `readonly` / `required` / `validatorFn` / `inline` / `inset` / `size` / `theme` / `inputStyle` / `inputClass` โ€” `sd-textfield` ์™€ ๋™์ผ ์˜๋ฏธ.
83
+
84
+ ### SdNumpad (`sd-numpad`)
85
+
86
+ ํ„ฐ์น˜ ์ˆซ์ž ์ž…๋ ฅ ํŒจ๋“œ + ํ‘œ์‹œ ํ•„๋“œ.
87
+
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 ํด๋ฆญ ์‹œ ๋ฐœํ™”(ํ™•์ • ์ฒ˜๋ฆฌ ํŠธ๋ฆฌ๊ฑฐ).
95
+
96
+ ### SdRange<K> (`sd-range`)
97
+
98
+ `from ~ to` ๋‘ ์ž…๋ ฅ. `to` ์˜ min ์„ `from` ์œผ๋กœ ์ž๋™ ์ œํ•œ.
99
+
100
+ - `type: input.required<K>` โ€” `sd-textfield` ์™€ ๋™์ผ ํƒ€์ž… ํ‚ค.
101
+ - `from: model<SdTextfieldTypes[K]>` / `to: model<SdTextfieldTypes[K]>` โ€” ๋ฒ”์œ„ ์–‘๋.
102
+ - `required` / `disabled` / `inputStyle` โ€” ๊ณตํ†ต.
103
+
104
+ ### SdDateRangePicker (`sd-date-range-picker`)
105
+
106
+ ๊ธฐ๊ฐ„ ์ข…๋ฅ˜(์ผ/์›”/๋ฒ”์œ„) ์„ ํƒ + ๊ทธ์— ๋งž๋Š” ๋‚ ์งœ ์ž…๋ ฅ. ์ข…๋ฅ˜ยท์‹œ์ž‘์ผ ๋ณ€๊ฒฝ ์‹œ `to` ์ž๋™ ๋™๊ธฐํ™”(์ผ=from๊ณผ ๋™์ผ, ์›”=๊ทธ ๋‹ฌ 1์ผ~๋ง์ผ, ๋ฒ”์œ„=from>to๋ฉด ๋ณด์ •).
107
+
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)" />`.
112
+
113
+ ## ์ฒดํฌ๋ฐ•์Šคยท์Šค์œ„์น˜
114
+
115
+ ### SdCheckbox (`sd-checkbox`)
116
+
117
+ ์ฒดํฌ๋ฐ•์Šค ๋˜๋Š” ๋ผ๋””์˜ค. `canChangeFn` ์œผ๋กœ ๋ณ€๊ฒฝ ๊ฐ€๋“œ.
118
+
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"` ์ฒดํฌ๋ฐ•์Šค ์—ฌ๋Ÿฌ ๊ฐœ๋กœ.
125
+
126
+ ### SdSwitch (`sd-switch`)
127
+
128
+ on/off ํ† ๊ธ€ ์Šค์œ„์น˜.
129
+
130
+ - `value: model<boolean>` / `canChangeFn` โ€” `sd-checkbox` ์™€ ๋™์ผ.
131
+ - `disabled` / `inline` / `inset` / `size` / `theme` โ€” ๊ณตํ†ต.
132
+
133
+ ### SdCheckboxGroup<T> / SdCheckboxGroupItem<T> (`sd-checkbox-group` / `-item`)
134
+
135
+ ๋ฐฐ์—ด ๊ฐ’์„ ํ•ญ๋ชฉ ์ฒดํฌ๋กœ ํ† ๊ธ€ํ•˜๋Š” ๊ทธ๋ฃน.
136
+
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,53 +1,41 @@
1
- # @simplysm/angular โ€” CRUD ํ™”๋ฉด ๊ณจ๊ฒฉยท์ƒํƒœํ”„๋ฆฌ์…‹ยท๊ถŒํ•œํ‘œ
2
-
3
- ์—…๋ฌด ๋ชฉ๋ก/์ƒ์„ธ ํ™”๋ฉด์˜ ๊ณตํ†ต ๊ณจ๊ฒฉ(ํƒ‘๋ฐ”ยทbusyยท๊ถŒํ•œ ์ œํ•œยท๋„๊ตฌ๋ฐ”)๊ณผ ๋ณด์กฐ ์ปดํฌ๋„ŒํŠธ. ๋ชจ๋‘ `viewType = input.required<SdViewType>()` ๋กœ page/modal/control ๋งฅ๋ฝ์„ ๋ฐ›์Œ(`injectViewTypeSignal()` ๊ฒฐ๊ณผ ์ „๋‹ฌ). ํ™”๋ฉด ์ง„์ž… ์‹œ ๊ณต์œ  ๋ฐ์ดํ„ฐ ์ค€๋น„๋ฅผ ๋Œ€๊ธฐํ•˜๊ณ  `ready` ๋กœ ์•Œ๋ฆผ.
4
-
5
- ## SdBaseContainer
6
-
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 โ€” ํƒ‘๋ฐ” ์šฐ์ธก/์ƒ๋‹จ ๋ช…๋ น/๋ณธ๋ฌธ/ํ•˜๋‹จ ๋ช…๋ น ์˜์—ญ.
14
-
15
- ## SdCrudDetail
16
-
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
+ # @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 ๋ฐ์ดํ„ฐ ํ๋ฆ„".