@livenetworks/ashlar 1.6.1 → 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/{js → components}/ln-confirm/README.md +69 -18
- 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 -171
- 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/_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
|
@@ -1,419 +0,0 @@
|
|
|
1
|
-
import { dispatch, fillTemplate, registerComponent } from '../../ln-core';
|
|
2
|
-
import { createBatcher } from '../../ln-core';
|
|
3
|
-
import { persistGet, persistSet } from '../../ln-core';
|
|
4
|
-
|
|
5
|
-
(function () {
|
|
6
|
-
const DOM_SELECTOR = 'data-ln-filter';
|
|
7
|
-
const DOM_ATTRIBUTE = 'lnFilter';
|
|
8
|
-
const KEY_ATTR = 'data-ln-filter-key';
|
|
9
|
-
const VALUE_ATTR = 'data-ln-filter-value';
|
|
10
|
-
const HIDE_ATTR = 'data-ln-filter-hide';
|
|
11
|
-
const RESET_ATTR = 'data-ln-filter-reset';
|
|
12
|
-
const COL_ATTR = 'data-ln-filter-col';
|
|
13
|
-
|
|
14
|
-
// Shared column filter state per table (AND across columns, OR within column)
|
|
15
|
-
const _tableFilters = new WeakMap();
|
|
16
|
-
|
|
17
|
-
if (window[DOM_ATTRIBUTE] !== undefined) return;
|
|
18
|
-
|
|
19
|
-
function _isReset(input) {
|
|
20
|
-
return input.hasAttribute(RESET_ATTR) || input.getAttribute(VALUE_ATTR) === '';
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function _deriveActive(self) {
|
|
24
|
-
let key = self._filterKey;
|
|
25
|
-
const values = [];
|
|
26
|
-
for (let i = 0; i < self.inputs.length; i++) {
|
|
27
|
-
const input = self.inputs[i];
|
|
28
|
-
if (input.checked && !_isReset(input)) {
|
|
29
|
-
const v = input.getAttribute(VALUE_ATTR);
|
|
30
|
-
if (v) values.push(v);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
return { key: key, values: values };
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function _arraysDiffer(a, b) {
|
|
37
|
-
if (a.length !== b.length) return true;
|
|
38
|
-
for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return true;
|
|
39
|
-
return false;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// ─── Auto-populate from table column ───────────────────────
|
|
43
|
-
|
|
44
|
-
function _populateFromColumn(instance) {
|
|
45
|
-
const dom = instance.dom;
|
|
46
|
-
const colIndex = instance.colIndex;
|
|
47
|
-
const tmpl = dom.querySelector('template');
|
|
48
|
-
if (!tmpl || colIndex === null) return;
|
|
49
|
-
|
|
50
|
-
const target = document.getElementById(instance.targetId);
|
|
51
|
-
if (!target) return;
|
|
52
|
-
|
|
53
|
-
const table = target.tagName === 'TABLE' ? target : target.querySelector('table');
|
|
54
|
-
if (!table || target.hasAttribute('data-ln-table')) return;
|
|
55
|
-
|
|
56
|
-
// Collect unique values from column
|
|
57
|
-
const seen = {};
|
|
58
|
-
const values = [];
|
|
59
|
-
const bodies = table.tBodies;
|
|
60
|
-
for (let b = 0; b < bodies.length; b++) {
|
|
61
|
-
const rows = bodies[b].rows;
|
|
62
|
-
for (let r = 0; r < rows.length; r++) {
|
|
63
|
-
const cell = rows[r].cells[colIndex];
|
|
64
|
-
const text = cell ? cell.textContent.trim() : '';
|
|
65
|
-
if (text && !seen[text]) {
|
|
66
|
-
seen[text] = true;
|
|
67
|
-
values.push(text);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
values.sort(function (a, b) {
|
|
72
|
-
return a.localeCompare(b);
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
// Determine the filter key from existing inputs or dom attribute
|
|
76
|
-
const existingInput = dom.querySelector('[' + KEY_ATTR + ']');
|
|
77
|
-
const filterKey = existingInput
|
|
78
|
-
? existingInput.getAttribute(KEY_ATTR)
|
|
79
|
-
: (dom.getAttribute('data-ln-filter-key') || 'col' + colIndex);
|
|
80
|
-
|
|
81
|
-
// Clone template for each value
|
|
82
|
-
for (let i = 0; i < values.length; i++) {
|
|
83
|
-
const clone = tmpl.content.cloneNode(true);
|
|
84
|
-
const input = clone.querySelector('input');
|
|
85
|
-
if (!input) continue;
|
|
86
|
-
input.setAttribute(KEY_ATTR, filterKey);
|
|
87
|
-
input.setAttribute(VALUE_ATTR, values[i]);
|
|
88
|
-
fillTemplate(clone, { text: values[i] });
|
|
89
|
-
dom.appendChild(clone);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// ─── Component ─────────────────────────────────────────────
|
|
94
|
-
|
|
95
|
-
function _component(dom) {
|
|
96
|
-
this.dom = dom;
|
|
97
|
-
this.targetId = dom.getAttribute(DOM_SELECTOR);
|
|
98
|
-
|
|
99
|
-
// Column index for table filtering (null = not a table column filter)
|
|
100
|
-
const colAttr = dom.getAttribute(COL_ATTR);
|
|
101
|
-
this.colIndex = colAttr !== null ? parseInt(colAttr, 10) : null;
|
|
102
|
-
|
|
103
|
-
// Auto-populate from table column if template present
|
|
104
|
-
_populateFromColumn(this);
|
|
105
|
-
|
|
106
|
-
// Collect inputs AFTER auto-populate (new inputs may have been added)
|
|
107
|
-
this.inputs = Array.from(dom.querySelectorAll('[' + KEY_ATTR + ']'));
|
|
108
|
-
this._filterKey = this.inputs.length > 0 ? this.inputs[0].getAttribute(KEY_ATTR) : null;
|
|
109
|
-
|
|
110
|
-
// Event-diff cache — null means never dispatched yet
|
|
111
|
-
this._lastSnapshot = null;
|
|
112
|
-
|
|
113
|
-
const self = this;
|
|
114
|
-
|
|
115
|
-
const queueRender = createBatcher(
|
|
116
|
-
function () { self._render(); },
|
|
117
|
-
function () { self._afterRender(); }
|
|
118
|
-
);
|
|
119
|
-
|
|
120
|
-
// Stash for use in change handler
|
|
121
|
-
this._queueRender = queueRender;
|
|
122
|
-
|
|
123
|
-
this._attachHandlers();
|
|
124
|
-
|
|
125
|
-
// ─── Restore persisted filter ─────────────────────────────
|
|
126
|
-
let _persistRestored = false;
|
|
127
|
-
if (dom.hasAttribute('data-ln-persist')) {
|
|
128
|
-
const saved = persistGet('filter', dom);
|
|
129
|
-
if (saved && saved.key && Array.isArray(saved.values) && saved.values.length > 0) {
|
|
130
|
-
// Write input.checked on matching inputs
|
|
131
|
-
for (let i = 0; i < this.inputs.length; i++) {
|
|
132
|
-
const input = this.inputs[i];
|
|
133
|
-
if (_isReset(input)) {
|
|
134
|
-
input.checked = false;
|
|
135
|
-
} else if (input.getAttribute(KEY_ATTR) === saved.key &&
|
|
136
|
-
saved.values.indexOf(input.getAttribute(VALUE_ATTR)) !== -1) {
|
|
137
|
-
input.checked = true;
|
|
138
|
-
} else {
|
|
139
|
-
input.checked = false;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
queueRender();
|
|
143
|
-
_persistRestored = true;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
if (!_persistRestored) {
|
|
148
|
-
// DOM is already canonical — only schedule render if anything is pre-checked
|
|
149
|
-
// so visibility is applied and the initial ln-filter:changed fires (via
|
|
150
|
-
// null-snapshot diff in _afterRender).
|
|
151
|
-
for (let i = 0; i < this.inputs.length; i++) {
|
|
152
|
-
if (this.inputs[i].checked && !_isReset(this.inputs[i])) {
|
|
153
|
-
queueRender();
|
|
154
|
-
break;
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
return this;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
// ─── Handlers ──────────────────────────────────────────────
|
|
163
|
-
|
|
164
|
-
_component.prototype._attachHandlers = function () {
|
|
165
|
-
const self = this;
|
|
166
|
-
|
|
167
|
-
this.inputs.forEach(function (input) {
|
|
168
|
-
if (input[DOM_ATTRIBUTE + 'Bound']) return;
|
|
169
|
-
input[DOM_ATTRIBUTE + 'Bound'] = true;
|
|
170
|
-
|
|
171
|
-
input._lnFilterChange = function () {
|
|
172
|
-
if (_isReset(input)) {
|
|
173
|
-
// Reset sentinel — regardless of direction, enforce checked + clear values
|
|
174
|
-
for (let i = 0; i < self.inputs.length; i++) {
|
|
175
|
-
if (!_isReset(self.inputs[i])) self.inputs[i].checked = false;
|
|
176
|
-
}
|
|
177
|
-
// Force sentinel back to checked (clicking an already-checked sentinel
|
|
178
|
-
// would natively uncheck it; force back to checked)
|
|
179
|
-
input.checked = true;
|
|
180
|
-
self._queueRender();
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
if (input.checked) {
|
|
185
|
-
// Mutual exclusion: uncheck all reset sentinels
|
|
186
|
-
for (let i = 0; i < self.inputs.length; i++) {
|
|
187
|
-
if (_isReset(self.inputs[i])) self.inputs[i].checked = false;
|
|
188
|
-
}
|
|
189
|
-
// If all non-reset inputs are now checked → collapse to sentinel
|
|
190
|
-
// (only when a reset sentinel exists; lists without one skip this)
|
|
191
|
-
let hasReset = false;
|
|
192
|
-
for (let ri = 0; ri < self.inputs.length; ri++) {
|
|
193
|
-
if (_isReset(self.inputs[ri])) { hasReset = true; break; }
|
|
194
|
-
}
|
|
195
|
-
if (hasReset) {
|
|
196
|
-
let allChecked = true;
|
|
197
|
-
for (let ci = 0; ci < self.inputs.length; ci++) {
|
|
198
|
-
if (!_isReset(self.inputs[ci]) && !self.inputs[ci].checked) {
|
|
199
|
-
allChecked = false;
|
|
200
|
-
break;
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
if (allChecked) {
|
|
204
|
-
for (let mi = 0; mi < self.inputs.length; mi++) {
|
|
205
|
-
if (_isReset(self.inputs[mi])) self.inputs[mi].checked = true;
|
|
206
|
-
else self.inputs[mi].checked = false;
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
} else {
|
|
211
|
-
// If no non-reset values remain checked, fall back to reset
|
|
212
|
-
let anyChecked = false;
|
|
213
|
-
for (let i = 0; i < self.inputs.length; i++) {
|
|
214
|
-
if (!_isReset(self.inputs[i]) && self.inputs[i].checked) {
|
|
215
|
-
anyChecked = true;
|
|
216
|
-
break;
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
if (!anyChecked) {
|
|
220
|
-
for (let i = 0; i < self.inputs.length; i++) {
|
|
221
|
-
if (_isReset(self.inputs[i])) self.inputs[i].checked = true;
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
self._queueRender();
|
|
227
|
-
};
|
|
228
|
-
input.addEventListener('change', input._lnFilterChange);
|
|
229
|
-
});
|
|
230
|
-
};
|
|
231
|
-
|
|
232
|
-
// ─── Render ────────────────────────────────────────────────
|
|
233
|
-
|
|
234
|
-
_component.prototype._render = function () {
|
|
235
|
-
const self = this;
|
|
236
|
-
const active = _deriveActive(this);
|
|
237
|
-
const isReset = active.key === null || active.values.length === 0;
|
|
238
|
-
|
|
239
|
-
// Build lowercase lookup for target filtering
|
|
240
|
-
const lowerValues = [];
|
|
241
|
-
for (let i = 0; i < active.values.length; i++) {
|
|
242
|
-
lowerValues.push(active.values[i].toLowerCase());
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
// Apply filter
|
|
246
|
-
if (self.colIndex !== null) {
|
|
247
|
-
// Table column filtering — shared multi-column logic
|
|
248
|
-
self._filterTableRows(active);
|
|
249
|
-
} else {
|
|
250
|
-
// Standard target-children filtering by data attribute
|
|
251
|
-
const target = document.getElementById(self.targetId);
|
|
252
|
-
if (!target) return;
|
|
253
|
-
|
|
254
|
-
const children = target.children;
|
|
255
|
-
for (let i = 0; i < children.length; i++) {
|
|
256
|
-
const el = children[i];
|
|
257
|
-
|
|
258
|
-
if (isReset) {
|
|
259
|
-
el.removeAttribute(HIDE_ATTR);
|
|
260
|
-
continue;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
const attr = el.getAttribute('data-' + active.key);
|
|
264
|
-
el.removeAttribute(HIDE_ATTR);
|
|
265
|
-
|
|
266
|
-
if (attr === null) continue;
|
|
267
|
-
|
|
268
|
-
// OR logic: visible if attr matches ANY active value
|
|
269
|
-
if (lowerValues.indexOf(attr.toLowerCase()) === -1) {
|
|
270
|
-
el.setAttribute(HIDE_ATTR, 'true');
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
};
|
|
275
|
-
|
|
276
|
-
_component.prototype._afterRender = function () {
|
|
277
|
-
const active = _deriveActive(this);
|
|
278
|
-
const prev = this._lastSnapshot;
|
|
279
|
-
const changed = !prev
|
|
280
|
-
|| prev.key !== active.key
|
|
281
|
-
|| _arraysDiffer(prev.values, active.values);
|
|
282
|
-
|
|
283
|
-
if (changed) {
|
|
284
|
-
// ln-filter:changed always fires when state moves
|
|
285
|
-
this._dispatchOnBoth('ln-filter:changed', {
|
|
286
|
-
key: active.key,
|
|
287
|
-
values: active.values.slice()
|
|
288
|
-
});
|
|
289
|
-
|
|
290
|
-
// ln-filter:reset fires only on transition into reset state
|
|
291
|
-
const wasActive = prev && prev.values.length > 0;
|
|
292
|
-
const nowReset = active.values.length === 0;
|
|
293
|
-
if (wasActive && nowReset) {
|
|
294
|
-
this._dispatchOnBoth('ln-filter:reset', {});
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
this._lastSnapshot = { key: active.key, values: active.values.slice() };
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
// Persist current filter state
|
|
301
|
-
if (this.dom.hasAttribute('data-ln-persist')) {
|
|
302
|
-
if (active.key && active.values.length > 0) {
|
|
303
|
-
persistSet('filter', this.dom, { key: active.key, values: active.values.slice() });
|
|
304
|
-
} else {
|
|
305
|
-
persistSet('filter', this.dom, null);
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
};
|
|
309
|
-
|
|
310
|
-
_component.prototype._dispatchOnBoth = function (eventName, detail) {
|
|
311
|
-
dispatch(this.dom, eventName, detail);
|
|
312
|
-
const target = document.getElementById(this.targetId);
|
|
313
|
-
if (target && target !== this.dom) {
|
|
314
|
-
dispatch(target, eventName, detail);
|
|
315
|
-
}
|
|
316
|
-
};
|
|
317
|
-
|
|
318
|
-
// ─── Table Row Filtering ───────────────────────────────────
|
|
319
|
-
|
|
320
|
-
_component.prototype._filterTableRows = function (active) {
|
|
321
|
-
const target = document.getElementById(this.targetId);
|
|
322
|
-
if (!target) return;
|
|
323
|
-
|
|
324
|
-
const table = target.tagName === 'TABLE' ? target : target.querySelector('table');
|
|
325
|
-
if (!table) return;
|
|
326
|
-
|
|
327
|
-
// Guard: don't filter if this is an ln-table (it handles its own filtering)
|
|
328
|
-
if (target.hasAttribute('data-ln-table')) return;
|
|
329
|
-
|
|
330
|
-
const key = active.key || this._filterKey;
|
|
331
|
-
const values = active.values;
|
|
332
|
-
|
|
333
|
-
// Get or create shared filter map for this table
|
|
334
|
-
if (!_tableFilters.has(table)) {
|
|
335
|
-
_tableFilters.set(table, {});
|
|
336
|
-
}
|
|
337
|
-
const filters = _tableFilters.get(table);
|
|
338
|
-
|
|
339
|
-
// Update this filter's entry
|
|
340
|
-
if (key && values.length > 0) {
|
|
341
|
-
const lower = [];
|
|
342
|
-
for (let i = 0; i < values.length; i++) {
|
|
343
|
-
lower.push(values[i].toLowerCase());
|
|
344
|
-
}
|
|
345
|
-
filters[key] = { col: this.colIndex, values: lower };
|
|
346
|
-
} else if (key) {
|
|
347
|
-
delete filters[key];
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
// Check if any column filters are active
|
|
351
|
-
const filterKeys = Object.keys(filters);
|
|
352
|
-
const hasFilters = filterKeys.length > 0;
|
|
353
|
-
|
|
354
|
-
// Apply all active filters to all rows (AND across columns, OR within column)
|
|
355
|
-
const bodies = table.tBodies;
|
|
356
|
-
for (let b = 0; b < bodies.length; b++) {
|
|
357
|
-
const rows = bodies[b].rows;
|
|
358
|
-
for (let r = 0; r < rows.length; r++) {
|
|
359
|
-
const row = rows[r];
|
|
360
|
-
|
|
361
|
-
if (!hasFilters) {
|
|
362
|
-
row.removeAttribute(HIDE_ATTR);
|
|
363
|
-
continue;
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
let visible = true;
|
|
367
|
-
for (let f = 0; f < filterKeys.length; f++) {
|
|
368
|
-
const filter = filters[filterKeys[f]];
|
|
369
|
-
const cell = row.cells[filter.col];
|
|
370
|
-
const cellText = cell ? cell.textContent.trim().toLowerCase() : '';
|
|
371
|
-
// OR within column: visible if cell text matches ANY filter value
|
|
372
|
-
if (filter.values.indexOf(cellText) === -1) {
|
|
373
|
-
visible = false;
|
|
374
|
-
break; // AND across columns: fail fast
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
if (visible) {
|
|
379
|
-
row.removeAttribute(HIDE_ATTR);
|
|
380
|
-
} else {
|
|
381
|
-
row.setAttribute(HIDE_ATTR, 'true');
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
};
|
|
386
|
-
|
|
387
|
-
// ─── Destroy ───────────────────────────────────────────────
|
|
388
|
-
|
|
389
|
-
_component.prototype.destroy = function () {
|
|
390
|
-
if (!this.dom[DOM_ATTRIBUTE]) return;
|
|
391
|
-
|
|
392
|
-
// Clean up table filter registry
|
|
393
|
-
if (this.colIndex !== null) {
|
|
394
|
-
const target = document.getElementById(this.targetId);
|
|
395
|
-
if (target) {
|
|
396
|
-
const table = target.tagName === 'TABLE' ? target : target.querySelector('table');
|
|
397
|
-
if (table && _tableFilters.has(table)) {
|
|
398
|
-
const filters = _tableFilters.get(table);
|
|
399
|
-
const key = this._filterKey;
|
|
400
|
-
if (key && filters[key]) delete filters[key];
|
|
401
|
-
if (Object.keys(filters).length === 0) _tableFilters.delete(table);
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
this.inputs.forEach(function (input) {
|
|
407
|
-
if (input._lnFilterChange) {
|
|
408
|
-
input.removeEventListener('change', input._lnFilterChange);
|
|
409
|
-
delete input._lnFilterChange;
|
|
410
|
-
}
|
|
411
|
-
delete input[DOM_ATTRIBUTE + 'Bound'];
|
|
412
|
-
});
|
|
413
|
-
delete this.dom[DOM_ATTRIBUTE];
|
|
414
|
-
};
|
|
415
|
-
|
|
416
|
-
// ─── Init ──────────────────────────────────────────────────
|
|
417
|
-
|
|
418
|
-
registerComponent(DOM_SELECTOR, DOM_ATTRIBUTE, _component, 'ln-filter');
|
|
419
|
-
})();
|
package/js/ln-form/ln-form.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 y={};function M(t,e){y[t]||(y[t]=document.querySelector('[data-ln-template="'+t+'"]'));const s=y[t];return s?s.content.cloneNode(!0):(console.warn("["+(e||"ln-core")+'] Template "'+t+'" not found'),null)}function D(t,e,s){t.dispatchEvent(new CustomEvent(e,{bubbles:!0,detail:s||{}}))}function v(t,e){if(!t||!e)return t;const s=t.querySelectorAll("[data-ln-field]");for(let n=0;n<s.length;n++){const i=s[n],l=i.getAttribute("data-ln-field");e[l]!=null&&(i.textContent=e[l])}const d=t.querySelectorAll("[data-ln-attr]");for(let n=0;n<d.length;n++){const i=d[n],l=i.getAttribute("data-ln-attr").split(",");for(let r=0;r<l.length;r++){const u=l[r].trim().split(":");if(u.length!==2)continue;const a=u[0].trim(),f=u[1].trim();e[f]!=null&&i.setAttribute(a,e[f])}}const c=t.querySelectorAll("[data-ln-show]");for(let n=0;n<c.length;n++){const i=c[n],l=i.getAttribute("data-ln-show");l in e&&i.classList.toggle("hidden",!e[l])}const o=t.querySelectorAll("[data-ln-class]");for(let n=0;n<o.length;n++){const i=o[n],l=i.getAttribute("data-ln-class").split(",");for(let r=0;r<l.length;r++){const u=l[r].trim().split(":");if(u.length!==2)continue;const a=u[0].trim(),f=u[1].trim();f in e&&i.classList.toggle(a,!!e[f])}}return t}function q(t,e){t.matches&&t.matches("[data-ln-form], [data-ln-fillable]")&&t.dispatchEvent(new CustomEvent("ln-fill",{detail:e??null,bubbles:!0}));const s=t.querySelectorAll("[data-ln-form], [data-ln-fillable]");for(let d=0;d<s.length;d++)s[d].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)v(t.target,t.detail);else{const e=t.target.querySelectorAll("[data-ln-field]");for(let s=0;s<e.length;s++)e[s].textContent=""}})));function x(t,e){if(!t||!e)return t;const s=document.createTreeWalker(t,NodeFilter.SHOW_TEXT);for(;s.nextNode();){const o=s.currentNode;o.textContent.indexOf("{{")!==-1&&(o.textContent=o.textContent.replace(/\{\{\s*(\w+)\s*\}\}/g,function(n,i){return e[i]!==void 0?e[i]:""}))}const d=function(o,n){return e[n]!==void 0?e[n]:""},c=Array.from(t.querySelectorAll("*"));t.nodeType===1&&c.push(t);for(let o=0;o<c.length;o++){const n=c[o],i=n.attributes;for(let l=0;l<i.length;l++){const r=i[l];r.value.indexOf("{{")!==-1&&n.setAttribute(r.name,r.value.replace(/\{\{\s*(\w+)\s*\}\}/g,d))}}return t}function I(t,e,s,d,c,o){const n={};for(let l=0;l<t.children.length;l++){const r=t.children[l],u=r.getAttribute("data-ln-key");u&&(n[u]=r)}const i=document.createDocumentFragment();for(let l=0;l<e.length;l++){const r=e[l],u=String(d(r));let a=n[u];if(a)c(a,r,l);else{const f=M(s,o);if(!f||(x(f,r),a=f.firstElementChild,!a))continue;a.setAttribute("data-ln-key",u),c(a,r,l)}i.appendChild(a)}t.textContent="",t.appendChild(i)}function _(t,e){if(!document.body){document.addEventListener("DOMContentLoaded",function(){_(t,e)}),console.warn("["+e+'] Script loaded before <body> — add "defer" to your <script> tag');return}t()}function g(t,e,s,d){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 i of n)i[s]||(i[s]=new d(i))}function N(t){if(typeof t!="string")return!!t;const e=t.trim().toLowerCase();return e!=="false"&&e!=="0"&&e!==""&&e!=="off"&&e!=="no"}function F(t,e){const s=t.elements,d=[],c={};for(let o=0;o<s.length;o++){const n=s[o];n.name&&n.type==="checkbox"&&(c[n.name]=(c[n.name]||0)+1)}for(let o=0;o<s.length;o++){const n=s[o];if(n.type==="file"||n.type==="submit"||n.type==="button")continue;const i=n.getAttribute("data-ln-fill-as")||n.name;if(!i||!(i in e))continue;const l=e[i];if(n.type==="checkbox"){if(Array.isArray(l))n.checked=l.indexOf(n.value)!==-1;else if(c[n.name]>1){const r=String(l).split(",").map(function(u){return u.trim()});n.checked=r.indexOf(n.value)!==-1}else n.checked=N(l);d.push(n)}else if(n.type==="radio")n.checked=n.value===String(l),d.push(n);else if(n.type==="select-multiple"){if(Array.isArray(l))for(let r=0;r<n.options.length;r++)n.options[r].selected=l.indexOf(n.options[r].value)!==-1;d.push(n)}else n.value=l,d.push(n)}return d}function R(t,e,s,d,c={}){const o=c.extraAttributes||[],n=c.onAttributeChange||null,i=c.onInit||null;function l(r){const u=r||document.body;g(u,t,e,s),i&&i(u)}return _(function(){const r=new MutationObserver(function(a){for(let f=0;f<a.length;f++){const h=a[f];if(h.type==="childList"){for(let m=0;m<h.addedNodes.length;m++){const p=h.addedNodes[m];p.nodeType===1&&(g(p,t,e,s),i&&i(p))}for(let m=0;m<h.removedNodes.length;m++){const p=h.removedNodes[m];if(p.nodeType===1){const O=t.indexOf("[")!==-1||t.indexOf(".")!==-1||t.indexOf("#")!==-1?t:"["+t+"]",b=Array.from(p.querySelectorAll(O));p.matches&&p.matches(O)&&b.push(p);for(let C=0;C<b.length;C++){const S=b[C];if(!document.contains(S)){const A=S[e];A&&typeof A.destroy=="function"&&A.destroy()}}}}}else h.type==="attributes"&&(n&&h.target[e]?n(h.target,h.attributeName):(g(h.target,t,e,s),i&&i(h.target)))}});let u=[];if(t.indexOf("[")!==-1){const a=/\[([\w-]+)/g;let f;for(;(f=a.exec(t))!==null;)u.push(f[1])}else u.push(t);r.observe(document.body,{childList:!0,subtree:!0,attributes:!0,attributeFilter:u.concat(o)})},d),window[e]=l,document.readyState==="loading"?document.addEventListener("DOMContentLoaded",function(){l(document.body)}):l(document.body),l}const L={};function j(t,e){L[t]=e}function B(t){return L[t]||{ingress:e=>e,egress:e=>e}}const E={};function k(t,e){if(!t||typeof e!="object")return;const s=t.toLowerCase().split("-")[0];E[s]=e}function W(t){if(!t)return null;const e=t.toLowerCase().split("-")[0];return E[e]||null}k("mk",{monthsLong:["јануари","февруари","март","април","мај","јуни","јули","август","септември","октомври","ноември","декември"],monthsShort:["јан","фев","мар","апр","мај","јун","јул","авг","септ","окт","ноем","дек"],daysLong:["недела","понеделник","вторник","среда","четврток","петок","сабота"],daysShort:["нед","пон","вт","ср","чет","пет","саб"]}),typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerDataMapper=j,window.lnCore.getDataMapper=B,window.lnCore.registerLocaleFallback=k,window.lnCore.getLocaleFallback=W,window.lnCore.fillTemplate=x,window.lnCore.fill=v,window.lnCore.lnFill=q,window.lnCore.renderList=I);function T(t){return(t||"").replace(/^#/,"")}function w(t){const e=t===void 0?location.hash:t,s={},d=T(e);if(!d)return s;const c=d.split("&");for(let o=0;o<c.length;o++){const n=c[o];if(!n)continue;const i=n.indexOf(":"),l=i>-1?n.slice(0,i):n,r=i>-1?n.slice(i+1):"";if(l)try{s[l]=decodeURIComponent(r)}catch{s[l]=r}}return s}function U(t){if(!t)return null;const e=w();return t in e?e[t]:null}function K(t,e){if(!t)return;const s=w();e==null?delete s[t]:s[t]=String(e);const c=Object.keys(s).map(function(o){const n=s[o];return n===""?o:o+":"+encodeURIComponent(n)}).join("&");T(location.hash)!==c&&(location.hash=c)}function G(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=U,window.lnCore.hashSet=K,window.lnCore.hashLinkClick=G),(function(){const t="data-ln-form",e="lnForm",s="data-ln-form-action-edit",d="data-ln-form-action-method";if(window[e]!==void 0)return;function c(o){this.dom=o,this._baseAction=o.getAttribute("action")||"";const n=this;return this._onLnFill=function(i){i.target===n.dom&&(i.detail?(n.fill(i.detail),n._applyActionMode(i.detail)):n.dom.reset())},this._onReset=function(){n._applyActionMode(null)},o.addEventListener("ln-fill",this._onLnFill),o.addEventListener("reset",this._onReset),this}c.prototype.fill=function(o){const n=F(this.dom,o);for(let i=0;i<n.length;i++){const l=n[i],r=l.tagName==="SELECT"||l.type==="checkbox"||l.type==="radio";l.dispatchEvent(new Event(r?"change":"input",{bubbles:!0}))}},c.prototype._ensureMethodInput=function(){let o=this.dom.querySelector('input[name="_method"]');return o||(o=document.createElement("input"),o.type="hidden",o.name="_method",o.value="",this.dom.appendChild(o)),o},c.prototype._applyActionMode=function(o){if(!this.dom.hasAttribute(s))return;const n=o&&o.id!=null&&o.id!==""?o.id:null,i=this._ensureMethodInput();if(n!==null){const l=this.dom.getAttribute(s);l?this.dom.setAttribute("action",l.replace(":id",encodeURIComponent(n))):this.dom.setAttribute("action",this._baseAction.replace(/\/$/,"")+"/"+encodeURIComponent(n)),i.value=this.dom.getAttribute(d)||"PUT"}else this.dom.setAttribute("action",this._baseAction),i.value=""},c.prototype.destroy=function(){this.dom[e]&&(this.dom.removeEventListener("ln-fill",this._onLnFill),this.dom.removeEventListener("reset",this._onReset),D(this.dom,"ln-form:destroyed",{target:this.dom}),delete this.dom[e])},R(t,e,c,"ln-form")})()})();
|
package/js/ln-http/ln-http.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(function(){"use strict";if(typeof window<"u"){const t=console.warn;console.warn=function(...n){typeof n[0]=="string"&&(n[0].startsWith("[ln-")||n[0].startsWith("[lnCore"))&&!(document.documentElement.hasAttribute("data-ln-debug")||document.body&&document.body.hasAttribute("data-ln-debug"))||t.apply(console,n)}}const m={};function _(t,n){m[t]||(m[t]=document.querySelector('[data-ln-template="'+t+'"]'));const o=m[t];return o?o.content.cloneNode(!0):(console.warn("["+(n||"ln-core")+'] Template "'+t+'" not found'),null)}function y(t,n,o){t.dispatchEvent(new CustomEvent(n,{bubbles:!0,detail:o||{}}))}function E(t,n){if(!t||!n)return t;const o=t.querySelectorAll("[data-ln-field]");for(let l=0;l<o.length;l++){const c=o[l],r=c.getAttribute("data-ln-field");n[r]!=null&&(c.textContent=n[r])}const u=t.querySelectorAll("[data-ln-attr]");for(let l=0;l<u.length;l++){const c=u[l],r=c.getAttribute("data-ln-attr").split(",");for(let e=0;e<r.length;e++){const i=r[e].trim().split(":");if(i.length!==2)continue;const f=i[0].trim(),s=i[1].trim();n[s]!=null&&c.setAttribute(f,n[s])}}const d=t.querySelectorAll("[data-ln-show]");for(let l=0;l<d.length;l++){const c=d[l],r=c.getAttribute("data-ln-show");r in n&&c.classList.toggle("hidden",!n[r])}const a=t.querySelectorAll("[data-ln-class]");for(let l=0;l<a.length;l++){const c=a[l],r=c.getAttribute("data-ln-class").split(",");for(let e=0;e<r.length;e++){const i=r[e].trim().split(":");if(i.length!==2)continue;const f=i[0].trim(),s=i[1].trim();s in n&&c.classList.toggle(f,!!n[s])}}return t}function x(t,n){t.matches&&t.matches("[data-ln-form], [data-ln-fillable]")&&t.dispatchEvent(new CustomEvent("ln-fill",{detail:n??null,bubbles:!0}));const o=t.querySelectorAll("[data-ln-form], [data-ln-fillable]");for(let u=0;u<o.length;u++)o[u].dispatchEvent(new CustomEvent("ln-fill",{detail:n??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 n=t.target.querySelectorAll("[data-ln-field]");for(let o=0;o<n.length;o++)n[o].textContent=""}})));function L(t,n){if(!t||!n)return t;const o=document.createTreeWalker(t,NodeFilter.SHOW_TEXT);for(;o.nextNode();){const a=o.currentNode;a.textContent.indexOf("{{")!==-1&&(a.textContent=a.textContent.replace(/\{\{\s*(\w+)\s*\}\}/g,function(l,c){return n[c]!==void 0?n[c]:""}))}const u=function(a,l){return n[l]!==void 0?n[l]:""},d=Array.from(t.querySelectorAll("*"));t.nodeType===1&&d.push(t);for(let a=0;a<d.length;a++){const l=d[a],c=l.attributes;for(let r=0;r<c.length;r++){const e=c[r];e.value.indexOf("{{")!==-1&&l.setAttribute(e.name,e.value.replace(/\{\{\s*(\w+)\s*\}\}/g,u))}}return t}function q(t,n,o,u,d,a){const l={};for(let r=0;r<t.children.length;r++){const e=t.children[r],i=e.getAttribute("data-ln-key");i&&(l[i]=e)}const c=document.createDocumentFragment();for(let r=0;r<n.length;r++){const e=n[r],i=String(u(e));let f=l[i];if(f)d(f,e,r);else{const s=_(o,a);if(!s||(L(s,e),f=s.firstElementChild,!f))continue;f.setAttribute("data-ln-key",i),d(f,e,r)}c.appendChild(f)}t.textContent="",t.appendChild(c)}const A={};function T(t,n){A[t]=n}function F(t){return A[t]||{ingress:n=>n,egress:n=>n}}const k={};function v(t,n){if(!t||typeof n!="object")return;const o=t.toLowerCase().split("-")[0];k[o]=n}function D(t){if(!t)return null;const n=t.toLowerCase().split("-")[0];return k[n]||null}v("mk",{monthsLong:["јануари","февруари","март","април","мај","јуни","јули","август","септември","октомври","ноември","декември"],monthsShort:["јан","фев","мар","апр","мај","јун","јул","авг","септ","окт","ноем","дек"],daysLong:["недела","понеделник","вторник","среда","четврток","петок","сабота"],daysShort:["нед","пон","вт","ср","чет","пет","саб"]}),typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerDataMapper=T,window.lnCore.getDataMapper=F,window.lnCore.registerLocaleFallback=v,window.lnCore.getLocaleFallback=D,window.lnCore.fillTemplate=L,window.lnCore.fill=E,window.lnCore.lnFill=x,window.lnCore.renderList=q);function S(t){return(t||"").replace(/^#/,"")}function C(t){const n=t===void 0?location.hash:t,o={},u=S(n);if(!u)return o;const d=u.split("&");for(let a=0;a<d.length;a++){const l=d[a];if(!l)continue;const c=l.indexOf(":"),r=c>-1?l.slice(0,c):l,e=c>-1?l.slice(c+1):"";if(r)try{o[r]=decodeURIComponent(e)}catch{o[r]=e}}return o}function O(t){if(!t)return null;const n=C();return t in n?n[t]:null}function H(t,n){if(!t)return;const o=C();n==null?delete o[t]:o[t]=String(n);const d=Object.keys(o).map(function(a){const l=o[a];return l===""?a:a+":"+encodeURIComponent(l)}).join("&");S(location.hash)!==d&&(location.hash=d)}function M(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=C,window.lnCore.hashGet=O,window.lnCore.hashSet=H,window.lnCore.hashLinkClick=M),(function(){if(window.lnHttp)return;const t=window.fetch.bind(window),n=new Map,o=new Map;function u(e){return typeof e=="string"?e:e instanceof URL?e.href:e instanceof Request?e.url:String(e)}function d(e,i){return i&&i.method?String(i.method).toUpperCase():e instanceof Request?e.method.toUpperCase():"GET"}function a(e,i){return i+" "+e}function l(e){return e==="GET"||e==="HEAD"}function c(e,i){i=i||{};const f=u(e),s=d(e,i),w=a(f,s);l(s)&&n.has(w)&&(n.get(w).abort(),n.delete(w));const h=new AbortController,p=i.signal;let b=null;p&&(p.aborted?h.abort(p.reason):(b=function(){h.abort(p.reason)},p.addEventListener("abort",b,{once:!0})));const g=Object.assign({},i,{signal:h.signal});return n.set(w,h),t(e,g).finally(function(){p&&b&&p.removeEventListener("abort",b),n.get(w)===h&&n.delete(w)})}c.toString=function(){return"function fetch() { [ln-http wrapped] }"},window.fetch=c;function r(e){if(!e.detail||!e.detail.url)return;const i=e.target,f=(e.detail.method||(e.detail.body?"POST":"GET")).toUpperCase(),s=e.detail.key;s&&o.has(s)&&(o.get(s).abort(),o.delete(s));const w=new AbortController,h=e.detail.signal;let p=null;h&&(h.aborted?w.abort(h.reason):(p=function(){w.abort(h.reason)},h.addEventListener("abort",p,{once:!0}))),s&&o.set(s,w);const b={method:f,signal:w.signal};e.detail.body!==void 0&&(b.body=e.detail.body),window.fetch(e.detail.url,b).then(function(g){h&&p&&h.removeEventListener("abort",p),s&&o.get(s)===w&&o.delete(s),y(i,"ln-http:response",{ok:g.ok,status:g.status,response:g})}).catch(function(g){h&&p&&h.removeEventListener("abort",p),s&&o.get(s)===w&&o.delete(s),!(g&&g.name==="AbortError")&&y(i,"ln-http:error",{ok:!1,status:0,error:g})})}document.addEventListener("ln-http:request",r),window.lnHttp={cancel:function(e){let i=!1;return n.forEach(function(f,s){s.endsWith(" "+e)&&(f.abort(),n.delete(s),i=!0)}),i},cancelByKey:function(e){return o.has(e)?(o.get(e).abort(),o.delete(e),!0):!1},cancelAll:function(){n.forEach(function(e){e.abort()}),n.clear(),o.forEach(function(e){e.abort()}),o.clear()},get inflight(){const e=[];return n.forEach(function(i,f){const s=f.indexOf(" ");e.push({method:f.slice(0,s),url:f.slice(s+1)})}),o.forEach(function(i,f){e.push({key:f})}),e},destroy:function(){window.lnHttp.cancelAll(),document.removeEventListener("ln-http:request",r),window.fetch=t,delete window.lnHttp}}})()})();
|
package/js/ln-link/ln-link.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 m={};function D(t,e){m[t]||(m[t]=document.querySelector('[data-ln-template="'+t+'"]'));const l=m[t];return l?l.content.cloneNode(!0):(console.warn("["+(e||"ln-core")+'] Template "'+t+'" not found'),null)}function O(t,e,l){const a=new CustomEvent(e,{bubbles:!0,cancelable:!0,detail:l||{}});return t.dispatchEvent(a),a}function L(t,e){if(!t||!e)return t;const l=t.querySelectorAll("[data-ln-field]");for(let i=0;i<l.length;i++){const r=l[i],o=r.getAttribute("data-ln-field");e[o]!=null&&(r.textContent=e[o])}const a=t.querySelectorAll("[data-ln-attr]");for(let i=0;i<a.length;i++){const r=a[i],o=r.getAttribute("data-ln-attr").split(",");for(let s=0;s<o.length;s++){const h=o[s].trim().split(":");if(h.length!==2)continue;const b=h[0].trim(),g=h[1].trim();e[g]!=null&&r.setAttribute(b,e[g])}}const d=t.querySelectorAll("[data-ln-show]");for(let i=0;i<d.length;i++){const r=d[i],o=r.getAttribute("data-ln-show");o in e&&r.classList.toggle("hidden",!e[o])}const c=t.querySelectorAll("[data-ln-class]");for(let i=0;i<c.length;i++){const r=c[i],o=r.getAttribute("data-ln-class").split(",");for(let s=0;s<o.length;s++){const h=o[s].trim().split(":");if(h.length!==2)continue;const b=h[0].trim(),g=h[1].trim();g in e&&r.classList.toggle(b,!!e[g])}}return t}function B(t,e){t.matches&&t.matches("[data-ln-form], [data-ln-fillable]")&&t.dispatchEvent(new CustomEvent("ln-fill",{detail:e??null,bubbles:!0}));const l=t.querySelectorAll("[data-ln-form], [data-ln-fillable]");for(let a=0;a<l.length;a++)l[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)L(t.target,t.detail);else{const e=t.target.querySelectorAll("[data-ln-field]");for(let l=0;l<e.length;l++)e[l].textContent=""}})));function k(t,e){if(!t||!e)return t;const l=document.createTreeWalker(t,NodeFilter.SHOW_TEXT);for(;l.nextNode();){const c=l.currentNode;c.textContent.indexOf("{{")!==-1&&(c.textContent=c.textContent.replace(/\{\{\s*(\w+)\s*\}\}/g,function(i,r){return e[r]!==void 0?e[r]:""}))}const a=function(c,i){return e[i]!==void 0?e[i]:""},d=Array.from(t.querySelectorAll("*"));t.nodeType===1&&d.push(t);for(let c=0;c<d.length;c++){const i=d[c],r=i.attributes;for(let o=0;o<r.length;o++){const s=r[o];s.value.indexOf("{{")!==-1&&i.setAttribute(s.name,s.value.replace(/\{\{\s*(\w+)\s*\}\}/g,a))}}return t}function M(t,e,l,a,d,c){const i={};for(let o=0;o<t.children.length;o++){const s=t.children[o],h=s.getAttribute("data-ln-key");h&&(i[h]=s)}const r=document.createDocumentFragment();for(let o=0;o<e.length;o++){const s=e[o],h=String(a(s));let b=i[h];if(b)d(b,s,o);else{const g=D(l,c);if(!g||(k(g,s),b=g.firstElementChild,!b))continue;b.setAttribute("data-ln-key",h),d(b,s,o)}r.appendChild(b)}t.textContent="",t.appendChild(r)}function A(t,e){if(!document.body){document.addEventListener("DOMContentLoaded",function(){A(t,e)}),console.warn("["+e+'] Script loaded before <body> — add "defer" to your <script> tag');return}t()}const v={};function R(t,e){v[t]=e}function N(t){return v[t]||{ingress:e=>e,egress:e=>e}}const _={};function E(t,e){if(!t||typeof e!="object")return;const l=t.toLowerCase().split("-")[0];_[l]=e}function F(t){if(!t)return null;const e=t.toLowerCase().split("-")[0];return _[e]||null}E("mk",{monthsLong:["јануари","февруари","март","април","мај","јуни","јули","август","септември","октомври","ноември","декември"],monthsShort:["јан","фев","мар","апр","мај","јун","јул","авг","септ","окт","ноем","дек"],daysLong:["недела","понеделник","вторник","среда","четврток","петок","сабота"],daysShort:["нед","пон","вт","ср","чет","пет","саб"]}),typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerDataMapper=R,window.lnCore.getDataMapper=N,window.lnCore.registerLocaleFallback=E,window.lnCore.getLocaleFallback=F,window.lnCore.fillTemplate=k,window.lnCore.fill=L,window.lnCore.lnFill=B,window.lnCore.renderList=M);function S(t){return(t||"").replace(/^#/,"")}function y(t){const e=t===void 0?location.hash:t,l={},a=S(e);if(!a)return l;const d=a.split("&");for(let c=0;c<d.length;c++){const i=d[c];if(!i)continue;const r=i.indexOf(":"),o=r>-1?i.slice(0,r):i,s=r>-1?i.slice(r+1):"";if(o)try{l[o]=decodeURIComponent(s)}catch{l[o]=s}}return l}function I(t){if(!t)return null;const e=y();return t in e?e[t]:null}function W(t,e){if(!t)return;const l=y();e==null?delete l[t]:l[t]=String(e);const d=Object.keys(l).map(function(c){const i=l[c];return i===""?c:c+":"+encodeURIComponent(i)}).join("&");S(location.hash)!==d&&(location.hash=d)}function j(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=I,window.lnCore.hashSet=W,window.lnCore.hashLinkClick=j),(function(){const t="data-ln-link",e="lnLink";if(window[e]!==void 0)return;let l=null;function a(){l=document.createElement("div"),l.className="ln-link-status",document.body.appendChild(l)}function d(n){l&&(l.textContent=n,l.classList.add("ln-link-status--visible"))}function c(){l&&l.classList.remove("ln-link-status--visible")}function i(n,f){if(f.target.closest("a, button, input, select, textarea"))return;const u=n.querySelector("a");if(!u)return;const p=u.getAttribute("href");if(!p)return;if(f.ctrlKey||f.metaKey||f.button===1){window.open(p,"_blank");return}O(n,"ln-link:navigate",{target:n,href:p,link:u}).defaultPrevented||u.click()}function r(n){const f=n.querySelector("a");if(!f)return;const u=f.getAttribute("href");u&&d(u)}function o(){c()}function s(n){n[e+"Row"]||!n.querySelector("a")||(n[e+"Row"]=!0,n._lnLinkClick=function(u){i(n,u)},n._lnLinkEnter=function(){r(n)},n.addEventListener("click",n._lnLinkClick),n.addEventListener("mouseenter",n._lnLinkEnter),n.addEventListener("mouseleave",o))}function h(n){n[e+"Row"]&&(n._lnLinkClick&&n.removeEventListener("click",n._lnLinkClick),n._lnLinkEnter&&n.removeEventListener("mouseenter",n._lnLinkEnter),n.removeEventListener("mouseleave",o),delete n._lnLinkClick,delete n._lnLinkEnter,delete n[e+"Row"])}function b(n){if(!n[e+"Init"])return;const f=n.tagName;if(f==="TABLE"||f==="TBODY"){const u=f==="TABLE"&&n.querySelector("tbody")||n;for(const p of u.querySelectorAll("tr"))h(p)}else h(n);delete n[e+"Init"]}function g(n){if(n[e+"Init"])return;n[e+"Init"]=!0;const f=n.tagName;if(f==="TABLE"||f==="TBODY"){const u=f==="TABLE"&&n.querySelector("tbody")||n;for(const p of u.querySelectorAll("tr"))s(p)}else s(n)}function w(n){n.hasAttribute&&n.hasAttribute(t)&&g(n);const f=n.querySelectorAll?n.querySelectorAll("["+t+"]"):[];for(const u of f)g(u)}function K(){A(function(){new MutationObserver(function(f){for(const u of f)if(u.type==="childList"){for(const p of u.addedNodes)if(p.nodeType===1){w(p);const C=p.closest("["+t+"]");if(C)if(p.tagName==="TR")s(p);else{const x=C.tagName;if(x==="TABLE"||x==="TBODY"){const U=p.querySelectorAll?p.querySelectorAll("tr"):[];for(const Y of U)s(Y)}}}}else u.type==="attributes"&&(u.target.hasAttribute&&u.target.hasAttribute(t)?w(u.target):b(u.target))}).observe(document.body,{childList:!0,subtree:!0,attributes:!0,attributeFilter:[t]})},"ln-link")}function T(n){w(n)}window[e]={init:T,destroy:b};function q(){a(),K(),T(document.body)}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",q):q()})()})();
|
package/js/ln-list/README.md
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
# ln-list
|
|
2
|
-
|
|
3
|
-
A unified, structure-agnostic, and local-first **Data Presenter Component** designed to render datasets in list, card, section, or grid layouts. It connects to `ln-data-store` via CustomEvents using the **Coordinator Pattern**, supporting client-side filtering, sorting, searching, and high-performance **Virtual Scrolling** for large datasets.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## 📦 Declarative Setup in HTML
|
|
8
|
-
|
|
9
|
-
### 1. Simple SSR List
|
|
10
|
-
For a server-rendered list where the backend outputs `<li>` elements directly:
|
|
11
|
-
|
|
12
|
-
```html
|
|
13
|
-
<form role="search" onsubmit="return false;">
|
|
14
|
-
<input type="search" data-ln-search="documents-list" placeholder="Search...">
|
|
15
|
-
</form>
|
|
16
|
-
|
|
17
|
-
<ul id="documents-list" data-ln-list="documents">
|
|
18
|
-
<li data-ln-item-id="1">Document A</li>
|
|
19
|
-
<li data-ln-item-id="2">Document B</li>
|
|
20
|
-
</ul>
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
### 2. Data-Driven Grid List (with Virtual Scroll)
|
|
24
|
-
Opted-in by adding the `data-ln-list-source` attribute. It clones and renders the specified `<template>`:
|
|
25
|
-
|
|
26
|
-
```html
|
|
27
|
-
<form role="search" onsubmit="return false;">
|
|
28
|
-
<input type="search" data-ln-search="documents-grid" placeholder="Search...">
|
|
29
|
-
</form>
|
|
30
|
-
|
|
31
|
-
<section id="documents-grid"
|
|
32
|
-
data-ln-list="documents"
|
|
33
|
-
data-ln-list-source="documents"
|
|
34
|
-
data-ln-list-selectable>
|
|
35
|
-
|
|
36
|
-
<!-- Items container -->
|
|
37
|
-
<ul class="grid-layout" data-ln-list-body></ul>
|
|
38
|
-
|
|
39
|
-
<!-- Row Template (Must contain an element with data-ln-item attribute) -->
|
|
40
|
-
<template data-ln-template="documents-row">
|
|
41
|
-
<li data-ln-item class="card-item">
|
|
42
|
-
<header>
|
|
43
|
-
<input type="checkbox" data-ln-item-select>
|
|
44
|
-
<h3 data-ln-field="title"></h3>
|
|
45
|
-
</header>
|
|
46
|
-
<p>{{ description }}</p>
|
|
47
|
-
<button type="button" data-ln-item-action="delete">Delete</button>
|
|
48
|
-
</li>
|
|
49
|
-
</template>
|
|
50
|
-
|
|
51
|
-
<!-- Empty States -->
|
|
52
|
-
<template data-ln-template="documents-empty">
|
|
53
|
-
<div class="empty-state">No documents found.</div>
|
|
54
|
-
</template>
|
|
55
|
-
|
|
56
|
-
<template data-ln-template="documents-empty-filtered">
|
|
57
|
-
<div class="empty-state">No matching documents found.</div>
|
|
58
|
-
</template>
|
|
59
|
-
</section>
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
---
|
|
63
|
-
|
|
64
|
-
## 🛠️ Attributes Reference
|
|
65
|
-
|
|
66
|
-
| Attribute | Elements | Description |
|
|
67
|
-
| :--- | :--- | :--- |
|
|
68
|
-
| `data-ln-list` | Root wrapper | Component identifier. Target must carry a unique `id`. |
|
|
69
|
-
| `data-ln-list-source` | Root wrapper | Opt-in indicator for Data-Driven Mode. |
|
|
70
|
-
| `data-ln-list-selectable` | Root wrapper | Enables checkbox-based item selections. |
|
|
71
|
-
| `data-ln-list-window="N"` | Root wrapper | Opt-in server-side sliding-window virtualization. `N` sets the resident-item cap (default 1000). Requires Data-Driven Mode. Observable: add/remove toggles windowed mode ON/OFF live; changing `N` while windowed reconfigures the live cache. `data-ln-list-window-page`, `data-ln-list-window-threshold`, and `data-ln-list-count` are likewise observable. |
|
|
72
|
-
|
|
73
|
-
---
|
|
74
|
-
|
|
75
|
-
## ⚡ DOM Events
|
|
76
|
-
|
|
77
|
-
### Listened Events
|
|
78
|
-
|
|
79
|
-
* `ln-list:set-data` `{ data, total, filtered }`: Hydrates/renders the items. Windowed mode expects `{ offset, queryGen }` echoed back — routed into the internal window cache.
|
|
80
|
-
* `ln-list:set-loading` `{ loading: true|false }`: Toggles the loading dimming overlay class (`.ln-list--loading`).
|
|
81
|
-
* `ln-list:page-failed` `{ offset }`: Windowed mode — the coordinator reports the page fetch at `offset` failed. Releases it from the cache's in-flight set; no auto-retry, the next `ensure()` requests it again.
|
|
82
|
-
* `ln-list:request-revalidate`: Windowed mode — the coordinator asks the cache to revalidate the currently visible page after a local mutation. Stale rows stay visible, no jump to page 0.
|
|
83
|
-
* `ln-search:change` `{ term }`: Captures search query from `data-ln-search` inputs.
|
|
84
|
-
* `ln-sort:change` `{ field, column, direction }`: Sets `currentSort` and re-sorts (data-driven only). Ignored when `field` is `null` (index-only events have nothing to key a record by).
|
|
85
|
-
|
|
86
|
-
### Emitted Events
|
|
87
|
-
|
|
88
|
-
* `ln-list:request-data` `{ list, search, sort, filters }`: Requests data query from the Coordinator. Windowed mode (`data-ln-list-window`) adds `{ offset, limit, queryGen }`. Disabling windowed mode live issues a fresh full `ln-list:request-data` (no `offset`/`limit`) to repopulate the complete dataset.
|
|
89
|
-
* `ln-list:ready` `{ total }`: Fired when initial markup parsing completes.
|
|
90
|
-
* `ln-list:rendered` `{ list, total, visible }`: Fired after items have been drawn to DOM.
|
|
91
|
-
* `ln-list:item-click` `{ list, id, record }`: Fired when clicking item body (excluding buttons, anchors, inputs).
|
|
92
|
-
* `ln-list:item-action` `{ list, id, action, record }`: Fired when clicking `[data-ln-item-action]`.
|
|
93
|
-
* `ln-list:select` `{ list, selectedIds, count }`: Fired when selection updates.
|
|
94
|
-
* `ln-list:select-all` `{ list, selected: true|false }`: Fired when select-all triggers.
|
|
95
|
-
|
|
96
|
-
---
|
|
97
|
-
|
|
98
|
-
## 🔧 Internals
|
|
99
|
-
|
|
100
|
-
Source: `js/ln-list/src/ln-list.js`.
|
|
101
|
-
|
|
102
|
-
### Spacer element matches container semantics
|
|
103
|
-
|
|
104
|
-
Virtual scroll (both plain and windowed) needs top/bottom spacer elements to preserve scroll height without rendering off-screen rows. If `[data-ln-list-body]` is a `<ul>`/`<ol>`, spacers are `<li class="ln-list__spacer">` to stay HTML5-valid; any other container gets `<div class="ln-list__spacer">`.
|
|
105
|
-
|
|
106
|
-
### `_renderVirtual()` vs `_renderWindowed()`
|
|
107
|
-
|
|
108
|
-
Both compute the visible `start`/`end` index range from the measured first-child height and the nearest scrollable ancestor's viewport, then mount spacers and clone the row template for the visible slice via `fillTemplate`/`fill`. They differ only in row source: `_renderVirtual()` reads `this._data[i]` (the full parsed/fetched dataset); `_renderWindowed()` reads `this._cache.get(i)` (the resident sliding window) and renders a blank placeholder spacer — no shimmer — for indices outside the cache, calling `this._cache.ensure(startRow, endRow)` every pass to debounce-fetch missing rows.
|
|
109
|
-
|
|
110
|
-
### Windowed mode (`data-ln-list-window="N"`)
|
|
111
|
-
|
|
112
|
-
Owns an `ln-core.createWindowCache` instance (`N` = resident cap, default 1000) instead of the full dataset. `ln-list:request-data` gains `{offset, limit, queryGen}`; `ln-list:set-data` echoes `{offset, queryGen}` back into `cache.ingest()`. Select-all is hidden under `data-ln-list-selectable` + windowed mode together — a windowed list can't select rows it hasn't fetched.
|
|
113
|
-
|
|
114
|
-
Every windowing attribute is live-observable, no re-init required: `data-ln-list-window-page`/`-threshold`/`data-ln-list-count` reconfigure the cache via `configure()`/`setGrandTotal()`. Adding `data-ln-list-window` to an already-initialized, non-windowed, data-driven list seeds the cache from resident items and enables windowing live. Removing it destroys the cache and issues one full (no `offset`/`limit`) `ln-list:request-data` to repopulate before rendering non-windowed again.
|
|
115
|
-
|
|
116
|
-
### `_parseChildren()`
|
|
117
|
-
|
|
118
|
-
Parses static children inside `[data-ln-list-body]` into `this._data` at mount (excluding existing spacers), and measures the first child's height for `this._itemHeight`.
|
|
119
|
-
|
|
120
|
-
### Sort (`ln-sort:change`)
|
|
121
|
-
|
|
122
|
-
Data-driven only — the SSR branch has no sort logic. `field === null` events (index-only, from an
|
|
123
|
-
`ln-sort` instance authored without `data-ln-sort-field`) are ignored; `ln-list` records are
|
|
124
|
-
field-keyed, not positional, so there is nothing to sort by without a field name. On a matching
|
|
125
|
-
event: `preventDefault()`, `currentSort = { field, direction }` (or `null` on `direction: 'none'`),
|
|
126
|
-
then mirrors `ln-table`'s own data-driven sort handling exactly — windowed lists call
|
|
127
|
-
`_requestData()` (cache invalidate + re-fetch, same scheme as `ln-table`'s windowed
|
|
128
|
-
`_requestData()`); non-windowed lists re-sort the already-fetched in-memory data directly
|
|
129
|
-
(`_applyFilterAndSort()` + `_render()`, no server round-trip).
|