@livenetworks/ashlar 1.6.0 → 2.0.0
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/LICENSE +641 -0
- package/README.md +202 -86
- package/{js → components}/COMPONENTS.md +1116 -1108
- package/{js → components}/index.js +81 -58
- package/{js → components}/ln-accordion/README.md +7 -6
- package/components/ln-accordion/ln-accordion-dev.scss +8 -0
- package/components/ln-accordion/ln-accordion.js +1 -0
- package/components/ln-accordion/ln-accordion.schema.json +30 -0
- package/components/ln-accordion/ln-accordion.scss +8 -0
- package/{js → components}/ln-accordion/src/ln-accordion.js +8 -2
- package/{js → components}/ln-ajax/README.md +171 -160
- package/components/ln-ajax/ln-ajax-dev.scss +8 -0
- package/components/ln-ajax/ln-ajax.js +1 -0
- package/components/ln-ajax/ln-ajax.schema.json +30 -0
- package/{js → components}/ln-ajax/src/ln-ajax.js +65 -30
- package/{js → components}/ln-api-connector/README.md +27 -5
- package/components/ln-api-connector/ln-api-connector.js +1 -0
- package/components/ln-api-connector/ln-api-connector.schema.json +96 -0
- package/components/ln-api-connector/src/connector-core.js +97 -0
- package/components/ln-api-connector/src/ln-api-connector.js +447 -0
- package/{js → components}/ln-api-queue/README.md +12 -9
- package/components/ln-api-queue/ln-api-queue.js +1 -0
- package/components/ln-api-queue/ln-api-queue.schema.json +34 -0
- package/{js → components}/ln-api-queue/src/ln-api-queue.js +33 -14
- package/{js → components}/ln-api-queue/src/queue-storage.js +7 -3
- package/{js → components}/ln-autoresize/README.md +129 -127
- package/components/ln-autoresize/ln-autoresize-dev.scss +8 -0
- package/components/ln-autoresize/ln-autoresize.js +1 -0
- package/components/ln-autoresize/ln-autoresize.schema.json +22 -0
- package/{js → components}/ln-autoresize/src/ln-autoresize.js +8 -1
- package/{js → components}/ln-autosave/README.md +127 -124
- package/components/ln-autosave/ln-autosave-dev.scss +13 -0
- package/components/ln-autosave/ln-autosave.js +1 -0
- package/components/ln-autosave/ln-autosave.schema.json +48 -0
- package/components/ln-autosave/src/autosave-model.js +34 -0
- package/{js → components}/ln-autosave/src/ln-autosave.js +65 -58
- package/components/ln-chart/README.md +145 -0
- package/components/ln-chart/ln-chart-dev.scss +20 -0
- package/components/ln-chart/ln-chart.js +1 -0
- package/components/ln-chart/ln-chart.schema.json +146 -0
- package/components/ln-chart/ln-chart.scss +8 -0
- package/components/ln-chart/src/chart-model.js +154 -0
- package/components/ln-chart/src/ln-chart.js +176 -0
- package/{js → components}/ln-circular-progress/README.md +15 -14
- package/components/ln-circular-progress/ln-circular-progress-dev.scss +8 -0
- package/components/ln-circular-progress/ln-circular-progress.js +1 -0
- package/components/ln-circular-progress/ln-circular-progress.schema.json +42 -0
- package/{js → components}/ln-circular-progress/src/ln-circular-progress.js +32 -50
- package/components/ln-confirm/README.md +216 -0
- package/components/ln-confirm/ln-confirm-dev.scss +24 -0
- package/components/ln-confirm/ln-confirm.js +1 -0
- package/components/ln-confirm/ln-confirm.schema.json +66 -0
- package/components/ln-confirm/ln-confirm.scss +24 -0
- package/{js → components}/ln-confirm/src/ln-confirm.js +180 -167
- package/{js → components}/ln-core/README.md +374 -149
- package/components/ln-core/attrs.js +273 -0
- package/components/ln-core/compare.js +40 -0
- package/components/ln-core/crypto.js +265 -0
- package/components/ln-core/date.js +50 -0
- package/components/ln-core/dom.js +115 -0
- package/components/ln-core/events.js +122 -0
- package/components/ln-core/form.js +136 -0
- package/{js → components}/ln-core/hash.js +149 -92
- package/components/ln-core/helpers.js +33 -0
- package/components/ln-core/http.js +48 -0
- package/components/ln-core/index.js +11 -0
- package/components/ln-core/lifecycle.js +403 -0
- package/components/ln-core/ln-core.schema.json +109 -0
- package/components/ln-core/locale.js +55 -0
- package/components/ln-core/matching.js +78 -0
- package/components/ln-core/number.js +125 -0
- package/components/ln-core/progress.js +30 -0
- package/components/ln-core/template.js +206 -0
- package/{js → components}/ln-core/window-cache.js +247 -213
- package/{js → components}/ln-couchdb-connector/README.md +7 -5
- package/components/ln-couchdb-connector/ln-couchdb-connector.js +1 -0
- package/components/ln-couchdb-connector/ln-couchdb-connector.schema.json +50 -0
- package/{js → components}/ln-couchdb-connector/src/ln-couchdb-connector.js +29 -43
- package/{js → components}/ln-data-coordinator/README.md +109 -73
- package/components/ln-data-coordinator/ln-data-coordinator-dev.scss +8 -0
- package/components/ln-data-coordinator/ln-data-coordinator.js +1 -0
- package/components/ln-data-coordinator/ln-data-coordinator.schema.json +196 -0
- package/components/ln-data-coordinator/src/data-read-policy.js +41 -0
- package/{js → components}/ln-data-coordinator/src/ln-data-coordinator.js +411 -154
- package/{js → components}/ln-data-coordinator/src/mutation-receipts.js +0 -5
- package/{js → components}/ln-data-store/README.md +42 -17
- package/components/ln-data-store/ln-data-store-dev.scss +13 -0
- package/components/ln-data-store/ln-data-store.js +1 -0
- package/components/ln-data-store/ln-data-store.schema.json +84 -0
- package/components/ln-data-store/src/data-store-model.js +155 -0
- package/{js → components}/ln-data-store/src/ln-data-store.js +407 -105
- package/components/ln-data-store/src/window-index.js +119 -0
- package/{js → components}/ln-date/README.md +17 -7
- package/{js → components}/ln-date/ln-date-dev.scss +14 -14
- package/components/ln-date/ln-date.js +1 -0
- package/components/ln-date/ln-date.schema.json +92 -0
- package/components/ln-date/src/date-model.js +186 -0
- package/components/ln-date/src/ln-date.js +486 -0
- package/components/ln-debug/README.md +132 -0
- package/components/ln-debug/ln-debug.js +1 -0
- package/components/ln-debug/ln-debug.schema.json +28 -0
- package/components/ln-debug/src/console-sink.js +19 -0
- package/components/ln-debug/src/debug-verifier.js +331 -0
- package/components/ln-debug/src/gate.js +95 -0
- package/components/ln-debug/src/generated-attributes.js +299 -0
- package/components/ln-debug/src/ln-debug.js +60 -0
- package/{js → components}/ln-dropdown/README.md +150 -140
- package/components/ln-dropdown/ln-dropdown-dev.scss +13 -0
- package/components/ln-dropdown/ln-dropdown.js +1 -0
- package/components/ln-dropdown/ln-dropdown.schema.json +90 -0
- package/components/ln-dropdown/ln-dropdown.scss +18 -0
- package/{js → components}/ln-dropdown/src/ln-dropdown.js +114 -11
- package/{js → components}/ln-editor/README.md +11 -9
- package/components/ln-editor/ln-editor-dev.scss +18 -0
- package/components/ln-editor/ln-editor.js +1 -0
- package/components/ln-editor/ln-editor.schema.json +58 -0
- package/components/ln-editor/ln-editor.scss +13 -0
- package/{js → components}/ln-editor/src/ln-editor.js +59 -11
- package/{js → components}/ln-external-links/README.md +10 -8
- package/components/ln-external-links/ln-external-links.js +1 -0
- package/components/ln-external-links/ln-external-links.schema.json +18 -0
- package/{js → components}/ln-external-links/src/ln-external-links.js +13 -11
- package/{js → components}/ln-fill/README.md +6 -8
- package/components/ln-fill/ln-fill.js +1 -0
- package/components/ln-fill/ln-fill.schema.json +23 -0
- package/{js → components}/ln-fill/src/ln-fill.js +7 -1
- package/components/ln-filter/README.md +131 -0
- package/components/ln-filter/ln-filter-dev.scss +13 -0
- package/components/ln-filter/ln-filter.js +1 -0
- package/components/ln-filter/ln-filter.schema.json +153 -0
- package/components/ln-filter/src/filter-model.js +185 -0
- package/components/ln-filter/src/ln-filter.js +435 -0
- package/{js → components}/ln-form/README.md +260 -264
- package/components/ln-form/ln-form-dev.scss +8 -0
- package/components/ln-form/ln-form.js +1 -0
- package/components/ln-form/ln-form.schema.json +45 -0
- package/{js → components}/ln-form/src/ln-form.js +107 -99
- package/{js → components}/ln-http/README.md +11 -6
- package/components/ln-http/ln-http.js +1 -0
- package/components/ln-http/ln-http.schema.json +6 -0
- package/components/ln-http/src/http-core.js +51 -0
- package/{js → components}/ln-http/src/ln-http.js +28 -33
- package/{js → components}/ln-icon/README.md +16 -9
- package/components/ln-icon/ln-icon.schema.json +6 -0
- package/components/ln-include/README.md +75 -0
- package/components/ln-include/ln-include-dev.scss +13 -0
- package/components/ln-include/ln-include.js +1 -0
- package/components/ln-include/ln-include.schema.json +23 -0
- package/components/ln-include/src/ln-include.js +111 -0
- package/components/ln-key/README.md +130 -0
- package/components/ln-key/ln-key-dev.scss +18 -0
- package/components/ln-key/ln-key.js +1 -0
- package/components/ln-key/ln-key.schema.json +56 -0
- package/components/ln-key/src/key-model.js +146 -0
- package/components/ln-key/src/ln-key.js +201 -0
- package/{js → components}/ln-link/README.md +7 -9
- package/components/ln-link/ln-link-dev.scss +8 -0
- package/components/ln-link/ln-link.js +1 -0
- package/components/ln-link/ln-link.schema.json +22 -0
- package/{js → components}/ln-link/src/ln-link.js +16 -11
- package/components/ln-list/README.md +152 -0
- package/components/ln-list/ln-list-dev.scss +8 -0
- package/components/ln-list/ln-list.js +1 -0
- package/components/ln-list/ln-list.schema.json +166 -0
- package/components/ln-list/ln-list.scss +25 -0
- package/{js → components}/ln-list/src/ln-list.js +1301 -1216
- package/{js → components}/ln-modal/README.md +13 -10
- package/components/ln-modal/ln-modal-dev.scss +18 -0
- package/components/ln-modal/ln-modal.js +1 -0
- package/components/ln-modal/ln-modal.schema.json +54 -0
- package/components/ln-modal/ln-modal.scss +51 -0
- package/{js → components}/ln-modal/src/ln-modal.js +164 -137
- package/{js → components}/ln-nav/README.md +11 -11
- package/components/ln-nav/ln-nav.js +1 -0
- package/components/ln-nav/ln-nav.schema.json +25 -0
- package/{js → components}/ln-nav/src/ln-nav.js +25 -14
- package/components/ln-number/README.md +205 -0
- package/{js → components}/ln-number/ln-number-dev.scss +13 -13
- package/components/ln-number/ln-number.js +1 -0
- package/components/ln-number/ln-number.schema.json +63 -0
- package/components/ln-number/src/ln-number.js +400 -0
- package/components/ln-number/src/number-model.js +31 -0
- package/components/ln-obfuscator/README.md +60 -0
- package/components/ln-obfuscator/ln-obfuscator.js +1 -0
- package/components/ln-obfuscator/ln-obfuscator.schema.json +49 -0
- package/components/ln-obfuscator/src/ln-obfuscator.js +159 -0
- package/components/ln-obfuscator/src/obfuscator-model.js +250 -0
- package/{js → components}/ln-options/README.md +3 -1
- package/components/ln-options/ln-options-dev.scss +13 -0
- package/components/ln-options/ln-options.js +1 -0
- package/components/ln-options/ln-options.schema.json +41 -0
- package/{js → components}/ln-options/src/ln-options.js +13 -5
- package/components/ln-persist/README.md +151 -0
- package/components/ln-persist/ln-persist.js +1 -0
- package/components/ln-persist/ln-persist.schema.json +28 -0
- package/components/ln-persist/src/ln-persist.js +83 -0
- package/components/ln-picklist/README.md +230 -0
- package/components/ln-picklist/ln-picklist-dev.scss +22 -0
- package/components/ln-picklist/ln-picklist.js +1 -0
- package/components/ln-picklist/ln-picklist.schema.json +49 -0
- package/components/ln-picklist/src/ln-picklist.js +228 -0
- package/{js → components}/ln-popover/README.md +164 -162
- package/components/ln-popover/ln-popover-dev.scss +13 -0
- package/components/ln-popover/ln-popover.js +1 -0
- package/components/ln-popover/ln-popover.schema.json +82 -0
- package/components/ln-popover/ln-popover.scss +18 -0
- package/{js → components}/ln-popover/src/ln-popover.js +42 -36
- package/{js → components}/ln-progress/README.md +410 -413
- package/components/ln-progress/ln-progress-dev.scss +8 -0
- package/components/ln-progress/ln-progress.js +1 -0
- package/components/ln-progress/ln-progress.schema.json +40 -0
- package/components/ln-progress/src/ln-progress.js +91 -0
- package/components/ln-progress/src/progress-model.js +20 -0
- package/{js → components}/ln-router/README.md +443 -432
- package/components/ln-router/ln-router-dev.scss +13 -0
- package/components/ln-router/ln-router.js +1 -0
- package/components/ln-router/ln-router.schema.json +68 -0
- package/{js → components}/ln-router/src/ln-router.js +585 -539
- package/components/ln-router/src/router-model.js +50 -0
- package/components/ln-scroll/README.md +45 -0
- package/components/ln-scroll/ln-scroll.js +1 -0
- package/components/ln-scroll/ln-scroll.schema.json +85 -0
- package/components/ln-scroll/src/ln-scroll.js +150 -0
- package/components/ln-search/README.md +188 -0
- package/components/ln-search/ln-search-dev.scss +13 -0
- package/components/ln-search/ln-search.js +1 -0
- package/components/ln-search/ln-search.schema.json +103 -0
- package/components/ln-search/src/ln-search.js +330 -0
- package/{js → components}/ln-slug/README.md +6 -3
- package/components/ln-slug/ln-slug-dev.scss +18 -0
- package/components/ln-slug/ln-slug.js +1 -0
- package/components/ln-slug/ln-slug.schema.json +23 -0
- package/{js → components}/ln-slug/src/ln-slug.js +20 -13
- package/components/ln-slug/src/slug-model.js +21 -0
- package/{js → components}/ln-sort/README.md +178 -170
- package/{js → components}/ln-sort/ln-sort-dev.scss +8 -8
- package/components/ln-sort/ln-sort.js +1 -0
- package/components/ln-sort/ln-sort.schema.json +104 -0
- package/components/ln-sort/src/ln-sort.js +321 -0
- package/components/ln-sort/src/sort-model.js +117 -0
- package/{js → components}/ln-sortable/README.md +7 -11
- package/components/ln-sortable/ln-sortable-dev.scss +13 -0
- package/components/ln-sortable/ln-sortable.js +1 -0
- package/components/ln-sortable/ln-sortable.schema.json +36 -0
- package/{js → components}/ln-sortable/src/ln-sortable.js +8 -13
- package/{js → components}/ln-stat/README.md +3 -1
- package/components/ln-stat/ln-stat-dev.scss +8 -0
- package/components/ln-stat/ln-stat.js +1 -0
- package/components/ln-stat/ln-stat.schema.json +32 -0
- package/{js → components}/ln-stat/src/ln-stat.js +14 -18
- package/components/ln-stat/src/stat-model.js +28 -0
- package/{js → components}/ln-table/README.md +37 -24
- package/{js → components}/ln-table/ln-table-dev.scss +17 -17
- package/components/ln-table/ln-table.js +1 -0
- package/components/ln-table/ln-table.schema.json +211 -0
- package/components/ln-table/ln-table.scss +15 -0
- package/{js → components}/ln-table/src/ln-table.js +1365 -1493
- package/components/ln-table/src/table-model.js +98 -0
- package/components/ln-table-coordinator/README.md +61 -0
- package/components/ln-table-coordinator/ln-table-coordinator.js +1 -0
- package/components/ln-table-coordinator/ln-table-coordinator.schema.json +93 -0
- package/components/ln-table-coordinator/src/ln-table-coordinator.js +193 -0
- package/{js → components}/ln-tabs/README.md +32 -14
- package/components/ln-tabs/ln-tabs-dev.scss +24 -0
- package/components/ln-tabs/ln-tabs.js +1 -0
- package/components/ln-tabs/ln-tabs.schema.json +75 -0
- package/components/ln-tabs/ln-tabs.scss +8 -0
- package/components/ln-tabs/src/ln-tabs.js +207 -0
- package/components/ln-tabs/src/tabs-model.js +82 -0
- package/{js → components}/ln-time/README.md +96 -95
- package/components/ln-time/ln-time-dev.scss +13 -0
- package/components/ln-time/ln-time.js +1 -0
- package/components/ln-time/ln-time.schema.json +38 -0
- package/{js → components}/ln-time/src/ln-time.js +206 -223
- package/components/ln-time/src/time-model.js +64 -0
- package/{js → components}/ln-toast/README.md +23 -5
- package/components/ln-toast/ln-toast-dev.scss +8 -0
- package/components/ln-toast/ln-toast.js +1 -0
- package/components/ln-toast/ln-toast.schema.json +65 -0
- package/components/ln-toast/ln-toast.scss +59 -0
- package/{js → components}/ln-toast/src/ln-toast.js +233 -232
- package/{js → components}/ln-toggle/README.md +198 -196
- package/{js → components}/ln-toggle/ln-toggle-dev.scss +13 -13
- package/components/ln-toggle/ln-toggle.js +1 -0
- package/components/ln-toggle/ln-toggle.schema.json +52 -0
- package/components/ln-toggle/ln-toggle.scss +37 -0
- package/{js → components}/ln-toggle/src/ln-toggle.js +61 -46
- package/{js → components}/ln-tooltip/README.md +6 -6
- package/{js → components}/ln-tooltip/ln-tooltip-dev.scss +9 -9
- package/components/ln-tooltip/ln-tooltip.js +1 -0
- package/components/ln-tooltip/ln-tooltip.schema.json +86 -0
- package/components/ln-tooltip/ln-tooltip.scss +9 -0
- package/{js → components}/ln-tooltip/src/ln-tooltip.js +14 -3
- package/{js → components}/ln-translations/README.md +3 -1
- package/components/ln-translations/ln-translations-dev.scss +13 -0
- package/components/ln-translations/ln-translations.js +1 -0
- package/components/ln-translations/ln-translations.schema.json +120 -0
- package/{js → components}/ln-translations/src/ln-translations.js +25 -10
- package/components/ln-ui-coordinator/README.md +101 -0
- package/components/ln-ui-coordinator/ln-ui-coordinator-dev.scss +8 -0
- package/components/ln-ui-coordinator/ln-ui-coordinator.js +1 -0
- package/components/ln-ui-coordinator/ln-ui-coordinator.schema.json +60 -0
- package/{js/ln-modal-coordinator/src/ln-modal-coordinator.js → components/ln-ui-coordinator/src/ln-ui-coordinator.js} +403 -345
- package/components/ln-upload/README.md +133 -0
- package/components/ln-upload/ln-upload-dev.scss +18 -0
- package/components/ln-upload/ln-upload.js +1 -0
- package/components/ln-upload/ln-upload.schema.json +193 -0
- package/components/ln-upload/ln-upload.scss +20 -0
- package/components/ln-upload/src/ln-upload.js +652 -0
- package/components/ln-upload/src/upload-model.js +78 -0
- package/{js → components}/ln-validate/README.md +182 -180
- package/{js → components}/ln-validate/ln-validate-dev.scss +15 -15
- package/components/ln-validate/ln-validate.js +1 -0
- package/components/ln-validate/ln-validate.schema.json +50 -0
- package/components/ln-validate/ln-validate.scss +7 -0
- package/{js → components}/ln-validate/src/ln-validate.js +23 -45
- package/components/ln-validate/src/validate-model.js +64 -0
- package/components/ln-websocket-connector/README.md +166 -0
- package/components/ln-websocket-connector/ln-websocket-connector.js +1 -0
- package/components/ln-websocket-connector/ln-websocket-connector.schema.json +29 -0
- package/components/ln-websocket-connector/src/ln-websocket-connector.js +279 -0
- package/ln-ashlar.html-data.json +1796 -0
- package/package.json +84 -61
- package/{scss → theme}/base/_global.scss +1 -2
- package/{scss → theme}/base/_reset.scss +1 -1
- package/{scss → theme}/base/_typography.scss +2 -0
- package/theme/brand.css +73 -0
- package/{scss → theme}/components/_app-shell.scss +8 -0
- package/theme/components/_button.scss +24 -0
- package/theme/components/_chart.scss +5 -0
- package/theme/components/_confirm.scss +6 -0
- package/{scss → theme}/components/_date.scss +30 -22
- package/{scss → theme}/components/_dropdown.scss +6 -1
- package/theme/components/_form.scss +140 -0
- package/{scss → theme}/components/_layout.scss +6 -0
- package/{scss → theme}/components/_ln-table.scss +1 -6
- package/theme/components/_picklist.scss +3 -0
- package/{scss → theme}/components/_sort.scss +10 -10
- package/theme/components/_status-badge.scss +6 -0
- package/{scss → theme}/components/_table.scss +16 -0
- package/{scss → theme}/components/_tabs.scss +0 -4
- package/theme/components/_toast.scss +48 -0
- package/{scss → theme}/components/_toggle.scss +1 -1
- package/theme/components/_upload.scss +45 -0
- package/{scss → theme}/config/_breakpoints.scss +1 -1
- package/theme/config/_contrast.scss +128 -0
- package/{scss → theme}/config/_density.scss +191 -205
- package/theme/config/_palette.scss +274 -0
- package/theme/config/_theme.scss +293 -0
- package/{scss → theme}/config/_tokens.scss +285 -441
- package/{scss → theme}/config/mixins/_accordion.scss +1 -1
- package/{scss → theme}/config/mixins/_alert.scss +1 -0
- package/{scss → theme}/config/mixins/_app-shell.scss +4 -2
- package/{scss → theme}/config/mixins/_borders.scss +2 -0
- package/theme/config/mixins/_btn.scss +175 -0
- package/{scss → theme}/config/mixins/_card.scss +55 -46
- package/theme/config/mixins/_chart.scss +82 -0
- package/{scss → theme}/config/mixins/_collapsible.scss +2 -1
- package/{scss → theme}/config/mixins/_colors.scss +8 -14
- package/{scss → theme}/config/mixins/_diagnostics.scss +48 -48
- package/theme/config/mixins/_dropdown.scss +169 -0
- package/{scss → theme}/config/mixins/_editor.scss +0 -7
- package/{scss → theme}/config/mixins/_filter.scss +47 -47
- package/{scss → theme}/config/mixins/_footer.scss +1 -1
- package/{scss → theme}/config/mixins/_form.scss +49 -18
- package/{scss → theme}/config/mixins/_index.scss +62 -61
- package/{scss → theme}/config/mixins/_layout.scss +6 -2
- package/{scss → theme}/config/mixins/_ln-table.scss +31 -10
- package/{scss → theme}/config/mixins/_loader.scss +1 -1
- package/{scss → theme}/config/mixins/_modal.scss +145 -149
- package/{scss → theme}/config/mixins/_motion.scss +13 -0
- package/{scss → theme}/config/mixins/_nav.scss +7 -7
- package/theme/config/mixins/_picklist.scss +66 -0
- package/theme/config/mixins/_popover.scss +96 -0
- package/{scss → theme}/config/mixins/_sidebar.scss +7 -4
- package/{scss → theme}/config/mixins/_sort.scss +43 -42
- package/{scss → theme}/config/mixins/_status-badge.scss +15 -2
- package/{scss → theme}/config/mixins/_table.scss +25 -14
- package/{scss → theme}/config/mixins/_tabs.scss +1 -1
- package/{scss → theme}/config/mixins/_toast.scss +174 -179
- package/{scss → theme}/config/mixins/_tooltip.scss +2 -2
- package/{scss → theme}/config/mixins/_typography.scss +16 -5
- package/{scss → theme}/config/mixins/_upload.scss +8 -6
- package/theme/ln-ashlar-core.scss +24 -0
- package/theme/ln-ashlar-dev.scss +66 -0
- package/theme/ln-ashlar-landing.scss +56 -0
- package/{scss/ln-ashlar.scss → theme/ln-ashlar-theme.scss} +63 -69
- package/theme/ln-ashlar.scss +8 -0
- package/theme/presentation/_bento.scss +151 -0
- package/theme/presentation/_cta.scss +111 -0
- package/theme/presentation/_effects.scss +216 -0
- package/theme/presentation/_features.scss +108 -0
- package/theme/presentation/_footer.scss +129 -0
- package/theme/presentation/_hero.scss +158 -0
- package/theme/presentation/_layout.scss +170 -0
- package/theme/presentation/_navbar.scss +140 -0
- package/theme/presentation/_pricing.scss +262 -0
- package/theme/presentation/_stats.scss +87 -0
- package/theme/presentation/_testimonials.scss +124 -0
- package/theme/presentation/_tokens.scss +39 -0
- package/theme/presentation/_typography.scss +163 -0
- package/{scss → theme}/utilities/_animations.scss +38 -0
- package/{scss → theme}/utilities/_utilities.scss +6 -0
- package/web-types.json +2312 -0
- package/js/ln-accordion/ln-accordion.js +0 -1
- package/js/ln-ajax/ln-ajax.js +0 -1
- package/js/ln-api-connector/ln-api-connector.js +0 -1
- package/js/ln-api-connector/src/ln-api-connector.js +0 -368
- package/js/ln-api-queue/ln-api-queue.js +0 -1
- package/js/ln-autoresize/ln-autoresize.js +0 -1
- package/js/ln-autosave/ln-autosave.js +0 -1
- package/js/ln-circular-progress/ln-circular-progress.js +0 -1
- package/js/ln-confirm/README.md +0 -162
- package/js/ln-confirm/_ln-confirm.scss +0 -24
- package/js/ln-confirm/ln-confirm.js +0 -1
- package/js/ln-core/crypto.js +0 -83
- package/js/ln-core/helpers.js +0 -788
- package/js/ln-core/index.js +0 -7
- package/js/ln-core/persist.js +0 -97
- package/js/ln-couchdb-connector/ln-couchdb-connector.js +0 -1
- package/js/ln-data-coordinator/ln-data-coordinator.js +0 -1
- package/js/ln-data-coordinator/src/data-read-policy.js +0 -18
- package/js/ln-data-store/ln-data-store.js +0 -1
- package/js/ln-date/ln-date.js +0 -1
- package/js/ln-date/src/ln-date.js +0 -603
- package/js/ln-debug/README.md +0 -58
- package/js/ln-debug/ln-debug.js +0 -1
- package/js/ln-debug/src/ln-debug.js +0 -19
- package/js/ln-dropdown/ln-dropdown.js +0 -1
- package/js/ln-dropdown/ln-dropdown.scss +0 -15
- package/js/ln-editor/ln-editor.js +0 -1
- package/js/ln-editor/ln-editor.scss +0 -43
- package/js/ln-external-links/ln-external-links.js +0 -1
- package/js/ln-fill/ln-fill.js +0 -1
- package/js/ln-filter/README.md +0 -189
- package/js/ln-filter/ln-filter-dev.scss +0 -8
- package/js/ln-filter/ln-filter.js +0 -1
- package/js/ln-filter/src/ln-filter.js +0 -419
- package/js/ln-form/ln-form.js +0 -1
- package/js/ln-http/ln-http.js +0 -1
- package/js/ln-link/ln-link.js +0 -1
- package/js/ln-list/README.md +0 -129
- package/js/ln-list/ln-list.js +0 -1
- package/js/ln-list/ln-list.scss +0 -28
- package/js/ln-modal/ln-modal-dev.scss +0 -13
- package/js/ln-modal/ln-modal.js +0 -1
- package/js/ln-modal/ln-modal.scss +0 -35
- package/js/ln-modal-coordinator/README.md +0 -99
- package/js/ln-modal-coordinator/ln-modal-coordinator-dev.scss +0 -8
- package/js/ln-modal-coordinator/ln-modal-coordinator.js +0 -1
- package/js/ln-nav/ln-nav.js +0 -1
- package/js/ln-number/README.md +0 -149
- package/js/ln-number/ln-number.js +0 -1
- package/js/ln-number/src/ln-number.js +0 -443
- package/js/ln-options/ln-options.js +0 -1
- package/js/ln-popover/ln-popover.js +0 -1
- package/js/ln-progress/ln-progress.js +0 -1
- package/js/ln-progress/src/ln-progress.js +0 -98
- package/js/ln-router/ln-router.js +0 -1
- package/js/ln-search/README.md +0 -158
- package/js/ln-search/ln-search-dev.scss +0 -8
- package/js/ln-search/ln-search.js +0 -1
- package/js/ln-search/src/ln-search.js +0 -117
- package/js/ln-slug/ln-slug.js +0 -1
- package/js/ln-sort/ln-sort.js +0 -1
- package/js/ln-sort/src/ln-sort.js +0 -178
- package/js/ln-sortable/ln-sortable.js +0 -1
- package/js/ln-stat/ln-stat.js +0 -1
- package/js/ln-table/ln-table.js +0 -1
- package/js/ln-table/ln-table.scss +0 -11
- package/js/ln-table-coordinator/README.md +0 -73
- package/js/ln-table-coordinator/ln-table-coordinator.js +0 -1
- package/js/ln-table-coordinator/src/ln-table-coordinator.js +0 -160
- package/js/ln-tabs/ln-tabs-dev.scss +0 -18
- package/js/ln-tabs/ln-tabs.js +0 -1
- package/js/ln-tabs/src/ln-tabs.js +0 -188
- package/js/ln-time/ln-time.js +0 -1
- package/js/ln-toast/ln-toast.js +0 -1
- package/js/ln-toggle/ln-toggle.js +0 -1
- package/js/ln-tooltip/ln-tooltip.js +0 -1
- package/js/ln-tooltip/ln-tooltip.scss +0 -9
- package/js/ln-translations/ln-translations.js +0 -1
- package/js/ln-upload/README.md +0 -255
- package/js/ln-upload/ln-upload.js +0 -1
- package/js/ln-upload/ln-upload.scss +0 -20
- package/js/ln-upload/src/ln-upload.js +0 -423
- package/js/ln-validate/ln-validate.js +0 -1
- package/scss/components/_button.scss +0 -20
- package/scss/components/_confirm.scss +0 -5
- package/scss/components/_form.scss +0 -107
- package/scss/components/_status-badge.scss +0 -4
- package/scss/components/_toast.scss +0 -68
- package/scss/components/_upload.scss +0 -51
- package/scss/config/_theme.scss +0 -216
- package/scss/config/mixins/_btn.scss +0 -179
- package/scss/config/mixins/_confirm.scss +0 -31
- package/scss/config/mixins/_dropdown.scss +0 -141
- package/scss/config/mixins/_popover.scss +0 -64
- package/scss/ln-ashlar-dev.scss +0 -39
- /package/{js → components}/ln-core/positioning.js +0 -0
- /package/{js → components}/ln-core/reactive.js +0 -0
- /package/{js → components}/ln-filter/ln-filter.scss +0 -0
- /package/{js → components}/ln-icon/ln-icon.js +0 -0
- /package/{js → components}/ln-icon/src/ln-icon.js +0 -0
- /package/{js → components}/ln-search/ln-search.scss +0 -0
- /package/{js → components}/ln-toast/template.html +0 -0
- /package/{scss → theme}/components/_accordion.scss +0 -0
- /package/{scss → theme}/components/_ajax.scss +0 -0
- /package/{scss → theme}/components/_alert.scss +0 -0
- /package/{scss → theme}/components/_avatar.scss +0 -0
- /package/{scss → theme}/components/_breadcrumbs.scss +0 -0
- /package/{scss → theme}/components/_card.scss +0 -0
- /package/{scss → theme}/components/_chip.scss +0 -0
- /package/{scss → theme}/components/_circular-progress.scss +0 -0
- /package/{scss → theme}/components/_editor.scss +0 -0
- /package/{scss → theme}/components/_empty-state.scss +0 -0
- /package/{scss → theme}/components/_filter.scss +0 -0
- /package/{scss → theme}/components/_link.scss +0 -0
- /package/{scss → theme}/components/_loader.scss +0 -0
- /package/{scss → theme}/components/_modal.scss +0 -0
- /package/{scss → theme}/components/_nav.scss +0 -0
- /package/{scss → theme}/components/_page-header.scss +0 -0
- /package/{scss → theme}/components/_popover.scss +0 -0
- /package/{scss → theme}/components/_progress.scss +0 -0
- /package/{scss → theme}/components/_prose.scss +0 -0
- /package/{scss → theme}/components/_scrollbar.scss +0 -0
- /package/{scss → theme}/components/_sections.scss +0 -0
- /package/{scss → theme}/components/_sidebar.scss +0 -0
- /package/{scss → theme}/components/_stat-card.scss +0 -0
- /package/{scss → theme}/components/_stepper.scss +0 -0
- /package/{scss → theme}/components/_timeline.scss +0 -0
- /package/{scss → theme}/components/_tooltip.scss +0 -0
- /package/{scss → theme}/components/_translations.scss +0 -0
- /package/{scss → theme}/config/_icons.scss +0 -0
- /package/{scss → theme}/config/_mixins.scss +0 -0
- /package/{scss → theme}/config/mixins/_ajax.scss +0 -0
- /package/{scss → theme}/config/mixins/_avatar.scss +0 -0
- /package/{scss → theme}/config/mixins/_breadcrumbs.scss +0 -0
- /package/{scss → theme}/config/mixins/_breakpoints.scss +0 -0
- /package/{scss → theme}/config/mixins/_chip.scss +0 -0
- /package/{scss → theme}/config/mixins/_circular-progress.scss +0 -0
- /package/{scss → theme}/config/mixins/_display.scss +0 -0
- /package/{scss → theme}/config/mixins/_empty-state.scss +0 -0
- /package/{scss → theme}/config/mixins/_focus.scss +0 -0
- /package/{scss → theme}/config/mixins/_interaction.scss +0 -0
- /package/{scss → theme}/config/mixins/_kbd.scss +0 -0
- /package/{scss → theme}/config/mixins/_link.scss +0 -0
- /package/{scss → theme}/config/mixins/_page-header.scss +0 -0
- /package/{scss → theme}/config/mixins/_position.scss +0 -0
- /package/{scss → theme}/config/mixins/_progress.scss +0 -0
- /package/{scss → theme}/config/mixins/_prose.scss +0 -0
- /package/{scss → theme}/config/mixins/_shadows.scss +0 -0
- /package/{scss → theme}/config/mixins/_sizing.scss +0 -0
- /package/{scss → theme}/config/mixins/_spacing.scss +0 -0
- /package/{scss → theme}/config/mixins/_stat-card.scss +0 -0
- /package/{scss → theme}/config/mixins/_stepper.scss +0 -0
- /package/{scss → theme}/config/mixins/_timeline.scss +0 -0
- /package/{scss → theme}/config/mixins/_transitions.scss +0 -0
- /package/{scss → theme}/config/mixins/_translations.scss +0 -0
- /package/{scss → theme}/tabler-icons.txt +0 -0
package/js/ln-table/ln-table.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(function(){"use strict";if(typeof window<"u"){const l=console.warn;console.warn=function(...o){typeof o[0]=="string"&&(o[0].startsWith("[ln-")||o[0].startsWith("[lnCore"))&&!(document.documentElement.hasAttribute("data-ln-debug")||document.body&&document.body.hasAttribute("data-ln-debug"))||l.apply(console,o)}}const q={};function N(l,o){q[l]||(q[l]=document.querySelector('[data-ln-template="'+l+'"]'));const a=q[l];return a?a.content.cloneNode(!0):(console.warn("["+(o||"ln-core")+'] Template "'+l+'" not found'),null)}function T(l,o,a){l.dispatchEvent(new CustomEvent(o,{bubbles:!0,detail:a||{}}))}function Z(l,o,a){l._applyFilterAndSort(),l._vStart=-1,l._vEnd=-1,l._render(),l._updateFooter();const g={sort:l.currentSort,filters:l.currentFilters,search:l.currentSearch};g[a]=l.name,T(l.dom,o,g)}function W(l,o){if(!l||!o)return l;const a=l.querySelectorAll("[data-ln-field]");for(let f=0;f<a.length;f++){const h=a[f],p=h.getAttribute("data-ln-field");o[p]!=null&&(h.textContent=o[p])}const g=l.querySelectorAll("[data-ln-attr]");for(let f=0;f<g.length;f++){const h=g[f],p=h.getAttribute("data-ln-attr").split(",");for(let y=0;y<p.length;y++){const S=p[y].trim().split(":");if(S.length!==2)continue;const E=S[0].trim(),D=S[1].trim();o[D]!=null&&h.setAttribute(E,o[D])}}const A=l.querySelectorAll("[data-ln-show]");for(let f=0;f<A.length;f++){const h=A[f],p=h.getAttribute("data-ln-show");p in o&&h.classList.toggle("hidden",!o[p])}const v=l.querySelectorAll("[data-ln-class]");for(let f=0;f<v.length;f++){const h=v[f],p=h.getAttribute("data-ln-class").split(",");for(let y=0;y<p.length;y++){const S=p[y].trim().split(":");if(S.length!==2)continue;const E=S[0].trim(),D=S[1].trim();D in o&&h.classList.toggle(E,!!o[D])}}return l}function $(l,o){l.matches&&l.matches("[data-ln-form], [data-ln-fillable]")&&l.dispatchEvent(new CustomEvent("ln-fill",{detail:o??null,bubbles:!0}));const a=l.querySelectorAll("[data-ln-form], [data-ln-fillable]");for(let g=0;g<a.length;g++)a[g].dispatchEvent(new CustomEvent("ln-fill",{detail:o??null,bubbles:!0}));return l}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._fillBound||(window.lnCore._fillBound=!0,document.addEventListener("ln-fill",function(l){if(!(!l.target.matches||!l.target.matches("[data-ln-fillable]")))if(l.detail)W(l.target,l.detail);else{const o=l.target.querySelectorAll("[data-ln-field]");for(let a=0;a<o.length;a++)o[a].textContent=""}})));function F(l,o){if(!l||!o)return l;const a=document.createTreeWalker(l,NodeFilter.SHOW_TEXT);for(;a.nextNode();){const v=a.currentNode;v.textContent.indexOf("{{")!==-1&&(v.textContent=v.textContent.replace(/\{\{\s*(\w+)\s*\}\}/g,function(f,h){return o[h]!==void 0?o[h]:""}))}const g=function(v,f){return o[f]!==void 0?o[f]:""},A=Array.from(l.querySelectorAll("*"));l.nodeType===1&&A.push(l);for(let v=0;v<A.length;v++){const f=A[v],h=f.attributes;for(let p=0;p<h.length;p++){const y=h[p];y.value.indexOf("{{")!==-1&&f.setAttribute(y.name,y.value.replace(/\{\{\s*(\w+)\s*\}\}/g,g))}}return l}function tt(l,o,a,g,A,v){const f={};for(let p=0;p<l.children.length;p++){const y=l.children[p],S=y.getAttribute("data-ln-key");S&&(f[S]=y)}const h=document.createDocumentFragment();for(let p=0;p<o.length;p++){const y=o[p],S=String(g(y));let E=f[S];if(E)A(E,y,p);else{const D=N(a,v);if(!D||(F(D,y),E=D.firstElementChild,!E))continue;E.setAttribute("data-ln-key",S),A(E,y,p)}h.appendChild(E)}l.textContent="",l.appendChild(h)}function P(l,o){if(!document.body){document.addEventListener("DOMContentLoaded",function(){P(l,o)}),console.warn("["+o+'] Script loaded before <body> — add "defer" to your <script> tag');return}l()}function z(l,o,a){if(l){const g=l.querySelector('[data-ln-template="'+o+'"]');if(g)return g.content.cloneNode(!0)}return N(o,a)}function O(l,o,a,g){if(l.nodeType!==1)return;const v=o.indexOf("[")!==-1||o.indexOf(".")!==-1||o.indexOf("#")!==-1?o:"["+o+"]",f=Array.from(l.querySelectorAll(v));l.matches&&l.matches(v)&&f.push(l);for(const h of f)h[a]||(h[a]=new g(h))}const V={mk:"mk-MK",de:"de-DE",fr:"fr-FR",es:"es-ES",it:"it-IT",nl:"nl-NL",pt:"pt-PT",ru:"ru-RU",bg:"bg-BG",hr:"hr-HR",sr:"sr-RS",sq:"sq-AL",el:"el-GR",en:"en-US"};function et(l){const o=l?l.closest("[lang]"):null,a=(o?o.getAttribute("lang")||o.lang:null)||(document.documentElement?document.documentElement.getAttribute("lang")||document.documentElement.lang:null)||navigator.language;if(!a)return"en-US";const g=a.trim().toLowerCase();return g.indexOf("-")===-1&&V[g]?V[g]:a}function B(l){return l.hasAttribute("data-ln-value")?l.getAttribute("data-ln-value"):l.textContent.trim()}function U(l){let o=!1;for(let a=0;a<l.length;a++){const g=l[a];if(!(g===""||g==null)&&(o=!0,!Number.isFinite(Number(g))))return"string"}return o?"number":"string"}function j(l,o,a,g){if(a==="number"){const f=parseFloat(l),h=parseFloat(o);return(isNaN(f)?0:f)-(isNaN(h)?0:h)}const A=l!=null?String(l):"",v=o!=null?String(o):"";return g?g.compare(A,v):A<v?-1:A>v?1:0}function nt(l,o,a,g,A={}){const v=A.extraAttributes||[],f=A.onAttributeChange||null,h=A.onInit||null;function p(y){const S=y||document.body;O(S,l,o,a),h&&h(S)}return P(function(){const y=new MutationObserver(function(E){for(let D=0;D<E.length;D++){const _=E[D];if(_.type==="childList"){for(let e=0;e<_.addedNodes.length;e++){const i=_.addedNodes[e];i.nodeType===1&&(O(i,l,o,a),h&&h(i))}for(let e=0;e<_.removedNodes.length;e++){const i=_.removedNodes[e];if(i.nodeType===1){const n=l.indexOf("[")!==-1||l.indexOf(".")!==-1||l.indexOf("#")!==-1?l:"["+l+"]",r=Array.from(i.querySelectorAll(n));i.matches&&i.matches(n)&&r.push(i);for(let c=0;c<r.length;c++){const b=r[c];if(!document.contains(b)){const u=b[o];u&&typeof u.destroy=="function"&&u.destroy()}}}}}else _.type==="attributes"&&(f&&_.target[o]?f(_.target,_.attributeName):(O(_.target,l,o,a),h&&h(_.target)))}});let S=[];if(l.indexOf("[")!==-1){const E=/\[([\w-]+)/g;let D;for(;(D=E.exec(l))!==null;)S.push(D[1])}else S.push(l);y.observe(document.body,{childList:!0,subtree:!0,attributes:!0,attributeFilter:S.concat(v)})},g),window[o]=p,document.readyState==="loading"?document.addEventListener("DOMContentLoaded",function(){p(document.body)}):p(document.body),p}const G={};function lt(l,o){G[l]=o}function it(l){return G[l]||{ingress:o=>o,egress:o=>o}}const K={};function Y(l,o){if(!l||typeof o!="object")return;const a=l.toLowerCase().split("-")[0];K[a]=o}function st(l){if(!l)return null;const o=l.toLowerCase().split("-")[0];return K[o]||null}Y("mk",{monthsLong:["јануари","февруари","март","април","мај","јуни","јули","август","септември","октомври","ноември","декември"],monthsShort:["јан","фев","мар","апр","мај","јун","јул","авг","септ","окт","ноем","дек"],daysLong:["недела","понеделник","вторник","среда","четврток","петок","сабота"],daysShort:["нед","пон","вт","ср","чет","пет","саб"]}),typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerDataMapper=lt,window.lnCore.getDataMapper=it,window.lnCore.registerLocaleFallback=Y,window.lnCore.getLocaleFallback=st,window.lnCore.fillTemplate=F,window.lnCore.fill=W,window.lnCore.lnFill=$,window.lnCore.renderList=tt);function ot(l,o){let a=!1;return function(){a||(a=!0,queueMicrotask(function(){a=!1,l()}))}}function rt(l){l=l||{};let o=l.windowSize>0?l.windowSize:1e3,a=l.pageSize>0?l.pageSize:200,g=l.threshold!=null?l.threshold:25,A=l.fetchDebounce!=null?l.fetchDebounce:120;const v=typeof l.requestPage=="function"?l.requestPage:function(){},f=typeof l.onChange=="function"?l.onChange:function(){},h=new Map,p=new Map,y=new Set;let S=0,E=0,D=0,_={sort:null,filters:{},search:""},e=null,i=0,t=0,n=!1;function r(s){p.set(s,++i)}function c(){return!!(_&&(_.search||_.filters&&Object.keys(_.filters).length))}function b(){if(h.size<=o)return;const s=Array.from(h.keys()).sort(function(w,C){return(p.get(w)||0)-(p.get(C)||0)});let d=0;for(;h.size>o&&d<s.length;)h.delete(s[d]),p.delete(s[d]),d++}function u(s,d){y.add(s),v(_,s,d)}return{get:function(s){return h.get(s)},has:function(s){return h.has(s)},peek:function(){return h.size?h.values().next().value:void 0},get logicalTotal(){return S},get grandTotal(){return E},get queryGen(){return D},get size(){return h.size},ensure:function(s,d){clearTimeout(e),t=s;for(let R=s;R<d;R++)h.has(R)&&r(R);if(S<=0)return;const w=Math.max(0,s-g),C=Math.min(S,d+g),L=Math.floor(w/a),x=Math.floor(Math.max(0,C-1)/a);let m=-1,k=a;for(let R=L;R<=x;R++){const I=R*a,Q=Math.min(a,S-I);let J=!1;for(let M=I;M<I+Q;M++)if(!h.has(M)){J=!0;break}if(J&&!y.has(I)){m=I,k=Q;break}}m!==-1&&(e=setTimeout(function(){u(m,k)},A))},ingest:function(s){if(s=s||{},s.queryGen!=null&&s.queryGen!==D)return;n&&(h.clear(),p.clear(),n=!1),E=s.total!=null?s.total:E,S=s.filtered!=null?s.filtered:s.data?s.data.length:S;const d=s.offset||0,w=s.data||[];for(let C=0;C<w.length;C++)h.set(d+C,w[C]),r(d+C);y.delete(d),b(),f()},requestInitial:function(s){s&&(_=s),u(0,a)},invalidate:function(s){D++,y.clear(),clearTimeout(e),s&&(_=s),n=!0,u(0,a)},revalidate:function(){D++,y.clear(),clearTimeout(e),n=!0;const s=Math.max(0,Math.floor(t/a)*a),d=S>0?Math.min(a,Math.max(1,S-s)):a;u(s,d)},release:function(s){y.delete(s)},destroy:function(){clearTimeout(e),h.clear(),p.clear(),y.clear()},configure:function(s){s=s||{};let d=!1;if(s.windowSize!=null&&s.windowSize>0&&s.windowSize!==o){const w=s.windowSize<o;o=s.windowSize,w&&b(),d=!0}s.pageSize!=null&&s.pageSize>0&&(a=s.pageSize),s.threshold!=null&&s.threshold>=0&&(g=s.threshold),s.fetchDebounce!=null&&s.fetchDebounce>=0&&(A=s.fetchDebounce),d&&f()},setGrandTotal:function(s){s==null||isNaN(s)||s<0||(E=s,c()||(S=s),f())}}}function X(l){return(l||"").replace(/^#/,"")}function H(l){const o=l===void 0?location.hash:l,a={},g=X(o);if(!g)return a;const A=g.split("&");for(let v=0;v<A.length;v++){const f=A[v];if(!f)continue;const h=f.indexOf(":"),p=h>-1?f.slice(0,h):f,y=h>-1?f.slice(h+1):"";if(p)try{a[p]=decodeURIComponent(y)}catch{a[p]=y}}return a}function at(l){if(!l)return null;const o=H();return l in o?o[l]:null}function ct(l,o){if(!l)return;const a=H();o==null?delete a[l]:a[l]=String(o);const A=Object.keys(a).map(function(v){const f=a[v];return f===""?v:v+":"+encodeURIComponent(f)}).join("&");X(location.hash)!==A&&(location.hash=A)}function dt(l){return l.button===1||l.ctrlKey||l.metaKey||l.shiftKey?!1:(l.preventDefault(),!0)}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.hashParse=H,window.lnCore.hashGet=at,window.lnCore.hashSet=ct,window.lnCore.hashLinkClick=dt),(function(){const l="data-ln-table",o="lnTable",a="data-ln-table-empty";if(window[o]!==void 0)return;const p=typeof Intl<"u"?new Intl.Collator(document.documentElement.lang||void 0,{sensitivity:"base"}):null;function y(e,i){if(e==null||isNaN(e))return"";try{return new Intl.NumberFormat(et(i)).format(e)}catch{return String(e)}}function S(e){let i=e.parentElement;for(;i&&i!==document.body&&i!==document.documentElement;){const n=getComputedStyle(i).overflowY;if(n==="auto"||n==="scroll")return i;i=i.parentElement}return null}function E(e){const i=e._scrollContainer||S(e.dom);return{container:i,top:i?i.scrollTop:window.scrollY}}function D(e){e.container?e.container.scrollTop=e.top:window.scrollTo(window.scrollX,e.top)}function _(e){this.dom=e,this.table=e.querySelector("table"),this.tbody=e.querySelector("[data-ln-table-body]")||e.querySelector("tbody"),this.thead=e.querySelector("thead");const i=this.thead?this.thead.querySelector("tr:last-child"):null;this.ths=i?Array.from(i.querySelectorAll("th")):[],this._totalSpan=e.querySelector("[data-ln-table-total]"),this._filteredSpan=e.querySelector("[data-ln-table-filtered]"),this._filteredSpan&&(this._filteredWrap=this._filteredSpan.parentElement!==e?this._filteredSpan.parentElement:null),this._selectedSpan=e.querySelector("[data-ln-table-selected]"),this._selectedSpan&&(this._selectedWrap=this._selectedSpan.parentElement!==e?this._selectedSpan.parentElement:null),this.isDataDriven=e.hasAttribute("data-ln-table-source"),this.name=e.getAttribute(l)||"",this.source=e.getAttribute("data-ln-table-source")||"",this._data=[],this._filteredData=[],this._searchTerm="",this._sortCol=-1,this._sortDir=null,this._columnFilters={},this.selectedIds=new Set,this._virtual=!1,this._rowHeight=0,this._vStart=-1,this._vEnd=-1,this._rafId=null,this._scrollHandler=null,this._scrollContainer=null,this._colgroup=null;const t=this;return this._onSetSearch=function(n){const r=(n.detail&&n.detail.query!=null?n.detail.query:n.detail&&n.detail.term!=null?n.detail.term:"").trim();t.isDataDriven?(t.currentSearch=r,T(e,"ln-table:search",{table:t.name,query:t.currentSearch}),t._requestData()):(t._searchTerm=r.toLowerCase(),t._applyFilterAndSort(),t._vStart=-1,t._vEnd=-1,t._render(),t._updateFooter(),T(e,"ln-table:filter",{term:t._searchTerm,matched:t._filteredData.length,total:t._data.length}))},e.addEventListener("ln-table:set-search",this._onSetSearch),this._onSetFilter=function(n){if(!n.detail)return;const r=n.detail.key,c=n.detail.values;if(t.isDataDriven)!c||c.length===0?delete t.currentFilters[r]:t.currentFilters[r]=c,t._requestData();else{if(!c||c.length===0)delete t._columnFilters[r];else{const b=[];for(let u=0;u<c.length;u++)b.push(c[u].toLowerCase());t._columnFilters[r]=b}t._applyFilterAndSort(),t._vStart=-1,t._vEnd=-1,t._render(),T(e,"ln-table:filter",{term:t._searchTerm,matched:t._filteredData.length,total:t._data.length})}},e.addEventListener("ln-table:set-filter",this._onSetFilter),this._onRequestClearFilters=function(){t.isDataDriven?(t.currentFilters={},t.currentSearch="",T(e,"ln-table:clear-filters",{table:t.name}),t._requestData()):(t._searchTerm="",t._columnFilters={},t._applyFilterAndSort(),t._vStart=-1,t._vEnd=-1,t._render(),t._updateFooter(),T(e,"ln-table:filter",{term:"",matched:t._filteredData.length,total:t._data.length}))},e.addEventListener("ln-table:request-clear-filters",this._onRequestClearFilters),this._selectable=e.hasAttribute("data-ln-table-selectable"),this._selectableActive=!1,this._selectable&&this._enableSelection(),this.isDataDriven?(this.isLoaded=!1,this.totalCount=0,this.visibleCount=0,this.currentSort=null,this.currentFilters={},this.currentSearch="",this._lastTotal=0,this._lastFiltered=0,this._windowed=!1,this._cache=null,this.isDataDriven&&e.hasAttribute("data-ln-table-window")&&this._enterWindowedMode(),this._onSetData=function(n){const r=n.detail||{};if(t._windowed){e.classList.remove("ln-table--loading"),t._cache.ingest(r);return}t._data=r.data||[],t._lastTotal=r.total!=null?r.total:t._data.length,t._lastFiltered=r.filtered!=null?r.filtered:t._data.length,t.totalCount=t._lastTotal,t.visibleCount=t._lastFiltered,t.isLoaded=!0,e.classList.remove("ln-table--loading"),t._vStart=-1,t._vEnd=-1,t._applyFilterAndSort(),t._render(),t._updateFooter(),T(e,"ln-table:rendered",{table:t.name,total:t.totalCount,visible:t.visibleCount})},e.addEventListener("ln-table:set-data",this._onSetData),this._onSetLoading=function(n){const r=n.detail&&n.detail.loading;e.classList.toggle("ln-table--loading",!!r),r&&(t.isLoaded=!1)},e.addEventListener("ln-table:set-loading",this._onSetLoading),this._onPageFailed=function(n){!t._windowed||!t._cache||t._cache.release(n.detail&&n.detail.offset)},e.addEventListener("ln-table:page-failed",this._onPageFailed),this._onRequestRevalidate=function(){!t._windowed||!t._cache||t._cache.revalidate()},e.addEventListener("ln-table:request-revalidate",this._onRequestRevalidate),this._onSort=function(n){n.preventDefault(),t.currentSort=n.detail.direction==="none"?null:{field:n.detail.field,direction:n.detail.direction},t._requestData()},e.addEventListener("ln-sort:change",this._onSort),this._windowed&&this._selectable&&this._selectAllCheckbox&&this._selectAllCheckbox.classList.add("hidden"),this._onRowClick=function(n){if(n.target.closest("[data-ln-table-row-select]")||n.target.closest("[data-ln-table-row-action]")||n.target.closest("a")||n.target.closest("button")||n.ctrlKey||n.metaKey||n.button===1)return;const r=n.target.closest("[data-ln-table-row]");if(!r)return;const c=r.getAttribute("data-ln-table-row-id"),b=r._lnRecord||{};T(e,"ln-table:row-click",{table:t.name,id:c,record:b})},this.tbody&&this.tbody.addEventListener("click",this._onRowClick),this._onRowAction=function(n){const r=n.target.closest("[data-ln-table-row-action]");if(!r)return;n.stopPropagation();const c=r.closest("[data-ln-table-row]");if(!c)return;const b=r.getAttribute("data-ln-table-row-action"),u=c.getAttribute("data-ln-table-row-id"),s=c._lnRecord||{};T(e,"ln-table:row-action",{table:t.name,id:u,action:b,record:s})},this.tbody&&this.tbody.addEventListener("click",this._onRowAction),this._focusedRowIndex=-1,this._onKeydown=function(n){if(!e.contains(document.activeElement)&&document.activeElement!==document.body||document.activeElement&&(document.activeElement.tagName==="INPUT"||document.activeElement.tagName==="TEXTAREA"))return;const r=t.tbody?Array.from(t.tbody.querySelectorAll("[data-ln-table-row]")):[];if(r.length)switch(n.key){case"ArrowDown":n.preventDefault(),t._focusedRowIndex=Math.min(t._focusedRowIndex+1,r.length-1),t._focusRow(r);break;case"ArrowUp":n.preventDefault(),t._focusedRowIndex=Math.max(t._focusedRowIndex-1,0),t._focusRow(r);break;case"Home":n.preventDefault(),t._focusedRowIndex=0,t._focusRow(r);break;case"End":n.preventDefault(),t._focusedRowIndex=r.length-1,t._focusRow(r);break;case"Enter":if(t._focusedRowIndex>=0&&t._focusedRowIndex<r.length){n.preventDefault();const c=r[t._focusedRowIndex];T(e,"ln-table:row-click",{table:t.name,id:c.getAttribute("data-ln-table-row-id"),record:c._lnRecord||{}})}break;case" ":if(t._selectable&&t._focusedRowIndex>=0&&t._focusedRowIndex<r.length){n.preventDefault();const c=r[t._focusedRowIndex].querySelector("[data-ln-table-row-select]");c&&(c.checked=!c.checked,c.dispatchEvent(new Event("change",{bubbles:!0})))}break}},document.addEventListener("keydown",this._onKeydown),this.tbody&&this.tbody.rows.length>0&&this._parseRows(),this._windowed?this._kickWindowInitial():T(e,"ln-table:request-data",{table:this.name,sort:this.currentSort,filters:this.currentFilters,search:this.currentSearch})):(this._emptyTbodyObserver=null,this.tbody&&this.tbody.rows.length>0?this._parseRows():this.tbody&&(this._emptyTbodyObserver=new MutationObserver(function(){t.tbody.rows.length>0&&(t._emptyTbodyObserver.disconnect(),t._emptyTbodyObserver=null,t._parseRows())}),this._emptyTbodyObserver.observe(this.tbody,{childList:!0})),this._onSort=function(n){n.preventDefault();const r=n.detail.direction==="none"?null:n.detail.direction;t._sortCol=r===null?-1:n.detail.column,t._sortDir=r,t._applyFilterAndSort(),t._vStart=-1,t._vEnd=-1,t._render(),T(e,"ln-table:sorted",{column:n.detail.column,direction:n.detail.direction,matched:t._filteredData.length,total:t._data.length})},e.addEventListener("ln-sort:change",this._onSort),this._onSearchChange=function(n){n.preventDefault(),t._onSetSearch(n)},e.addEventListener("ln-search:change",this._onSearchChange)),this}_.prototype._parseRows=function(){const e=this.tbody.rows,i=this.ths;this._data=[],e.length>0&&(this._rowHeight=e[0].offsetHeight||40),this._lockColumnWidths();for(let t=0;t<e.length;t++){const n=e[t],r=[],c=[],b=[];for(let s=0;s<n.cells.length;s++){const d=n.cells[s],w=d.textContent.trim();r[s]=B(d),c[s]=w.toLowerCase(),s<n.cells.length-1&&b.push(w.toLowerCase())}let u=null;if(this.isDataDriven){u={};const s=n.getAttribute("data-ln-table-row-id");s!=null&&(u.id=s);for(let d=0;d<i.length;d++){const w=i[d].getAttribute("data-ln-table-col");if(w){const C=d;if(C<n.cells.length){const L=n.cells[C];u[w]=B(L)}}}}this._data.push({values:r,rawTexts:c,html:n.outerHTML,searchText:b.join(" "),id:this.isDataDriven&&u?u.id:void 0,...u})}this._filteredData=this._data.slice(),this.isDataDriven&&(this._lastTotal=this._data.length,this._lastFiltered=this._data.length,this.totalCount=this._data.length,this.visibleCount=this._data.length,this._updateFooter()),this._render(),T(this.dom,"ln-table:ready",{total:this._data.length})},_.prototype._applyFilterAndSort=function(){if(this.isDataDriven){const e=(this.currentSearch||"").trim().toLowerCase(),i=this.currentFilters||{},t=Object.keys(i).length>0;if(this._filteredData=this._data.filter(function(s){if(e){let d=!1;for(const w in s)if(s.hasOwnProperty(w)&&typeof s[w]=="string"&&w!=="html"&&w!=="searchText"&&s[w].toLowerCase().indexOf(e)!==-1){d=!0;break}if(!d)return!1}if(t)for(const d in i){const w=i[d];if(w&&w.length>0){const C=s[d],L=C!=null?String(C):"";if(w.indexOf(L)===-1)return!1}}return!0}),this.visibleCount=this._filteredData.length,!this.currentSort||!this.currentSort.field||!this.currentSort.direction)return;const n=this.currentSort.field,c=this.currentSort.direction==="desc"?-1:1,b=this._filteredData.map(function(s){return s[n]}),u=U(b);this._filteredData.sort(function(s,d){return j(s[n],d[n],u,p)*c})}else{const e=this._searchTerm,i=this._columnFilters,t=Object.keys(i).length>0,n=this.ths,r={};if(t)for(let d=0;d<n.length;d++){const w=n[d].getAttribute("data-ln-table-filter-col");w&&(r[w]=d)}if(!e&&!t?this._filteredData=this._data.slice():this._filteredData=this._data.filter(function(d){if(e&&d.searchText.indexOf(e)===-1)return!1;if(t)for(const w in i){const C=r[w];if(C!==void 0&&i[w].indexOf(d.rawTexts[C])===-1)return!1}return!0}),this._sortCol<0||!this._sortDir)return;const c=this._sortCol,b=this._sortDir==="desc"?-1:1,u=this._filteredData.map(function(d){return d.values[c]}),s=U(u);this._filteredData.sort(function(d,w){return j(d.values[c],w.values[c],s,p)*b})}},_.prototype._lockColumnWidths=function(){if(!this.table||!this.thead||this._colgroup)return;const e=document.createElement("colgroup");this.ths.forEach(function(i){const t=document.createElement("col");t.style.width=i.offsetWidth+"px",e.appendChild(t)}),this.table.insertBefore(e,this.table.firstChild),this.table.style.tableLayout="fixed",this._colgroup=e},_.prototype._render=function(){if(this.tbody)if(this.isDataDriven){if(this._windowed){this._renderWindowed();return}const e=this._lastTotal,i=this.visibleCount;if(e===0){this._disableVirtualScroll(),this._showEmptyState();return}if(this._filteredData.length===0||i===0){this._disableVirtualScroll(),this._showEmptyState();return}this._filteredData.length>200?(this._enableVirtualScroll(),this._renderVirtual()):(this._disableVirtualScroll(),this._renderAll())}else{const e=this._filteredData.length;e===0&&(this._searchTerm||Object.keys(this._columnFilters).length>0)?(this._disableVirtualScroll(),this._showEmptyState()):e>200?(this._enableVirtualScroll(),this._renderVirtual()):(this._disableVirtualScroll(),this._renderAll())}},_.prototype._renderAll=function(){if(this.isDataDriven){const e=this._filteredData,i=document.createDocumentFragment();for(let n=0;n<e.length;n++){const r=this._buildRow(e[n]);if(!r)break;i.appendChild(r)}const t=E(this);this.tbody.textContent="",this.tbody.appendChild(i),D(t),this._selectable&&this._updateSelectAll()}else{const e=[],i=this._filteredData;for(let n=0;n<i.length;n++)e.push(i[n].html);const t=E(this);this.tbody.innerHTML=e.join(""),D(t),this._selectable&&this._restoreSelection()}},_.prototype._enableVirtualScroll=function(){if(this._virtual)return;this._virtual=!0,this._vStart=-1,this._vEnd=-1;const e=this;if(!this._rowHeight)if(this._windowed){let t=null;const n=this._cache.peek();n?t=this._buildRow(n):t=this._buildPlaceholderRow(),t&&(this.tbody.textContent="",this.tbody.appendChild(t),this._rowHeight=t.offsetHeight||40,this.tbody.textContent="")}else if(this.isDataDriven){if(this._data.length>0){const t=this._buildRow(this._data[0]);t&&(this.tbody.textContent="",this.tbody.appendChild(t),this._rowHeight=t.offsetHeight||40,this.tbody.textContent="")}}else{const t=this.tbody?this.tbody.rows:[];t.length>0&&(this._rowHeight=t[0].offsetHeight||40)}this.isDataDriven?this._scrollContainer=S(this.dom):this._scrollContainer=null;const i=this._scrollContainer||window;this._scrollHandler=function(){e._rafId||(e._rafId=requestAnimationFrame(function(){e._rafId=null,e._windowed?e._renderWindowed():e._renderVirtual()}))},i.addEventListener("scroll",this._scrollHandler,{passive:!0}),window.addEventListener("resize",this._scrollHandler,{passive:!0})},_.prototype._disableVirtualScroll=function(){this._virtual&&(this._virtual=!1,this._scrollHandler&&((this._scrollContainer||window).removeEventListener("scroll",this._scrollHandler),window.removeEventListener("resize",this._scrollHandler),this._scrollHandler=null),this._scrollContainer=null,this._rafId&&(cancelAnimationFrame(this._rafId),this._rafId=null),this._vStart=-1,this._vEnd=-1)},_.prototype._renderVirtual=function(){const e=this._filteredData,i=e.length,t=this._rowHeight;if(!t||!i)return;const n=this.thead?this.thead.offsetHeight:0,r=this._scrollContainer;let c,b;if(r){const L=this.table.getBoundingClientRect(),x=r.getBoundingClientRect(),m=L.top-x.top+r.scrollTop+n;c=r.scrollTop-m,b=r.clientHeight}else{const m=this.table.getBoundingClientRect().top+window.scrollY+n;c=window.scrollY-m,b=window.innerHeight}let u=Math.max(0,Math.floor(c/t)-15);u=Math.min(u,i);const s=Math.min(u+Math.ceil(b/t)+30,i);if(u===this._vStart&&s===this._vEnd)return;this._vStart=u,this._vEnd=s;const d=this.ths.length||1,w=u*t,C=(i-s)*t;if(this.isDataDriven){const L=document.createDocumentFragment();if(w>0){const m=document.createElement("tr");m.className="ln-table__spacer",m.setAttribute("aria-hidden","true");const k=document.createElement("td");k.setAttribute("colspan",d),k.style.height=w+"px",m.appendChild(k),L.appendChild(m)}for(let m=u;m<s;m++){const k=this._buildRow(e[m]);k&&L.appendChild(k)}if(C>0){const m=document.createElement("tr");m.className="ln-table__spacer",m.setAttribute("aria-hidden","true");const k=document.createElement("td");k.setAttribute("colspan",d),k.style.height=C+"px",m.appendChild(k),L.appendChild(m)}const x=E(this);this.tbody.textContent="",this.tbody.appendChild(L),D(x),this._selectable&&this._updateSelectAll()}else{let L="";w>0&&(L+='<tr class="ln-table__spacer" aria-hidden="true"><td colspan="'+d+'" style="height:'+w+'px;padding:0;border:none"></td></tr>');for(let m=u;m<s;m++)L+=e[m].html;C>0&&(L+='<tr class="ln-table__spacer" aria-hidden="true"><td colspan="'+d+'" style="height:'+C+'px;padding:0;border:none"></td></tr>');const x=E(this);this.tbody.innerHTML=L,D(x),this._selectable&&this._restoreSelection()}},_.prototype._buildPlaceholderRow=function(){const e=document.createElement("tr");e.className="ln-table__placeholder",e.setAttribute("aria-hidden","true");const i=document.createElement("td");return i.setAttribute("colspan",this.ths.length||1),i.style.height=this._rowHeight+"px",e.appendChild(i),e},_.prototype._renderWindowed=function(){if(this.isLoaded&&this._cache.logicalTotal===0){this._disableVirtualScroll(),this._showEmptyState();return}this._virtual||this._enableVirtualScroll();const e=this._rowHeight;if(!e)return;const i=this._cache.logicalTotal,t=this.thead?this.thead.offsetHeight:0,n=this._scrollContainer;let r,c;if(n){const x=this.table.getBoundingClientRect(),m=n.getBoundingClientRect(),k=x.top-m.top+n.scrollTop+t;r=n.scrollTop-k,c=n.clientHeight}else{const k=this.table.getBoundingClientRect().top+window.scrollY+t;r=window.scrollY-k,c=window.innerHeight}let b=Math.max(0,Math.floor(r/e)-15);b=Math.min(b,i);const u=Math.min(b+Math.ceil(c/e)+30,i),s=this.ths.length||1,d=b*e,w=(i-u)*e,C=document.createDocumentFragment();if(d>0){const x=document.createElement("tr");x.className="ln-table__spacer",x.setAttribute("aria-hidden","true");const m=document.createElement("td");m.setAttribute("colspan",s),m.style.height=d+"px",x.appendChild(m),C.appendChild(x)}for(let x=b;x<u;x++)if(this._cache.has(x)){const m=this._buildRow(this._cache.get(x));m&&C.appendChild(m)}else C.appendChild(this._buildPlaceholderRow());if(w>0){const x=document.createElement("tr");x.className="ln-table__spacer",x.setAttribute("aria-hidden","true");const m=document.createElement("td");m.setAttribute("colspan",s),m.style.height=w+"px",x.appendChild(m),C.appendChild(x)}const L=E(this);this.tbody.textContent="",this.tbody.appendChild(C),D(L),this._vStart=b,this._vEnd=u,this._cache.ensure(b,u)},_.prototype._showEmptyState=function(){const e=this.ths.length||1;this.tbody.textContent="";let i=null;if(this.isDataDriven){const t=this._lastTotal!=null?this._lastTotal:this._data.length,n=this.visibleCount,r=(this.currentSearch||Object.keys(this.currentFilters).length>0)&&(n<t||n===0),c=r?this.name+"-empty-filtered":this.name+"-empty";if(i=z(this.dom,c,"ln-table"),!i){const b=this.dom.querySelector("template[data-ln-table-empty]");if(b){const u=r?"search":"initial",s=b.content.querySelector('[data-ln-table-empty-when="'+u+'"]')||b.content.firstElementChild;s&&(i=document.importNode(s,!0))}}if(i)if(i.tagName==="TR")this.tbody.appendChild(i);else{const b=document.createElement("td");b.setAttribute("colspan",String(e)),b.appendChild(i);const u=document.createElement("tr");u.className="ln-table__empty",u.appendChild(b),this.tbody.appendChild(u)}}else{const t=this.dom.querySelector("template["+a+"]"),n=document.createElement("td");n.setAttribute("colspan",String(e)),t&&n.appendChild(document.importNode(t.content,!0));const r=document.createElement("tr");r.className="ln-table__empty",r.appendChild(n),this.tbody.appendChild(r)}T(this.dom,"ln-table:empty",{term:this.isDataDriven?this.currentSearch||"":this._searchTerm,total:this.isDataDriven?this._lastTotal!=null?this._lastTotal:this._data.length:this._data.length})},_.prototype._fillRow=function(e,i){F(e,i);const t=e.querySelectorAll("[data-ln-table-cell-attr]");for(let n=0;n<t.length;n++){const r=t[n],c=r.getAttribute("data-ln-table-cell-attr").split(",");for(let b=0;b<c.length;b++){const u=c[b].trim().split(":");if(u.length!==2)continue;const s=u[0].trim(),d=u[1].trim();i[s]!=null&&r.setAttribute(d,i[s])}}},_.prototype._buildRow=function(e){const i=z(this.dom,this.name+"-row","ln-table");if(!i)return null;const t=i.querySelector("[data-ln-table-row]")||i.firstElementChild;if(!t)return null;if(this._fillRow(t,e),t._lnRecord=e,e.id!=null&&t.setAttribute("data-ln-table-row-id",e.id),this._selectable&&e.id!=null&&this.selectedIds.has(String(e.id))){t.classList.add("ln-row-selected");const n=t.querySelector("[data-ln-table-row-select]");n&&(n.checked=!0)}return t},_.prototype._requestData=function(){if(this._windowed){this.dom.classList.add("ln-table--loading"),this._cache.invalidate({sort:this.currentSort,filters:this.currentFilters,search:this.currentSearch});return}Z(this,"ln-table:request-data","table")},_.prototype._enterWindowedMode=function(){const e=this,i=this.dom,t=parseInt(i.getAttribute("data-ln-table-window"),10),n=parseInt(i.getAttribute("data-ln-table-window-page"),10),r=parseInt(i.getAttribute("data-ln-table-window-threshold"),10);this._onCacheChange=function(){!e._windowed||!e._cache||(e.totalCount=e._cache.grandTotal,e.visibleCount=e._cache.logicalTotal,e._lastTotal=e._cache.grandTotal,e.isLoaded=!0,e._vStart=-1,e._vEnd=-1,e._render(),e._updateFooter(),T(i,"ln-table:rendered",{table:e.name,total:e.totalCount,visible:e.visibleCount}))},this._renderBatch=ot(this._onCacheChange),this._cache=rt({windowSize:t>0?t:1e3,pageSize:n>0?n:200,threshold:r>=0?r:25,fetchDebounce:120,requestPage:function(c,b,u){T(i,"ln-table:request-data",{table:e.name,sort:c.sort,filters:c.filters,search:c.search,offset:b,limit:u,queryGen:e._cache.queryGen})},onChange:this._renderBatch}),this._windowed=!0,this._selectable&&this._selectAllCheckbox&&this._selectAllCheckbox.classList.add("hidden")},_.prototype._kickWindowInitial=function(){if(this._data.length>0){let e=parseInt(this.dom.getAttribute("data-ln-table-count"),10);if(isNaN(e)&&this._totalSpan){const t=this._totalSpan.textContent.replace(/[^\d]/g,"");t&&(e=parseInt(t,10))}const i=e>0?e:this._data.length;this._cache.ingest({data:this._data,offset:0,total:i,filtered:i})}else this.dom.classList.add("ln-table--loading"),this._cache.requestInitial({sort:this.currentSort,filters:this.currentFilters,search:this.currentSearch})},_.prototype._exitWindowedMode=function(){this._disableVirtualScroll(),this._cache&&this._cache.destroy(),this._cache=null,this._windowed=!1,this._renderBatch=null,this._onCacheChange=null,this._selectAllCheckbox&&this._selectAllCheckbox.classList.remove("hidden"),this._rowHeight=0,this._vStart=-1,this._vEnd=-1,this._data=[],this._filteredData=[],this.dom.classList.add("ln-table--loading"),this._requestData()},_.prototype._updateSelectAll=function(){if(!this._selectAllCheckbox||!this.tbody)return;const e=this.tbody.querySelectorAll("[data-ln-table-row]");let i=e.length>0;for(let t=0;t<e.length;t++){const n=e[t].getAttribute("data-ln-table-row-id");if(n!=null&&!this.selectedIds.has(n)){i=!1;break}}this._selectAllCheckbox.checked=i},_.prototype._restoreSelection=function(){if(!this.tbody)return;const e=this.tbody.querySelectorAll("[data-ln-table-row]");for(let i=0;i<e.length;i++){const t=e[i].getAttribute("data-ln-table-row-id"),n=t!=null&&this.selectedIds.has(t);e[i].classList.toggle("ln-row-selected",n);const r=e[i].querySelector("[data-ln-table-row-select]");r&&(r.checked=n)}this._updateSelectAll()},Object.defineProperty(_.prototype,"selectedCount",{get:function(){return this.selectedIds.size},set:function(){}}),_.prototype._enableSelection=function(){if(this._selectableActive)return;this._selectableActive=!0;const e=this;if(this._onSelectionChange=function(i){const t=i.target.closest("[data-ln-table-row-select]");if(!t)return;const n=t.closest("[data-ln-table-row]");if(!n)return;const r=n.getAttribute("data-ln-table-row-id");r!=null&&(t.checked?(e.selectedIds.add(r),n.classList.add("ln-row-selected")):(e.selectedIds.delete(r),n.classList.remove("ln-row-selected")),e.selectedCount=e.selectedIds.size,e._updateSelectAll(),e._updateFooter(),T(e.dom,"ln-table:select",{table:e.name,selectedIds:e.selectedIds,count:e.selectedCount}))},this.tbody&&this.tbody.addEventListener("change",this._onSelectionChange),this._selectAllCheckbox=this.dom.querySelector('[data-ln-table-col-select] input[type="checkbox"]')||this.dom.querySelector("[data-ln-table-col-select]"),this._selectAllCheckbox&&this._selectAllCheckbox.tagName==="TH"){const i=document.createElement("input");i.type="checkbox";const t=e.dom.querySelector('[data-ln-table-dict="select-all"]'),n=e.dom.getAttribute("data-ln-table-select-all-label")||(t?t.textContent.trim():null)||"Select all";i.setAttribute("aria-label",n),this._selectAllCheckbox.appendChild(i),this._selectAllCheckbox=i}if(this._selectAllCheckbox&&(this._onSelectAll=function(){const i=e._selectAllCheckbox.checked,t=e.tbody?e.tbody.querySelectorAll("[data-ln-table-row]"):[];for(let n=0;n<t.length;n++){const r=t[n].getAttribute("data-ln-table-row-id"),c=t[n].querySelector("[data-ln-table-row-select]");r!=null&&(i?(e.selectedIds.add(r),t[n].classList.add("ln-row-selected")):(e.selectedIds.delete(r),t[n].classList.remove("ln-row-selected")),c&&(c.checked=i))}e.selectedCount=e.selectedIds.size,T(e.dom,"ln-table:select-all",{table:e.name,selected:i}),T(e.dom,"ln-table:select",{table:e.name,selectedIds:e.selectedIds,count:e.selectedCount}),e._updateFooter()},this._selectAllCheckbox.addEventListener("change",this._onSelectAll)),this.tbody){const i=this.tbody.querySelectorAll("[data-ln-table-row]");for(let t=0;t<i.length;t++){const n=i[t].querySelector("[data-ln-table-row-select]"),r=i[t].getAttribute("data-ln-table-row-id");n&&n.checked&&r!=null&&(this.selectedIds.add(r),i[t].classList.add("ln-row-selected"))}this.selectedCount=this.selectedIds.size,this.selectedCount>0&&this._updateSelectAll()}},_.prototype._disableSelection=function(){if(!this._selectableActive)return;this._selectableActive=!1,this.tbody&&this._onSelectionChange&&this.tbody.removeEventListener("change",this._onSelectionChange),this._selectAllCheckbox&&this._onSelectAll&&this._selectAllCheckbox.removeEventListener("change",this._onSelectAll);const e=this.dom.querySelector("[data-ln-table-col-select]");if(e){const i=e.querySelector('input[type="checkbox"]');i&&i.remove()}if(this._selectAllCheckbox=null,this.selectedIds.clear(),this.selectedCount=0,this.tbody){const i=this.tbody.querySelectorAll("[data-ln-table-row]");for(let t=0;t<i.length;t++){i[t].classList.remove("ln-row-selected");const n=i[t].querySelector("[data-ln-table-row-select]");n&&(n.checked=!1)}}this._updateFooter()},_.prototype._updateFooter=function(){let e=0,i=0;this.isDataDriven?(e=this._lastTotal!=null?this._lastTotal:this._data.length,i=this.visibleCount):(e=this._data.length,i=this._filteredData.length);const t=i<e;if(this._totalSpan&&(this._totalSpan.textContent=y(e,this.dom)),this._filteredSpan&&(this._filteredSpan.textContent=t?y(i,this.dom):""),this._filteredWrap&&this._filteredWrap.classList.toggle("hidden",!t),this._selectedSpan){const n=this.selectedIds?this.selectedIds.size:0;this._selectedSpan.textContent=n>0?y(n,this.dom):"",this._selectedWrap&&this._selectedWrap.classList.toggle("hidden",n===0)}},_.prototype._focusRow=function(e){for(let i=0;i<e.length;i++)e[i].classList.remove("ln-row-focused"),e[i].removeAttribute("tabindex");if(this._focusedRowIndex>=0&&this._focusedRowIndex<e.length){const i=e[this._focusedRowIndex];i.classList.add("ln-row-focused"),i.setAttribute("tabindex","0"),i.focus(),i.scrollIntoView({block:"nearest"})}},_.prototype.destroy=function(){this.dom[o]&&(this._disableVirtualScroll(),this.dom.removeEventListener("ln-table:set-search",this._onSetSearch),this.dom.removeEventListener("ln-table:set-filter",this._onSetFilter),this.dom.removeEventListener("ln-table:request-clear-filters",this._onRequestClearFilters),this.isDataDriven?(this.dom.removeEventListener("ln-table:set-data",this._onSetData),this.dom.removeEventListener("ln-table:set-loading",this._onSetLoading),this.dom.removeEventListener("ln-table:page-failed",this._onPageFailed),this.dom.removeEventListener("ln-table:request-revalidate",this._onRequestRevalidate),this.dom.removeEventListener("ln-sort:change",this._onSort),document.removeEventListener("keydown",this._onKeydown),this.tbody&&(this.tbody.removeEventListener("click",this._onRowClick),this.tbody.removeEventListener("click",this._onRowAction)),this._cache&&this._cache.destroy()):(this._emptyTbodyObserver&&(this._emptyTbodyObserver.disconnect(),this._emptyTbodyObserver=null),this.dom.removeEventListener("ln-sort:change",this._onSort),this.dom.removeEventListener("ln-search:change",this._onSearchChange)),this._onSelectionChange&&this.tbody&&this.tbody.removeEventListener("change",this._onSelectionChange),this._selectAllCheckbox&&this._onSelectAll&&this._selectAllCheckbox.removeEventListener("change",this._onSelectAll),this._colgroup&&(this._colgroup.remove(),this._colgroup=null),this.table&&(this.table.style.tableLayout=""),this._data=[],this._filteredData=[],delete this.dom[o])},nt(l,o,_,"ln-table",{extraAttributes:["data-ln-table-window","data-ln-table-window-page","data-ln-table-window-threshold","data-ln-table-count"],onAttributeChange:function(e,i){const t=e[o];if(!(!t||!t.isDataDriven)){if(i==="data-ln-table-window"){const n=e.hasAttribute("data-ln-table-window");if(n&&!t._windowed)t._enterWindowedMode(),t._kickWindowInitial();else if(!n&&t._windowed)t._exitWindowedMode();else if(n&&t._windowed){const r=parseInt(e.getAttribute("data-ln-table-window"),10);r>0&&t._cache.configure({windowSize:r})}return}if(!(!t._windowed||!t._cache)){if(i==="data-ln-table-window-page"){const n=parseInt(e.getAttribute("data-ln-table-window-page"),10);n>0&&t._cache.configure({pageSize:n})}else if(i==="data-ln-table-window-threshold"){const n=parseInt(e.getAttribute("data-ln-table-window-threshold"),10);n>=0&&t._cache.configure({threshold:n})}else if(i==="data-ln-table-count"){const n=parseInt(e.getAttribute("data-ln-table-count"),10);n>=0&&t._cache.setGrandTotal(n)}}}}})})()})();
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
// ── JS state: ln-table structural/state overrides ──
|
|
2
|
-
|
|
3
|
-
// gls compat — remove when gls migrates to ln-popover filter pattern
|
|
4
|
-
.content:has([data-ln-table]) {
|
|
5
|
-
overflow: visible;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
// Sort icon visibility toggled by JS (.hidden class)
|
|
9
|
-
[data-ln-table] th[data-ln-sort] [data-ln-sort-icon].hidden {
|
|
10
|
-
display: none;
|
|
11
|
-
}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
# ln-table-coordinator
|
|
2
|
-
|
|
3
|
-
A zero-dependency, per-instance, host-scoped coordinator component that wires external search hosts (`ln-search`), column filter popovers (`ln-filter`), header filter indicators, and clear button triggers to a single `ln-table`.
|
|
4
|
-
|
|
5
|
-
`ln-table` itself is a Layer 1 primitive: it manages internal data state, virtual scroll rendering, pagination/windowing cache, row template cloning, cell formatting, and selection DOM state. `ln-table-coordinator` is the Layer 2 policy and mediator that wires external UI controls to `ln-table`.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## 🧭 Philosophy & Architecture
|
|
10
|
-
|
|
11
|
-
1. **Layer Separation.** `ln-table` manages its own internal table state and DOM subtree only — no external DOM querying, no external input mirroring, and no visual indicator class toggles on header buttons. `ln-table-coordinator` handles all project UI wiring on top.
|
|
12
|
-
2. **Host-Scoped, Per-Instance.** The coordinator is a real component: `[data-ln-table-coordinator]` is a **required wrapper**. Its handlers are bound to its own host element (`self.dom`), not `document`. The table, its `[data-ln-filter]` popovers, and its clear button(s) must all be descendants of the same coordinator host — outside its own subtree, the coordinator does not exist and does not look.
|
|
13
|
-
3. **Event-Driven Communication.** Communication with `ln-table` occurs strictly via CustomEvents (`ln-table:set-search`, `ln-table:set-filter`, `ln-table:request-clear-filters`).
|
|
14
|
-
|
|
15
|
-
**Breaking change:** a data-driven table's search/filter/clear-all only works when wrapped in `[data-ln-table-coordinator]`. There is no page-wide fallback — the coordinator does not resolve a table by scanning the whole document.
|
|
16
|
-
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
## 🛠️ Declarative API & Wire Contract
|
|
20
|
-
|
|
21
|
-
| Target / Trigger | Event / Trigger | Behavior |
|
|
22
|
-
| :--- | :--- | :--- |
|
|
23
|
-
| `[data-ln-search="tableId"]` (delivered by `ln-search` directly to the table) | `ln-search:change` | Guards `e.target` carries `data-ln-table` and `data-ln-table-source` (data-driven only), dispatches `ln-table:set-search`. |
|
|
24
|
-
| `[data-ln-filter="tableId"]` (delivered by `ln-filter` directly to the table) | `ln-filter:changed` | Guards `e.target` carries `data-ln-table`, toggles `.ln-filter-active` indicator on filter button, dispatches `ln-table:set-filter`. |
|
|
25
|
-
| `[data-ln-table-clear]`, `[data-ln-table-clear-all]` | `click` | Resolves the table structurally within this host, clears the linked search input and filter reset checkboxes, removes `.ln-filter-active` visual classes, dispatches `ln-table:request-clear-filters`. |
|
|
26
|
-
| Document | `keydown` (`'/'`) | Focuses the search input inside the active coordinator wrapper on the page (or the first `[data-ln-search]` if none). |
|
|
27
|
-
|
|
28
|
-
Column filters (`data-ln-table-filter-col`) and clear-all (`data-ln-table-clear` / `data-ln-table-clear-all`) route through `ln-table-coordinator` in both SSR and data-driven modes — an SSR table using them still requires the `[data-ln-table-coordinator]` wrapper, even though SSR search and sort do not (see below).
|
|
29
|
-
|
|
30
|
-
Search is the one asymmetric control: the coordinator only intercepts search for **data-driven** tables. SSR tables self-bind `ln-search:change` directly (see [`js/ln-table/README.md`](../ln-table/README.md)) and never need the wrapper for search alone.
|
|
31
|
-
|
|
32
|
-
---
|
|
33
|
-
|
|
34
|
-
## ⚡ Consumed & Dispatched Events
|
|
35
|
-
|
|
36
|
-
### Consumed Events
|
|
37
|
-
- `ln-search:change` (on `self.dom`, the coordinator host)
|
|
38
|
-
- `ln-filter:changed` (on `self.dom`)
|
|
39
|
-
- `click` (on `self.dom` — targets `[data-ln-table-clear]` and `[data-ln-table-clear-all]`)
|
|
40
|
-
- `keydown` (`document` — key `'/'`, the sole document-level exception, see below)
|
|
41
|
-
|
|
42
|
-
### Dispatched Events
|
|
43
|
-
- `ln-table:set-search` (Target: the table inside this host, Payload: `{ query, term, table }`)
|
|
44
|
-
- `ln-table:set-filter` (Target: the table inside this host, Payload: `{ key, values, table }`)
|
|
45
|
-
- `ln-table:request-clear-filters` (Target: the table inside this host, Payload: `{ table }`)
|
|
46
|
-
|
|
47
|
-
The coordinator does not dispatch anything from its own host element — it has no outward/notification event. It only relays inward, to the table.
|
|
48
|
-
|
|
49
|
-
---
|
|
50
|
-
|
|
51
|
-
## 🔧 Internals
|
|
52
|
-
|
|
53
|
-
Source: `js/ln-table-coordinator/src/ln-table-coordinator.js`. This is a real per-instance component: `_component(dom)` calls `_bindEvents(self)`, which stores its three listeners on `self._handlers` and attaches them to `self.dom` — mirroring the `js/ln-data-coordinator` idiom. `destroy()` removes all three symmetrically and clears `self._handlers`. `registerComponent` also supplies the `window.lnTableCoordinator` double-load guard.
|
|
54
|
-
|
|
55
|
-
### Search
|
|
56
|
-
|
|
57
|
-
`ln-search` dispatches `ln-search:change` directly on its resolved target (`document.getElementById(targetId)`) — when that target IS the table, `e.target` already carries `data-ln-table`. The coordinator does no ID resolution for search, only a guard: `e.target` must carry both `data-ln-table` and `data-ln-table-source` (data-driven). An SSR table caught by this listener is a markup mistake — it self-binds `ln-search:change` on its own, and wrapping it in `[data-ln-table-coordinator]` would double-fire; the `data-ln-table-source` guard prevents that.
|
|
58
|
-
|
|
59
|
-
### Column-filter indicator
|
|
60
|
-
|
|
61
|
-
`ln-filter` dispatches `ln-filter:changed` on both its own `<ul data-ln-filter>` root and, if different, directly on the table via `getElementById` — again, no ID resolution needed, only the `data-ln-table` guard. On a match, the coordinator finds the `th[data-ln-table-filter-col="key"]` and toggles `.ln-filter-active` on that header's `[data-ln-table-col-filter]` button based on `values.length > 0`, then dispatches `ln-table:set-filter`. This header-indicator class is Layer-2 policy — which is exactly why `ln-table` itself never sets it.
|
|
62
|
-
|
|
63
|
-
### Clear
|
|
64
|
-
|
|
65
|
-
A `click` on `[data-ln-table-clear]` / `[data-ln-table-clear-all]` has no ID binding of its own, so it resolves structurally: `clearBtn.closest('[data-ln-table]')`, falling back to `dom.querySelector('[data-ln-table]')` — always scoped to this host, never document-wide. It then runs: (1) strip `.ln-filter-active` off every filter button in the table, (2) blank the linked search input (scoped to this host), (3) check each linked filter popover's `[data-ln-filter-reset]` and fire a bubbling `change`, (4) dispatch `ln-table:request-clear-filters`.
|
|
66
|
-
|
|
67
|
-
### `/` focus shortcut
|
|
68
|
-
|
|
69
|
-
The sole deliberate exception to host-scoping. It remains a single `document`-level `keydown` listener registered once at module scope (outside `_component`/`_bindEvents`) — a page-level keyboard affordance, not coordination between a host and its children. Registering it per-instance would fire it once per coordinator on the page. It focuses the search input inside the active `[data-ln-table-coordinator]` wrapper, or the first `[data-ln-search]` on the page if none. Ignored when focus is already in an `INPUT`/`TEXTAREA`, or when the event was already `defaultPrevented`.
|
|
70
|
-
|
|
71
|
-
### Multi-coordinator isolation
|
|
72
|
-
|
|
73
|
-
Each `_component(dom)` instance closures its handlers over its own `dom`; `addEventListener` on a specific host node only fires for events whose bubble path passes through that node. Two coordinator hosts on the same page cannot see each other's descendants' events — no shared/global state exists to leak. The `/` shortcut is the sole intentional exception to this isolation — it is document-scoped by design.
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(function(){"use strict";if(typeof window<"u"){const t=console.warn;console.warn=function(...e){typeof e[0]=="string"&&(e[0].startsWith("[ln-")||e[0].startsWith("[lnCore"))&&!(document.documentElement.hasAttribute("data-ln-debug")||document.body&&document.body.hasAttribute("data-ln-debug"))||t.apply(console,e)}}const b={};function O(t,e){b[t]||(b[t]=document.querySelector('[data-ln-template="'+t+'"]'));const i=b[t];return i?i.content.cloneNode(!0):(console.warn("["+(e||"ln-core")+'] Template "'+t+'" not found'),null)}function g(t,e,i){t.dispatchEvent(new CustomEvent(e,{bubbles:!0,detail:i||{}}))}function E(t,e){if(!t||!e)return t;const i=t.querySelectorAll("[data-ln-field]");for(let n=0;n<i.length;n++){const l=i[n],r=l.getAttribute("data-ln-field");e[r]!=null&&(l.textContent=e[r])}const f=t.querySelectorAll("[data-ln-attr]");for(let n=0;n<f.length;n++){const l=f[n],r=l.getAttribute("data-ln-attr").split(",");for(let a=0;a<r.length;a++){const d=r[a].trim().split(":");if(d.length!==2)continue;const u=d[0].trim(),c=d[1].trim();e[c]!=null&&l.setAttribute(u,e[c])}}const s=t.querySelectorAll("[data-ln-show]");for(let n=0;n<s.length;n++){const l=s[n],r=l.getAttribute("data-ln-show");r in e&&l.classList.toggle("hidden",!e[r])}const o=t.querySelectorAll("[data-ln-class]");for(let n=0;n<o.length;n++){const l=o[n],r=l.getAttribute("data-ln-class").split(",");for(let a=0;a<r.length;a++){const d=r[a].trim().split(":");if(d.length!==2)continue;const u=d[0].trim(),c=d[1].trim();c in e&&l.classList.toggle(u,!!e[c])}}return t}function D(t,e){t.matches&&t.matches("[data-ln-form], [data-ln-fillable]")&&t.dispatchEvent(new CustomEvent("ln-fill",{detail:e??null,bubbles:!0}));const i=t.querySelectorAll("[data-ln-form], [data-ln-fillable]");for(let f=0;f<i.length;f++)i[f].dispatchEvent(new CustomEvent("ln-fill",{detail:e??null,bubbles:!0}));return t}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._fillBound||(window.lnCore._fillBound=!0,document.addEventListener("ln-fill",function(t){if(!(!t.target.matches||!t.target.matches("[data-ln-fillable]")))if(t.detail)E(t.target,t.detail);else{const e=t.target.querySelectorAll("[data-ln-field]");for(let i=0;i<e.length;i++)e[i].textContent=""}})));function S(t,e){if(!t||!e)return t;const i=document.createTreeWalker(t,NodeFilter.SHOW_TEXT);for(;i.nextNode();){const o=i.currentNode;o.textContent.indexOf("{{")!==-1&&(o.textContent=o.textContent.replace(/\{\{\s*(\w+)\s*\}\}/g,function(n,l){return e[l]!==void 0?e[l]:""}))}const f=function(o,n){return e[n]!==void 0?e[n]:""},s=Array.from(t.querySelectorAll("*"));t.nodeType===1&&s.push(t);for(let o=0;o<s.length;o++){const n=s[o],l=n.attributes;for(let r=0;r<l.length;r++){const a=l[r];a.value.indexOf("{{")!==-1&&n.setAttribute(a.name,a.value.replace(/\{\{\s*(\w+)\s*\}\}/g,f))}}return t}function I(t,e,i,f,s,o){const n={};for(let r=0;r<t.children.length;r++){const a=t.children[r],d=a.getAttribute("data-ln-key");d&&(n[d]=a)}const l=document.createDocumentFragment();for(let r=0;r<e.length;r++){const a=e[r],d=String(f(a));let u=n[d];if(u)s(u,a,r);else{const c=O(i,o);if(!c||(S(c,a),u=c.firstElementChild,!u))continue;u.setAttribute("data-ln-key",d),s(u,a,r)}l.appendChild(u)}t.textContent="",t.appendChild(l)}function L(t,e){if(!document.body){document.addEventListener("DOMContentLoaded",function(){L(t,e)}),console.warn("["+e+'] Script loaded before <body> — add "defer" to your <script> tag');return}t()}function y(t,e,i,f){if(t.nodeType!==1)return;const o=e.indexOf("[")!==-1||e.indexOf(".")!==-1||e.indexOf("#")!==-1?e:"["+e+"]",n=Array.from(t.querySelectorAll(o));t.matches&&t.matches(o)&&n.push(t);for(const l of n)l[i]||(l[i]=new f(l))}function M(t,e,i,f,s={}){const o=s.extraAttributes||[],n=s.onAttributeChange||null,l=s.onInit||null;function r(a){const d=a||document.body;y(d,t,e,i),l&&l(d)}return L(function(){const a=new MutationObserver(function(u){for(let c=0;c<u.length;c++){const m=u[c];if(m.type==="childList"){for(let h=0;h<m.addedNodes.length;h++){const p=m.addedNodes[h];p.nodeType===1&&(y(p,t,e,i),l&&l(p))}for(let h=0;h<m.removedNodes.length;h++){const p=m.removedNodes[h];if(p.nodeType===1){const _=t.indexOf("[")!==-1||t.indexOf(".")!==-1||t.indexOf("#")!==-1?t:"["+t+"]",C=Array.from(p.querySelectorAll(_));p.matches&&p.matches(_)&&C.push(p);for(let v=0;v<C.length;v++){const N=C[v];if(!document.contains(N)){const A=N[e];A&&typeof A.destroy=="function"&&A.destroy()}}}}}else m.type==="attributes"&&(n&&m.target[e]?n(m.target,m.attributeName):(y(m.target,t,e,i),l&&l(m.target)))}});let d=[];if(t.indexOf("[")!==-1){const u=/\[([\w-]+)/g;let c;for(;(c=u.exec(t))!==null;)d.push(c[1])}else d.push(t);a.observe(document.body,{childList:!0,subtree:!0,attributes:!0,attributeFilter:d.concat(o)})},f),window[e]=r,document.readyState==="loading"?document.addEventListener("DOMContentLoaded",function(){r(document.body)}):r(document.body),r}const T={};function j(t,e){T[t]=e}function B(t){return T[t]||{ingress:e=>e,egress:e=>e}}const q={};function x(t,e){if(!t||typeof e!="object")return;const i=t.toLowerCase().split("-")[0];q[i]=e}function R(t){if(!t)return null;const e=t.toLowerCase().split("-")[0];return q[e]||null}x("mk",{monthsLong:["јануари","февруари","март","април","мај","јуни","јули","август","септември","октомври","ноември","декември"],monthsShort:["јан","фев","мар","апр","мај","јун","јул","авг","септ","окт","ноем","дек"],daysLong:["недела","понеделник","вторник","среда","четврток","петок","сабота"],daysShort:["нед","пон","вт","ср","чет","пет","саб"]}),typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerDataMapper=j,window.lnCore.getDataMapper=B,window.lnCore.registerLocaleFallback=x,window.lnCore.getLocaleFallback=R,window.lnCore.fillTemplate=S,window.lnCore.fill=E,window.lnCore.lnFill=D,window.lnCore.renderList=I);function k(t){return(t||"").replace(/^#/,"")}function w(t){const e=t===void 0?location.hash:t,i={},f=k(e);if(!f)return i;const s=f.split("&");for(let o=0;o<s.length;o++){const n=s[o];if(!n)continue;const l=n.indexOf(":"),r=l>-1?n.slice(0,l):n,a=l>-1?n.slice(l+1):"";if(r)try{i[r]=decodeURIComponent(a)}catch{i[r]=a}}return i}function W(t){if(!t)return null;const e=w();return t in e?e[t]:null}function F(t,e){if(!t)return;const i=w();e==null?delete i[t]:i[t]=String(e);const s=Object.keys(i).map(function(o){const n=i[o];return n===""?o:o+":"+encodeURIComponent(n)}).join("&");k(location.hash)!==s&&(location.hash=s)}function U(t){return t.button===1||t.ctrlKey||t.metaKey||t.shiftKey?!1:(t.preventDefault(),!0)}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.hashParse=w,window.lnCore.hashGet=W,window.lnCore.hashSet=F,window.lnCore.hashLinkClick=U),(function(){const t="data-ln-table-coordinator",e="lnTableCoordinator";if(window[e]!==void 0)return;document.addEventListener("keydown",function(s){if(s.key!=="/"||s.defaultPrevented||document.activeElement&&(document.activeElement.tagName==="INPUT"||document.activeElement.tagName==="TEXTAREA"))return;const o=document.querySelector("["+t+"] [data-ln-search]")||document.querySelector("[data-ln-search]");if(!o)return;const n=o.tagName==="INPUT"||o.tagName==="TEXTAREA"?o:o.querySelector('input[type="search"], input[type="text"], input');n&&(s.preventDefault(),n.focus())});function i(s){return this.dom=s,f(this),this}function f(s){const o=s.dom;s._handlers={search:function(n){const l=n.target;if(!l.hasAttribute||!l.hasAttribute("data-ln-table")||!l.lnTable||!l.hasAttribute("data-ln-table-source"))return;n.preventDefault();const r=n.detail&&n.detail.term!=null?n.detail.term:"",a=l.lnTable.name||l.id;g(l,"ln-table:set-search",{query:r,term:r,table:a})},filter:function(n){if(!n.detail)return;const l=n.target;if(!l.hasAttribute||!l.hasAttribute("data-ln-table")||!l.lnTable)return;const r=n.detail.key,a=n.detail.values||[],d=l.lnTable.name||l.id,u=l.querySelectorAll("th");for(let c=0;c<u.length;c++)if(u[c].getAttribute("data-ln-table-filter-col")===r){const m=u[c].querySelector("[data-ln-table-col-filter]");m&&m.classList.toggle("ln-filter-active",a.length>0);break}g(l,"ln-table:set-filter",{key:r,values:a,table:d})},clear:function(n){const l=n.target.closest("[data-ln-table-clear], [data-ln-table-clear-all]");if(!l)return;const r=l.closest("[data-ln-table]")||o.querySelector("[data-ln-table]");if(!r||!r.lnTable)return;const a=r.lnTable.name||r.id,d=r.querySelectorAll("th");for(let h=0;h<d.length;h++){const p=d[h].querySelector("[data-ln-table-col-filter]");p&&p.classList.remove("ln-filter-active")}const u=r.id,c=u&&o.querySelector('[data-ln-search="'+u+'"]')||o.querySelector("[data-ln-search]");if(c){const h=c.tagName==="INPUT"||c.tagName==="TEXTAREA"?c:c.querySelector("input");h&&(h.value="")}const m=u&&o.querySelectorAll('[data-ln-filter="'+u+'"]')||o.querySelectorAll("[data-ln-filter]");for(let h=0;h<m.length;h++){const p=m[h].querySelector("[data-ln-filter-reset]");p&&(p.checked=!0,p.dispatchEvent(new Event("change",{bubbles:!0})))}g(r,"ln-table:request-clear-filters",{table:a})}},o.addEventListener("ln-search:change",s._handlers.search),o.addEventListener("ln-filter:changed",s._handlers.filter),o.addEventListener("click",s._handlers.clear)}i.prototype.destroy=function(){this.dom[e]&&(this._handlers&&(this.dom.removeEventListener("ln-search:change",this._handlers.search),this.dom.removeEventListener("ln-filter:changed",this._handlers.filter),this.dom.removeEventListener("click",this._handlers.clear),this._handlers=null),delete this.dom[e])},M(t,e,i,"ln-table-coordinator")})()})();
|
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
import { registerComponent, dispatch } from '../../ln-core';
|
|
2
|
-
|
|
3
|
-
(function () {
|
|
4
|
-
const DOM_SELECTOR = 'data-ln-table-coordinator';
|
|
5
|
-
const DOM_ATTRIBUTE = 'lnTableCoordinator';
|
|
6
|
-
|
|
7
|
-
if (window[DOM_ATTRIBUTE] !== undefined) return;
|
|
8
|
-
|
|
9
|
-
// ─── Keyboard Navigation Search Focus ('/' shortcut) ──
|
|
10
|
-
// Deliberate, user-approved exception to host-scoping: this is a
|
|
11
|
-
// page-level keyboard affordance, not coordination between a host and
|
|
12
|
-
// its children, so it stays a single module-scope document listener
|
|
13
|
-
// exactly as it behaves today (unchanged resolution order). Registering
|
|
14
|
-
// it per-instance inside _bindEvents would fire it once per coordinator
|
|
15
|
-
// on the page — this is why it lives outside _component/_bindEvents.
|
|
16
|
-
|
|
17
|
-
document.addEventListener('keydown', function (e) {
|
|
18
|
-
if (e.key !== '/') return;
|
|
19
|
-
if (e.defaultPrevented) return;
|
|
20
|
-
if (document.activeElement && (document.activeElement.tagName === 'INPUT' || document.activeElement.tagName === 'TEXTAREA')) return;
|
|
21
|
-
|
|
22
|
-
// Resolve search input inside active coordinator wrapper or first visible search
|
|
23
|
-
const searchHost = document.querySelector('[' + DOM_SELECTOR + '] [data-ln-search]') || document.querySelector('[data-ln-search]');
|
|
24
|
-
if (!searchHost) return;
|
|
25
|
-
|
|
26
|
-
const input = (searchHost.tagName === 'INPUT' || searchHost.tagName === 'TEXTAREA')
|
|
27
|
-
? searchHost
|
|
28
|
-
: searchHost.querySelector('input[type="search"], input[type="text"], input');
|
|
29
|
-
|
|
30
|
-
if (input) {
|
|
31
|
-
e.preventDefault();
|
|
32
|
-
input.focus();
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
// ─── Component Constructor ─────────────────────────────
|
|
37
|
-
|
|
38
|
-
function _component(dom) {
|
|
39
|
-
this.dom = dom;
|
|
40
|
-
_bindEvents(this);
|
|
41
|
-
return this;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// ─── Event Binding (host-scoped — own subtree only) ────
|
|
45
|
-
|
|
46
|
-
function _bindEvents(self) {
|
|
47
|
-
const dom = self.dom;
|
|
48
|
-
|
|
49
|
-
self._handlers = {
|
|
50
|
-
// ln-search dispatches ln-search:change directly on its resolved
|
|
51
|
-
// target — when that target IS the table, e.target already carries
|
|
52
|
-
// data-ln-table. No ID resolution needed here, only a guard.
|
|
53
|
-
search: function (e) {
|
|
54
|
-
const table = e.target;
|
|
55
|
-
if (!table.hasAttribute || !table.hasAttribute('data-ln-table')) return;
|
|
56
|
-
if (!table.lnTable) return;
|
|
57
|
-
// SSR tables self-bind ln-search:change directly (see ln-table.js) —
|
|
58
|
-
// the coordinator only owns the data-driven path. A table wrapped
|
|
59
|
-
// here that happens to be SSR is a markup mistake (rule: coordinator
|
|
60
|
-
// is data-driven-only); this guard prevents a double-fire rather
|
|
61
|
-
// than silently mishandling it.
|
|
62
|
-
if (!table.hasAttribute('data-ln-table-source')) return;
|
|
63
|
-
|
|
64
|
-
e.preventDefault();
|
|
65
|
-
const term = e.detail && e.detail.term != null ? e.detail.term : '';
|
|
66
|
-
const name = table.lnTable.name || table.id;
|
|
67
|
-
|
|
68
|
-
dispatch(table, 'ln-table:set-search', { query: term, term: term, table: name });
|
|
69
|
-
},
|
|
70
|
-
|
|
71
|
-
// ln-filter dispatches ln-filter:changed on both its own <ul> root
|
|
72
|
-
// and (if different) directly on the table via getElementById — same
|
|
73
|
-
// reasoning: no ID resolution needed, only a guard.
|
|
74
|
-
filter: function (e) {
|
|
75
|
-
if (!e.detail) return;
|
|
76
|
-
const table = e.target;
|
|
77
|
-
if (!table.hasAttribute || !table.hasAttribute('data-ln-table')) return;
|
|
78
|
-
if (!table.lnTable) return;
|
|
79
|
-
|
|
80
|
-
const key = e.detail.key;
|
|
81
|
-
const values = e.detail.values || [];
|
|
82
|
-
const name = table.lnTable.name || table.id;
|
|
83
|
-
|
|
84
|
-
// Header filter-button indicator — Layer 2 policy; ln-table itself
|
|
85
|
-
// never sets this class.
|
|
86
|
-
const ths = table.querySelectorAll('th');
|
|
87
|
-
for (let i = 0; i < ths.length; i++) {
|
|
88
|
-
if (ths[i].getAttribute('data-ln-table-filter-col') === key) {
|
|
89
|
-
const btn = ths[i].querySelector('[data-ln-table-col-filter]');
|
|
90
|
-
if (btn) btn.classList.toggle('ln-filter-active', values.length > 0);
|
|
91
|
-
break;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
dispatch(table, 'ln-table:set-filter', { key: key, values: values, table: name });
|
|
96
|
-
},
|
|
97
|
-
|
|
98
|
-
// Clear-all has no ID binding of its own — resolve structurally,
|
|
99
|
-
// scoped to this host only (never document-wide).
|
|
100
|
-
clear: function (e) {
|
|
101
|
-
const clearBtn = e.target.closest('[data-ln-table-clear], [data-ln-table-clear-all]');
|
|
102
|
-
if (!clearBtn) return;
|
|
103
|
-
|
|
104
|
-
const table = clearBtn.closest('[data-ln-table]') || dom.querySelector('[data-ln-table]');
|
|
105
|
-
if (!table || !table.lnTable) return;
|
|
106
|
-
|
|
107
|
-
const name = table.lnTable.name || table.id;
|
|
108
|
-
|
|
109
|
-
const ths = table.querySelectorAll('th');
|
|
110
|
-
for (let i = 0; i < ths.length; i++) {
|
|
111
|
-
const filterBtn = ths[i].querySelector('[data-ln-table-col-filter]');
|
|
112
|
-
if (filterBtn) filterBtn.classList.remove('ln-filter-active');
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const tableId = table.id;
|
|
116
|
-
const searchEl = (tableId && dom.querySelector('[data-ln-search="' + tableId + '"]'))
|
|
117
|
-
|| dom.querySelector('[data-ln-search]');
|
|
118
|
-
if (searchEl) {
|
|
119
|
-
const input = (searchEl.tagName === 'INPUT' || searchEl.tagName === 'TEXTAREA')
|
|
120
|
-
? searchEl
|
|
121
|
-
: searchEl.querySelector('input');
|
|
122
|
-
if (input) input.value = '';
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const filters = (tableId && dom.querySelectorAll('[data-ln-filter="' + tableId + '"]'))
|
|
126
|
-
|| dom.querySelectorAll('[data-ln-filter]');
|
|
127
|
-
for (let i = 0; i < filters.length; i++) {
|
|
128
|
-
const resetInput = filters[i].querySelector('[data-ln-filter-reset]');
|
|
129
|
-
if (resetInput) {
|
|
130
|
-
resetInput.checked = true;
|
|
131
|
-
resetInput.dispatchEvent(new Event('change', { bubbles: true }));
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
dispatch(table, 'ln-table:request-clear-filters', { table: name });
|
|
136
|
-
}
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
dom.addEventListener('ln-search:change', self._handlers.search);
|
|
140
|
-
dom.addEventListener('ln-filter:changed', self._handlers.filter);
|
|
141
|
-
dom.addEventListener('click', self._handlers.clear);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// ─── Destroy ────────────────────────────────────────────
|
|
145
|
-
|
|
146
|
-
_component.prototype.destroy = function () {
|
|
147
|
-
if (!this.dom[DOM_ATTRIBUTE]) return;
|
|
148
|
-
|
|
149
|
-
if (this._handlers) {
|
|
150
|
-
this.dom.removeEventListener('ln-search:change', this._handlers.search);
|
|
151
|
-
this.dom.removeEventListener('ln-filter:changed', this._handlers.filter);
|
|
152
|
-
this.dom.removeEventListener('click', this._handlers.clear);
|
|
153
|
-
this._handlers = null;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
delete this.dom[DOM_ATTRIBUTE];
|
|
157
|
-
};
|
|
158
|
-
|
|
159
|
-
registerComponent(DOM_SELECTOR, DOM_ATTRIBUTE, _component, 'ln-table-coordinator');
|
|
160
|
-
})();
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
@use '../../scss/config/mixins' as *;
|
|
2
|
-
|
|
3
|
-
[data-ln-debug] {
|
|
4
|
-
// 1. Tabs Configuration Check: [data-ln-tabs] must have an id or data-ln-tabs-key
|
|
5
|
-
[data-ln-tabs]:not([id]):not([data-ln-tabs-key]) {
|
|
6
|
-
@include dev-dom-error("[data-ln-tabs] must have an 'id' or 'data-ln-tabs-key' for state tracking.");
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
// 2. Tab Trigger Type: triggers inside forms must be explicitly type="button" to prevent submit events
|
|
10
|
-
form [data-ln-tabs-for]:not([type="button"]) {
|
|
11
|
-
@include dev-inline-error("tab trigger within form must have type='button'");
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
// 3. Tab Trigger Nesting Check: [data-ln-tabs-for] must be nested inside a [data-ln-tabs] parent container
|
|
15
|
-
[data-ln-tabs-for]:not([data-ln-tabs] *) {
|
|
16
|
-
@include dev-inline-error("[data-ln-tabs-for] is orphaned (not inside a [data-ln-tabs] container)");
|
|
17
|
-
}
|
|
18
|
-
}
|
package/js/ln-tabs/ln-tabs.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(function(){"use strict";if(typeof window<"u"){const t=console.warn;console.warn=function(...e){typeof e[0]=="string"&&(e[0].startsWith("[ln-")||e[0].startsWith("[lnCore"))&&!(document.documentElement.hasAttribute("data-ln-debug")||document.body&&document.body.hasAttribute("data-ln-debug"))||t.apply(console,e)}}const g={};function P(t,e){g[t]||(g[t]=document.querySelector('[data-ln-template="'+t+'"]'));const o=g[t];return o?o.content.cloneNode(!0):(console.warn("["+(e||"ln-core")+'] Template "'+t+'" not found'),null)}function S(t,e,o){t.dispatchEvent(new CustomEvent(e,{bubbles:!0,detail:o||{}}))}function _(t,e){if(!t||!e)return t;const o=t.querySelectorAll("[data-ln-field]");for(let r=0;r<o.length;r++){const s=o[r],n=s.getAttribute("data-ln-field");e[n]!=null&&(s.textContent=e[n])}const a=t.querySelectorAll("[data-ln-attr]");for(let r=0;r<a.length;r++){const s=a[r],n=s.getAttribute("data-ln-attr").split(",");for(let l=0;l<n.length;l++){const c=n[l].trim().split(":");if(c.length!==2)continue;const f=c[0].trim(),d=c[1].trim();e[d]!=null&&s.setAttribute(f,e[d])}}const u=t.querySelectorAll("[data-ln-show]");for(let r=0;r<u.length;r++){const s=u[r],n=s.getAttribute("data-ln-show");n in e&&s.classList.toggle("hidden",!e[n])}const i=t.querySelectorAll("[data-ln-class]");for(let r=0;r<i.length;r++){const s=i[r],n=s.getAttribute("data-ln-class").split(",");for(let l=0;l<n.length;l++){const c=n[l].trim().split(":");if(c.length!==2)continue;const f=c[0].trim(),d=c[1].trim();d in e&&s.classList.toggle(f,!!e[d])}}return t}function R(t,e){t.matches&&t.matches("[data-ln-form], [data-ln-fillable]")&&t.dispatchEvent(new CustomEvent("ln-fill",{detail:e??null,bubbles:!0}));const o=t.querySelectorAll("[data-ln-form], [data-ln-fillable]");for(let a=0;a<o.length;a++)o[a].dispatchEvent(new CustomEvent("ln-fill",{detail:e??null,bubbles:!0}));return t}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._fillBound||(window.lnCore._fillBound=!0,document.addEventListener("ln-fill",function(t){if(!(!t.target.matches||!t.target.matches("[data-ln-fillable]")))if(t.detail)_(t.target,t.detail);else{const e=t.target.querySelectorAll("[data-ln-field]");for(let o=0;o<e.length;o++)e[o].textContent=""}})));function x(t,e){if(!t||!e)return t;const o=document.createTreeWalker(t,NodeFilter.SHOW_TEXT);for(;o.nextNode();){const i=o.currentNode;i.textContent.indexOf("{{")!==-1&&(i.textContent=i.textContent.replace(/\{\{\s*(\w+)\s*\}\}/g,function(r,s){return e[s]!==void 0?e[s]:""}))}const a=function(i,r){return e[r]!==void 0?e[r]:""},u=Array.from(t.querySelectorAll("*"));t.nodeType===1&&u.push(t);for(let i=0;i<u.length;i++){const r=u[i],s=r.attributes;for(let n=0;n<s.length;n++){const l=s[n];l.value.indexOf("{{")!==-1&&r.setAttribute(l.name,l.value.replace(/\{\{\s*(\w+)\s*\}\}/g,a))}}return t}function j(t,e,o,a,u,i){const r={};for(let n=0;n<t.children.length;n++){const l=t.children[n],c=l.getAttribute("data-ln-key");c&&(r[c]=l)}const s=document.createDocumentFragment();for(let n=0;n<e.length;n++){const l=e[n],c=String(a(l));let f=r[c];if(f)u(f,l,n);else{const d=P(o,i);if(!d||(x(d,l),f=d.firstElementChild,!f))continue;f.setAttribute("data-ln-key",c),u(f,l,n)}s.appendChild(f)}t.textContent="",t.appendChild(s)}function k(t,e){if(!document.body){document.addEventListener("DOMContentLoaded",function(){k(t,e)}),console.warn("["+e+'] Script loaded before <body> — add "defer" to your <script> tag');return}t()}function w(t,e,o,a){if(t.nodeType!==1)return;const i=e.indexOf("[")!==-1||e.indexOf(".")!==-1||e.indexOf("#")!==-1?e:"["+e+"]",r=Array.from(t.querySelectorAll(i));t.matches&&t.matches(i)&&r.push(t);for(const s of r)s[o]||(s[o]=new a(s))}function W(t,e,o,a,u={}){const i=u.extraAttributes||[],r=u.onAttributeChange||null,s=u.onInit||null;function n(l){const c=l||document.body;w(c,t,e,o),s&&s(c)}return k(function(){const l=new MutationObserver(function(f){for(let d=0;d<f.length;d++){const h=f[d];if(h.type==="childList"){for(let m=0;m<h.addedNodes.length;m++){const p=h.addedNodes[m];p.nodeType===1&&(w(p,t,e,o),s&&s(p))}for(let m=0;m<h.removedNodes.length;m++){const p=h.removedNodes[m];if(p.nodeType===1){const I=t.indexOf("[")!==-1||t.indexOf(".")!==-1||t.indexOf("#")!==-1?t:"["+t+"]",C=Array.from(p.querySelectorAll(I));p.matches&&p.matches(I)&&C.push(p);for(let v=0;v<C.length;v++){const M=C[v];if(!document.contains(M)){const L=M[e];L&&typeof L.destroy=="function"&&L.destroy()}}}}}else h.type==="attributes"&&(r&&h.target[e]?r(h.target,h.attributeName):(w(h.target,t,e,o),s&&s(h.target)))}});let c=[];if(t.indexOf("[")!==-1){const f=/\[([\w-]+)/g;let d;for(;(d=f.exec(t))!==null;)c.push(d[1])}else c.push(t);l.observe(document.body,{childList:!0,subtree:!0,attributes:!0,attributeFilter:c.concat(i)})},a),window[e]=n,document.readyState==="loading"?document.addEventListener("DOMContentLoaded",function(){n(document.body)}):n(document.body),n}const E={};function H(t,e){E[t]=e}function B(t){return E[t]||{ingress:e=>e,egress:e=>e}}const T={};function q(t,e){if(!t||typeof e!="object")return;const o=t.toLowerCase().split("-")[0];T[o]=e}function U(t){if(!t)return null;const e=t.toLowerCase().split("-")[0];return T[e]||null}q("mk",{monthsLong:["јануари","февруари","март","април","мај","јуни","јули","август","септември","октомври","ноември","декември"],monthsShort:["јан","фев","мар","апр","мај","јун","јул","авг","септ","окт","ноем","дек"],daysLong:["недела","понеделник","вторник","среда","четврток","петок","сабота"],daysShort:["нед","пон","вт","ср","чет","пет","саб"]}),typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerDataMapper=H,window.lnCore.getDataMapper=B,window.lnCore.registerLocaleFallback=q,window.lnCore.getLocaleFallback=U,window.lnCore.fillTemplate=x,window.lnCore.fill=_,window.lnCore.lnFill=R,window.lnCore.renderList=j);const G="ln:";let b=null;function O(){if(b!==null)return b;try{if(typeof localStorage>"u")return b=!1,!1;const t="__ln_test__";localStorage.setItem(t,t),localStorage.removeItem(t),b=!0}catch{b=!1}return b}function J(){return location.pathname.replace(/\/+$/,"").toLowerCase()||"/"}function K(t,e){const o=e.getAttribute("data-ln-persist"),a=o!==null&&o!==""?o:e.id;return a?G+t+":"+J()+":"+a:(console.warn('[ln-persist] Element requires id or data-ln-persist="key"',e),null)}function X(t,e){if(!O())return null;const o=K(t,e);if(!o)return null;try{const a=localStorage.getItem(o);return a!==null?JSON.parse(a):null}catch{return null}}function $(t,e,o){if(!O())return;const a=K(t,e);if(a)try{o==null?localStorage.removeItem(a):localStorage.setItem(a,JSON.stringify(o))}catch{}}function N(t){return(t||"").replace(/^#/,"")}function y(t){const e=t===void 0?location.hash:t,o={},a=N(e);if(!a)return o;const u=a.split("&");for(let i=0;i<u.length;i++){const r=u[i];if(!r)continue;const s=r.indexOf(":"),n=s>-1?r.slice(0,s):r,l=s>-1?r.slice(s+1):"";if(n)try{o[n]=decodeURIComponent(l)}catch{o[n]=l}}return o}function A(t){if(!t)return null;const e=y();return t in e?e[t]:null}function D(t,e){if(!t)return;const o=y();e==null?delete o[t]:o[t]=String(e);const u=Object.keys(o).map(function(i){const r=o[i];return r===""?i:i+":"+encodeURIComponent(r)}).join("&");N(location.hash)!==u&&(location.hash=u)}function F(t){return t.button===1||t.ctrlKey||t.metaKey||t.shiftKey?!1:(t.preventDefault(),!0)}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.hashParse=y,window.lnCore.hashGet=A,window.lnCore.hashSet=D,window.lnCore.hashLinkClick=F),(function(){const t="data-ln-tabs",e="lnTabs";if(window[e]!==void 0&&window[e]!==null)return;function o(i,r){const s=(i.getAttribute("data-ln-tab")||"").toLowerCase().trim();if(s)return s;if(i.tagName!=="A")return"";const n=i.getAttribute("href")||"";if(!n.startsWith("#"))return"";const l=n.slice(1);if(!l)return"";const c=l.split("&");if(r)for(const h of c){const m=h.indexOf(":");if(m>0&&h.slice(0,m).toLowerCase().trim()===r)return h.slice(m+1).toLowerCase().trim()}const f=c[c.length-1]||"",d=f.indexOf(":");return(d>0?f.slice(d+1):f).toLowerCase().trim()}function a(i){return this.dom=i,u.call(this),this}function u(){this.tabs=Array.from(this.dom.querySelectorAll("[data-ln-tab]")),this.panels=Array.from(this.dom.querySelectorAll("[data-ln-panel]"));const i=this.tabs.filter(n=>n.tagName==="A"&&(n.getAttribute("href")||"").startsWith("#")),r=i.length>0&&i.length===this.tabs.length;this.nsKey=(this.dom.getAttribute("data-ln-tabs-key")||this.dom.id||"").toLowerCase().trim(),this.hashEnabled=r&&!!this.nsKey,i.length>0&&i.length!==this.tabs.length?console.warn('[ln-tabs] Mixed <a href="#…"> and <button> triggers in one group — using persist mode. Pick one: anchors for URL hash, buttons for localStorage persist.',this.dom):r&&!this.nsKey&&console.warn("[ln-tabs] Anchor triggers need a hash namespace — add id or data-ln-tabs-key to the wrapper. Falling back to non-hash mode.",this.dom),this.mapTabs={},this.mapPanels={};for(const n of this.tabs){const l=o(n,this.nsKey);l?this.mapTabs[l]=n:console.warn('[ln-tabs] Trigger has no resolvable key — needs `data-ln-tab="key"` or `<a href="#…">`.',n)}for(const n of this.panels){const l=(n.getAttribute("data-ln-panel")||"").toLowerCase().trim();l&&(this.mapPanels[l]=n)}this.defaultKey=(this.dom.getAttribute("data-ln-tabs-default")||"").toLowerCase().trim()||Object.keys(this.mapTabs)[0]||"",this.autoFocus=(this.dom.getAttribute("data-ln-tabs-focus")||"true").toLowerCase()!=="false";const s=this;this._clickHandlers=[];for(const n of this.tabs){if(n[e+"Trigger"])continue;const l=function(c){const f=n.tagName==="A";if(!f&&(c.ctrlKey||c.metaKey||c.button===1))return;const d=o(n,s.nsKey);d&&(f&&!F(c)||(s.hashEnabled?A(s.nsKey)===d?s.dom.setAttribute("data-ln-tabs-active",d):D(s.nsKey,d):s.dom.setAttribute("data-ln-tabs-active",d)))};n.addEventListener("click",l),n[e+"Trigger"]=l,s._clickHandlers.push({el:n,handler:l})}if(this._onRequestSelect=function(n){const l=n.detail&&(n.detail.key||n.detail.tab);l&&s.dom.setAttribute("data-ln-tabs-active",(l+"").toLowerCase().trim())},this.dom.addEventListener("ln-tabs:request-select",this._onRequestSelect),this.dom.addEventListener("ln-tabs:request-activate",this._onRequestSelect),this._hashHandler=function(){if(!s.hashEnabled)return;const n=A(s.nsKey);s.dom.setAttribute("data-ln-tabs-active",n!==null?n:s.defaultKey)},this.hashEnabled)window.addEventListener("hashchange",this._hashHandler),this._hashHandler();else{let n=this.defaultKey;if(this.dom.hasAttribute("data-ln-persist")&&!this.hashEnabled){const l=X("tabs",this.dom);l!==null&&l in this.mapPanels&&(n=l)}this.dom.setAttribute("data-ln-tabs-active",n)}}a.prototype._applyActive=function(i){var r;(!i||!(i in this.mapPanels))&&(i=this.defaultKey);for(const s in this.mapTabs){const n=this.mapTabs[s];s===i?(n.setAttribute("data-active",""),n.setAttribute("aria-selected","true")):(n.removeAttribute("data-active"),n.setAttribute("aria-selected","false"))}for(const s in this.mapPanels){const n=this.mapPanels[s],l=s===i;n.classList.toggle("hidden",!l),n.setAttribute("aria-hidden",l?"false":"true")}if(this.autoFocus){const s=(r=this.mapPanels[i])==null?void 0:r.querySelector('input,button,select,textarea,[tabindex]:not([tabindex="-1"])');s&&setTimeout(()=>s.focus({preventScroll:!0}),0)}S(this.dom,"ln-tabs:change",{key:i,tab:this.mapTabs[i],panel:this.mapPanels[i]}),this.dom.hasAttribute("data-ln-persist")&&!this.hashEnabled&&$("tabs",this.dom,i)},a.prototype.destroy=function(){if(this.dom[e]){this.dom.removeEventListener("ln-tabs:request-select",this._onRequestSelect),this.dom.removeEventListener("ln-tabs:request-activate",this._onRequestSelect);for(const{el:i,handler:r}of this._clickHandlers)i.removeEventListener("click",r),delete i[e+"Trigger"];this.hashEnabled&&window.removeEventListener("hashchange",this._hashHandler),S(this.dom,"ln-tabs:destroyed",{target:this.dom}),delete this.dom[e]}},W(t,e,a,"ln-tabs",{extraAttributes:["data-ln-tabs-active"],onAttributeChange:function(i){const r=i.getAttribute("data-ln-tabs-active");i[e]._applyActive(r)}})})()})();
|
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
/* Live Networks - lnTabs (hash-aware tabs — supports <button> and <a href="#nsKey:key"> triggers) */
|
|
2
|
-
import { registerComponent, dispatch } from '../../ln-core';
|
|
3
|
-
import { persistGet, persistSet } from '../../ln-core';
|
|
4
|
-
import { hashGet, hashSet, hashLinkClick } from '../../ln-core';
|
|
5
|
-
|
|
6
|
-
(function () {
|
|
7
|
-
const DOM_SELECTOR = "data-ln-tabs";
|
|
8
|
-
const DOM_ATTRIBUTE = "lnTabs";
|
|
9
|
-
|
|
10
|
-
if (window[DOM_ATTRIBUTE] !== undefined && window[DOM_ATTRIBUTE] !== null) return;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
function _keyFromTrigger(t, nsKey) {
|
|
14
|
-
const explicit = (t.getAttribute("data-ln-tab") || "").toLowerCase().trim();
|
|
15
|
-
if (explicit) return explicit;
|
|
16
|
-
if (t.tagName !== "A") return "";
|
|
17
|
-
const href = t.getAttribute("href") || "";
|
|
18
|
-
if (!href.startsWith("#")) return "";
|
|
19
|
-
const raw = href.slice(1);
|
|
20
|
-
if (!raw) return "";
|
|
21
|
-
const fragments = raw.split("&");
|
|
22
|
-
if (nsKey) {
|
|
23
|
-
for (const frag of fragments) {
|
|
24
|
-
const sep = frag.indexOf(":");
|
|
25
|
-
if (sep > 0 && frag.slice(0, sep).toLowerCase().trim() === nsKey) {
|
|
26
|
-
return frag.slice(sep + 1).toLowerCase().trim();
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
const last = fragments[fragments.length - 1] || "";
|
|
31
|
-
const sep = last.indexOf(":");
|
|
32
|
-
return (sep > 0 ? last.slice(sep + 1) : last).toLowerCase().trim();
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function _component(dom) { this.dom = dom; _init.call(this); return this; }
|
|
36
|
-
|
|
37
|
-
function _init() {
|
|
38
|
-
this.tabs = Array.from(this.dom.querySelectorAll("[data-ln-tab]"));
|
|
39
|
-
this.panels = Array.from(this.dom.querySelectorAll("[data-ln-panel]"));
|
|
40
|
-
|
|
41
|
-
// Mode is declared by the TRIGGER TYPE, not by presence of an id:
|
|
42
|
-
// <a href="#…"> → URL hash sync (shareable, back/forward aware)
|
|
43
|
-
// <button> → localStorage persist (opt-in via data-ln-persist)
|
|
44
|
-
// This decouples the two axes that used to collide on `id`: now
|
|
45
|
-
// `id`/`data-ln-tabs-key` only NAMESPACE the hash, and
|
|
46
|
-
// `data-ln-persist` only names the storage key — neither selects the
|
|
47
|
-
// mode. The markup does. Mixed triggers almost always signal a markup
|
|
48
|
-
// mistake, so we fall back to persist and warn rather than guess.
|
|
49
|
-
//
|
|
50
|
-
// nsKey resolved BEFORE mapTabs build — anchor key derivation in
|
|
51
|
-
// _keyFromTrigger needs nsKey to pick the right fragment.
|
|
52
|
-
const anchorTabs = this.tabs.filter(t => t.tagName === "A" && (t.getAttribute("href") || "").startsWith("#"));
|
|
53
|
-
const allAnchors = anchorTabs.length > 0 && anchorTabs.length === this.tabs.length;
|
|
54
|
-
this.nsKey = (this.dom.getAttribute("data-ln-tabs-key") || this.dom.id || "").toLowerCase().trim();
|
|
55
|
-
this.hashEnabled = allAnchors && !!this.nsKey;
|
|
56
|
-
|
|
57
|
-
if (anchorTabs.length > 0 && anchorTabs.length !== this.tabs.length) {
|
|
58
|
-
console.warn('[ln-tabs] Mixed <a href="#…"> and <button> triggers in one group — using persist mode. Pick one: anchors for URL hash, buttons for localStorage persist.', this.dom);
|
|
59
|
-
} else if (allAnchors && !this.nsKey) {
|
|
60
|
-
console.warn('[ln-tabs] Anchor triggers need a hash namespace — add id or data-ln-tabs-key to the wrapper. Falling back to non-hash mode.', this.dom);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
this.mapTabs = {};
|
|
64
|
-
this.mapPanels = {};
|
|
65
|
-
for (const t of this.tabs) {
|
|
66
|
-
const key = _keyFromTrigger(t, this.nsKey);
|
|
67
|
-
if (key) {
|
|
68
|
-
this.mapTabs[key] = t;
|
|
69
|
-
} else {
|
|
70
|
-
console.warn('[ln-tabs] Trigger has no resolvable key — needs `data-ln-tab="key"` or `<a href="#…">`.', t);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
for (const p of this.panels) {
|
|
74
|
-
const key = (p.getAttribute("data-ln-panel") || "").toLowerCase().trim();
|
|
75
|
-
if (key) this.mapPanels[key] = p;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
this.defaultKey = (this.dom.getAttribute("data-ln-tabs-default") || "").toLowerCase().trim()
|
|
79
|
-
|| Object.keys(this.mapTabs)[0] || "";
|
|
80
|
-
this.autoFocus = (this.dom.getAttribute("data-ln-tabs-focus") || "true").toLowerCase() !== "false";
|
|
81
|
-
|
|
82
|
-
const self = this;
|
|
83
|
-
this._clickHandlers = [];
|
|
84
|
-
for (const t of this.tabs) {
|
|
85
|
-
if (t[DOM_ATTRIBUTE + 'Trigger']) continue;
|
|
86
|
-
const handler = function (e) {
|
|
87
|
-
const isAnchor = t.tagName === "A";
|
|
88
|
-
// Buttons keep their plain modifier/middle-click guard. Anchor
|
|
89
|
-
// triggers route through the shared core hash-link helper, which
|
|
90
|
-
// owns the guard (incl. shiftKey) AND the preventDefault — the
|
|
91
|
-
// same path ln-modal uses, so anchor click handling is unified.
|
|
92
|
-
if (!isAnchor && (e.ctrlKey || e.metaKey || e.button === 1)) return;
|
|
93
|
-
const key = _keyFromTrigger(t, self.nsKey);
|
|
94
|
-
if (!key) return;
|
|
95
|
-
if (isAnchor && !hashLinkClick(e)) return;
|
|
96
|
-
if (self.hashEnabled) {
|
|
97
|
-
if (hashGet(self.nsKey) === key) self.dom.setAttribute('data-ln-tabs-active', key);
|
|
98
|
-
else hashSet(self.nsKey, key);
|
|
99
|
-
} else {
|
|
100
|
-
self.dom.setAttribute('data-ln-tabs-active', key);
|
|
101
|
-
}
|
|
102
|
-
};
|
|
103
|
-
t.addEventListener("click", handler);
|
|
104
|
-
t[DOM_ATTRIBUTE + 'Trigger'] = handler;
|
|
105
|
-
self._clickHandlers.push({ el: t, handler: handler });
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
this._onRequestSelect = function (e) {
|
|
109
|
-
const key = e.detail && (e.detail.key || e.detail.tab);
|
|
110
|
-
if (key) self.dom.setAttribute('data-ln-tabs-active', (key + '').toLowerCase().trim());
|
|
111
|
-
};
|
|
112
|
-
this.dom.addEventListener('ln-tabs:request-select', this._onRequestSelect);
|
|
113
|
-
this.dom.addEventListener('ln-tabs:request-activate', this._onRequestSelect);
|
|
114
|
-
|
|
115
|
-
this._hashHandler = function () {
|
|
116
|
-
if (!self.hashEnabled) return;
|
|
117
|
-
const val = hashGet(self.nsKey);
|
|
118
|
-
self.dom.setAttribute('data-ln-tabs-active', val !== null ? val : self.defaultKey);
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
if (this.hashEnabled) {
|
|
122
|
-
window.addEventListener("hashchange", this._hashHandler);
|
|
123
|
-
this._hashHandler();
|
|
124
|
-
} else {
|
|
125
|
-
let initialKey = this.defaultKey;
|
|
126
|
-
if (this.dom.hasAttribute('data-ln-persist') && !this.hashEnabled) {
|
|
127
|
-
const saved = persistGet('tabs', this.dom);
|
|
128
|
-
if (saved !== null && saved in this.mapPanels) {
|
|
129
|
-
initialKey = saved;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
this.dom.setAttribute('data-ln-tabs-active', initialKey);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
_component.prototype._applyActive = function (key) {
|
|
137
|
-
if (!key || !(key in this.mapPanels)) key = this.defaultKey;
|
|
138
|
-
for (const k in this.mapTabs) {
|
|
139
|
-
const btn = this.mapTabs[k];
|
|
140
|
-
if (k === key) {
|
|
141
|
-
btn.setAttribute("data-active", "");
|
|
142
|
-
btn.setAttribute("aria-selected", "true");
|
|
143
|
-
} else {
|
|
144
|
-
btn.removeAttribute("data-active");
|
|
145
|
-
btn.setAttribute("aria-selected", "false");
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
for (const k in this.mapPanels) {
|
|
149
|
-
const panel = this.mapPanels[k];
|
|
150
|
-
const show = (k === key);
|
|
151
|
-
panel.classList.toggle("hidden", !show);
|
|
152
|
-
panel.setAttribute("aria-hidden", show ? "false" : "true");
|
|
153
|
-
}
|
|
154
|
-
if (this.autoFocus) {
|
|
155
|
-
const first = this.mapPanels[key]?.querySelector('input,button,select,textarea,[tabindex]:not([tabindex="-1"])');
|
|
156
|
-
if (first) setTimeout(() => first.focus({ preventScroll: true }), 0);
|
|
157
|
-
}
|
|
158
|
-
dispatch(this.dom, 'ln-tabs:change', { key: key, tab: this.mapTabs[key], panel: this.mapPanels[key] });
|
|
159
|
-
if (this.dom.hasAttribute('data-ln-persist') && !this.hashEnabled) {
|
|
160
|
-
persistSet('tabs', this.dom, key);
|
|
161
|
-
}
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
_component.prototype.destroy = function () {
|
|
165
|
-
if (!this.dom[DOM_ATTRIBUTE]) return;
|
|
166
|
-
this.dom.removeEventListener('ln-tabs:request-select', this._onRequestSelect);
|
|
167
|
-
this.dom.removeEventListener('ln-tabs:request-activate', this._onRequestSelect);
|
|
168
|
-
for (const { el, handler } of this._clickHandlers) {
|
|
169
|
-
el.removeEventListener("click", handler);
|
|
170
|
-
delete el[DOM_ATTRIBUTE + 'Trigger'];
|
|
171
|
-
}
|
|
172
|
-
if (this.hashEnabled) {
|
|
173
|
-
window.removeEventListener("hashchange", this._hashHandler);
|
|
174
|
-
}
|
|
175
|
-
dispatch(this.dom, 'ln-tabs:destroyed', { target: this.dom });
|
|
176
|
-
delete this.dom[DOM_ATTRIBUTE];
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
// ─── Init ──────────────────────────────────────────────────
|
|
180
|
-
|
|
181
|
-
registerComponent(DOM_SELECTOR, DOM_ATTRIBUTE, _component, 'ln-tabs', {
|
|
182
|
-
extraAttributes: ['data-ln-tabs-active'],
|
|
183
|
-
onAttributeChange: function (el) {
|
|
184
|
-
const key = el.getAttribute('data-ln-tabs-active');
|
|
185
|
-
el[DOM_ATTRIBUTE]._applyActive(key);
|
|
186
|
-
}
|
|
187
|
-
});
|
|
188
|
-
})();
|