@simplysm/angular 14.0.6 → 14.0.8

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 (105) hide show
  1. package/dist/core/directives/sd-router-link.directive.d.ts.map +1 -1
  2. package/dist/core/directives/sd-router-link.directive.js +5 -10
  3. package/dist/core/plugins/events/sd-resize-event.plugin.d.ts.map +1 -1
  4. package/dist/core/plugins/events/sd-resize-event.plugin.js +3 -0
  5. package/dist/core/plugins/sd-global-error-handler.plugin.d.ts +1 -0
  6. package/dist/core/plugins/sd-global-error-handler.plugin.d.ts.map +1 -1
  7. package/dist/core/plugins/sd-global-error-handler.plugin.js +4 -0
  8. package/dist/core/providers/sd-app-structure.provider.d.ts.map +1 -1
  9. package/dist/core/providers/sd-app-structure.provider.js +4 -1
  10. package/dist/core/providers/sd-navigate-window.provider.d.ts +2 -1
  11. package/dist/core/providers/sd-navigate-window.provider.d.ts.map +1 -1
  12. package/dist/core/providers/sd-navigate-window.provider.js +13 -10
  13. package/dist/core/utils/injectParent.d.ts +7 -0
  14. package/dist/core/utils/injectParent.d.ts.map +1 -0
  15. package/dist/core/utils/injectParent.js +26 -0
  16. package/dist/core/utils/setups/setupCanDeactivate.d.ts.map +1 -1
  17. package/dist/core/utils/setups/setupCanDeactivate.js +9 -2
  18. package/dist/core/utils/setups/setupInvalid.d.ts.map +1 -1
  19. package/dist/core/utils/setups/setupInvalid.js +4 -0
  20. package/dist/core/utils/setups/setupModelHook.d.ts +1 -1
  21. package/dist/core/utils/setups/setupModelHook.d.ts.map +1 -1
  22. package/dist/core/utils/setups/setupModelHook.js +5 -1
  23. package/dist/core/utils/setups/setupRipple.d.ts.map +1 -1
  24. package/dist/core/utils/setups/setupRipple.js +3 -2
  25. package/dist/core/utils/useExpandingManager.d.ts.map +1 -1
  26. package/dist/core/utils/useExpandingManager.js +2 -1
  27. package/dist/core/utils/useSdSystemConfigResource.d.ts.map +1 -1
  28. package/dist/core/utils/useSdSystemConfigResource.js +6 -3
  29. package/dist/features/base/sd-base-container.control.d.ts +26 -0
  30. package/dist/features/base/sd-base-container.control.d.ts.map +1 -0
  31. package/dist/features/base/sd-base-container.control.js +183 -0
  32. package/dist/index.d.ts +2 -0
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +3 -0
  35. package/dist/ui/data/list/sd-list-item.control.js +1 -1
  36. package/dist/ui/data/sheet/sd-sheet.control.d.ts +2 -1
  37. package/dist/ui/data/sheet/sd-sheet.control.d.ts.map +1 -1
  38. package/dist/ui/data/sheet/sd-sheet.control.js +16 -13
  39. package/dist/ui/data/sheet/useSheetCellAgent.d.ts.map +1 -1
  40. package/dist/ui/data/sheet/useSheetCellAgent.js +1 -2
  41. package/dist/ui/data/sheet/useSheetLayoutEngine.d.ts.map +1 -1
  42. package/dist/ui/data/sheet/useSheetLayoutEngine.js +1 -0
  43. package/dist/ui/form/editor/sd-tiptap-editor.control.d.ts +5 -5
  44. package/dist/ui/form/editor/sd-tiptap-editor.control.d.ts.map +1 -1
  45. package/dist/ui/form/editor/sd-tiptap-editor.control.js +79 -78
  46. package/dist/ui/form/input/sd-date-range.picker.d.ts.map +1 -1
  47. package/dist/ui/form/input/sd-date-range.picker.js +4 -3
  48. package/dist/ui/form/input/sd-textfield-type-handlers.d.ts.map +1 -1
  49. package/dist/ui/form/input/sd-textfield-type-handlers.js +21 -2
  50. package/dist/ui/form/input/sd-textfield.control.d.ts.map +1 -1
  51. package/dist/ui/form/input/sd-textfield.control.js +1 -0
  52. package/dist/ui/layout/dock/sd-dock.control.d.ts +2 -0
  53. package/dist/ui/layout/dock/sd-dock.control.d.ts.map +1 -1
  54. package/dist/ui/layout/dock/sd-dock.control.js +13 -4
  55. package/dist/ui/layout/kanban/sd-kanban-lane.control.d.ts.map +1 -1
  56. package/dist/ui/layout/kanban/sd-kanban-lane.control.js +7 -1
  57. package/dist/ui/layout/sd-gap.control.d.ts +2 -2
  58. package/dist/ui/navigation/pagination/sd-pagination.control.d.ts.map +1 -1
  59. package/dist/ui/navigation/pagination/sd-pagination.control.js +7 -3
  60. package/dist/ui/navigation/sidebar/sd-sidebar-container.control.js +1 -1
  61. package/dist/ui/overlay/dropdown/sd-dropdown-popup.control.js +1 -1
  62. package/dist/ui/overlay/modal/sd-modal.control.d.ts +1 -0
  63. package/dist/ui/overlay/modal/sd-modal.control.d.ts.map +1 -1
  64. package/dist/ui/overlay/modal/sd-modal.control.js +11 -3
  65. package/dist/ui/overlay/modal/sd-modal.provider.d.ts +1 -1
  66. package/dist/ui/overlay/modal/sd-modal.provider.js +1 -1
  67. package/dist/ui/overlay/toast/sd-toast.provider.d.ts.map +1 -1
  68. package/dist/ui/overlay/toast/sd-toast.provider.js +7 -3
  69. package/dist/ui/visual/sd-progress.control.d.ts +1 -0
  70. package/dist/ui/visual/sd-progress.control.d.ts.map +1 -1
  71. package/dist/ui/visual/sd-progress.control.js +5 -4
  72. package/docs/providers.md +1 -1
  73. package/docs/setup-functions.md +1 -1
  74. package/package.json +7 -10
  75. package/src/core/directives/sd-router-link.directive.ts +5 -13
  76. package/src/core/plugins/events/sd-resize-event.plugin.ts +3 -0
  77. package/src/core/plugins/sd-global-error-handler.plugin.ts +4 -0
  78. package/src/core/providers/sd-app-structure.provider.ts +4 -1
  79. package/src/core/providers/sd-navigate-window.provider.ts +12 -13
  80. package/src/core/utils/injectParent.ts +41 -0
  81. package/src/core/utils/setups/setupCanDeactivate.ts +10 -2
  82. package/src/core/utils/setups/setupInvalid.ts +5 -0
  83. package/src/core/utils/setups/setupModelHook.ts +5 -2
  84. package/src/core/utils/setups/setupRipple.ts +3 -2
  85. package/src/core/utils/useExpandingManager.ts +2 -1
  86. package/src/core/utils/useSdSystemConfigResource.ts +6 -3
  87. package/src/features/base/sd-base-container.control.ts +113 -0
  88. package/src/index.ts +4 -0
  89. package/src/ui/data/list/sd-list-item.control.ts +1 -1
  90. package/src/ui/data/sheet/sd-sheet.control.ts +17 -13
  91. package/src/ui/data/sheet/useSheetCellAgent.ts +1 -2
  92. package/src/ui/data/sheet/useSheetLayoutEngine.ts +1 -0
  93. package/src/ui/form/editor/sd-tiptap-editor.control.ts +64 -61
  94. package/src/ui/form/input/sd-date-range.picker.ts +4 -3
  95. package/src/ui/form/input/sd-textfield-type-handlers.ts +25 -5
  96. package/src/ui/form/input/sd-textfield.control.ts +1 -0
  97. package/src/ui/layout/dock/sd-dock.control.ts +15 -2
  98. package/src/ui/layout/kanban/sd-kanban-lane.control.ts +6 -3
  99. package/src/ui/navigation/pagination/sd-pagination.control.ts +5 -3
  100. package/src/ui/navigation/sidebar/sd-sidebar-container.control.ts +1 -1
  101. package/src/ui/overlay/dropdown/sd-dropdown-popup.control.ts +1 -1
  102. package/src/ui/overlay/modal/sd-modal.control.ts +10 -1
  103. package/src/ui/overlay/modal/sd-modal.provider.ts +1 -1
  104. package/src/ui/overlay/toast/sd-toast.provider.ts +9 -3
  105. package/src/ui/visual/sd-progress.control.ts +4 -1
@@ -39,7 +39,7 @@ function createStringHandler(type) {
39
39
  }
40
40
  return errors;
41
41
  }
42
- if (type === "text") {
42
+ if (type !== "color") {
43
43
  const str = value;
44
44
  if (opts.minlength !== undefined && opts.minlength > str.length) {
45
45
  errors.push(`문자의 길이가 ${opts.minlength}보다 길거나 같아야 합니다.`);
@@ -135,7 +135,8 @@ function createFormatHandler() {
135
135
  return raw;
136
136
  const nonFormatChars = format.match(/[^X]/g)?.filter((v, i, a) => a.indexOf(v) === i);
137
137
  if (nonFormatChars != null && nonFormatChars.length > 0) {
138
- return raw.replace(new RegExp(`[${nonFormatChars.map((item) => "\\" + item).join("")}]`, "g"), "");
138
+ const escaped = nonFormatChars.map((ch) => ch === "]" || ch === "\\" || ch === "^" || ch === "-" ? "\\" + ch : ch).join("");
139
+ return raw.replace(new RegExp(`[${escaped}]`, "g"), "");
139
140
  }
140
141
  return raw;
141
142
  },
@@ -272,6 +273,15 @@ function createDateTimeHandler(withSeconds) {
272
273
  }
273
274
  if (!(value instanceof DateTime)) {
274
275
  errors.push("날짜 및 시간을 입력하세요");
276
+ return errors;
277
+ }
278
+ const min = opts.min;
279
+ const max = opts.max;
280
+ if (min instanceof DateTime && min.tick > value.tick) {
281
+ errors.push(`${min}보다 크거나 같아야 합니다.`);
282
+ }
283
+ if (max instanceof DateTime && max.tick < value.tick) {
284
+ errors.push(`${max}보다 작거나 같아야 합니다.`);
275
285
  }
276
286
  return errors;
277
287
  },
@@ -311,6 +321,15 @@ function createTimeHandler(withSeconds) {
311
321
  }
312
322
  if (!(value instanceof Time)) {
313
323
  errors.push("시간을 입력하세요");
324
+ return errors;
325
+ }
326
+ const min = opts.min;
327
+ const max = opts.max;
328
+ if (min instanceof Time && min.tick > value.tick) {
329
+ errors.push(`${min}보다 크거나 같아야 합니다.`);
330
+ }
331
+ if (max instanceof Time && max.tick < value.tick) {
332
+ errors.push(`${max}보다 작거나 같아야 합니다.`);
314
333
  }
315
334
  return errors;
316
335
  },
@@ -1 +1 @@
1
- {"version":3,"file":"sd-textfield.control.d.ts","sourceRoot":"","sources":["..\\..\\..\\..\\src\\ui\\form\\input\\sd-textfield.control.ts"],"names":[],"mappings":"AAUA,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,8BAA8B,CAAC;;AAEtC,qBA8Qa,kBAAkB,CAAC,CAAC,SAAS,MAAM,iBAAiB;IAC/D,KAAK,wEAAiC;IAEtC,IAAI,yCAAuB;IAC3B,WAAW,0DAAmB;IAC9B,KAAK,0DAAmB;IACxB,UAAU,0DAAmB;IAC7B,UAAU,0DAAmB;IAE7B,QAAQ,qEAAiD;IACzD,QAAQ,qEAAiD;IAEzD,QAAQ,qEAAiD;IACzD,GAAG,wEAAiC;IACpC,GAAG,wEAAiC;IACpC,SAAS,0DAAmB;IAC5B,SAAS,0DAAmB;IAC5B,OAAO,0DAAmB;IAC1B,WAAW,+CAAiB,iBAAiB,CAAC,CAAC,CAAC,GAAG,SAAS,KAAK,MAAM,GAAG,SAAS,eAAI;IACvF,MAAM,0DAAmB;IAEzB,IAAI,0DAAmB;IACvB,YAAY,0DAAmB;IAC/B,cAAc,qEAAgD;IAC9D,SAAS,0DAAmB;IAE5B,MAAM,qEAAiD;IACvD,KAAK,qEAAiD;IACtD,IAAI,+DAAwB;IAC5B,KAAK,8IAED;IAEJ,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsD;IAE9E,WAAW,yCAA8C;IAEzD,WAAW,kDAA8D;IAEzE,YAAY,yCAOT;IAEH,gBAAgB,qDAMb;;IA4BH,OAAO,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAa3B,YAAY,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI;yCA/F9B,kBAAkB;2CAAlB,kBAAkB;CA6G9B"}
1
+ {"version":3,"file":"sd-textfield.control.d.ts","sourceRoot":"","sources":["..\\..\\..\\..\\src\\ui\\form\\input\\sd-textfield.control.ts"],"names":[],"mappings":"AAUA,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,8BAA8B,CAAC;;AAEtC,qBA8Qa,kBAAkB,CAAC,CAAC,SAAS,MAAM,iBAAiB;IAC/D,KAAK,wEAAiC;IAEtC,IAAI,yCAAuB;IAC3B,WAAW,0DAAmB;IAC9B,KAAK,0DAAmB;IACxB,UAAU,0DAAmB;IAC7B,UAAU,0DAAmB;IAE7B,QAAQ,qEAAiD;IACzD,QAAQ,qEAAiD;IAEzD,QAAQ,qEAAiD;IACzD,GAAG,wEAAiC;IACpC,GAAG,wEAAiC;IACpC,SAAS,0DAAmB;IAC5B,SAAS,0DAAmB;IAC5B,OAAO,0DAAmB;IAC1B,WAAW,+CAAiB,iBAAiB,CAAC,CAAC,CAAC,GAAG,SAAS,KAAK,MAAM,GAAG,SAAS,eAAI;IACvF,MAAM,0DAAmB;IAEzB,IAAI,0DAAmB;IACvB,YAAY,0DAAmB;IAC/B,cAAc,qEAAgD;IAC9D,SAAS,0DAAmB;IAE5B,MAAM,qEAAiD;IACvD,KAAK,qEAAiD;IACtD,IAAI,+DAAwB;IAC5B,KAAK,8IAED;IAEJ,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsD;IAE9E,WAAW,yCAA8C;IAEzD,WAAW,kDAA8D;IAEzE,YAAY,yCAOT;IAEH,gBAAgB,qDAMb;;IA4BH,OAAO,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAa3B,YAAY,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI;yCA/F9B,kBAAkB;2CAAlB,kBAAkB;CA8G9B"}
@@ -128,6 +128,7 @@ export class SdTextfieldControl {
128
128
  this.value.set(parsed);
129
129
  }
130
130
  onInputPaste(event) {
131
+ event.preventDefault();
131
132
  const text = event.clipboardData?.getData("text/plain").trim();
132
133
  if (text == null || text === "") {
133
134
  this.value.set(undefined);
@@ -2,6 +2,8 @@ import type { ISdResizeEvent } from "../../../core/plugins/events/sd-resize-even
2
2
  import * as i0 from "@angular/core";
3
3
  export declare class SdDockControl {
4
4
  private readonly _elRef;
5
+ private readonly _destroyRef;
6
+ private _dragCleanup;
5
7
  key: import("@angular/core").InputSignal<string | undefined>;
6
8
  position: import("@angular/core").InputSignal<"bottom" | "left" | "right" | "top">;
7
9
  resizable: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
@@ -1 +1 @@
1
- {"version":3,"file":"sd-dock.control.d.ts","sourceRoot":"","sources":["..\\..\\..\\..\\src\\ui\\layout\\dock\\sd-dock.control.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qDAAqD,CAAC;;AAE1F,qBAyEa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmC;IAE1D,GAAG,0DAAmB;IACtB,QAAQ,2EAAqD;IAC7D,SAAS,qEAAiD;IAE1D,IAAI,iDAAa;IAEjB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmE;;IAgB3F,WAAW,CAAC,KAAK,EAAE,OAAO,CAAC,mBAAmB,CAAC;IAI/C,YAAY,CAAC,KAAK,EAAE,cAAc;IASlC,oBAAoB,CAAC,KAAK,EAAE,UAAU;yCAtC3B,aAAa;2CAAb,aAAa;CAmFzB"}
1
+ {"version":3,"file":"sd-dock.control.d.ts","sourceRoot":"","sources":["..\\..\\..\\..\\src\\ui\\layout\\dock\\sd-dock.control.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qDAAqD,CAAC;;AAE1F,qBAyEa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmC;IAC1D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAsB;IAElD,OAAO,CAAC,YAAY,CAA2B;IAE/C,GAAG,0DAAmB;IACtB,QAAQ,2EAAqD;IAC7D,SAAS,qEAAiD;IAE1D,IAAI,iDAAa;IAEjB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmE;;IAoB3F,WAAW,CAAC,KAAK,EAAE,OAAO,CAAC,mBAAmB,CAAC;IAI/C,YAAY,CAAC,KAAK,EAAE,cAAc;IASlC,oBAAoB,CAAC,KAAK,EAAE,UAAU;yCA7C3B,aAAa;2CAAb,aAAa;CA+FzB"}
@@ -1,4 +1,4 @@
1
- import { booleanAttribute, ChangeDetectionStrategy, Component, effect, ElementRef, inject, input, signal, ViewEncapsulation, } from "@angular/core";
1
+ import { booleanAttribute, ChangeDetectionStrategy, Component, DestroyRef, effect, ElementRef, inject, input, signal, ViewEncapsulation, } from "@angular/core";
2
2
  import { useSdSystemConfigResource } from "../../../core/utils/useSdSystemConfigResource";
3
3
  import * as i0 from "@angular/core";
4
4
  const _c0 = ["*"];
@@ -10,12 +10,17 @@ function SdDockControl_Conditional_1_Template(rf, ctx) { if (rf & 1) {
10
10
  } }
11
11
  export class SdDockControl {
12
12
  _elRef = inject((ElementRef));
13
+ _destroyRef = inject(DestroyRef);
14
+ _dragCleanup;
13
15
  key = input(...(ngDevMode ? [undefined, { debugName: "key" }] : /* istanbul ignore next */ []));
14
16
  position = input("top", ...(ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []));
15
17
  resizable = input(false, { ...(ngDevMode ? { debugName: "resizable" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
16
18
  size = signal(0, ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
17
19
  _config = useSdSystemConfigResource({ key: this.key });
18
20
  constructor() {
21
+ this._destroyRef.onDestroy(() => {
22
+ this._dragCleanup?.();
23
+ });
19
24
  effect(() => {
20
25
  const conf = this._config.value();
21
26
  if (this.resizable() && conf && conf.size != null) {
@@ -65,8 +70,7 @@ export class SdDockControl {
65
70
  const stopDrag = (e) => {
66
71
  e.stopPropagation();
67
72
  e.preventDefault();
68
- document.removeEventListener("mousemove", doDrag);
69
- document.removeEventListener("mouseup", stopDrag);
73
+ this._dragCleanup?.();
70
74
  if (this.key() != null) {
71
75
  const newConf = {};
72
76
  if (["right", "left"].includes(this.position())) {
@@ -80,6 +84,11 @@ export class SdDockControl {
80
84
  };
81
85
  document.addEventListener("mousemove", doDrag);
82
86
  document.addEventListener("mouseup", stopDrag);
87
+ this._dragCleanup = () => {
88
+ document.removeEventListener("mousemove", doDrag);
89
+ document.removeEventListener("mouseup", stopDrag);
90
+ this._dragCleanup = undefined;
91
+ };
83
92
  }
84
93
  static ɵfac = function SdDockControl_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || SdDockControl)(); };
85
94
  static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SdDockControl, selectors: [["sd-dock"]], hostVars: 2, hostBindings: function SdDockControl_HostBindings(rf, ctx) { if (rf & 1) {
@@ -108,4 +117,4 @@ export class SdDockControl {
108
117
  }
109
118
  `, styles: ["sd-dock {\n display: block;\n position: absolute;\n overflow: auto;\n}\nsd-dock[data-sd-resizable=true] > ._resize-bar {\n position: absolute;\n}\nsd-dock[data-sd-resizable=true][data-sd-position=top] > ._resize-bar {\n bottom: 0;\n left: 0;\n width: 100%;\n height: 2px;\n cursor: ns-resize;\n}\nsd-dock[data-sd-resizable=true][data-sd-position=bottom] > ._resize-bar {\n top: 0;\n left: 0;\n width: 100%;\n height: 2px;\n cursor: ns-resize;\n}\nsd-dock[data-sd-resizable=true][data-sd-position=left] > ._resize-bar {\n top: 0;\n right: 0;\n height: 100%;\n width: 2px;\n cursor: ew-resize;\n}\nsd-dock[data-sd-resizable=true][data-sd-position=right] > ._resize-bar {\n top: 0;\n left: 0;\n height: 100%;\n width: 2px;\n cursor: ew-resize;\n}"] }]
110
119
  }], () => [], { key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], resizable: [{ type: i0.Input, args: [{ isSignal: true, alias: "resizable", required: false }] }] }); })();
111
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SdDockControl, { className: "SdDockControl", filePath: "packages/angular/src/ui/layout/dock/sd-dock.control.ts", lineNumber: 88 }); })();
120
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SdDockControl, { className: "SdDockControl", filePath: "packages/angular/src/ui/layout/dock/sd-dock.control.ts", lineNumber: 89 }); })();
@@ -1 +1 @@
1
- {"version":3,"file":"sd-kanban-lane.control.d.ts","sourceRoot":"","sources":["..\\..\\..\\..\\src\\ui\\layout\\kanban\\sd-kanban-lane.control.ts"],"names":[],"mappings":"AACA,OAAO,EAYL,WAAW,EAEZ,MAAM,eAAe,CAAC;AAGvB,OAAO,EAEL,KAAK,mBAAmB,EACzB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;;AAKtD,qBA6Fa,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAE,YAAW,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC;IACzE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAE5B;IAEF,IAAI,qEAAiD;IAErD,WAAW,qEAAiD;IAE5D,QAAQ,+CAAgB;IAExB,KAAK,qDAAc;IAEnB,cAAc,mEAAkF;IAEhG,UAAU,gEAA0E;IACpF,WAAW,gEAA2E;IAEtF,aAAa,0CAEX;IAEF,UAAU,yGAAmD;IAE7D,UAAU,kDAAiB;IAE3B,sBAAsB,yCAEpB;IAEF,eAAe;IAIf,2BAA2B;IAI3B,sBAAsB,CAAC,GAAG,EAAE,OAAO;IAuBnC,UAAU,CAAC,KAAK,EAAE,SAAS;IAS3B,WAAW,CAAC,KAAK,EAAE,SAAS;IAO5B,UAAU,CAAC,KAAK,EAAE,SAAS;IAU3B,SAAS,CAAC,QAAQ,CAAC,YAAY,wkBAAgB;IAC/C,SAAS,CAAC,QAAQ,CAAC,SAAS,ubAAa;yCAxF9B,mBAAmB;2CAAnB,mBAAmB;CAyF/B"}
1
+ {"version":3,"file":"sd-kanban-lane.control.d.ts","sourceRoot":"","sources":["..\\..\\..\\..\\src\\ui\\layout\\kanban\\sd-kanban-lane.control.ts"],"names":[],"mappings":"AACA,OAAO,EAYL,WAAW,EAEZ,MAAM,eAAe,CAAC;AAGvB,OAAO,EAEL,KAAK,mBAAmB,EACzB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;;AAKtD,qBA6Fa,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAE,YAAW,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC;IACzE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAE5B;IAEF,IAAI,qEAAiD;IAErD,WAAW,qEAAiD;IAE5D,QAAQ,+CAAgB;IAExB,KAAK,qDAAc;IAEnB,cAAc,mEAAkF;IAEhG,UAAU,gEAA0E;IACpF,WAAW,gEAA2E;IAEtF,aAAa,0CAGV;IAEH,UAAU,yGAAmD;IAE7D,UAAU,kDAAiB;IAE3B,sBAAsB,yCAEpB;IAEF,eAAe;IAIf,2BAA2B;IAI3B,sBAAsB,CAAC,GAAG,EAAE,OAAO;IAyBnC,UAAU,CAAC,KAAK,EAAE,SAAS;IAS3B,WAAW,CAAC,KAAK,EAAE,SAAS;IAO5B,UAAU,CAAC,KAAK,EAAE,SAAS;IAU3B,SAAS,CAAC,QAAQ,CAAC,YAAY,wkBAAgB;IAC/C,SAAS,CAAC,QAAQ,CAAC,SAAS,ubAAa;yCA3F9B,mBAAmB;2CAAnB,mBAAmB;CA4F/B"}
@@ -79,7 +79,10 @@ export class SdKanbanLaneControl {
79
79
  kanbanControls = contentChildren(SdKanbanControl, { ...(ngDevMode ? { debugName: "kanbanControls" } : /* istanbul ignore next */ {}), descendants: true });
80
80
  toolTplRef = contentChild("toolTpl", { ...(ngDevMode ? { debugName: "toolTplRef" } : /* istanbul ignore next */ {}), read: TemplateRef });
81
81
  titleTplRef = contentChild("titleTpl", { ...(ngDevMode ? { debugName: "titleTplRef" } : /* istanbul ignore next */ {}), read: TemplateRef });
82
- isAllSelected = computed(() => this.kanbanControls().length > 0 && this.kanbanControls().every((ctrl) => ctrl.selected()), ...(ngDevMode ? [{ debugName: "isAllSelected" }] : /* istanbul ignore next */ []));
82
+ isAllSelected = computed(() => {
83
+ const selectableControls = this.kanbanControls().filter((ctrl) => ctrl.selectable());
84
+ return selectableControls.length > 0 && selectableControls.every((ctrl) => ctrl.selected());
85
+ }, ...(ngDevMode ? [{ debugName: "isAllSelected" }] : /* istanbul ignore next */ []));
83
86
  dragKanban = computed(() => this._boardControl.dragKanban(), ...(ngDevMode ? [{ debugName: "dragKanban" }] : /* istanbul ignore next */ []));
84
87
  dragOvered = signal(false, ...(ngDevMode ? [{ debugName: "dragOvered" }] : /* istanbul ignore next */ []));
85
88
  selectableKanbanLength = computed(() => this.kanbanControls().filter((ctrl) => ctrl.selectable()).length, ...(ngDevMode ? [{ debugName: "selectableKanbanLength" }] : /* istanbul ignore next */ []));
@@ -94,6 +97,8 @@ export class SdKanbanLaneControl {
94
97
  this._boardControl.selectedValues.update((v) => {
95
98
  const r = [...v];
96
99
  for (const ctrl of this.kanbanControls()) {
100
+ if (!ctrl.selectable())
101
+ continue;
97
102
  if (ctrl.value() == null)
98
103
  continue;
99
104
  if (!v.includes(ctrl.value())) {
@@ -106,6 +111,7 @@ export class SdKanbanLaneControl {
106
111
  else {
107
112
  this._boardControl.selectedValues.update((v) => {
108
113
  const kanbanValues = this.kanbanControls()
114
+ .filter((ctrl) => ctrl.selectable())
109
115
  .map((ctrl) => ctrl.value())
110
116
  .filter((v2) => v2 != null);
111
117
  const result = v.filter((item) => !kanbanValues.includes(item));
@@ -1,9 +1,9 @@
1
1
  import * as i0 from "@angular/core";
2
2
  export declare class SdGapControl {
3
3
  private readonly _elRef;
4
- height: import("@angular/core").InputSignal<"default" | "xxs" | "xs" | "sm" | "lg" | "xl" | "xxl" | undefined>;
4
+ height: import("@angular/core").InputSignal<"default" | "sm" | "lg" | "xxs" | "xs" | "xl" | "xxl" | undefined>;
5
5
  heightPx: import("@angular/core").InputSignal<number | undefined>;
6
- width: import("@angular/core").InputSignal<"default" | "xxs" | "xs" | "sm" | "lg" | "xl" | "xxl" | undefined>;
6
+ width: import("@angular/core").InputSignal<"default" | "sm" | "lg" | "xxs" | "xs" | "xl" | "xxl" | undefined>;
7
7
  widthPx: import("@angular/core").InputSignal<number | undefined>;
8
8
  widthEm: import("@angular/core").InputSignal<number | undefined>;
9
9
  constructor();
@@ -1 +1 @@
1
- {"version":3,"file":"sd-pagination.control.d.ts","sourceRoot":"","sources":["..\\..\\..\\..\\src\\ui\\navigation\\pagination\\sd-pagination.control.ts"],"names":[],"mappings":";AAkBA,qBA2Ca,mBAAmB;IAC9B,KAAK;;;;;MAAsF;IAE3F,WAAW,8CAAY;IACvB,cAAc,oEAA4C;IAC1D,gBAAgB,oEAA6C;IAE7D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAExB;IAEH,OAAO,0CAKJ;IAEH,OAAO,0CAOJ;IAEH,YAAY,2CAeT;IAEH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI5B,aAAa,IAAI,IAAI;IAIrB,aAAa,IAAI,IAAI;IAIrB,SAAS,IAAI,IAAI;IAIjB,QAAQ,IAAI,IAAI;yCA5DL,mBAAmB;2CAAnB,mBAAmB;CA+D/B"}
1
+ {"version":3,"file":"sd-pagination.control.d.ts","sourceRoot":"","sources":["..\\..\\..\\..\\src\\ui\\navigation\\pagination\\sd-pagination.control.ts"],"names":[],"mappings":";AAkBA,qBA2Ca,mBAAmB;IAC9B,KAAK;;;;;MAAsF;IAE3F,WAAW,8CAAY;IACvB,cAAc,oEAA4C;IAC1D,gBAAgB,oEAA6C;IAE7D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAExB;IAEH,OAAO,0CAKJ;IAEH,OAAO,0CAOJ;IAEH,YAAY,2CAeT;IAEH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI5B,aAAa,IAAI,IAAI;IAIrB,aAAa,IAAI,IAAI;IAKrB,SAAS,IAAI,IAAI;IAIjB,QAAQ,IAAI,IAAI;yCA7DL,mBAAmB;2CAAnB,mBAAmB;CAiE/B"}
@@ -22,7 +22,7 @@ export class SdPaginationControl {
22
22
  totalPageCount = input(0, { ...(ngDevMode ? { debugName: "totalPageCount" } : /* istanbul ignore next */ {}), transform: numberAttribute });
23
23
  visiblePageCount = input(10, { ...(ngDevMode ? { debugName: "visiblePageCount" } : /* istanbul ignore next */ {}), transform: numberAttribute });
24
24
  groupIndex = computed(() => {
25
- return Math.floor(this.currentPage() / this.visiblePageCount());
25
+ return Math.floor(this.currentPage() / Math.max(this.visiblePageCount(), 1));
26
26
  }, ...(ngDevMode ? [{ debugName: "groupIndex" }] : /* istanbul ignore next */ []));
27
27
  hasPrev = computed(() => {
28
28
  if (this.totalPageCount() === 0) {
@@ -35,7 +35,7 @@ export class SdPaginationControl {
35
35
  if (totalPageCount === 0) {
36
36
  return false;
37
37
  }
38
- const lastGroupIndex = Math.floor((totalPageCount - 1) / this.visiblePageCount());
38
+ const lastGroupIndex = Math.floor((totalPageCount - 1) / Math.max(this.visiblePageCount(), 1));
39
39
  return this.groupIndex() < lastGroupIndex;
40
40
  }, ...(ngDevMode ? [{ debugName: "hasNext" }] : /* istanbul ignore next */ []));
41
41
  displayPages = computed(() => {
@@ -59,12 +59,16 @@ export class SdPaginationControl {
59
59
  this.currentPage.set((this.groupIndex() + 1) * this.visiblePageCount());
60
60
  }
61
61
  goToPrevGroup() {
62
- this.currentPage.set((this.groupIndex() - 1) * this.visiblePageCount());
62
+ if (!this.hasPrev())
63
+ return;
64
+ this.currentPage.set((this.groupIndex() - 1) * Math.max(this.visiblePageCount(), 1));
63
65
  }
64
66
  goToFirst() {
65
67
  this.currentPage.set(0);
66
68
  }
67
69
  goToLast() {
70
+ if (this.totalPageCount() === 0)
71
+ return;
68
72
  this.currentPage.set(this.totalPageCount() - 1);
69
73
  }
70
74
  static ɵfac = function SdPaginationControl_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || SdPaginationControl)(); };
@@ -21,7 +21,7 @@ export class SdSidebarContainerControl {
21
21
  }
22
22
  }
23
23
  onBackdropClick() {
24
- this.toggle.update((v) => !v);
24
+ this.toggle.set(false);
25
25
  }
26
26
  static ɵfac = function SdSidebarContainerControl_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || SdSidebarContainerControl)(); };
27
27
  static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SdSidebarContainerControl, selectors: [["sd-sidebar-container"]], hostVars: 1, hostBindings: function SdSidebarContainerControl_HostBindings(rf, ctx) { if (rf & 2) {
@@ -13,7 +13,7 @@ export class SdDropdownPopupControl {
13
13
  const el = this._elRef.nativeElement;
14
14
  const divEl = el.firstElementChild;
15
15
  if (divEl.clientHeight > 300) {
16
- el.style.height = "18.75rem";
16
+ el.style.height = "300px";
17
17
  }
18
18
  else {
19
19
  el.style.height = "";
@@ -5,6 +5,7 @@ export declare class SdModalControl {
5
5
  private readonly _elRef;
6
6
  private readonly _activatedModal;
7
7
  private readonly _systemConfig;
8
+ private readonly _destroyRef;
8
9
  open: import("@angular/core").ModelSignal<boolean>;
9
10
  key: import("@angular/core").InputSignal<string | undefined>;
10
11
  title: import("@angular/core").InputSignal<string>;
@@ -1 +1 @@
1
- {"version":3,"file":"sd-modal.control.d.ts","sourceRoot":"","sources":["..\\..\\..\\..\\src\\ui\\overlay\\modal\\sd-modal.control.ts"],"names":[],"mappings":"AAAA,OAAO,EASL,KAAK,WAAW,EAEjB,MAAM,eAAe,CAAC;AAKvB,OAAO,wBAAwB,CAAC;;AAEhC,qBA0Ca,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmC;IAC1D,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAwD;IACxF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAsD;IAEpF,IAAI,+CAAgB;IACpB,GAAG,0DAAwC;IAC3C,KAAK,8CAAa;IAClB,UAAU,+CAAgB;IAC1B,eAAe,+CAAgB;IAC/B,kBAAkB,+CAAe;IACjC,mBAAmB,+CAAe;IAClC,KAAK,+CAAgB;IACrB,IAAI,+CAAgB;IACpB,SAAS,+CAAgB;IACzB,OAAO,+CAAgB;IACvB,QAAQ,gFAA8D;IACtE,WAAW,0DAAwC;IACnD,UAAU,0DAAwC;IAClD,QAAQ,0DAAwC;IAChD,OAAO,0DAAwC;IAC/C,WAAW,0DAAwC;IACnD,sBAAsB,+CAAgB;IACtC,YAAY,oEAAkD;IAE9D,YAAY,iDAAkB;IAE9B,OAAO,CAAC,UAAU,CAEJ;IAEd,OAAO,CAAC,YAAY,CAUN;IAEd,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAA8B;IACnE,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAa;;IA+ChD,iBAAiB,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAkBvD,iBAAiB,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAkB1C,eAAe,IAAI,IAAI;IAKvB,kBAAkB,IAAI,IAAI;IAI1B,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAS3C,aAAa,IAAI,IAAI;IAIrB,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,cAAc;IAuBtB,OAAO,CAAC,oBAAoB;IAa5B,OAAO,CAAC,aAAa;IAcrB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,YAAY;IA4CpB,OAAO,CAAC,UAAU;YAcJ,WAAW;YAgBX,cAAc;yCA7RjB,cAAc;2CAAd,cAAc;CA6S1B"}
1
+ {"version":3,"file":"sd-modal.control.d.ts","sourceRoot":"","sources":["..\\..\\..\\..\\src\\ui\\overlay\\modal\\sd-modal.control.ts"],"names":[],"mappings":"AAAA,OAAO,EAUL,KAAK,WAAW,EAEjB,MAAM,eAAe,CAAC;AAKvB,OAAO,wBAAwB,CAAC;;AAEhC,qBA0Ca,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmC;IAC1D,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAwD;IACxF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAsD;IACpF,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAsB;IAElD,IAAI,+CAAgB;IACpB,GAAG,0DAAwC;IAC3C,KAAK,8CAAa;IAClB,UAAU,+CAAgB;IAC1B,eAAe,+CAAgB;IAC/B,kBAAkB,+CAAe;IACjC,mBAAmB,+CAAe;IAClC,KAAK,+CAAgB;IACrB,IAAI,+CAAgB;IACpB,SAAS,+CAAgB;IACzB,OAAO,+CAAgB;IACvB,QAAQ,gFAA8D;IACtE,WAAW,0DAAwC;IACnD,UAAU,0DAAwC;IAClD,QAAQ,0DAAwC;IAChD,OAAO,0DAAwC;IAC/C,WAAW,0DAAwC;IACnD,sBAAsB,+CAAgB;IACtC,YAAY,oEAAkD;IAE9D,YAAY,iDAAkB;IAE9B,OAAO,CAAC,UAAU,CAEJ;IAEd,OAAO,CAAC,YAAY,CAUN;IAEd,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAA8B;IACnE,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAa;;IAoDhD,iBAAiB,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAkBvD,iBAAiB,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAkB1C,eAAe,IAAI,IAAI;IAKvB,kBAAkB,IAAI,IAAI;IAI1B,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAS3C,aAAa,IAAI,IAAI;IAIrB,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,cAAc;IAuBtB,OAAO,CAAC,oBAAoB;IAa5B,OAAO,CAAC,aAAa;IAgBrB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,YAAY;IA4CpB,OAAO,CAAC,UAAU;YAcJ,WAAW;YAgBX,cAAc;yCArSjB,cAAc;2CAAd,cAAc;CAqT1B"}
@@ -1,4 +1,4 @@
1
- import { ChangeDetectionStrategy, Component, effect, ElementRef, inject, input, model, output, ViewEncapsulation, } from "@angular/core";
1
+ import { ChangeDetectionStrategy, Component, DestroyRef, effect, ElementRef, inject, input, model, output, ViewEncapsulation, } from "@angular/core";
2
2
  import { isTabbable } from "tabbable";
3
3
  import { NgTemplateOutlet } from "@angular/common";
4
4
  import { SdActivatedModalProvider } from "./sd-modal.provider";
@@ -72,6 +72,7 @@ export class SdModalControl {
72
72
  _elRef = inject((ElementRef));
73
73
  _activatedModal = inject(SdActivatedModalProvider, { optional: true });
74
74
  _systemConfig = inject(SdSystemConfigProvider, { optional: true });
75
+ _destroyRef = inject(DestroyRef);
75
76
  open = model(false, ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
76
77
  key = input(undefined, ...(ngDevMode ? [{ debugName: "key" }] : /* istanbul ignore next */ []));
77
78
  title = input("", ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
@@ -137,6 +138,10 @@ export class SdModalControl {
137
138
  void this._saveConfig();
138
139
  }
139
140
  };
141
+ this._destroyRef.onDestroy(() => {
142
+ document.removeEventListener("mousemove", this._onDocumentMouseMove);
143
+ document.removeEventListener("mouseup", this._onDocumentMouseUp);
144
+ });
140
145
  }
141
146
  onResizeMouseDown(event, dir) {
142
147
  event.preventDefault();
@@ -195,7 +200,7 @@ export class SdModalControl {
195
200
  this._bringToFront();
196
201
  }
197
202
  _requestClose() {
198
- if (this._activatedModal !== null && !this._activatedModal.canDeactivefn()) {
203
+ if (this._activatedModal !== null && !this._activatedModal.canDeactiveFn()) {
199
204
  return;
200
205
  }
201
206
  void this._saveConfig();
@@ -247,6 +252,9 @@ export class SdModalControl {
247
252
  maxZ = z;
248
253
  }
249
254
  }
255
+ const currentZ = parseInt(hostEl.style.zIndex, 10);
256
+ if (currentZ >= maxZ)
257
+ return;
250
258
  hostEl.style.zIndex = String(maxZ + 1);
251
259
  }
252
260
  _getDialogEl() {
@@ -408,4 +416,4 @@ export class SdModalControl {
408
416
  `,
409
417
  }]
410
418
  }], () => [], { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], hideHeader: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideHeader", required: false }] }], hideCloseButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideCloseButton", required: false }] }], useCloseByBackdrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "useCloseByBackdrop", required: false }] }], useCloseByEscapeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "useCloseByEscapeKey", required: false }] }], float: [{ type: i0.Input, args: [{ isSignal: true, alias: "float", required: false }] }], fill: [{ type: i0.Input, args: [{ isSignal: true, alias: "fill", required: false }] }], resizable: [{ type: i0.Input, args: [{ isSignal: true, alias: "resizable", required: false }] }], movable: [{ type: i0.Input, args: [{ isSignal: true, alias: "movable", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], minHeightPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "minHeightPx", required: false }] }], minWidthPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "minWidthPx", required: false }] }], heightPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "heightPx", required: false }] }], widthPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "widthPx", required: false }] }], headerStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerStyle", required: false }] }], noFirstControlFocusing: [{ type: i0.Input, args: [{ isSignal: true, alias: "noFirstControlFocusing", required: false }] }], actionTplRef: [{ type: i0.Input, args: [{ isSignal: true, alias: "actionTplRef", required: false }] }], closeRequest: [{ type: i0.Output, args: ["closeRequest"] }] }); })();
411
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SdModalControl, { className: "SdModalControl", filePath: "packages/angular/src/ui/overlay/modal/sd-modal.control.ts", lineNumber: 61 }); })();
419
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SdModalControl, { className: "SdModalControl", filePath: "packages/angular/src/ui/overlay/modal/sd-modal.control.ts", lineNumber: 62 }); })();
@@ -45,7 +45,7 @@ export interface ISdModalOptions {
45
45
  export declare class SdActivatedModalProvider<T extends ISdModal<any> = ISdModal<any>> {
46
46
  modalComponent: import("@angular/core").WritableSignal<any>;
47
47
  contentComponent: import("@angular/core").WritableSignal<T | undefined>;
48
- canDeactivefn: () => boolean;
48
+ canDeactiveFn: () => boolean;
49
49
  static ɵfac: i0.ɵɵFactoryDeclaration<SdActivatedModalProvider<any>, never>;
50
50
  static ɵprov: i0.ɵɵInjectableDeclaration<SdActivatedModalProvider<any>>;
51
51
  }
@@ -10,7 +10,7 @@ import * as i0 from "@angular/core";
10
10
  export class SdActivatedModalProvider {
11
11
  modalComponent = signal(undefined, ...(ngDevMode ? [{ debugName: "modalComponent" }] : /* istanbul ignore next */ []));
12
12
  contentComponent = signal(undefined, ...(ngDevMode ? [{ debugName: "contentComponent" }] : /* istanbul ignore next */ []));
13
- canDeactivefn = () => true;
13
+ canDeactiveFn = () => true;
14
14
  static ɵfac = function SdActivatedModalProvider_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || SdActivatedModalProvider)(); };
15
15
  static ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: SdActivatedModalProvider, factory: SdActivatedModalProvider.ɵfac });
16
16
  }
@@ -1 +1 @@
1
- {"version":3,"file":"sd-toast.provider.d.ts","sourceRoot":"","sources":["..\\..\\..\\..\\src\\ui\\overlay\\toast\\sd-toast.provider.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sd-toast.provider.d.ts","sourceRoot":"","sources":["..\\..\\..\\..\\src\\ui\\overlay\\toast\\sd-toast.provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAUL,KAAK,gBAAgB,EACrB,KAAK,IAAI,EACT,KAAK,cAAc,EACpB,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,4CAA4C,CAAC;AAIzF,OAAO,wBAAwB,CAAC;;AAEhC,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;AACzE,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,WAAW,GAAG,gBAAgB,GAAG,MAAM,GAAG,WAAW,CAAC;AAE9F,MAAM,WAAW,QAAQ,CAAC,CAAC;IACzB,KAAK,EAAE,gBAAgB,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;CACxC;AAED,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,QAAQ,CAAC,GAAG,CAAC;IACpD,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IACd,MAAM,EAAE,IAAI,CAAC,sBAAsB,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;CAClD;AAED,qBACa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;IAClD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA+B;IAC5D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoB;IAC9C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA+B;IAE1D,WAAW,qCAAkC;IAC7C,OAAO,0BAAiB;IACxB,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAEjD,OAAO,CAAC,aAAa,CAAoD;IACzE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAsC;IACjE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA8D;IAE3F,OAAO,KAAK,YAAY,GAUvB;IAED,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,IAAI,GAAG,cAAc,CAAC,MAAM,CAAC;IACjE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,KAAK,GAAG,IAAI;IAKhD,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,IAAI,GAAG,cAAc,CAAC,MAAM,CAAC;IACpE,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,KAAK,GAAG,IAAI;IAKnD,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,IAAI,GAAG,cAAc,CAAC,MAAM,CAAC;IACpE,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,KAAK,GAAG,IAAI;IAKnD,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,IAAI,GAAG,cAAc,CAAC,MAAM,CAAC;IACnE,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,KAAK,GAAG,IAAI;IAKlD,MAAM,CAAC,CAAC,SAAS,QAAQ,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;IAuD1G,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IACpD,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAmB/F,OAAO,CAAC,KAAK;IA+Db,OAAO,CAAC,iBAAiB;IAqCzB,OAAO,CAAC,aAAa;IAqBrB,OAAO,CAAC,aAAa;IAsBrB,OAAO,CAAC,gBAAgB;yCA5Qb,eAAe;6CAAf,eAAe;CAiR3B"}
@@ -129,12 +129,13 @@ export class SdToastProvider {
129
129
  if (useProgress) {
130
130
  // progress 모드: effect로 100% 감지 후 1초 뒤 자동 해제
131
131
  const progressSignal = toastRef.instance.progress;
132
- effect(() => {
132
+ effect((onCleanup) => {
133
133
  const val = progressSignal();
134
134
  if (val >= 100) {
135
- setTimeout(() => {
135
+ const timerId = setTimeout(() => {
136
136
  this._dismissToast(toastRef);
137
137
  }, 1000);
138
+ onCleanup(() => clearTimeout(timerId));
138
139
  }
139
140
  }, { injector: toastRef.injector });
140
141
  return progressSignal;
@@ -176,13 +177,16 @@ export class SdToastProvider {
176
177
  _dismissToast(toastRef) {
177
178
  toastRef.instance.open.set(false);
178
179
  const el = toastRef.location.nativeElement;
180
+ let fallbackId;
179
181
  const onTransitionEnd = () => {
182
+ clearTimeout(fallbackId);
180
183
  el.removeEventListener("transitionend", onTransitionEnd);
181
184
  this._destroyToast(toastRef);
182
185
  };
183
186
  el.addEventListener("transitionend", onTransitionEnd);
184
187
  // fallback: transition이 없는 경우 300ms 후 파괴
185
- setTimeout(() => {
188
+ fallbackId = setTimeout(() => {
189
+ el.removeEventListener("transitionend", onTransitionEnd);
186
190
  this._destroyToast(toastRef);
187
191
  }, 300);
188
192
  }
@@ -4,6 +4,7 @@ export declare class SdProgressControl {
4
4
  size: import("@angular/core").InputSignal<"sm" | "lg" | undefined>;
5
5
  theme: import("@angular/core").InputSignal<"info" | "success" | "primary" | "secondary" | "warning" | "danger" | "gray" | "blue-gray">;
6
6
  value: import("@angular/core").InputSignal<number>;
7
+ _barWidth: import("@angular/core").Signal<string>;
7
8
  static ɵfac: i0.ɵɵFactoryDeclaration<SdProgressControl, never>;
8
9
  static ɵcmp: i0.ɵɵComponentDeclaration<SdProgressControl, "sd-progress", never, { "inset": { "alias": "inset"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "theme": { "alias": "theme"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
9
10
  }
@@ -1 +1 @@
1
- {"version":3,"file":"sd-progress.control.d.ts","sourceRoot":"","sources":["..\\..\\..\\src\\ui\\visual\\sd-progress.control.ts"],"names":[],"mappings":";AASA,qBAsEa,iBAAiB;IAC5B,KAAK,qEAAiD;IACtD,IAAI,+DAAwB;IAC5B,KAAK,kIAED;IAEJ,KAAK,8CAA4B;yCAPtB,iBAAiB;2CAAjB,iBAAiB;CAQ7B"}
1
+ {"version":3,"file":"sd-progress.control.d.ts","sourceRoot":"","sources":["..\\..\\..\\src\\ui\\visual\\sd-progress.control.ts"],"names":[],"mappings":";AAUA,qBAsEa,iBAAiB;IAC5B,KAAK,qEAAiD;IACtD,IAAI,+DAAwB;IAC5B,KAAK,kIAED;IAEJ,KAAK,8CAA4B;IAEjC,SAAS,yCAA2D;yCATzD,iBAAiB;2CAAjB,iBAAiB;CAU7B"}
@@ -1,4 +1,4 @@
1
- import { booleanAttribute, ChangeDetectionStrategy, Component, input, ViewEncapsulation, } from "@angular/core";
1
+ import { booleanAttribute, ChangeDetectionStrategy, Component, computed, input, ViewEncapsulation, } from "@angular/core";
2
2
  import { PercentPipe } from "@angular/common";
3
3
  import * as i0 from "@angular/core";
4
4
  export class SdProgressControl {
@@ -6,6 +6,7 @@ export class SdProgressControl {
6
6
  size = input(...(ngDevMode ? [undefined, { debugName: "size" }] : /* istanbul ignore next */ []));
7
7
  theme = input.required(...(ngDevMode ? [{ debugName: "theme" }] : /* istanbul ignore next */ []));
8
8
  value = input.required(...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
9
+ _barWidth = computed(() => Math.min(this.value() * 100, 100) + "%", ...(ngDevMode ? [{ debugName: "_barWidth" }] : /* istanbul ignore next */ []));
9
10
  static ɵfac = function SdProgressControl_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || SdProgressControl)(); };
10
11
  static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SdProgressControl, selectors: [["sd-progress"]], hostVars: 3, hostBindings: function SdProgressControl_HostBindings(rf, ctx) { if (rf & 2) {
11
12
  i0.ɵɵattribute("data-sd-inset", ctx.inset())("data-sd-size", ctx.size())("data-sd-theme", ctx.theme());
@@ -19,7 +20,7 @@ export class SdProgressControl {
19
20
  i0.ɵɵadvance();
20
21
  i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind2(2, 3, ctx.value(), "1.0-2"), " ");
21
22
  i0.ɵɵadvance(2);
22
- i0.ɵɵstyleProp("width", ctx.value() * 100 + "%");
23
+ i0.ɵɵstyleProp("width", ctx._barWidth());
23
24
  } }, dependencies: [PercentPipe], styles: ["sd-progress {\n position: relative;\n display: block;\n width: 100%;\n white-space: nowrap;\n background: var(--theme-gray-lightest);\n border: 1px solid var(--theme-gray-lightest);\n border-radius: var(--border-radius-default);\n overflow: hidden;\n}\nsd-progress > ._content {\n position: relative;\n z-index: 2;\n padding: var(--gap-lg) var(--gap-default);\n}\nsd-progress > ._progress {\n position: absolute;\n z-index: 1;\n top: 0;\n left: 0;\n height: 100%;\n}\nsd-progress[data-sd-theme=gray] > ._progress {\n background: var(--theme-gray-default);\n}\nsd-progress[data-sd-theme=blue-gray] > ._progress {\n background: var(--theme-blue-gray-default);\n}\nsd-progress[data-sd-theme=primary] > ._progress {\n background: var(--theme-primary-default);\n}\nsd-progress[data-sd-theme=secondary] > ._progress {\n background: var(--theme-secondary-default);\n}\nsd-progress[data-sd-theme=info] > ._progress {\n background: var(--theme-info-default);\n}\nsd-progress[data-sd-theme=success] > ._progress {\n background: var(--theme-success-default);\n}\nsd-progress[data-sd-theme=warning] > ._progress {\n background: var(--theme-warning-default);\n}\nsd-progress[data-sd-theme=danger] > ._progress {\n background: var(--theme-danger-default);\n}\nsd-progress[data-sd-size=sm] > ._content {\n padding: var(--gap-xs) var(--gap-default);\n}\nsd-progress[data-sd-size=lg] > ._content {\n padding: var(--gap-default) var(--gap-xl);\n}\nsd-progress[data-sd-inset=true] {\n border-radius: 0;\n border: none;\n background: var(--control-color);\n}"], encapsulation: 2, changeDetection: 0 });
24
25
  }
25
26
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SdProgressControl, [{
@@ -32,7 +33,7 @@ export class SdProgressControl {
32
33
  <div class="_content tx-right">
33
34
  {{ value() | percent: "1.0-2" }}
34
35
  </div>
35
- <div class="_progress" [style.width]="value() * 100 + '%'"></div>
36
+ <div class="_progress" [style.width]="_barWidth()"></div>
36
37
  `, styles: ["sd-progress {\n position: relative;\n display: block;\n width: 100%;\n white-space: nowrap;\n background: var(--theme-gray-lightest);\n border: 1px solid var(--theme-gray-lightest);\n border-radius: var(--border-radius-default);\n overflow: hidden;\n}\nsd-progress > ._content {\n position: relative;\n z-index: 2;\n padding: var(--gap-lg) var(--gap-default);\n}\nsd-progress > ._progress {\n position: absolute;\n z-index: 1;\n top: 0;\n left: 0;\n height: 100%;\n}\nsd-progress[data-sd-theme=gray] > ._progress {\n background: var(--theme-gray-default);\n}\nsd-progress[data-sd-theme=blue-gray] > ._progress {\n background: var(--theme-blue-gray-default);\n}\nsd-progress[data-sd-theme=primary] > ._progress {\n background: var(--theme-primary-default);\n}\nsd-progress[data-sd-theme=secondary] > ._progress {\n background: var(--theme-secondary-default);\n}\nsd-progress[data-sd-theme=info] > ._progress {\n background: var(--theme-info-default);\n}\nsd-progress[data-sd-theme=success] > ._progress {\n background: var(--theme-success-default);\n}\nsd-progress[data-sd-theme=warning] > ._progress {\n background: var(--theme-warning-default);\n}\nsd-progress[data-sd-theme=danger] > ._progress {\n background: var(--theme-danger-default);\n}\nsd-progress[data-sd-size=sm] > ._content {\n padding: var(--gap-xs) var(--gap-default);\n}\nsd-progress[data-sd-size=lg] > ._content {\n padding: var(--gap-default) var(--gap-xl);\n}\nsd-progress[data-sd-inset=true] {\n border-radius: 0;\n border: none;\n background: var(--control-color);\n}"] }]
37
38
  }], null, { inset: [{ type: i0.Input, args: [{ isSignal: true, alias: "inset", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], theme: [{ type: i0.Input, args: [{ isSignal: true, alias: "theme", required: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }] }); })();
38
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SdProgressControl, { className: "SdProgressControl", filePath: "packages/angular/src/ui/visual/sd-progress.control.ts", lineNumber: 80 }); })();
39
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SdProgressControl, { className: "SdProgressControl", filePath: "packages/angular/src/ui/visual/sd-progress.control.ts", lineNumber: 81 }); })();
package/docs/providers.md CHANGED
@@ -343,7 +343,7 @@ Injectable. Available inside modal content components via DI. Provides access to
343
343
  class SdActivatedModalProvider<T extends ISdModal<any> = ISdModal<any>> {
344
344
  modalComponent: WritableSignal<any>;
345
345
  contentComponent: WritableSignal<T | undefined>;
346
- canDeactivefn: () => boolean;
346
+ canDeactiveFn: () => boolean;
347
347
  }
348
348
  ```
349
349
 
@@ -59,7 +59,7 @@ function setupModelHook<T, S extends WritableSignal<T>>(
59
59
 
60
60
  ## `setupCanDeactivate`
61
61
 
62
- Registers a route or modal can-deactivate guard. When inside a modal, sets `SdActivatedModalProvider.canDeactivefn`. When inside a route, pushes a `CanDeactivateFn` to the route config.
62
+ Registers a route or modal can-deactivate guard. When inside a modal, sets `SdActivatedModalProvider.canDeactiveFn`. When inside a route, pushes a `CanDeactivateFn` to the route config.
63
63
 
64
64
  ```typescript
65
65
  function setupCanDeactivate(fn: () => boolean): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simplysm/angular",
3
- "version": "14.0.6",
3
+ "version": "14.0.8",
4
4
  "description": "심플리즘 패키지 - Angular",
5
5
  "author": "심플리즘",
6
6
  "license": "Apache-2.0",
@@ -34,18 +34,15 @@
34
34
  "@ng-icons/core": "^33.2.0",
35
35
  "@ng-icons/tabler-icons": "^33.2.0",
36
36
  "@tiptap/core": "^3.21.0",
37
- "@tiptap/extension-bold": "^3.21.0",
38
37
  "@tiptap/extension-color": "^3.21.0",
39
38
  "@tiptap/extension-document": "^3.21.0",
39
+ "@tiptap/extension-paragraph": "^3.21.0",
40
+ "@tiptap/extension-text": "^3.21.0",
40
41
  "@tiptap/extension-highlight": "^3.21.0",
41
42
  "@tiptap/extension-image": "^3.21.0",
42
- "@tiptap/extension-paragraph": "^3.21.0",
43
43
  "@tiptap/extension-placeholder": "^3.21.0",
44
- "@tiptap/extension-text": "^3.21.0",
45
44
  "@tiptap/extension-text-align": "^3.21.0",
46
45
  "@tiptap/extension-text-style": "^3.21.0",
47
- "@tiptap/extension-underline": "^3.21.0",
48
- "@tiptap/pm": "^3.21.0",
49
46
  "@tiptap/starter-kit": "^3.21.0",
50
47
  "bwip-js": "^4.8.0",
51
48
  "echarts": "^6.0.0",
@@ -53,10 +50,10 @@
53
50
  "jspdf": "^4.2.1",
54
51
  "rxjs": "^7.8.2",
55
52
  "tabbable": "^6.4.0",
56
- "@simplysm/core-browser": "14.0.6",
57
- "@simplysm/core-common": "14.0.6",
58
- "@simplysm/service-client": "14.0.6",
59
- "@simplysm/service-common": "14.0.6"
53
+ "@simplysm/core-common": "14.0.8",
54
+ "@simplysm/service-common": "14.0.8",
55
+ "@simplysm/core-browser": "14.0.8",
56
+ "@simplysm/service-client": "14.0.8"
60
57
  },
61
58
  "devDependencies": {
62
59
  "@angular/compiler": "^21.2.6",
@@ -33,6 +33,9 @@ export class SdRouterLinkDirective {
33
33
 
34
34
  if (!option) return;
35
35
 
36
+ // Alt+click → 무시 (Chrome 표준: 다운로드, SPA에서는 해당 없음)
37
+ if (event.altKey) return;
38
+
36
39
  event.preventDefault();
37
40
  event.stopPropagation();
38
41
 
@@ -47,22 +50,11 @@ export class SdRouterLinkDirective {
47
50
  option.params,
48
51
  `width=${width},height=${height}`,
49
52
  );
50
- } else if (event.ctrlKey || event.altKey) {
51
- const qp = option.queryParams
52
- ? "?" + new URLSearchParams(option.queryParams).toString()
53
- : "";
54
- this._navWindow.open(option.link + qp, option.params, "_blank");
55
- } else if (event.shiftKey) {
56
- const width = option.window?.width ?? 800;
57
- const height = option.window?.height ?? 800;
53
+ } else if (event.ctrlKey || event.shiftKey) {
58
54
  const qp = option.queryParams
59
55
  ? "?" + new URLSearchParams(option.queryParams).toString()
60
56
  : "";
61
- this._navWindow.open(
62
- option.link + qp,
63
- option.params,
64
- `width=${width},height=${height}`,
65
- );
57
+ this._navWindow.open(option.link + qp, option.params);
66
58
  } else if (option.outletName === undefined) {
67
59
  await this._router.navigate(
68
60
  [option.link, ...(option.params ? [option.params] : [])],
@@ -45,6 +45,9 @@ export class SdResizeEventPlugin extends EventManagerPlugin {
45
45
  resizeObserver.observe(element);
46
46
 
47
47
  return (): void => {
48
+ if (animationFrameId != null) {
49
+ cancelAnimationFrame(animationFrameId);
50
+ }
48
51
  resizeObserver.disconnect();
49
52
  };
50
53
  }
@@ -12,6 +12,7 @@ import { SdSystemLogProvider } from "../providers/sd-system-log.provider";
12
12
  export class SdGlobalErrorHandlerPlugin implements ErrorHandler {
13
13
  private readonly _envInjector = inject(EnvironmentInjector);
14
14
  private readonly _systemLog = inject(SdSystemLogProvider);
15
+ private _hasDisplayedError = false;
15
16
 
16
17
  handleError(event: any) {
17
18
  try {
@@ -82,6 +83,9 @@ export class SdGlobalErrorHandlerPlugin implements ErrorHandler {
82
83
  }
83
84
 
84
85
  private _displayErrorMessage(title: string, param: Record<string, string>) {
86
+ if (this._hasDisplayedError) return;
87
+ this._hasDisplayedError = true;
88
+
85
89
  const paramLines = Object.keys(param).map((key) => key + ": " + param[key]);
86
90
 
87
91
  void this._systemLog.writeAsync("error", `[${title}]\n${paramLines.join("\n")}`);
@@ -48,6 +48,9 @@ export abstract class SdAppStructureUtils {
48
48
 
49
49
  static getTitleByFullCode<TModule>(items: TSdAppStructureItem<TModule>[], fullCode: string) {
50
50
  const itemChain = this.getItemChainByFullCode(items, fullCode);
51
+ if (itemChain.length === 0) {
52
+ throw new Error(`Item not found for fullCode: ${fullCode}`);
53
+ }
51
54
  const parent = itemChain
52
55
  .slice(0, -1)
53
56
  .map((item) => item.title)
@@ -72,7 +75,7 @@ export abstract class SdAppStructureUtils {
72
75
  else if (
73
76
  fullCodes.every((fullCode) => {
74
77
  const item = this.getItemChainByFullCode(items, fullCode).last();
75
- return !item || !("perms" in item);
78
+ return item != null && !("perms" in item);
76
79
  })
77
80
  ) {
78
81
  result.push(permKey);