@sd-angular/core 19.0.0-beta.8 → 19.0.0-beta.81
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +686 -33
- package/assets/scss/ckeditor5.scss +61 -4
- package/assets/scss/core/bootstrap.scss +17 -0
- package/assets/scss/core/form.scss +32 -6
- package/assets/scss/core/grid.scss +40 -0
- package/assets/scss/sd-core.scss +5 -0
- package/assets/scss/themes/material-theme.scss +82 -40
- package/components/anchor-v2/src/components/anchor-item-v2/anchor-item-v2.component.d.ts +5 -5
- package/components/anchor-v2/src/components/anchor-v2/anchor-v2.component.d.ts +12 -18
- package/components/anchor-v2/src/components/anchor-vertical-v2/anchor-vertical-list-v2.component.d.ts +9 -10
- package/components/anchor-v2/src/models/sd-anchor-v2.model.d.ts +3 -3
- package/components/avatar/index.d.ts +1 -0
- package/components/avatar/src/avatar.component.d.ts +19 -0
- package/components/badge/src/badge.component.d.ts +77 -19
- package/components/button/src/button.component.d.ts +30 -28
- package/components/chart/index.d.ts +4 -0
- package/components/chart/src/bar-chart.component.d.ts +18 -0
- package/components/chart/src/doughnut-chart.component.d.ts +16 -0
- package/components/chart/src/line-chart.component.d.ts +18 -0
- package/components/chart/src/pie-chart.component.d.ts +16 -0
- package/components/code-editor/index.d.ts +1 -0
- package/components/code-editor/src/code-editor.component.d.ts +25 -0
- package/components/document-builder/index.d.ts +1 -0
- package/components/document-builder/src/document-builder.component.d.ts +13 -42
- package/components/document-builder/src/document-builder.model.d.ts +15 -12
- package/components/document-builder/src/plugins/block-space/block-space.plugin.d.ts +9 -0
- package/components/document-builder/src/plugins/ck-comment/ck-comment.plugin.d.ts +44 -0
- package/components/document-builder/src/plugins/ck-comment/ck-comment.plugin.model.d.ts +57 -0
- package/components/document-builder/src/plugins/heading/heading.plugin.d.ts +1 -0
- package/components/document-builder/src/plugins/highlight-range/highlight-range.plugin.d.ts +4 -0
- package/components/document-builder/src/plugins/image-custom/image-custom.plugin.d.ts +31 -0
- package/components/document-builder/src/plugins/index.d.ts +7 -2
- package/components/document-builder/src/plugins/page-orientation/page-orientation.plugin.d.ts +2 -2
- package/components/document-builder/src/plugins/paste-handler/filters/bookmark.d.ts +14 -0
- package/components/document-builder/src/plugins/paste-handler/filters/br.d.ts +15 -0
- package/components/document-builder/src/plugins/paste-handler/filters/image.d.ts +25 -0
- package/components/document-builder/src/plugins/paste-handler/filters/list.d.ts +29 -0
- package/components/document-builder/src/plugins/paste-handler/filters/parse.d.ts +35 -0
- package/components/document-builder/src/plugins/paste-handler/filters/removeboldwrapper.d.ts +15 -0
- package/components/document-builder/src/plugins/paste-handler/filters/removegooglesheetstag.d.ts +15 -0
- package/components/document-builder/src/plugins/paste-handler/filters/removeinvalidtablewidth.d.ts +15 -0
- package/components/document-builder/src/plugins/paste-handler/filters/removemsattributes.d.ts +15 -0
- package/components/document-builder/src/plugins/paste-handler/filters/removestyleblock.d.ts +15 -0
- package/components/document-builder/src/plugins/paste-handler/filters/removexmlns.d.ts +15 -0
- package/components/document-builder/src/plugins/paste-handler/filters/replacemsfootnotes.d.ts +54 -0
- package/components/document-builder/src/plugins/paste-handler/filters/replacetabswithinprewithspaces.d.ts +24 -0
- package/components/document-builder/src/plugins/paste-handler/filters/space.d.ts +27 -0
- package/components/document-builder/src/plugins/paste-handler/filters/table.d.ts +16 -0
- package/components/document-builder/src/plugins/paste-handler/filters/utils.d.ts +25 -0
- package/components/document-builder/src/plugins/paste-handler/index.d.ts +35 -0
- package/components/document-builder/src/plugins/paste-handler/normalizers/googledocsnormalizer.d.ts +31 -0
- package/components/document-builder/src/plugins/paste-handler/normalizers/googlesheetsnormalizer.d.ts +31 -0
- package/components/document-builder/src/plugins/paste-handler/normalizers/mswordnormalizer.d.ts +29 -0
- package/components/document-builder/src/plugins/paste-handler/types.d.ts +30 -0
- package/components/document-builder/src/plugins/table-custom/index.d.ts +34 -0
- package/components/document-builder/src/plugins/variable/variable.plugin.d.ts +39 -0
- package/components/editor/index.d.ts +3 -0
- package/components/editor/src/configurations/editor.configuration.d.ts +12 -0
- package/components/editor/src/configurations/index.d.ts +1 -0
- package/components/editor/src/editor.component.d.ts +42 -0
- package/components/editor/src/models/editor.model.d.ts +8 -0
- package/components/editor/src/models/image-upload.plugin.model.d.ts +20 -0
- package/components/editor/src/models/index.d.ts +2 -0
- package/components/editor/src/plugins/image-upload/image-upload.plugin.d.ts +22 -0
- package/components/editor/src/plugins/image-upload/utils/batch.utils.d.ts +14 -0
- package/components/editor/src/plugins/image-upload/utils/index.d.ts +3 -0
- package/components/editor/src/plugins/image-upload/utils/style.utils.d.ts +2 -0
- package/components/editor/src/plugins/image-upload/utils/validate.utils.d.ts +3 -0
- package/components/index.d.ts +6 -0
- package/components/mini-editor/index.d.ts +2 -0
- package/components/mini-editor/src/mini-editor.component.d.ts +91 -0
- package/components/mini-editor/src/mini-editor.model.d.ts +44 -0
- package/components/modal/index.d.ts +1 -1
- package/components/modal/src/modal.component.d.ts +26 -0
- package/components/section/index.d.ts +1 -0
- package/components/section/src/section-item/section-item.component.d.ts +7 -0
- package/components/section/src/section.component.d.ts +11 -11
- package/components/side-drawer/src/side-drawer.component.d.ts +11 -24
- package/components/tab-router/src/components/tab-router-item/tab-router-item.component.d.ts +4 -1
- package/components/tab-router/src/components/tab-router-outlet/tab-router-outlet.component.d.ts +3 -15
- package/components/table/index.d.ts +2 -0
- package/components/table/src/components/column-filter/column-filter.component.d.ts +3 -3
- package/components/table/src/components/column-title/column-title.component.d.ts +10 -0
- package/components/table/src/components/desktop-cell/desktop-cell.component.d.ts +18 -11
- package/components/table/src/components/desktop-cell/view/view.component.d.ts +24 -0
- package/components/table/src/components/external-filter/external-filter.component.d.ts +1 -1
- package/components/table/src/components/index.d.ts +1 -0
- package/components/table/src/components/selector-action/action-filter.pipe.d.ts +11 -10
- package/components/table/src/components/selector-action/selector-action.component.d.ts +5 -3
- package/components/table/src/directives/index.d.ts +4 -0
- package/components/table/src/directives/sd-table-cell-def.directive.d.ts +2 -3
- package/components/table/src/directives/sd-table-column-filter-def.directive.d.ts +8 -0
- package/components/table/src/directives/sd-table-expand-def.directive.d.ts +0 -1
- package/components/table/src/directives/sd-table-filter-def.directive.d.ts +4 -6
- package/components/table/src/directives/sd-table-footer-def.directive.d.ts +2 -3
- package/components/table/src/directives/sd-table-title-def.directive.d.ts +8 -0
- package/components/table/src/directives/sticky-shadow.directive.d.ts +17 -0
- package/components/table/src/models/table-column.model.d.ts +49 -40
- package/components/table/src/models/table-command.model.d.ts +7 -3
- package/components/table/src/models/table-item.model.d.ts +5 -4
- package/components/table/src/models/table-option-config.model.d.ts +3 -0
- package/components/table/src/models/table-option-export.model.d.ts +3 -2
- package/components/table/src/models/table-option-selector.model.d.ts +17 -10
- package/components/table/src/models/table-option.model.d.ts +15 -8
- package/components/table/src/services/index.d.ts +3 -0
- package/components/table/src/services/table-export/table-export.service.d.ts +26 -0
- package/components/table/src/services/table-filter/table-filter.model.d.ts +6 -5
- package/components/table/src/services/table-format/table-format.service.d.ts +16 -0
- package/components/table/src/table.component.d.ts +46 -53
- package/components/upload-file/src/configurations/upload-file.configuration.d.ts +34 -1
- package/components/upload-file/src/services/upload-file.service.d.ts +0 -1
- package/components/upload-file/src/upload-file.component.d.ts +52 -54
- package/components/view/index.d.ts +1 -0
- package/components/view/src/view.component.d.ts +16 -0
- package/components/workflow/src/models/form-generic-component.model.d.ts +5 -4
- package/components/workflow/src/models/form-generic-expression.model.d.ts +1 -0
- package/components/workflow/src/models/index.d.ts +1 -0
- package/components/workflow/src/pipes/html.pipe.d.ts +4 -4
- package/directives/index.d.ts +2 -0
- package/directives/src/sd-href.directive.d.ts +9 -0
- package/directives/src/sd-tooltip.directive.d.ts +26 -0
- package/fesm2022/sd-angular-core-components-anchor-v2.mjs +79 -154
- package/fesm2022/sd-angular-core-components-anchor-v2.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-avatar.mjs +103 -0
- package/fesm2022/sd-angular-core-components-avatar.mjs.map +1 -0
- package/fesm2022/sd-angular-core-components-badge.mjs +101 -91
- package/fesm2022/sd-angular-core-components-badge.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-button.mjs +70 -96
- package/fesm2022/sd-angular-core-components-button.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-chart.mjs +290 -0
- package/fesm2022/sd-angular-core-components-chart.mjs.map +1 -0
- package/fesm2022/sd-angular-core-components-code-editor.mjs +127 -0
- package/fesm2022/sd-angular-core-components-code-editor.mjs.map +1 -0
- package/fesm2022/sd-angular-core-components-document-builder.mjs +4005 -611
- package/fesm2022/sd-angular-core-components-document-builder.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-editor.mjs +933 -0
- package/fesm2022/sd-angular-core-components-editor.mjs.map +1 -0
- package/fesm2022/sd-angular-core-components-history.mjs +1 -1
- package/fesm2022/sd-angular-core-components-history.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-import-excel.mjs +1 -1
- package/fesm2022/sd-angular-core-components-import-excel.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-mini-editor.mjs +332 -0
- package/fesm2022/sd-angular-core-components-mini-editor.mjs.map +1 -0
- package/fesm2022/sd-angular-core-components-modal.mjs +63 -92
- package/fesm2022/sd-angular-core-components-modal.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-preview.mjs +1 -1
- package/fesm2022/sd-angular-core-components-preview.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-quick-action.mjs +2 -2
- package/fesm2022/sd-angular-core-components-quick-action.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-section.mjs +41 -43
- package/fesm2022/sd-angular-core-components-section.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-side-drawer.mjs +78 -84
- package/fesm2022/sd-angular-core-components-side-drawer.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-tab-router.mjs +151 -241
- package/fesm2022/sd-angular-core-components-tab-router.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-table.mjs +1394 -1254
- package/fesm2022/sd-angular-core-components-table.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-upload-file.mjs +390 -443
- package/fesm2022/sd-angular-core-components-upload-file.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-view.mjs +45 -0
- package/fesm2022/sd-angular-core-components-view.mjs.map +1 -0
- package/fesm2022/sd-angular-core-components-workflow.mjs +165 -168
- package/fesm2022/sd-angular-core-components-workflow.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components.mjs +6 -0
- package/fesm2022/sd-angular-core-components.mjs.map +1 -1
- package/fesm2022/sd-angular-core-directives.mjs +286 -27
- package/fesm2022/sd-angular-core-directives.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-autocomplete.mjs +289 -363
- package/fesm2022/sd-angular-core-forms-autocomplete.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-chip-calendar.mjs +170 -189
- package/fesm2022/sd-angular-core-forms-chip-calendar.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-chip.mjs +184 -194
- package/fesm2022/sd-angular-core-forms-chip.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-date-range.mjs +180 -242
- package/fesm2022/sd-angular-core-forms-date-range.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-date.mjs +178 -270
- package/fesm2022/sd-angular-core-forms-date.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-datetime.mjs +177 -285
- package/fesm2022/sd-angular-core-forms-datetime.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-input-number.mjs +210 -337
- package/fesm2022/sd-angular-core-forms-input-number.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-input.mjs +169 -286
- package/fesm2022/sd-angular-core-forms-input.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-radio.mjs +3 -2
- package/fesm2022/sd-angular-core-forms-radio.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-select.mjs +390 -447
- package/fesm2022/sd-angular-core-forms-select.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-textarea.mjs +167 -226
- package/fesm2022/sd-angular-core-forms-textarea.mjs.map +1 -1
- package/fesm2022/sd-angular-core-modules-authom.mjs +359 -0
- package/fesm2022/sd-angular-core-modules-authom.mjs.map +1 -0
- package/fesm2022/sd-angular-core-modules-keycloak.mjs +126 -0
- package/fesm2022/sd-angular-core-modules-keycloak.mjs.map +1 -0
- package/fesm2022/sd-angular-core-modules-layout.mjs +709 -456
- package/fesm2022/sd-angular-core-modules-layout.mjs.map +1 -1
- package/fesm2022/sd-angular-core-modules-permission.mjs +160 -74
- package/fesm2022/sd-angular-core-modules-permission.mjs.map +1 -1
- package/fesm2022/sd-angular-core-modules.mjs +2 -1
- package/fesm2022/sd-angular-core-modules.mjs.map +1 -1
- package/fesm2022/sd-angular-core-services-api.mjs +5 -10
- package/fesm2022/sd-angular-core-services-api.mjs.map +1 -1
- package/fesm2022/sd-angular-core-services-confirm.mjs +9 -7
- package/fesm2022/sd-angular-core-services-confirm.mjs.map +1 -1
- package/fesm2022/sd-angular-core-services-docx.mjs +173 -0
- package/fesm2022/sd-angular-core-services-docx.mjs.map +1 -0
- package/fesm2022/sd-angular-core-services-notify.mjs +2 -2
- package/fesm2022/sd-angular-core-services-notify.mjs.map +1 -1
- package/fesm2022/sd-angular-core-services.mjs +1 -0
- package/fesm2022/sd-angular-core-services.mjs.map +1 -1
- package/fesm2022/sd-angular-core-utilities-extensions.mjs +58 -80
- package/fesm2022/sd-angular-core-utilities-extensions.mjs.map +1 -1
- package/fesm2022/sd-angular-core-utilities-models.mjs +15 -1
- package/fesm2022/sd-angular-core-utilities-models.mjs.map +1 -1
- package/fesm2022/sd-angular-core.mjs +0 -1
- package/fesm2022/sd-angular-core.mjs.map +1 -1
- package/forms/autocomplete/src/autocomplete.component.d.ts +55 -55
- package/forms/chip/src/chip.component.d.ts +37 -40
- package/forms/chip-calendar/src/chip-calendar.component.d.ts +37 -38
- package/forms/date/src/date.component.d.ts +48 -46
- package/forms/date-range/src/date-range.component.d.ts +35 -34
- package/forms/datetime/src/datetime.component.d.ts +48 -49
- package/forms/input/src/input.component.d.ts +54 -57
- package/forms/input-number/src/input-number.component.d.ts +53 -54
- package/forms/select/src/select.component.d.ts +67 -64
- package/forms/textarea/src/textarea.component.d.ts +40 -43
- package/modules/authom/authom.configuration.d.ts +17 -0
- package/modules/authom/authom.interceptor.d.ts +3 -0
- package/modules/authom/authom.module.d.ts +16 -0
- package/modules/authom/authom.service.d.ts +32 -0
- package/modules/authom/index.d.ts +35 -0
- package/modules/index.d.ts +2 -1
- package/modules/keycloak/index.d.ts +4 -0
- package/modules/keycloak/keycloak.configuration.d.ts +11 -0
- package/modules/keycloak/keycloak.interceptor.d.ts +2 -0
- package/modules/keycloak/keycloak.module.d.ts +18 -0
- package/modules/keycloak/keycloak.service.d.ts +14 -0
- package/modules/layout/components/index.d.ts +2 -0
- package/modules/layout/components/layout-main/layout-main.component.d.ts +8 -12
- package/modules/layout/components/page/page.component.d.ts +5 -7
- package/modules/layout/components/sidebar-mobile-v1/components/sidebar/sidebar.component.d.ts +35 -0
- package/modules/layout/components/sidebar-mobile-v1/components/user/user.component.d.ts +24 -0
- package/modules/layout/components/sidebar-mobile-v1/main.component.d.ts +21 -0
- package/modules/layout/components/sidebar-v1/components/sidebar/sidebar.component.d.ts +22 -29
- package/modules/layout/components/sidebar-v1/components/user/user.component.d.ts +11 -17
- package/modules/layout/components/sidebar-v1/main.component.d.ts +14 -14
- package/modules/layout/configurations/layout.configuration.d.ts +46 -3
- package/modules/layout/modules/forbidden/pages/root/root.component.d.ts +3 -8
- package/modules/layout/modules/home/components/home-page/home-page.component.d.ts +2 -5
- package/modules/layout/modules/not-found/pages/root/root.component.d.ts +3 -8
- package/modules/layout/pipes/high-light-search.pipe.d.ts +1 -1
- package/modules/layout/services/index.d.ts +1 -0
- package/modules/layout/services/layout.service.d.ts +10 -0
- package/modules/layout/services/menu/menu.model.d.ts +4 -1
- package/modules/layout/services/storage/storage.service.d.ts +0 -3
- package/modules/permission/src/configurations/permission.configuration.d.ts +56 -2
- package/modules/permission/src/directives/permission.directive.d.ts +5 -8
- package/modules/permission/src/guards/permission.guard.d.ts +2 -1
- package/modules/permission/src/services/permission.service.d.ts +6 -9
- package/package.json +107 -79
- package/public-api.d.ts +0 -1
- package/sd-angular-core-19.0.0-beta.81.tgz +0 -0
- package/services/api/src/api.model.d.ts +6 -1
- package/services/confirm/src/lib/confirm.service.d.ts +5 -0
- package/services/docx/index.d.ts +1 -0
- package/services/docx/src/lib/docx.model.d.ts +9 -0
- package/services/docx/src/lib/docx.service.d.ts +13 -0
- package/services/docx/src/public-api.d.ts +2 -0
- package/services/index.d.ts +1 -0
- package/services/notify/index.d.ts +1 -0
- package/services/notify/src/notify.model.d.ts +1 -1
- package/services/notify/src/notify.service.d.ts +5 -5
- package/utilities/extensions/src/string.extension.d.ts +3 -0
- package/utilities/extensions/src/utility.extension.d.ts +1 -0
- package/utilities/models/index.d.ts +3 -0
- package/utilities/models/src/filter.model.d.ts +17 -4
- package/utilities/models/src/icon.model.d.ts +2 -0
- package/utilities/models/src/nested-key-of.model.d.ts +5 -0
- package/utilities/models/src/order.model.d.ts +2 -1
- package/utilities/models/src/paging.model.d.ts +2 -1
- package/utilities/models/src/pattern.model.d.ts +1 -1
- package/utilities/models/src/unwrap-signal.model.d.ts +6 -0
- package/components/document-builder/src/plugins/comment/comment.plugin.d.ts +0 -4
- package/components/document-builder/src/plugins/table-fit/table-fit.plugin.d.ts +0 -4
- package/components/modal/src/modal/modal.component.d.ts +0 -31
- package/components/table/src/components/desktop-cell-view/desktop-cell-view.component.d.ts +0 -14
- package/fesm2022/sd-angular-core-guards-permission.mjs +0 -155
- package/fesm2022/sd-angular-core-guards-permission.mjs.map +0 -1
- package/fesm2022/sd-angular-core-guards.mjs +0 -6
- package/fesm2022/sd-angular-core-guards.mjs.map +0 -1
- package/fesm2022/sd-angular-core-modules-oidc.mjs +0 -127
- package/fesm2022/sd-angular-core-modules-oidc.mjs.map +0 -1
- package/guards/index.d.ts +0 -1
- package/guards/permission/index.d.ts +0 -4
- package/guards/permission/src/configurations/index.d.ts +0 -1
- package/guards/permission/src/configurations/permission.configuration.d.ts +0 -8
- package/guards/permission/src/directives/index.d.ts +0 -1
- package/guards/permission/src/directives/permission.directive.d.ts +0 -12
- package/guards/permission/src/guards/index.d.ts +0 -1
- package/guards/permission/src/guards/permission.guard.d.ts +0 -13
- package/guards/permission/src/services/index.d.ts +0 -1
- package/guards/permission/src/services/permission.service.d.ts +0 -15
- package/modules/oidc/dynamic-sts.loader.d.ts +0 -11
- package/modules/oidc/index.d.ts +0 -2
- package/modules/oidc/oidc.configuration.d.ts +0 -11
- package/modules/oidc/oidc.module.d.ts +0 -14
- package/sd-angular-core-19.0.0-beta.8.tgz +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sd-angular-core-components-mini-editor.mjs","sources":["../../../projects/sd-angular/components/mini-editor/src/mini-editor.component.ts","../../../projects/sd-angular/components/mini-editor/src/mini-editor.component.html","../../../projects/sd-angular/components/mini-editor/sd-angular-core-components-mini-editor.ts"],"sourcesContent":["import { CommonModule } from '@angular/common';\r\nimport { Component, EventEmitter, HostBinding, Input, Output, forwardRef } from '@angular/core';\r\nimport { CKEditorModule } from '@ckeditor/ckeditor5-angular';\r\nimport {\r\n Bold,\r\n ClassicEditor,\r\n Essentials,\r\n Italic,\r\n Link,\r\n List,\r\n FontColor,\r\n Markdown,\r\n Mention,\r\n Paragraph,\r\n Underline,\r\n Undo,\r\n Widget,\r\n} from 'ckeditor5';\r\nimport { Subject, Subscription } from 'rxjs';\r\nimport { throttleTime } from 'rxjs/operators';\r\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\r\n\r\nimport { SdMiniEditorOption, SdMiniEditorConfig, SdMiniEditorMentionItem } from './mini-editor.model';\r\n\r\n/**\r\n * Component sd-mini-editor - Editor đơn giản cho comment input\r\n * Sử dụng CKEditor với chế độ đơn giản (bold, italic, link)\r\n * Hỗ trợ mention và output format (html/markdown)\r\n *\r\n * @example\r\n * ```html\r\n * <sd-mini-editor\r\n * [option]=\"editorOption\"\r\n * [(ngModel)]=\"content\"\r\n * (contentChange)=\"onContentChange($event)\"\r\n * >\r\n * </sd-mini-editor>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'sd-mini-editor',\r\n standalone: true,\r\n imports: [CommonModule, CKEditorModule],\r\n templateUrl: './mini-editor.component.html',\r\n styleUrls: ['./mini-editor.component.scss'],\r\n providers: [\r\n {\r\n provide: NG_VALUE_ACCESSOR,\r\n useExisting: forwardRef(() => SdMiniEditor),\r\n multi: true,\r\n },\r\n ],\r\n})\r\nexport class SdMiniEditor implements ControlValueAccessor {\r\n /** Cấu hình option cho editor */\r\n @Input({ required: true }) option!: SdMiniEditorOption;\r\n\r\n @HostBinding('style.--sd-mini-editor-max-height')\r\n get maxEditorHeight(): string | undefined {\r\n return this.option?.maxHeight;\r\n }\r\n\r\n /** NgModel binding - nội dung HTML/Markdown */\r\n @Input() value = '';\r\n @Output() valueChange = new EventEmitter<string>();\r\n\r\n /** Event emitter khi content thay đổi */\r\n @Output() contentChange = new EventEmitter<string>();\r\n\r\n /** Event emitter khi blur */\r\n @Output() blur = new EventEmitter<FocusEvent>();\r\n\r\n /** Event emitter khi focus */\r\n @Output() focus = new EventEmitter<FocusEvent>();\r\n\r\n /** Disabled state */\r\n @Input() disabled = false;\r\n\r\n Editor = ClassicEditor;\r\n #editor!: ClassicEditor;\r\n #subscription = new Subscription();\r\n #contentChangeSubject = new Subject<string>();\r\n\r\n // Build editor config dynamically\r\n get editorConfig(): SdMiniEditorConfig {\r\n const enableMention = this.option?.enableMention ?? false;\r\n const useMarkdown = this.option?.outputFormat === 'markdown';\r\n const plugins: any[] = [Essentials, FontColor, Paragraph, Bold, Italic, Underline, Link, List, Undo, Widget];\r\n\r\n // Add Markdown plugin if outputFormat is markdown\r\n if (useMarkdown) {\r\n plugins.push(Markdown);\r\n }\r\n\r\n // Add Mention plugin if enabled\r\n if (enableMention) {\r\n plugins.push(Mention);\r\n }\r\n\r\n // Build base config\r\n const config: SdMiniEditorConfig = {\r\n licenseKey: 'GPL',\r\n getOption: () => this.option,\r\n plugins,\r\n toolbar: {\r\n items: ['bold', 'italic', 'underline', '|', 'fontColor', '|', 'bulletedList', 'numberedList', '|', 'link'],\r\n shouldNotGroupWhenFull: true,\r\n },\r\n placeholder: this.option?.placeholder,\r\n link: {\r\n addTargetToExternalLinks: true,\r\n defaultProtocol: 'https://',\r\n },\r\n fontColor: {\r\n columns: 5,\r\n documentColors: 10,\r\n colorPicker: { format: 'hex' },\r\n },\r\n };\r\n\r\n // Add mention configuration if enabled\r\n if (enableMention && this.option?.mentionConfig?.feeds) {\r\n config.mention = {\r\n feeds: this.option.mentionConfig.feeds,\r\n };\r\n }\r\n\r\n return config;\r\n }\r\n\r\n constructor() {\r\n // Setup debounce cho content change\r\n this.#subscription.add(\r\n this.#contentChangeSubject.pipe(throttleTime(500, undefined, { leading: true, trailing: true })).subscribe(content => {\r\n const output = this.#convertOutput(content);\r\n this.value = output;\r\n this.#onChange(output);\r\n this.valueChange.emit(output);\r\n this.contentChange.emit(output);\r\n this.option?.onChange?.(output);\r\n })\r\n );\r\n }\r\n\r\n ngOnDestroy() {\r\n this.#subscription.unsubscribe();\r\n this.#editor?.destroy?.();\r\n }\r\n\r\n /**\r\n * Kiểm tra có nên enable mention plugin không\r\n */\r\n #shouldEnableMention(): boolean {\r\n return this.option?.enableMention ?? false;\r\n }\r\n\r\n /**\r\n * Xử lý khi editor ready\r\n */\r\n onReady(editor: ClassicEditor) {\r\n this.#editor = editor;\r\n\r\n // Set initial content\r\n if (this.value) {\r\n this.setContent(this.value);\r\n }\r\n\r\n // Lắng nghe sự kiện thay đổi nội dung\r\n editor.model.document.on('change:data', () => {\r\n const content = editor.getData();\r\n this.#contentChangeSubject.next(content);\r\n });\r\n\r\n // Lắng nghe focus/blur events\r\n editor.editing.view.document.on('focus', evt => {\r\n const domEvent = (evt as any).domEvent as FocusEvent;\r\n this.focus.emit(domEvent);\r\n this.option?.onFocus?.(domEvent);\r\n });\r\n\r\n editor.editing.view.document.on('blur', evt => {\r\n const domEvent = (evt as any).domEvent as FocusEvent;\r\n this.blur.emit(domEvent);\r\n this.option?.onBlur?.(domEvent);\r\n });\r\n\r\n // Lắng nghe sự kiện mention được chọn\r\n if (this.#shouldEnableMention()) {\r\n editor.commands.get('mention')?.on('execute', (_evt, data: any) => {\r\n const mentionData = data[0];\r\n this.option?.onMentionSelect?.(mentionData.mention);\r\n // Trigger content change sau khi insert mention\r\n const content = editor.getData();\r\n this.#contentChangeSubject.next(content);\r\n });\r\n\r\n // Custom downcast converter để thay đổi cấu trúc mention HTML\r\n editor.conversion.for('downcast').attributeToElement({\r\n model: 'mention',\r\n view: (mentionData, { writer }) => {\r\n const data = mentionData as SdMiniEditorMentionItem;\r\n const rawId = data?.id || '';\r\n const marker = rawId[0];\r\n const cleanId = rawId.slice(1);\r\n\r\n return writer.createAttributeElement('span', {\r\n class: 'ck-custom-mention',\r\n 'data-id': cleanId,\r\n 'data-marker': marker,\r\n contenteditable: 'false',\r\n });\r\n },\r\n converterPriority: 'highest',\r\n });\r\n\r\n // Xử lý keyboard để xóa mention 1 lần\r\n editor.editing.view.document.on('keydown', (evt, data) => {\r\n const keyEvent = data as { keyCode: number; domEvent: KeyboardEvent };\r\n // Delete (46) hoặc Backspace (8)\r\n if (keyEvent.keyCode === 46 || keyEvent.keyCode === 8) {\r\n const model = editor.model;\r\n const selection = model.document.selection;\r\n const position = selection.getFirstPosition();\r\n if (!position) return;\r\n\r\n // Tìm text node có mention attribute\r\n const node = position.textNode || position.nodeBefore || position.nodeAfter;\r\n if (node && node.is('$text')) {\r\n const mentionAttr = node.getAttribute('mention');\r\n if (mentionAttr) {\r\n // Xóa toàn bộ text node chứa mention\r\n model.change(writer => {\r\n writer.remove(node);\r\n });\r\n evt.stop();\r\n }\r\n }\r\n }\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Convert output theo format (html hoặc markdown)\r\n * Khi sử dụng CKEditor Markdown plugin, getData() tự động trả về Markdown\r\n */\r\n #convertOutput(content: string): string {\r\n // CKEditor Markdown plugin tự động xử lý conversion\r\n // Không cần manual conversion nữa\r\n return content;\r\n }\r\n\r\n /**\r\n * Set nội dung cho editor\r\n */\r\n setContent(content: string) {\r\n this.#editor?.setData?.(content);\r\n }\r\n\r\n /**\r\n * Get nội dung từ editor\r\n */\r\n getContent(): string {\r\n if (this.#editor) {\r\n const html = this.#editor.getData();\r\n return this.#convertOutput(html);\r\n }\r\n return '';\r\n }\r\n\r\n /**\r\n * Get nội dung HTML gốc (không convert)\r\n */\r\n getHtmlContent(): string {\r\n return this.#editor?.getData?.() || '';\r\n }\r\n\r\n /**\r\n * Focus vào editor\r\n */\r\n focusEditor() {\r\n this.#editor?.editing?.view?.focus?.();\r\n }\r\n\r\n /**\r\n * Insert mention vào vị trí con trỏ hiện tại\r\n */\r\n insertMention(item: { id: string; name: string; marker?: string }) {\r\n if (!this.#editor) return;\r\n\r\n const firstFeed = this.option?.mentionConfig?.feeds?.[0];\r\n const marker = item.marker || (firstFeed as any)?.marker || '@';\r\n\r\n // Sử dụng CKEditor mention command\r\n this.#editor.execute('mention', {\r\n marker,\r\n mention: {\r\n id: item.id,\r\n text: `${marker}${item.name}`,\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Get danh sách mentions trong nội dung\r\n */\r\n getMentions(): Array<{ id: string; name: string; marker: string }> {\r\n if (!this.#editor) return [];\r\n\r\n const mentions: Array<{ id: string; name: string; marker: string }> = [];\r\n const root = this.#editor.model.document.getRoot();\r\n if (!root) return mentions;\r\n\r\n const range = this.#editor.model.createRangeIn(root);\r\n\r\n for (const item of range.getItems()) {\r\n if (item.is('$text')) {\r\n const mentionAttr = item.getAttribute('mention');\r\n if (mentionAttr) {\r\n const text = (item as any).data as string;\r\n const marker = text.charAt(0);\r\n const name = text.substring(1);\r\n const id = item.getAttribute('data-user-id') as string;\r\n\r\n mentions.push({ id, name, marker });\r\n }\r\n }\r\n }\r\n\r\n return mentions;\r\n }\r\n\r\n /**\r\n * ControlValueAccessor: Write value\r\n */\r\n writeValue(value: string): void {\r\n this.value = value || '';\r\n if (this.#editor) {\r\n this.setContent(this.value);\r\n }\r\n }\r\n\r\n /**\r\n * ControlValueAccessor: Register change callback\r\n */\r\n registerOnChange(fn: (value: string) => void): void {\r\n this.#onChange = fn;\r\n }\r\n\r\n /**\r\n * ControlValueAccessor: Register touched callback\r\n */\r\n registerOnTouched(fn: () => void): void {\r\n this.#onTouched = fn;\r\n }\r\n\r\n /** ControlValueAccessor callbacks */\r\n #onChange: (value: string) => void = () => {};\r\n #onTouched: () => void = () => {};\r\n}\r\n","<ckeditor class=\"sd-mini-editor\" [editor]=\"Editor\" [config]=\"editorConfig\" [disabled]=\"disabled\" (ready)=\"onReady($event)\"> </ckeditor>\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -1,127 +1,98 @@
|
|
|
1
1
|
import { CommonModule } from '@angular/common';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import { MatBottomSheetModule } from '@angular/material/bottom-sheet';
|
|
3
|
+
import { signal, viewChild, input, booleanAttribute, output, inject, DestroyRef, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
4
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
5
|
+
import { MatBottomSheet, MatBottomSheetModule } from '@angular/material/bottom-sheet';
|
|
6
6
|
import { MatButtonModule } from '@angular/material/button';
|
|
7
|
-
import
|
|
8
|
-
import { MatDialogModule } from '@angular/material/dialog';
|
|
7
|
+
import { MatDialog, MatDialogModule } from '@angular/material/dialog';
|
|
9
8
|
import { MatDividerModule } from '@angular/material/divider';
|
|
10
|
-
import * as
|
|
9
|
+
import * as i1 from '@angular/material/icon';
|
|
11
10
|
import { MatIconModule } from '@angular/material/icon';
|
|
12
11
|
import { SdUtilities } from '@sd-angular/core/utilities';
|
|
13
|
-
import { Subscription } from 'rxjs';
|
|
14
12
|
|
|
15
13
|
class SdModal {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
isOpened = false;
|
|
30
|
-
alreadyOpened = false;
|
|
14
|
+
static index = signal(0);
|
|
15
|
+
templateRef = viewChild.required('templateRef');
|
|
16
|
+
modal = viewChild('modal');
|
|
17
|
+
title = input('', { transform: (v) => v ?? '' });
|
|
18
|
+
color = input('primary', { transform: (v) => v ?? 'primary' });
|
|
19
|
+
width = input('md', { transform: (v) => v ?? 'md' });
|
|
20
|
+
height = input('auto', { transform: (v) => v ?? 'auto' });
|
|
21
|
+
view = input(undefined, { transform: (v) => v ?? undefined });
|
|
22
|
+
modalClass = input('', { transform: (v) => v ?? '' });
|
|
23
|
+
lazyLoadContent = input(true, { transform: booleanAttribute });
|
|
24
|
+
hideClose = input(false, { transform: booleanAttribute });
|
|
25
|
+
disableBackdropClose = input(true, { transform: booleanAttribute }); // default to true to keep backward compatibility
|
|
26
|
+
sdClosed = output();
|
|
27
|
+
isOpened = signal(false);
|
|
28
|
+
alreadyOpened = signal(false);
|
|
31
29
|
#isMobile = false;
|
|
30
|
+
#resolvedWidth = 'md';
|
|
32
31
|
#bottomSheetRef;
|
|
33
32
|
#dialogRef;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
this.bottomSheet = bottomSheet;
|
|
33
|
+
#dialog = inject(MatDialog);
|
|
34
|
+
#bottomSheet = inject(MatBottomSheet);
|
|
35
|
+
#destroyRef = inject(DestroyRef);
|
|
36
|
+
constructor() {
|
|
39
37
|
this.#isMobile = SdUtilities.isMobile();
|
|
40
38
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if (
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
case 'sm':
|
|
52
|
-
this.width = '40vw';
|
|
53
|
-
break;
|
|
54
|
-
case 'sx':
|
|
55
|
-
this.width = '20vw';
|
|
56
|
-
break;
|
|
57
|
-
}
|
|
39
|
+
#resolveWidth() {
|
|
40
|
+
const w = this.width() || '80vw';
|
|
41
|
+
if (this.#isMobile)
|
|
42
|
+
return w;
|
|
43
|
+
switch (w) {
|
|
44
|
+
case 'lg': return '80vw';
|
|
45
|
+
case 'md': return '60vw';
|
|
46
|
+
case 'sm': return '40vw';
|
|
47
|
+
case 'sx': return '20vw';
|
|
48
|
+
default: return w;
|
|
58
49
|
}
|
|
59
50
|
}
|
|
60
|
-
ngOnDestroy() {
|
|
61
|
-
this.subcription.unsubscribe();
|
|
62
|
-
}
|
|
63
51
|
open = () => {
|
|
64
|
-
if (this.isOpened) {
|
|
52
|
+
if (this.isOpened()) {
|
|
65
53
|
return;
|
|
66
54
|
}
|
|
67
|
-
this.
|
|
68
|
-
this.
|
|
69
|
-
this
|
|
70
|
-
if ((!this.view && this.#isMobile) || this.view === 'bottom-sheet') {
|
|
71
|
-
this.#bottomSheetRef = this
|
|
72
|
-
|
|
73
|
-
this.
|
|
55
|
+
this.alreadyOpened.set(true);
|
|
56
|
+
this.isOpened.set(true);
|
|
57
|
+
this.#resolvedWidth = this.#resolveWidth();
|
|
58
|
+
if ((!this.view() && this.#isMobile) || this.view() === 'bottom-sheet') {
|
|
59
|
+
this.#bottomSheetRef = this.#bottomSheet.open(this.templateRef(), {
|
|
60
|
+
panelClass: this.modalClass(),
|
|
61
|
+
disableClose: this.disableBackdropClose()
|
|
62
|
+
});
|
|
63
|
+
this.#bottomSheetRef.afterDismissed()
|
|
64
|
+
.pipe(takeUntilDestroyed(this.#destroyRef))
|
|
65
|
+
.subscribe(() => {
|
|
66
|
+
this.isOpened.set(false);
|
|
74
67
|
this.sdClosed.emit();
|
|
75
|
-
})
|
|
68
|
+
});
|
|
76
69
|
}
|
|
77
70
|
else {
|
|
78
|
-
this.#dialogRef = this
|
|
79
|
-
width: this
|
|
80
|
-
maxWidth: this
|
|
81
|
-
|
|
71
|
+
this.#dialogRef = this.#dialog.open(this.templateRef(), {
|
|
72
|
+
width: this.#resolvedWidth,
|
|
73
|
+
maxWidth: this.#resolvedWidth,
|
|
74
|
+
panelClass: this.modalClass(),
|
|
75
|
+
disableClose: this.disableBackdropClose(),
|
|
82
76
|
});
|
|
83
|
-
this
|
|
84
|
-
this
|
|
77
|
+
this.#dialogRef.afterClosed()
|
|
78
|
+
.pipe(takeUntilDestroyed(this.#destroyRef))
|
|
79
|
+
.subscribe(() => {
|
|
80
|
+
this.isOpened.set(false);
|
|
85
81
|
this.sdClosed.emit();
|
|
86
|
-
})
|
|
82
|
+
});
|
|
87
83
|
}
|
|
88
84
|
};
|
|
89
85
|
close = () => {
|
|
90
|
-
this.ref.markForCheck();
|
|
91
86
|
this.#bottomSheetRef?.dismiss();
|
|
92
87
|
this.#dialogRef?.close();
|
|
93
88
|
};
|
|
94
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdModal, deps: [
|
|
95
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: SdModal, isStandalone: true, selector: "sd-modal", inputs: { title: "title", color: "color", width: "width", height: "height", view: "view", lazyLoadContent: "lazyLoadContent" }, outputs: { sdClosed: "sdClosed" }, viewQueries: [{ propertyName: "templateRef", first: true, predicate: ["templateRef"], descendants: true }, { propertyName: "modal", first: true, predicate: ["modal"], descendants: true }], ngImport: i0, template: "<ng-template #templateRef>\r\n @if (!lazyLoadContent || alreadyOpened) {\r\n <!-- Header -->\r\n <!-- D\u00F9ng scss thu\u1EA7n -->\r\n @if (title) {\r\n <div class=\"d-flex align-items-center p-16\">\r\n <div class=\"T18M\">{{ title }}</div>\r\n <div class=\"d-flex align-items-center ml-auto\">\r\n <ng-content select=\"[sdHeader]\"></ng-content>\r\n <mat-icon class=\"text-secondary pointer\" fontIcon=\"close\" (click)=\"close()\"></mat-icon>\r\n </div>\r\n </div>\r\n }\r\n <!-- <mat-divider></mat-divider> -->\r\n <!-- Body -->\r\n <div class=\"overflow-auto w-full px-16\" style=\"max-height: 80vh
|
|
89
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdModal, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
90
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: SdModal, isStandalone: true, selector: "sd-modal", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: false, transformFunction: null }, modalClass: { classPropertyName: "modalClass", publicName: "modalClass", isSignal: true, isRequired: false, transformFunction: null }, lazyLoadContent: { classPropertyName: "lazyLoadContent", publicName: "lazyLoadContent", isSignal: true, isRequired: false, transformFunction: null }, hideClose: { classPropertyName: "hideClose", publicName: "hideClose", isSignal: true, isRequired: false, transformFunction: null }, disableBackdropClose: { classPropertyName: "disableBackdropClose", publicName: "disableBackdropClose", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sdClosed: "sdClosed" }, viewQueries: [{ propertyName: "templateRef", first: true, predicate: ["templateRef"], descendants: true, isSignal: true }, { propertyName: "modal", first: true, predicate: ["modal"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-template #templateRef>\r\n @if (!lazyLoadContent() || alreadyOpened()) {\r\n <!-- Header -->\r\n <!-- D\u00F9ng scss thu\u1EA7n -->\r\n @if (title()) {\r\n <div class=\"d-flex align-items-center p-16\">\r\n <ng-content select=\"[sdHeaderLeft]\">\r\n <div class=\"T18M\">{{ title() }}</div>\r\n </ng-content>\r\n <div class=\"d-flex align-items-center ml-auto\">\r\n <ng-content select=\"[sdHeaderRight]\"></ng-content>\r\n <ng-content select=\"[sdHeader]\"></ng-content>\r\n @if (!hideClose()) {\r\n <mat-icon class=\"text-secondary pointer\" fontIcon=\"close\" (click)=\"close()\"></mat-icon>\r\n }\r\n </div>\r\n </div>\r\n }\r\n <!-- <mat-divider></mat-divider> -->\r\n <!-- Body -->\r\n <div class=\"overflow-auto w-full px-16\" style=\"max-height: 80vh\">\r\n <ng-content></ng-content>\r\n </div>\r\n <!-- Footer -->\r\n <!-- <mat-divider></mat-divider> -->\r\n <div class=\"d-flex align-items-center p-8\" #footer>\r\n <ng-content select=\"[sdFooterLeft]\"></ng-content>\r\n <div class=\"ml-auto\">\r\n <ng-content select=\"[sdFooterRight]\"></ng-content>\r\n <ng-content select=\"[sdFooter]\"></ng-content>\r\n </div>\r\n </div>\r\n }\r\n</ng-template>\r\n\r\n<!-- <ng-template #templateRef>\r\n @if(!lazyLoadContent || alreadyOpened) {\r\n <sd-modal-header *ngIf=\"title\">\r\n <span [innerHtml]=\"title\"></span>\r\n <div class=\"d-flex align-items-center\">\r\n <ng-content select=\"[sdModalHeaderRight]\"></ng-content>\r\n <button type=\"button\" (click)=\"close()\" mat-icon-button>\r\n <mat-icon fontIcon=\"close\"></mat-icon>\r\n </button>\r\n </div>\r\n </sd-modal-header>\r\n }\r\n <ng-container *ngIf=\"!lazyLoadContent || alreadyOpened\">\r\n <sd-modal-header *ngIf=\"title\">\r\n <span [innerHtml]=\"title\"></span>\r\n <div class=\"d-flex align-items-center\">\r\n <ng-content select=\"[sdModalHeaderRight]\"></ng-content>\r\n <button type=\"button\" (click)=\"close()\" mat-icon-button>\r\n <mat-icon fontIcon=\"close\"></mat-icon>\r\n </button>\r\n </div>\r\n </sd-modal-header>\r\n <div class=\"d-flex flex-column px-12 px-md-24 pb-6 overflow-auto w-full mh-full\">\r\n <ng-content></ng-content>\r\n </div>\r\n </ng-container>\r\n</ng-template> -->\r\n", styles: ["button:focus{outline:none!important}.mat-dialog-container{padding:0!important}.mat-dialog-container .mat-dialog-content{max-height:80vh}.mat-dialog-container .mat-dialog-actions{min-height:auto;margin-bottom:0;padding:0}.mat-bottom-sheet-container{max-height:\"inherit\"}sd-modal-header{padding:12px 24px;display:block;width:100%}@media(max-width:640px){sd-modal-header{padding:12px}}.cdk-global-overlay-wrapper .mat-bottom-sheet-container{padding:0;min-width:100vw;box-sizing:border-box;outline:0;max-height:80vh;overflow:hidden;border-top-left-radius:4px;border-top-right-radius:4px;display:flex;flex-direction:column}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatBottomSheetModule }, { kind: "ngmodule", type: MatDialogModule }, { kind: "ngmodule", type: MatDividerModule }, { kind: "ngmodule", type: MatButtonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
96
91
|
}
|
|
97
92
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdModal, decorators: [{
|
|
98
93
|
type: Component,
|
|
99
|
-
args: [{ selector: 'sd-modal', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, MatIconModule, MatBottomSheetModule, MatDialogModule, MatDividerModule, MatButtonModule], template: "<ng-template #templateRef>\r\n @if (!lazyLoadContent || alreadyOpened) {\r\n <!-- Header -->\r\n <!-- D\u00F9ng scss thu\u1EA7n -->\r\n @if (title) {\r\n <div class=\"d-flex align-items-center p-16\">\r\n <div class=\"T18M\">{{ title }}</div>\r\n <div class=\"d-flex align-items-center ml-auto\">\r\n <ng-content select=\"[sdHeader]\"></ng-content>\r\n <mat-icon class=\"text-secondary pointer\" fontIcon=\"close\" (click)=\"close()\"></mat-icon>\r\n </div>\r\n </div>\r\n }\r\n <!-- <mat-divider></mat-divider> -->\r\n <!-- Body -->\r\n <div class=\"overflow-auto w-full px-16\" style=\"max-height: 80vh
|
|
100
|
-
}], ctorParameters: () => [
|
|
101
|
-
type: ViewChild,
|
|
102
|
-
args: ['templateRef']
|
|
103
|
-
}], title: [{
|
|
104
|
-
type: Input
|
|
105
|
-
}], color: [{
|
|
106
|
-
type: Input
|
|
107
|
-
}], width: [{
|
|
108
|
-
type: Input
|
|
109
|
-
}], height: [{
|
|
110
|
-
type: Input
|
|
111
|
-
}], view: [{
|
|
112
|
-
type: Input
|
|
113
|
-
}], lazyLoadContent: [{
|
|
114
|
-
type: Input
|
|
115
|
-
}], sdClosed: [{
|
|
116
|
-
type: Output
|
|
117
|
-
}], modal: [{
|
|
118
|
-
type: ViewChild,
|
|
119
|
-
args: ['modal']
|
|
120
|
-
}] } });
|
|
121
|
-
|
|
122
|
-
// export * from './src/modal/modal-header/modal-header.component';
|
|
123
|
-
// export * from './src/modal/modal-body/modal-body.component';
|
|
124
|
-
// export * from './src/modal/modal-footer/modal-footer.component';
|
|
94
|
+
args: [{ selector: 'sd-modal', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, MatIconModule, MatBottomSheetModule, MatDialogModule, MatDividerModule, MatButtonModule], template: "<ng-template #templateRef>\r\n @if (!lazyLoadContent() || alreadyOpened()) {\r\n <!-- Header -->\r\n <!-- D\u00F9ng scss thu\u1EA7n -->\r\n @if (title()) {\r\n <div class=\"d-flex align-items-center p-16\">\r\n <ng-content select=\"[sdHeaderLeft]\">\r\n <div class=\"T18M\">{{ title() }}</div>\r\n </ng-content>\r\n <div class=\"d-flex align-items-center ml-auto\">\r\n <ng-content select=\"[sdHeaderRight]\"></ng-content>\r\n <ng-content select=\"[sdHeader]\"></ng-content>\r\n @if (!hideClose()) {\r\n <mat-icon class=\"text-secondary pointer\" fontIcon=\"close\" (click)=\"close()\"></mat-icon>\r\n }\r\n </div>\r\n </div>\r\n }\r\n <!-- <mat-divider></mat-divider> -->\r\n <!-- Body -->\r\n <div class=\"overflow-auto w-full px-16\" style=\"max-height: 80vh\">\r\n <ng-content></ng-content>\r\n </div>\r\n <!-- Footer -->\r\n <!-- <mat-divider></mat-divider> -->\r\n <div class=\"d-flex align-items-center p-8\" #footer>\r\n <ng-content select=\"[sdFooterLeft]\"></ng-content>\r\n <div class=\"ml-auto\">\r\n <ng-content select=\"[sdFooterRight]\"></ng-content>\r\n <ng-content select=\"[sdFooter]\"></ng-content>\r\n </div>\r\n </div>\r\n }\r\n</ng-template>\r\n\r\n<!-- <ng-template #templateRef>\r\n @if(!lazyLoadContent || alreadyOpened) {\r\n <sd-modal-header *ngIf=\"title\">\r\n <span [innerHtml]=\"title\"></span>\r\n <div class=\"d-flex align-items-center\">\r\n <ng-content select=\"[sdModalHeaderRight]\"></ng-content>\r\n <button type=\"button\" (click)=\"close()\" mat-icon-button>\r\n <mat-icon fontIcon=\"close\"></mat-icon>\r\n </button>\r\n </div>\r\n </sd-modal-header>\r\n }\r\n <ng-container *ngIf=\"!lazyLoadContent || alreadyOpened\">\r\n <sd-modal-header *ngIf=\"title\">\r\n <span [innerHtml]=\"title\"></span>\r\n <div class=\"d-flex align-items-center\">\r\n <ng-content select=\"[sdModalHeaderRight]\"></ng-content>\r\n <button type=\"button\" (click)=\"close()\" mat-icon-button>\r\n <mat-icon fontIcon=\"close\"></mat-icon>\r\n </button>\r\n </div>\r\n </sd-modal-header>\r\n <div class=\"d-flex flex-column px-12 px-md-24 pb-6 overflow-auto w-full mh-full\">\r\n <ng-content></ng-content>\r\n </div>\r\n </ng-container>\r\n</ng-template> -->\r\n", styles: ["button:focus{outline:none!important}.mat-dialog-container{padding:0!important}.mat-dialog-container .mat-dialog-content{max-height:80vh}.mat-dialog-container .mat-dialog-actions{min-height:auto;margin-bottom:0;padding:0}.mat-bottom-sheet-container{max-height:\"inherit\"}sd-modal-header{padding:12px 24px;display:block;width:100%}@media(max-width:640px){sd-modal-header{padding:12px}}.cdk-global-overlay-wrapper .mat-bottom-sheet-container{padding:0;min-width:100vw;box-sizing:border-box;outline:0;max-height:80vh;overflow:hidden;border-top-left-radius:4px;border-top-right-radius:4px;display:flex;flex-direction:column}\n"] }]
|
|
95
|
+
}], ctorParameters: () => [] });
|
|
125
96
|
|
|
126
97
|
/**
|
|
127
98
|
* Generated bundle index. Do not edit.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sd-angular-core-components-modal.mjs","sources":["../../../projects/sd-angular/components/modal/src/modal/modal.component.ts","../../../projects/sd-angular/components/modal/src/modal/modal.component.html","../../../projects/sd-angular/components/modal/index.ts","../../../projects/sd-angular/components/modal/sd-angular-core-components-modal.ts"],"sourcesContent":["import { CommonModule } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n ElementRef,\n EventEmitter,\n Input,\n OnDestroy,\n OnInit,\n Output,\n TemplateRef,\n ViewChild\n} from '@angular/core';\nimport { MatBottomSheet, MatBottomSheetModule, MatBottomSheetRef } from '@angular/material/bottom-sheet';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatDialog, MatDialogModule, MatDialogRef } from '@angular/material/dialog';\nimport { MatDividerModule } from '@angular/material/divider';\nimport { MatIconModule } from '@angular/material/icon';\nimport { SdUtilities } from '@sd-angular/core/utilities';\nimport { SdColor, SdSize } from '@sd-angular/core/utilities/models';\nimport { Subscription } from 'rxjs';\n\n@Component({\n selector: 'sd-modal',\n templateUrl: './modal.component.html',\n styleUrls: ['./modal.component.scss'],\n // encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [CommonModule, MatIconModule, MatBottomSheetModule, MatDialogModule, MatDividerModule, MatButtonModule],\n})\nexport class SdModal implements OnInit, OnDestroy {\n static index = 0;\n @ViewChild('templateRef') templateRef!: TemplateRef<any>;\n @Input() title?: string;\n @Input() color: SdColor = 'primary';\n @Input() width: SdSize | string = 'md';\n @Input() height = 'auto';\n @Input() view?: 'dialog' | 'bottom-sheet';\n @Input() lazyLoadContent = true;\n @Output() sdClosed = new EventEmitter();\n @ViewChild('modal') modal!: ElementRef;\n isOpened = false;\n alreadyOpened = false;\n #isMobile = false;\n #bottomSheetRef!: MatBottomSheetRef<any>;\n #dialogRef!: MatDialogRef<any>;\n private subcription = new Subscription();\n constructor(\n private ref: ChangeDetectorRef,\n private dialog: MatDialog,\n private bottomSheet: MatBottomSheet\n ) {\n this.#isMobile = SdUtilities.isMobile();\n }\n ngOnInit(): void {\n this.width = this.width || '80vw';\n if (!this.#isMobile) {\n switch (this.width) {\n case 'lg':\n this.width = '80vw';\n break;\n case 'md':\n this.width = '60vw';\n break;\n case 'sm':\n this.width = '40vw';\n break;\n case 'sx':\n this.width = '20vw';\n break;\n }\n }\n }\n\n ngOnDestroy() {\n this.subcription.unsubscribe();\n }\n\n open = (): void => {\n if (this.isOpened) {\n return;\n }\n this.ref.markForCheck();\n this.alreadyOpened = true;\n this.isOpened = true;\n if ((!this.view && this.#isMobile) || this.view === 'bottom-sheet') {\n this.#bottomSheetRef = this.bottomSheet.open(this.templateRef);\n this.subcription.add(\n this.#bottomSheetRef.afterDismissed().subscribe(() => {\n this.isOpened = false;\n this.sdClosed.emit();\n })\n );\n } else {\n this.#dialogRef = this.dialog.open(this.templateRef, {\n width: this.width,\n maxWidth: this.width,\n disableClose: true, // mặc định ko cho đóng modal khi click out side\n });\n this.subcription.add(\n this.#dialogRef.afterClosed().subscribe(() => {\n this.isOpened = false;\n this.sdClosed.emit();\n })\n );\n }\n };\n\n close = (): void => {\n this.ref.markForCheck();\n this.#bottomSheetRef?.dismiss();\n this.#dialogRef?.close();\n };\n}\n","<ng-template #templateRef>\r\n @if (!lazyLoadContent || alreadyOpened) {\r\n <!-- Header -->\r\n <!-- Dùng scss thuần -->\r\n @if (title) {\r\n <div class=\"d-flex align-items-center p-16\">\r\n <div class=\"T18M\">{{ title }}</div>\r\n <div class=\"d-flex align-items-center ml-auto\">\r\n <ng-content select=\"[sdHeader]\"></ng-content>\r\n <mat-icon class=\"text-secondary pointer\" fontIcon=\"close\" (click)=\"close()\"></mat-icon>\r\n </div>\r\n </div>\r\n }\r\n <!-- <mat-divider></mat-divider> -->\r\n <!-- Body -->\r\n <div class=\"overflow-auto w-full px-16\" style=\"max-height: 80vh;\">\r\n <ng-content></ng-content>\r\n </div>\r\n <!-- Footer -->\r\n <!-- <mat-divider></mat-divider> -->\r\n <div class=\"d-flex align-items-center p-16\" #footer>\r\n <ng-content select=\"[sdFooterLeft]\"></ng-content>\r\n <div class=\"ml-auto\">\r\n <ng-content select=\"[sdFooter]\"></ng-content>\r\n </div>\r\n </div>\r\n }\r\n</ng-template>\r\n\r\n<!-- <ng-template #templateRef>\r\n @if(!lazyLoadContent || alreadyOpened) {\r\n <sd-modal-header *ngIf=\"title\">\r\n <span [innerHtml]=\"title\"></span>\r\n <div class=\"d-flex align-items-center\">\r\n <ng-content select=\"[sdModalHeaderRight]\"></ng-content>\r\n <button type=\"button\" (click)=\"close()\" mat-icon-button>\r\n <mat-icon fontIcon=\"close\"></mat-icon>\r\n </button>\r\n </div>\r\n </sd-modal-header>\r\n }\r\n <ng-container *ngIf=\"!lazyLoadContent || alreadyOpened\">\r\n <sd-modal-header *ngIf=\"title\">\r\n <span [innerHtml]=\"title\"></span>\r\n <div class=\"d-flex align-items-center\">\r\n <ng-content select=\"[sdModalHeaderRight]\"></ng-content>\r\n <button type=\"button\" (click)=\"close()\" mat-icon-button>\r\n <mat-icon fontIcon=\"close\"></mat-icon>\r\n </button>\r\n </div>\r\n </sd-modal-header>\r\n <div class=\"d-flex flex-column px-12 px-md-24 pb-6 overflow-auto w-full mh-full\">\r\n <ng-content></ng-content>\r\n </div>\r\n </ng-container>\r\n</ng-template> -->\r\n","export * from './src/modal/modal.component';\n// export * from './src/modal/modal-header/modal-header.component';\n// export * from './src/modal/modal-body/modal-body.component';\n// export * from './src/modal/modal-footer/modal-footer.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sd-angular-core-components-modal.mjs","sources":["../../../projects/sd-angular/components/modal/src/modal.component.ts","../../../projects/sd-angular/components/modal/src/modal.component.html","../../../projects/sd-angular/components/modal/sd-angular-core-components-modal.ts"],"sourcesContent":["import { CommonModule } from '@angular/common';\r\nimport {\r\n ChangeDetectionStrategy,\r\n Component,\r\n DestroyRef,\r\n ElementRef,\r\n TemplateRef,\r\n booleanAttribute,\r\n inject,\r\n input,\r\n output,\r\n signal,\r\n viewChild\r\n} from '@angular/core';\r\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\r\nimport { MatBottomSheet, MatBottomSheetModule, MatBottomSheetRef } from '@angular/material/bottom-sheet';\r\nimport { MatButtonModule } from '@angular/material/button';\r\nimport { MatDialog, MatDialogModule, MatDialogRef } from '@angular/material/dialog';\r\nimport { MatDividerModule } from '@angular/material/divider';\r\nimport { MatIconModule } from '@angular/material/icon';\r\nimport { SdUtilities } from '@sd-angular/core/utilities';\r\nimport { SdColor, SdSize } from '@sd-angular/core/utilities/models';\r\n\r\n@Component({\r\n selector: 'sd-modal',\r\n templateUrl: './modal.component.html',\r\n styleUrls: ['./modal.component.scss'],\r\n // encapsulation: ViewEncapsulation.None,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n standalone: true,\r\n imports: [CommonModule, MatIconModule, MatBottomSheetModule, MatDialogModule, MatDividerModule, MatButtonModule],\r\n})\r\nexport class SdModal {\r\n static index = signal(0);\r\n\r\n templateRef = viewChild.required<TemplateRef<any>>('templateRef');\r\n modal = viewChild<ElementRef>('modal');\r\n\r\n title = input<string, string | null | undefined>('', { transform: (v) => v ?? '' });\r\n color = input<SdColor, SdColor | null | undefined>('primary', { transform: (v) => v ?? 'primary' });\r\n width = input<SdSize | string, SdSize | string | null | undefined>('md', { transform: (v) => v ?? 'md' });\r\n height = input<string, string | null | undefined>('auto', { transform: (v) => v ?? 'auto' });\r\n view = input<'dialog' | 'bottom-sheet' | undefined, 'dialog' | 'bottom-sheet' | null | undefined>(undefined, { transform: (v) => v ?? undefined });\r\n modalClass = input<string | string[] | Record<string, boolean>, string | string[] | Record<string, boolean> | null | undefined>('', { transform: (v) => v ?? '' });\r\n lazyLoadContent = input(true, { transform: booleanAttribute });\r\n hideClose = input<boolean, boolean | ''>(false, { transform: booleanAttribute });\r\n disableBackdropClose = input<boolean, boolean | ''>(true, { transform: booleanAttribute }); // default to true to keep backward compatibility\r\n\r\n sdClosed = output<void>();\r\n\r\n isOpened = signal(false);\r\n alreadyOpened = signal(false);\r\n\r\n #isMobile = false;\r\n #resolvedWidth = 'md';\r\n #bottomSheetRef!: MatBottomSheetRef<any>;\r\n #dialogRef!: MatDialogRef<any>;\r\n\r\n #dialog = inject(MatDialog);\r\n #bottomSheet = inject(MatBottomSheet);\r\n #destroyRef = inject(DestroyRef);\r\n\r\n constructor() {\r\n this.#isMobile = SdUtilities.isMobile();\r\n }\r\n\r\n #resolveWidth(): string {\r\n const w = this.width() || '80vw';\r\n if (this.#isMobile) return w;\r\n switch (w) {\r\n case 'lg': return '80vw';\r\n case 'md': return '60vw';\r\n case 'sm': return '40vw';\r\n case 'sx': return '20vw';\r\n default: return w;\r\n }\r\n }\r\n\r\n open = (): void => {\r\n if (this.isOpened()) {\r\n return;\r\n }\r\n this.alreadyOpened.set(true);\r\n this.isOpened.set(true);\r\n this.#resolvedWidth = this.#resolveWidth();\r\n\r\n if ((!this.view() && this.#isMobile) || this.view() === 'bottom-sheet') {\r\n this.#bottomSheetRef = this.#bottomSheet.open(this.templateRef(), {\r\n panelClass: this.modalClass() as string | string[],\r\n disableClose: this.disableBackdropClose()\r\n });\r\n this.#bottomSheetRef.afterDismissed()\r\n .pipe(takeUntilDestroyed(this.#destroyRef))\r\n .subscribe(() => {\r\n this.isOpened.set(false);\r\n this.sdClosed.emit();\r\n });\r\n } else {\r\n this.#dialogRef = this.#dialog.open(this.templateRef(), {\r\n width: this.#resolvedWidth,\r\n maxWidth: this.#resolvedWidth,\r\n panelClass: this.modalClass() as string | string[],\r\n disableClose: this.disableBackdropClose(),\r\n });\r\n this.#dialogRef.afterClosed()\r\n .pipe(takeUntilDestroyed(this.#destroyRef))\r\n .subscribe(() => {\r\n this.isOpened.set(false);\r\n this.sdClosed.emit();\r\n });\r\n }\r\n };\r\n\r\n close = (): void => {\r\n this.#bottomSheetRef?.dismiss();\r\n this.#dialogRef?.close();\r\n };\r\n}\r\n","<ng-template #templateRef>\r\n @if (!lazyLoadContent() || alreadyOpened()) {\r\n <!-- Header -->\r\n <!-- Dùng scss thuần -->\r\n @if (title()) {\r\n <div class=\"d-flex align-items-center p-16\">\r\n <ng-content select=\"[sdHeaderLeft]\">\r\n <div class=\"T18M\">{{ title() }}</div>\r\n </ng-content>\r\n <div class=\"d-flex align-items-center ml-auto\">\r\n <ng-content select=\"[sdHeaderRight]\"></ng-content>\r\n <ng-content select=\"[sdHeader]\"></ng-content>\r\n @if (!hideClose()) {\r\n <mat-icon class=\"text-secondary pointer\" fontIcon=\"close\" (click)=\"close()\"></mat-icon>\r\n }\r\n </div>\r\n </div>\r\n }\r\n <!-- <mat-divider></mat-divider> -->\r\n <!-- Body -->\r\n <div class=\"overflow-auto w-full px-16\" style=\"max-height: 80vh\">\r\n <ng-content></ng-content>\r\n </div>\r\n <!-- Footer -->\r\n <!-- <mat-divider></mat-divider> -->\r\n <div class=\"d-flex align-items-center p-8\" #footer>\r\n <ng-content select=\"[sdFooterLeft]\"></ng-content>\r\n <div class=\"ml-auto\">\r\n <ng-content select=\"[sdFooterRight]\"></ng-content>\r\n <ng-content select=\"[sdFooter]\"></ng-content>\r\n </div>\r\n </div>\r\n }\r\n</ng-template>\r\n\r\n<!-- <ng-template #templateRef>\r\n @if(!lazyLoadContent || alreadyOpened) {\r\n <sd-modal-header *ngIf=\"title\">\r\n <span [innerHtml]=\"title\"></span>\r\n <div class=\"d-flex align-items-center\">\r\n <ng-content select=\"[sdModalHeaderRight]\"></ng-content>\r\n <button type=\"button\" (click)=\"close()\" mat-icon-button>\r\n <mat-icon fontIcon=\"close\"></mat-icon>\r\n </button>\r\n </div>\r\n </sd-modal-header>\r\n }\r\n <ng-container *ngIf=\"!lazyLoadContent || alreadyOpened\">\r\n <sd-modal-header *ngIf=\"title\">\r\n <span [innerHtml]=\"title\"></span>\r\n <div class=\"d-flex align-items-center\">\r\n <ng-content select=\"[sdModalHeaderRight]\"></ng-content>\r\n <button type=\"button\" (click)=\"close()\" mat-icon-button>\r\n <mat-icon fontIcon=\"close\"></mat-icon>\r\n </button>\r\n </div>\r\n </sd-modal-header>\r\n <div class=\"d-flex flex-column px-12 px-md-24 pb-6 overflow-auto w-full mh-full\">\r\n <ng-content></ng-content>\r\n </div>\r\n </ng-container>\r\n</ng-template> -->\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -93,7 +93,7 @@ class SdPreviewImage {
|
|
|
93
93
|
this.activeIndex = 0;
|
|
94
94
|
};
|
|
95
95
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdPreviewImage, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
96
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: SdPreviewImage, isStandalone: true, selector: "sd-preview-image", outputs: { close: "close" }, viewQueries: [{ propertyName: "modal", first: true, predicate: SdModal, descendants: true }], ngImport: i0, template: "<sd-modal [title]=\"title\" (sdClosed)=\"close.emit()\" #modal>\r\n <div class=\"p-16\" style=\"overflow: hidden; height: 100%\">\r\n <!-- Main image -->\r\n @if (images.length) {\r\n <div style=\"gap: 8px;\" class=\"image-gallery\">\r\n <div class=\"thumbnail-container\">\r\n @for (image of images; track image.id; let i = $index) {\r\n <button\r\n type=\"button\"\r\n class=\"thumbnail-wrapper\"\r\n (click)=\"onClickThumbnailImage(i)\"\r\n [ngStyle]=\"{\r\n border: activeIndex === i ? '2px solid #2962ff' : 'none'\r\n }\">\r\n @if (image.src) {\r\n <img fill loading=\"lazy\" [ngSrc]=\"image.src\" alt=\"thumbnail\" [id]=\"image.id\" class=\"thumbnail-img\" />\r\n } @else {\r\n <img fill loading=\"lazy\" [src]=\"image.blobSrc\" alt=\"thumbnail\" [id]=\"image.id\" class=\"thumbnail-img\" />\r\n }\r\n </button>\r\n }\r\n </div>\r\n <div class=\"main-image-container\" #mainImage>\r\n @let activedImage = images[activeIndex];\r\n @if (activedImage.src) {\r\n <img fill priority [ngSrc]=\"activedImage.src\" class=\"main-image\" alt=\"Main display image\" />\r\n } @else {\r\n <img fill priority [src]=\"activedImage.blobSrc!\" class=\"main-image\" alt=\"Main display image\" />\r\n }\r\n <sd-button prefixIcon=\"arrow_forward_ios\" class=\"next-icon\" (click)=\"updateCurrentImage(1)\"></sd-button>\r\n <sd-button prefixIcon=\"arrow_back_ios_new\" class=\"back-icon\" (click)=\"updateCurrentImage(-1)\"></sd-button>\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"no-image d-flex justify-content-center align-items-center flex-column m-20\" style=\"height: 80%\">\r\n <i class=\"icon-no-image mb-16\"></i>\r\n <div>Kh\u00F4ng c\u00F3 th\u00F4ng tin \u1EA3nh</div>\r\n </div>\r\n }\r\n </div>\r\n</sd-modal>\r\n", styles: [".image-gallery{display:flex;width:100%;max-height:60vh;min-height:60vh}.image-gallery .main-image-container{flex:1;position:relative}.image-gallery .main-image-container .next-icon{position:absolute;top:45%;right:10px;cursor:pointer;color:#000;z-index:9999}.image-gallery .main-image-container .back-icon{position:absolute;top:45%;left:0;cursor:pointer;color:#000;z-index:9999}.image-gallery .thumbnail-container{width:120px;overflow-y:auto;display:flex;flex-direction:column;gap:8px;box-sizing:border-box}.image-gallery .thumbnail-wrapper{position:relative;width:100px;aspect-ratio:1;flex:0 0 auto;overflow:hidden;padding:0;border:none;background:transparent}.image-gallery .thumbnail-wrapper .thumbnail-img{object-fit:cover;width:100%;height:100%;display:block}.image-gallery .main-image{object-fit:contain;width:100%;height:100%;display:block}\n"], dependencies: [{ kind: "component", type: SdModal, selector: "sd-modal", inputs: ["title", "color", "width", "height", "view", "lazyLoadContent"], outputs: ["sdClosed"] }, { kind: "component", type: SdButton, selector: "sd-button", inputs: ["autoId", "type", "color", "
|
|
96
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: SdPreviewImage, isStandalone: true, selector: "sd-preview-image", outputs: { close: "close" }, viewQueries: [{ propertyName: "modal", first: true, predicate: SdModal, descendants: true }], ngImport: i0, template: "<sd-modal [title]=\"title\" (sdClosed)=\"close.emit()\" #modal>\r\n <div class=\"p-16\" style=\"overflow: hidden; height: 100%\">\r\n <!-- Main image -->\r\n @if (images.length) {\r\n <div style=\"gap: 8px;\" class=\"image-gallery\">\r\n <div class=\"thumbnail-container\">\r\n @for (image of images; track image.id; let i = $index) {\r\n <button\r\n type=\"button\"\r\n class=\"thumbnail-wrapper\"\r\n (click)=\"onClickThumbnailImage(i)\"\r\n [ngStyle]=\"{\r\n border: activeIndex === i ? '2px solid #2962ff' : 'none'\r\n }\">\r\n @if (image.src) {\r\n <img fill loading=\"lazy\" [ngSrc]=\"image.src\" alt=\"thumbnail\" [id]=\"image.id\" class=\"thumbnail-img\" />\r\n } @else {\r\n <img fill loading=\"lazy\" [src]=\"image.blobSrc\" alt=\"thumbnail\" [id]=\"image.id\" class=\"thumbnail-img\" />\r\n }\r\n </button>\r\n }\r\n </div>\r\n <div class=\"main-image-container\" #mainImage>\r\n @let activedImage = images[activeIndex];\r\n @if (activedImage.src) {\r\n <img fill priority [ngSrc]=\"activedImage.src\" class=\"main-image\" alt=\"Main display image\" />\r\n } @else {\r\n <img fill priority [src]=\"activedImage.blobSrc!\" class=\"main-image\" alt=\"Main display image\" />\r\n }\r\n <sd-button prefixIcon=\"arrow_forward_ios\" class=\"next-icon\" (click)=\"updateCurrentImage(1)\"></sd-button>\r\n <sd-button prefixIcon=\"arrow_back_ios_new\" class=\"back-icon\" (click)=\"updateCurrentImage(-1)\"></sd-button>\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"no-image d-flex justify-content-center align-items-center flex-column m-20\" style=\"height: 80%\">\r\n <i class=\"icon-no-image mb-16\"></i>\r\n <div>Kh\u00F4ng c\u00F3 th\u00F4ng tin \u1EA3nh</div>\r\n </div>\r\n }\r\n </div>\r\n</sd-modal>\r\n", styles: [".image-gallery{display:flex;width:100%;max-height:60vh;min-height:60vh}.image-gallery .main-image-container{flex:1;position:relative}.image-gallery .main-image-container .next-icon{position:absolute;top:45%;right:10px;cursor:pointer;color:#000;z-index:9999}.image-gallery .main-image-container .back-icon{position:absolute;top:45%;left:0;cursor:pointer;color:#000;z-index:9999}.image-gallery .thumbnail-container{width:120px;overflow-y:auto;display:flex;flex-direction:column;gap:8px;box-sizing:border-box}.image-gallery .thumbnail-wrapper{position:relative;width:100px;aspect-ratio:1;flex:0 0 auto;overflow:hidden;padding:0;border:none;background:transparent}.image-gallery .thumbnail-wrapper .thumbnail-img{object-fit:cover;width:100%;height:100%;display:block}.image-gallery .main-image{object-fit:contain;width:100%;height:100%;display:block}\n"], dependencies: [{ kind: "component", type: SdModal, selector: "sd-modal", inputs: ["title", "color", "width", "height", "view", "modalClass", "lazyLoadContent", "hideClose", "disableBackdropClose"], outputs: ["sdClosed"] }, { kind: "component", type: SdButton, selector: "sd-button", inputs: ["autoId", "type", "color", "size", "fontSet", "title", "width", "tooltip", "prefixIcon", "suffixIcon", "disabled", "loading", "block", "htmlType"], outputs: ["click"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgOptimizedImage, selector: "img[ngSrc]", inputs: ["ngSrc", "ngSrcset", "sizes", "width", "height", "loading", "priority", "loaderParams", "disableOptimizedSrcset", "fill", "placeholder", "placeholderConfig", "src", "srcset"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
97
97
|
}
|
|
98
98
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdPreviewImage, decorators: [{
|
|
99
99
|
type: Component,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sd-angular-core-components-preview.mjs","sources":["../../../projects/sd-angular/components/preview/src/preview-image/preview-image.component.ts","../../../projects/sd-angular/components/preview/src/preview-image/preview-image.component.html","../../../projects/sd-angular/components/preview/sd-angular-core-components-preview.ts"],"sourcesContent":["import { CommonModule, NgOptimizedImage } from '@angular/common';\r\nimport { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, Output, ViewChild } from '@angular/core';\r\nimport { SdButton } from '@sd-angular/core/components/button';\r\nimport { SdModal } from '@sd-angular/core/components/modal';\r\nimport * as uuid from 'uuid';\r\n\r\ninterface Image {\r\n id: string;\r\n // Vì NgOptimizedImage không thể sử dụng với blobSrc nên đối với url từ cdn sẽ vẫn lưu ở src\r\n blobSrc: string;\r\n src?: string;\r\n name: string;\r\n size: number;\r\n}\r\n\r\n@Component({\r\n selector: 'sd-preview-image',\r\n imports: [SdModal, SdButton, CommonModule, NgOptimizedImage],\r\n templateUrl: './preview-image.component.html',\r\n styleUrl: './preview-image.component.scss',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n})\r\nexport class SdPreviewImage {\r\n @ViewChild(SdModal) modal!: SdModal;\r\n @Output() close = new EventEmitter<void>();\r\n\r\n title: string = 'Xem ảnh';\r\n thumbnailPosition: 'right' | 'left' | 'bottom' | 'top' = 'right';\r\n activeIndex = 0;\r\n images: Image[] = [];\r\n constructor(private cd: ChangeDetectorRef) {}\r\n\r\n #loadImages = async (urlOrFiles: (string | File)[]) => {\r\n urlOrFiles = urlOrFiles.filter(url => !!url);\r\n // Xử lý nếu là url thì thực hiện fetch lấy blob rồi từ blob => file\r\n const promises = urlOrFiles.map<Promise<Image | null>>(async urlOrFile => {\r\n if (typeof urlOrFile === 'string') {\r\n return fetch(urlOrFile)\r\n .then(async r => {\r\n const blob = await r.blob();\r\n // Lấy filename dựa vào url src\r\n const baseSrc = urlOrFile.split('?')[0];\r\n const filename = baseSrc.substring(baseSrc.lastIndexOf('/') + 1);\r\n const file = new File([blob], filename);\r\n const image: Image = {\r\n id: uuid.v4(),\r\n blobSrc: URL.createObjectURL(file!),\r\n src: urlOrFile,\r\n name: file!.name,\r\n size: file!.size,\r\n };\r\n return image;\r\n })\r\n .catch(err => {\r\n console.error(err);\r\n return null;\r\n });\r\n } else {\r\n if (urlOrFile.type.split('/')[0] === 'image') {\r\n const image: Image = {\r\n id: uuid.v4(),\r\n blobSrc: URL.createObjectURL(urlOrFile),\r\n name: urlOrFile.name,\r\n size: urlOrFile.size,\r\n };\r\n return image;\r\n }\r\n return null;\r\n }\r\n });\r\n this.images = (await Promise.all(promises)).filter(image => image !== null);\r\n };\r\n\r\n // Nên sử dụng urlOrFiles ở tham số khi open thay vì dùng @Input để component sử dụng sẽ chỉ cần map ở hàm khi gọi open thay vì phải mất công map mọi lúc để binding vào @Input\r\n open = async (urlOrFiles: (string | File)[] | undefined | null) => {\r\n if (!Array.isArray(urlOrFiles)) {\r\n return;\r\n }\r\n await this.#loadImages(urlOrFiles);\r\n this.#reset();\r\n this.modal?.open();\r\n this.cd.markForCheck();\r\n };\r\n\r\n onClickThumbnailImage = (index: number) => {\r\n this.activeIndex = index;\r\n this.cd.markForCheck();\r\n };\r\n\r\n updateCurrentImage = (direction: 1 | -1) => {\r\n this.activeIndex = (this.activeIndex + direction + this.images.length) % this.images.length;\r\n this.#scrollView(this.activeIndex, direction === 1 ? 'start' : 'end');\r\n this.cd.markForCheck();\r\n };\r\n\r\n onClose = () => {\r\n this.close.emit();\r\n };\r\n\r\n #scrollView = (index: number, type?: 'center' | 'end' | 'nearest' | 'start') => {\r\n const nameId: string = 'thumbnailImage' + index;\r\n const element = document.getElementById(nameId);\r\n if (!element) {\r\n return;\r\n }\r\n const blockType: ScrollLogicalPosition = type || 'start';\r\n element.scrollIntoView({ behavior: 'smooth', block: blockType });\r\n };\r\n\r\n #reset = () => {\r\n this.activeIndex = 0;\r\n };\r\n}\r\n","<sd-modal [title]=\"title\" (sdClosed)=\"close.emit()\" #modal>\r\n <div class=\"p-16\" style=\"overflow: hidden; height: 100%\">\r\n <!-- Main image -->\r\n @if (images.length) {\r\n <div style=\"gap: 8px;\" class=\"image-gallery\">\r\n <div class=\"thumbnail-container\">\r\n @for (image of images; track image.id; let i = $index) {\r\n <button\r\n type=\"button\"\r\n class=\"thumbnail-wrapper\"\r\n (click)=\"onClickThumbnailImage(i)\"\r\n [ngStyle]=\"{\r\n border: activeIndex === i ? '2px solid #2962ff' : 'none'\r\n }\">\r\n @if (image.src) {\r\n <img fill loading=\"lazy\" [ngSrc]=\"image.src\" alt=\"thumbnail\" [id]=\"image.id\" class=\"thumbnail-img\" />\r\n } @else {\r\n <img fill loading=\"lazy\" [src]=\"image.blobSrc\" alt=\"thumbnail\" [id]=\"image.id\" class=\"thumbnail-img\" />\r\n }\r\n </button>\r\n }\r\n </div>\r\n <div class=\"main-image-container\" #mainImage>\r\n @let activedImage = images[activeIndex];\r\n @if (activedImage.src) {\r\n <img fill priority [ngSrc]=\"activedImage.src\" class=\"main-image\" alt=\"Main display image\" />\r\n } @else {\r\n <img fill priority [src]=\"activedImage.blobSrc!\" class=\"main-image\" alt=\"Main display image\" />\r\n }\r\n <sd-button prefixIcon=\"arrow_forward_ios\" class=\"next-icon\" (click)=\"updateCurrentImage(1)\"></sd-button>\r\n <sd-button prefixIcon=\"arrow_back_ios_new\" class=\"back-icon\" (click)=\"updateCurrentImage(-1)\"></sd-button>\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"no-image d-flex justify-content-center align-items-center flex-column m-20\" style=\"height: 80%\">\r\n <i class=\"icon-no-image mb-16\"></i>\r\n <div>Không có thông tin ảnh</div>\r\n </div>\r\n }\r\n </div>\r\n</sd-modal>\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sd-angular-core-components-preview.mjs","sources":["../../../projects/sd-angular/components/preview/src/preview-image/preview-image.component.ts","../../../projects/sd-angular/components/preview/src/preview-image/preview-image.component.html","../../../projects/sd-angular/components/preview/sd-angular-core-components-preview.ts"],"sourcesContent":["import { CommonModule, NgOptimizedImage } from '@angular/common';\r\nimport { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, Output, ViewChild } from '@angular/core';\r\nimport { SdButton } from '@sd-angular/core/components/button';\r\nimport { SdModal } from '@sd-angular/core/components/modal';\r\nimport * as uuid from 'uuid';\r\n\r\ninterface Image {\r\n id: string;\r\n // Vì NgOptimizedImage không thể sử dụng với blobSrc nên đối với url từ cdn sẽ vẫn lưu ở src\r\n blobSrc: string;\r\n src?: string;\r\n name: string;\r\n size: number;\r\n}\r\n\r\n@Component({\r\n selector: 'sd-preview-image',\r\n imports: [SdModal, SdButton, CommonModule, NgOptimizedImage],\r\n templateUrl: './preview-image.component.html',\r\n styleUrl: './preview-image.component.scss',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n})\r\nexport class SdPreviewImage {\r\n @ViewChild(SdModal) modal!: SdModal;\r\n @Output() close = new EventEmitter<void>();\r\n\r\n title: string = 'Xem ảnh';\r\n thumbnailPosition: 'right' | 'left' | 'bottom' | 'top' = 'right';\r\n activeIndex = 0;\r\n images: Image[] = [];\r\n constructor(private cd: ChangeDetectorRef) {}\r\n\r\n #loadImages = async (urlOrFiles: (string | File)[]) => {\r\n urlOrFiles = urlOrFiles.filter(url => !!url);\r\n // Xử lý nếu là url thì thực hiện fetch lấy blob rồi từ blob => file\r\n const promises = urlOrFiles.map<Promise<Image | null>>(async urlOrFile => {\r\n if (typeof urlOrFile === 'string') {\r\n return fetch(urlOrFile)\r\n .then(async r => {\r\n const blob = await r.blob();\r\n // Lấy filename dựa vào url src\r\n const baseSrc = urlOrFile.split('?')[0];\r\n const filename = baseSrc.substring(baseSrc.lastIndexOf('/') + 1);\r\n const file = new File([blob], filename);\r\n const image: Image = {\r\n id: uuid.v4(),\r\n blobSrc: URL.createObjectURL(file!),\r\n src: urlOrFile,\r\n name: file!.name,\r\n size: file!.size,\r\n };\r\n return image;\r\n })\r\n .catch(err => {\r\n console.error(err);\r\n return null;\r\n });\r\n } else {\r\n if (urlOrFile.type.split('/')[0] === 'image') {\r\n const image: Image = {\r\n id: uuid.v4(),\r\n blobSrc: URL.createObjectURL(urlOrFile),\r\n name: urlOrFile.name,\r\n size: urlOrFile.size,\r\n };\r\n return image;\r\n }\r\n return null;\r\n }\r\n });\r\n this.images = (await Promise.all(promises)).filter(image => image !== null);\r\n };\r\n\r\n // Nên sử dụng urlOrFiles ở tham số khi open thay vì dùng @Input để component sử dụng sẽ chỉ cần map ở hàm khi gọi open thay vì phải mất công map mọi lúc để binding vào @Input\r\n open = async (urlOrFiles: (string | File)[] | undefined | null) => {\r\n if (!Array.isArray(urlOrFiles)) {\r\n return;\r\n }\r\n await this.#loadImages(urlOrFiles);\r\n this.#reset();\r\n this.modal?.open();\r\n this.cd.markForCheck();\r\n };\r\n\r\n onClickThumbnailImage = (index: number) => {\r\n this.activeIndex = index;\r\n this.cd.markForCheck();\r\n };\r\n\r\n updateCurrentImage = (direction: 1 | -1) => {\r\n this.activeIndex = (this.activeIndex + direction + this.images.length) % this.images.length;\r\n this.#scrollView(this.activeIndex, direction === 1 ? 'start' : 'end');\r\n this.cd.markForCheck();\r\n };\r\n\r\n onClose = () => {\r\n this.close.emit();\r\n };\r\n\r\n #scrollView = (index: number, type?: 'center' | 'end' | 'nearest' | 'start') => {\r\n const nameId: string = 'thumbnailImage' + index;\r\n const element = document.getElementById(nameId);\r\n if (!element) {\r\n return;\r\n }\r\n const blockType: ScrollLogicalPosition = type || 'start';\r\n element.scrollIntoView({ behavior: 'smooth', block: blockType });\r\n };\r\n\r\n #reset = () => {\r\n this.activeIndex = 0;\r\n };\r\n}\r\n","<sd-modal [title]=\"title\" (sdClosed)=\"close.emit()\" #modal>\r\n <div class=\"p-16\" style=\"overflow: hidden; height: 100%\">\r\n <!-- Main image -->\r\n @if (images.length) {\r\n <div style=\"gap: 8px;\" class=\"image-gallery\">\r\n <div class=\"thumbnail-container\">\r\n @for (image of images; track image.id; let i = $index) {\r\n <button\r\n type=\"button\"\r\n class=\"thumbnail-wrapper\"\r\n (click)=\"onClickThumbnailImage(i)\"\r\n [ngStyle]=\"{\r\n border: activeIndex === i ? '2px solid #2962ff' : 'none'\r\n }\">\r\n @if (image.src) {\r\n <img fill loading=\"lazy\" [ngSrc]=\"image.src\" alt=\"thumbnail\" [id]=\"image.id\" class=\"thumbnail-img\" />\r\n } @else {\r\n <img fill loading=\"lazy\" [src]=\"image.blobSrc\" alt=\"thumbnail\" [id]=\"image.id\" class=\"thumbnail-img\" />\r\n }\r\n </button>\r\n }\r\n </div>\r\n <div class=\"main-image-container\" #mainImage>\r\n @let activedImage = images[activeIndex];\r\n @if (activedImage.src) {\r\n <img fill priority [ngSrc]=\"activedImage.src\" class=\"main-image\" alt=\"Main display image\" />\r\n } @else {\r\n <img fill priority [src]=\"activedImage.blobSrc!\" class=\"main-image\" alt=\"Main display image\" />\r\n }\r\n <sd-button prefixIcon=\"arrow_forward_ios\" class=\"next-icon\" (click)=\"updateCurrentImage(1)\"></sd-button>\r\n <sd-button prefixIcon=\"arrow_back_ios_new\" class=\"back-icon\" (click)=\"updateCurrentImage(-1)\"></sd-button>\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"no-image d-flex justify-content-center align-items-center flex-column m-20\" style=\"height: 80%\">\r\n <i class=\"icon-no-image mb-16\"></i>\r\n <div>Không có thông tin ảnh</div>\r\n </div>\r\n }\r\n </div>\r\n</sd-modal>\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -15,11 +15,11 @@ class SdQuickAction {
|
|
|
15
15
|
this.isOpened = false;
|
|
16
16
|
};
|
|
17
17
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdQuickAction, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
18
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.17", type: SdQuickAction, isStandalone: true, selector: "sd-quick-action", inputs: { _isOpened: ["isOpened", "_isOpened"] }, ngImport: i0, template: "<div class=\"c-quick-action d-flex align-items-center\" [class.active]=\"isOpened\">\n <div class=\"
|
|
18
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.17", type: SdQuickAction, isStandalone: true, selector: "sd-quick-action", inputs: { _isOpened: ["isOpened", "_isOpened"] }, ngImport: i0, template: "<div class=\"c-quick-action d-flex align-items-center gap-16\" [class.active]=\"isOpened\">\r\n <div class=\"flex-1 T14R\">\r\n <ng-content select=\"[sdMessage]\"></ng-content>\r\n </div>\r\n <ng-content select=\"[sdAction]\"></ng-content>\r\n</div>\r\n", styles: [".c-quick-action{box-shadow:0 .4px .8px #0000001a,0 3px 6px #0003;border-radius:4px;position:fixed;min-width:320px;width:max-content;background-color:#fff;bottom:90px;left:0;right:0;margin:auto;visibility:hidden;opacity:0;pointer-events:none;transition:all .2s ease-in-out;transform:translate3d(0,100%,0);z-index:99}.c-quick-action.active{transform:translateZ(0);opacity:1;visibility:visible;pointer-events:all}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
|
|
19
19
|
}
|
|
20
20
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdQuickAction, decorators: [{
|
|
21
21
|
type: Component,
|
|
22
|
-
args: [{ selector: 'sd-quick-action', standalone: true, imports: [CommonModule], template: "<div class=\"c-quick-action d-flex align-items-center\" [class.active]=\"isOpened\">\n <div class=\"
|
|
22
|
+
args: [{ selector: 'sd-quick-action', standalone: true, imports: [CommonModule], template: "<div class=\"c-quick-action d-flex align-items-center gap-16\" [class.active]=\"isOpened\">\r\n <div class=\"flex-1 T14R\">\r\n <ng-content select=\"[sdMessage]\"></ng-content>\r\n </div>\r\n <ng-content select=\"[sdAction]\"></ng-content>\r\n</div>\r\n", styles: [".c-quick-action{box-shadow:0 .4px .8px #0000001a,0 3px 6px #0003;border-radius:4px;position:fixed;min-width:320px;width:max-content;background-color:#fff;bottom:90px;left:0;right:0;margin:auto;visibility:hidden;opacity:0;pointer-events:none;transition:all .2s ease-in-out;transform:translate3d(0,100%,0);z-index:99}.c-quick-action.active{transform:translateZ(0);opacity:1;visibility:visible;pointer-events:all}\n"] }]
|
|
23
23
|
}], ctorParameters: () => [], propDecorators: { _isOpened: [{
|
|
24
24
|
type: Input,
|
|
25
25
|
args: ['isOpened']
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sd-angular-core-components-quick-action.mjs","sources":["../../../projects/sd-angular/components/quick-action/src/quick-action.component.ts","../../../projects/sd-angular/components/quick-action/src/quick-action.component.html","../../../projects/sd-angular/components/quick-action/sd-angular-core-components-quick-action.ts"],"sourcesContent":["import { CommonModule } from '@angular/common';\nimport { Component, Input } from '@angular/core';\n\n@Component({\n selector: 'sd-quick-action',\n templateUrl: './quick-action.component.html',\n styleUrls: ['./quick-action.component.scss'],\n standalone: true,\n imports: [CommonModule],\n})\nexport class SdQuickAction {\n isOpened = false;\n @Input('isOpened') set _isOpened(isOpened: '' | boolean | undefined | null) {\n this.isOpened = !!isOpened;\n }\n constructor() {}\n open = () => {\n this.isOpened = true;\n };\n\n close = () => {\n this.isOpened = false;\n };\n}\n","<div class=\"c-quick-action d-flex align-items-center\" [class.active]=\"isOpened\">\n <div class=\"
|
|
1
|
+
{"version":3,"file":"sd-angular-core-components-quick-action.mjs","sources":["../../../projects/sd-angular/components/quick-action/src/quick-action.component.ts","../../../projects/sd-angular/components/quick-action/src/quick-action.component.html","../../../projects/sd-angular/components/quick-action/sd-angular-core-components-quick-action.ts"],"sourcesContent":["import { CommonModule } from '@angular/common';\nimport { Component, Input } from '@angular/core';\n\n@Component({\n selector: 'sd-quick-action',\n templateUrl: './quick-action.component.html',\n styleUrls: ['./quick-action.component.scss'],\n standalone: true,\n imports: [CommonModule],\n})\nexport class SdQuickAction {\n isOpened = false;\n @Input('isOpened') set _isOpened(isOpened: '' | boolean | undefined | null) {\n this.isOpened = !!isOpened;\n }\n constructor() {}\n open = () => {\n this.isOpened = true;\n };\n\n close = () => {\n this.isOpened = false;\n };\n}\n","<div class=\"c-quick-action d-flex align-items-center gap-16\" [class.active]=\"isOpened\">\r\n <div class=\"flex-1 T14R\">\r\n <ng-content select=\"[sdMessage]\"></ng-content>\r\n </div>\r\n <ng-content select=\"[sdAction]\"></ng-content>\r\n</div>\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;MAUa,aAAa,CAAA;IACxB,QAAQ,GAAG,KAAK;IAChB,IAAuB,SAAS,CAAC,QAAyC,EAAA;AACxE,QAAA,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ;IAC5B;AACA,IAAA,WAAA,GAAA,EAAe;IACf,IAAI,GAAG,MAAK;AACV,QAAA,IAAI,CAAC,QAAQ,GAAG,IAAI;AACtB,IAAA,CAAC;IAED,KAAK,GAAG,MAAK;AACX,QAAA,IAAI,CAAC,QAAQ,GAAG,KAAK;AACvB,IAAA,CAAC;wGAZU,aAAa,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;4FAAb,aAAa,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,EAAA,SAAA,EAAA,CAAA,UAAA,EAAA,WAAA,CAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECV1B,qQAMA,EAAA,MAAA,EAAA,CAAA,8ZAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EDEY,YAAY,EAAA,CAAA,EAAA,CAAA;;4FAEX,aAAa,EAAA,UAAA,EAAA,CAAA;kBAPzB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,iBAAiB,EAAA,UAAA,EAGf,IAAI,EAAA,OAAA,EACP,CAAC,YAAY,CAAC,EAAA,QAAA,EAAA,qQAAA,EAAA,MAAA,EAAA,CAAA,8ZAAA,CAAA,EAAA;wDAIA,SAAS,EAAA,CAAA;sBAA/B,KAAK;uBAAC,UAAU;;;AEZnB;;AAEG;;;;"}
|