@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,170 +1,178 @@
|
|
|
1
|
-
# ln-sort
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
it
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
`
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
`
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
`
|
|
24
|
-
|
|
25
|
-
`ln-sort
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
<
|
|
41
|
-
|
|
42
|
-
<li><button type="button" data-ln-sort-dir="
|
|
43
|
-
<li><button type="button" data-ln-sort-dir="
|
|
44
|
-
|
|
45
|
-
</
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
| `data-ln-sort-dir="
|
|
55
|
-
| `data-ln-sort-dir="
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
|
84
|
-
|
|
|
85
|
-
| `data-ln-sort
|
|
86
|
-
| `data-ln-sort-
|
|
87
|
-
| `data-ln-sort-
|
|
88
|
-
| `data-ln-sort-
|
|
89
|
-
| `data-ln-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
|
96
|
-
|
|
|
97
|
-
| `
|
|
98
|
-
| `
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
- **
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
- **
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
###
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
1
|
+
# ln-sort
|
|
2
|
+
|
|
3
|
+
> Applied to a `<ul data-ln-sort="targetId" data-ln-sort-state="none">` control containing directional buttons (`data-ln-sort-dir="asc|desc|none"`).
|
|
4
|
+
> Clicking a button updates `data-ln-sort-state` on the control and dispatches a cancelable `ln-sort:change` event to the target element.
|
|
5
|
+
> If unprevented, it reorders target child rows or items in the DOM using numeric or `localeCompare` string sorting.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 🧭 Philosophy & Architecture
|
|
10
|
+
|
|
11
|
+
1. **No cycle logic in JS.** A click reads `data-ln-sort-dir` off the clicked button, writes it to
|
|
12
|
+
`data-ln-sort-state` on the root, and dispatches. The circular order
|
|
13
|
+
`none → asc → desc → none` is produced entirely by CSS — only one `<button data-ln-sort-dir>`
|
|
14
|
+
is visible at a time, selected by `[data-ln-sort-state]` on the root. See
|
|
15
|
+
`theme/config/mixins/_sort.scss`.
|
|
16
|
+
2. **Field is optional.** Author `data-ln-sort-field="name"` when the target is data-driven
|
|
17
|
+
(server needs a name, not an index). Omit it inside a `<th>` to fall back to
|
|
18
|
+
`th.cellIndex` — SSR/DOM-only, resolved once at construction, never bridged to `field`.
|
|
19
|
+
The dispatched payload always carries both keys, exactly one non-null:
|
|
20
|
+
`{ field: string|null, column: number|null, direction, targetId }`.
|
|
21
|
+
3. **Single sort, mutual exclusion & multi-control sync.** Every instance listens for
|
|
22
|
+
`ln-sort:change` on its OWN target. When an incoming event's field/column doesn't match this
|
|
23
|
+
instance's own, it resets its own `data-ln-sort-state` to `"none"`. When an incoming event matches
|
|
24
|
+
the same field/column, duplicate controls (e.g. table header button and mobile toolbar)
|
|
25
|
+
synchronize their `data-ln-sort-state` in real time.
|
|
26
|
+
4. **Deferred initialization via `queueBoot`.** Restoring saved sort (`data-ln-persist`) or booting
|
|
27
|
+
pre-authored `data-ln-sort-state="asc"|"desc"` is deferred via `queueBoot` to ensure consumers
|
|
28
|
+
(`ln-table`, `ln-list`, `ln-data-store`) have finished initializing before the initial sort fires.
|
|
29
|
+
5. **Type is inferred once per sort, not per pair.** `ln-core.detectValueType` scans the current
|
|
30
|
+
value set; if every non-empty value is a finite number, comparison is numeric, else
|
|
31
|
+
`localeCompare` via `ln-core.getLocale`. Per-pair type inference breaks comparator
|
|
32
|
+
transitivity and produces wrong ordering — never do it.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## ✅ Canonical Markup
|
|
37
|
+
|
|
38
|
+
```html
|
|
39
|
+
<th>
|
|
40
|
+
<span>Name</span>
|
|
41
|
+
<ul data-ln-sort="users-table" data-ln-sort-field="name" data-ln-sort-state="none">
|
|
42
|
+
<li><button type="button" data-ln-sort-dir="asc" aria-label="Sort ascending"><svg class="ln-icon" aria-hidden="true"><use href="#ln-icon-arrows-sort"></use></svg></button></li>
|
|
43
|
+
<li><button type="button" data-ln-sort-dir="desc" aria-label="Sort descending"><svg class="ln-icon" aria-hidden="true"><use href="#ln-icon-arrow-up"></use></svg></button></li>
|
|
44
|
+
<li><button type="button" data-ln-sort-dir="none" aria-label="Remove sort"><svg class="ln-icon" aria-hidden="true"><use href="#ln-icon-arrow-down"></use></svg></button></li>
|
|
45
|
+
</ul>
|
|
46
|
+
</th>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**Icon convention — READ BEFORE COPYING THIS MARKUP.** Each button carries the icon of the sort
|
|
50
|
+
STATE it is visible in, never the icon of the direction it sets:
|
|
51
|
+
|
|
52
|
+
| Button | Visible when `data-ln-sort-state` = | Icon it carries |
|
|
53
|
+
|---|---|---|
|
|
54
|
+
| `data-ln-sort-dir="asc"` | `none` | `#ln-icon-arrows-sort` |
|
|
55
|
+
| `data-ln-sort-dir="desc"` | `asc` | `#ln-icon-arrow-up` |
|
|
56
|
+
| `data-ln-sort-dir="none"` | `desc` | `#ln-icon-arrow-down` |
|
|
57
|
+
|
|
58
|
+
**This is not a typo.** The `dir="desc"` button contains an UP arrow. The visible button always
|
|
59
|
+
performs the NEXT action (clicking `dir="desc"` sorts descending), but its icon always reports the
|
|
60
|
+
CURRENT state (the column is currently ascending — hence the up arrow). If the icon instead
|
|
61
|
+
matched the button's own `data-ln-sort-dir`, the header would visually lie about its own sort
|
|
62
|
+
order the instant the column reaches `state="asc"`: the user would see a down-arrow next to a
|
|
63
|
+
column that is actually sorted up. Do not "fix" the icons to match `data-ln-sort-dir` when
|
|
64
|
+
hand-authoring markup — that reintroduces the exact bug this convention exists to prevent. `content`
|
|
65
|
+
cannot substitute for this — these icons are an SVG sprite via `<use href>`, not a font glyph a
|
|
66
|
+
`::before { content }` rule could swap (see `docs/architecture/reference.md` §Icons).
|
|
67
|
+
|
|
68
|
+
- **SSR table column** — omit `data-ln-sort-field`; the `<ul>` must be a descendant of the `<th>`
|
|
69
|
+
so the `th.cellIndex` fallback resolves. `data-ln-sort-field` and the SSR index path are never
|
|
70
|
+
bridged — setting a field on an SSR-table column leaves `column` null and `ln-table`'s SSR sort
|
|
71
|
+
has nothing to key off. Don't do both.
|
|
72
|
+
- **Data-driven table column** — set `data-ln-sort-field` to the same value as the `<th>`'s
|
|
73
|
+
`data-ln-table-col`.
|
|
74
|
+
- **Plain list** — target a generic `<ul>`/`<li>` container by `id`; set
|
|
75
|
+
`data-ln-sort-items="<selector>"` for deep targeting (mirrors `data-ln-search-items`).
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## 🛠️ Declarative API Contract
|
|
80
|
+
|
|
81
|
+
### HTML Attributes
|
|
82
|
+
|
|
83
|
+
| Attribute | Elements | Description |
|
|
84
|
+
| :--- | :--- | :--- |
|
|
85
|
+
| `data-ln-sort` | `<ul>` (root) | Component root. Value is the `id` of the target being sorted. |
|
|
86
|
+
| `data-ln-sort-field` | Same as root | Opt-in. The record field name (data-driven). Omit for the `th.cellIndex` fallback (SSR/DOM only). |
|
|
87
|
+
| `data-ln-sort-state` | Same as root | *State*. `"none" \| "asc" \| "desc"`. Drives which trigger button is visible via CSS. Observed by `MutationObserver`. |
|
|
88
|
+
| `data-ln-sort-items` | Same as root | Opt-in. Deep CSS selector for default-DOM-behaviour reordering (mirrors `data-ln-search-items`). |
|
|
89
|
+
| `data-ln-sort-dir` | `<button>` (inside root) | `"asc" \| "desc" \| "none"`. Identifies which action this trigger performs. |
|
|
90
|
+
| `data-ln-persist` | Same as root | Opt-in. Persists `{ field, column, direction }` to `localStorage`. Give each `[data-ln-sort]` its own value (or `id`) — persistence is per-instance, not per-table. |
|
|
91
|
+
| `data-ln-hash` | Same as root | Opt-in. Synchronizes sort state to URL hash fragment (e.g. `#users-sort:price.asc`). Value is custom namespace; if empty defaults to `[targetId]-sort`. |
|
|
92
|
+
|
|
93
|
+
### JavaScript API (`el.lnSort`)
|
|
94
|
+
|
|
95
|
+
| Member | Type | Description |
|
|
96
|
+
| :--- | :--- | :--- |
|
|
97
|
+
| `targetId` | `string` | The `id` of the target element. |
|
|
98
|
+
| `field` | `string \| null` | The authored field name, or `null`. |
|
|
99
|
+
| `column` | `number \| null` | The resolved `th.cellIndex` fallback, or `null`. |
|
|
100
|
+
| `nsKey` | `string \| null` | The resolved URL hash namespace, or `null`. |
|
|
101
|
+
| `hashEnabled` | `boolean` | True if URL hash synchronization is active on this instance. |
|
|
102
|
+
| `destroy()` | `() => void` | Removes listeners and tears down the instance. |
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## ⚡ DOM Events
|
|
108
|
+
|
|
109
|
+
### `ln-sort:change`
|
|
110
|
+
|
|
111
|
+
Dispatched on the **target** element (never on the sort control itself) whenever a trigger button
|
|
112
|
+
is clicked, or on persisted-state restore.
|
|
113
|
+
- **Cancelable**: Yes. `e.preventDefault()` disables the default DOM-reorder and hands the intent
|
|
114
|
+
fully to the consumer (e.g. `ln-table`, `ln-list`).
|
|
115
|
+
- **Payload (`detail`)**: `{ field: string|null, column: number|null, direction: 'asc'|'desc'|'none', targetId: string }`.
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## ⚠️ Common Pitfalls
|
|
120
|
+
|
|
121
|
+
- **Setting both `data-ln-sort-field` and expecting the index fallback to also work.** They are
|
|
122
|
+
never bridged. Pick one per instance based on the mode (SSR → index fallback; data-driven →
|
|
123
|
+
field).
|
|
124
|
+
- **Multi-column sort.** Not supported — single sort only. Multiple `[data-ln-sort]` instances
|
|
125
|
+
targeting the same target enforce mutual exclusion automatically (see Philosophy §3).
|
|
126
|
+
- **Expecting JS to own the click cycle.** It doesn't — the circular order is CSS-driven via
|
|
127
|
+
`[data-ln-sort-state]`. If the three trigger buttons aren't authored per the canonical markup,
|
|
128
|
+
the cycle breaks visually even though the JS click handling still works.
|
|
129
|
+
- **Persisting without a stable key.** `data-ln-persist` with no value falls back to `el.id`; a
|
|
130
|
+
bare `<ul data-ln-sort data-ln-persist>` with no `id` silently skips persistence
|
|
131
|
+
(see `ln-core.persistGet`/`persistSet` — `console.warn`s once).
|
|
132
|
+
- **Assuming every item carries the declared field.** When `data-ln-sort-field`
|
|
133
|
+
is set and an item has no matching `[data-ln-field]`, that item's value is
|
|
134
|
+
empty — it never contributes to type detection and sorts as `0` in a numeric
|
|
135
|
+
column. Permanent non-data siblings (empty-state rows, totals rows) are the
|
|
136
|
+
usual case.
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## 🔧 Internals
|
|
141
|
+
|
|
142
|
+
Source: `components/ln-sort/ln-sort.js`. One instance per `[data-ln-sort]`, stored at `element.lnSort`.
|
|
143
|
+
|
|
144
|
+
### The three-step click (no cycle logic)
|
|
145
|
+
|
|
146
|
+
`_onClick` reads `data-ln-sort-dir` off the clicked button and sets `data-ln-sort-state` on the root,
|
|
147
|
+
which triggers `_syncAttribute` and `_apply(direction)`. `_apply()` updates `aria-sort` on parent `<th>`,
|
|
148
|
+
dispatches `ln-sort:change` on the target, and — only if not prevented — runs `_defaultSort`. There is no
|
|
149
|
+
`if (current === 'asc') then 'desc'` branch anywhere in this file; the SCSS cycle in
|
|
150
|
+
`theme/config/mixins/_sort.scss` decides which button is even clickable next.
|
|
151
|
+
|
|
152
|
+
### Mutual exclusion & Multi-Control Sync
|
|
153
|
+
|
|
154
|
+
Each instance adds its `ln-sort:change` listener to the resolved **target** element. When an incoming
|
|
155
|
+
event's field/column matches this instance's own, duplicate controls sync their `data-ln-sort-state`
|
|
156
|
+
and `aria-sort`. When an incoming event belongs to a different column, the losing instance resets to `"none"`
|
|
157
|
+
and drops its persist key.
|
|
158
|
+
|
|
159
|
+
### Default DOM behaviour
|
|
160
|
+
|
|
161
|
+
Only runs when the consumer does not call `preventDefault()`. Reorders `target.children` (or
|
|
162
|
+
`data-ln-sort-items` matches) by moving nodes into a `DocumentFragment` and re-appending — a single
|
|
163
|
+
reflow, not N individual moves. Value extraction: `readValue` on the `[data-ln-field="<field>"]`
|
|
164
|
+
descendant if `field` is set, else `readValue(item)` directly. The `column` index fallback is
|
|
165
|
+
**never** consulted here — it exists solely to populate the event payload for SSR/DOM table
|
|
166
|
+
consumers; see README "Field is optional" above.
|
|
167
|
+
|
|
168
|
+
### Persistence & Boot
|
|
169
|
+
|
|
170
|
+
`data-ln-persist` on the root, restored in the constructor via `persistGet('sort', dom)` and
|
|
171
|
+
applied via `_apply(saved.direction, true)` through `queueBoot`. Authoring `data-ln-sort-state="asc"|"desc"`
|
|
172
|
+
is also applied safely at boot via `queueBoot`.
|
|
173
|
+
|
|
174
|
+
### Destroy
|
|
175
|
+
|
|
176
|
+
Removes the click listener (root) and the `ln-sort:change` listener (target, if resolved). Does
|
|
177
|
+
not restore the DOM to its pre-sort order — that's a rendering side effect, not the component's
|
|
178
|
+
own teardown responsibility (same doctrine as `ln-search.destroy()`).
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
@use '../../
|
|
2
|
-
|
|
3
|
-
[data-ln-debug] {
|
|
4
|
-
// 1. Sort Target Check: an empty target id resolves to getElementById('') → null, so the control is silently inert
|
|
5
|
-
[data-ln-sort=""] {
|
|
6
|
-
@include dev-inline-error("data-ln-sort target is empty");
|
|
7
|
-
}
|
|
8
|
-
}
|
|
1
|
+
@use '../../theme/config/mixins' as *;
|
|
2
|
+
|
|
3
|
+
[data-ln-debug] {
|
|
4
|
+
// 1. Sort Target Check: an empty target id resolves to getElementById('') → null, so the control is silently inert
|
|
5
|
+
[data-ln-sort=""] {
|
|
6
|
+
@include dev-inline-error("data-ln-sort target is empty");
|
|
7
|
+
}
|
|
8
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(){"use strict";function V(){return typeof window>"u"?!1:window.lnDebug===!0||window.lnCore&&window.lnCore._debugSink?!0:typeof document<"u"&&document.body?document.body.hasAttribute("data-ln-debug")||document.body.querySelector("[data-ln-debug]")!==null:!1}function O(e){if(typeof window>"u")return!1;if(window.lnDebug===!0)return!0;if(window.lnCore&&window.lnCore._debugIsContained)return e?window.lnCore._debugIsContained(e):window.lnCore._debugSink!==null;if(e&&e.closest){const t=e.closest("[data-ln-debug]");return!(!t||typeof document<"u"&&t===document.documentElement)}return typeof document<"u"&&document.body?document.body.hasAttribute("data-ln-debug"):!1}if(typeof window<"u"&&(window.lnCore=window.lnCore||{},!window.lnCore._warnBound)){window.lnCore._warnBound=!0;const e=console.warn;console.warn=function(...t){if(typeof t[0]=="string"&&(t[0].startsWith("[ln-")||t[0].startsWith("[lnCore"))){let r=null;for(let o=1;o<t.length;o++)if(t[o]&&t[o].nodeType===1){r=t[o];break}if(!O(r))return}e.apply(console,t)}}function te(e,t,n){const r=n||{};window.lnCore._debugSink&&window.lnCore._debugSink("event",t,e,r),e.dispatchEvent(new CustomEvent(t,{bubbles:!0,detail:r}))}function W(e,t,n){const r=n||{};window.lnCore._debugSink&&window.lnCore._debugSink("event",t,e,r);const o=new CustomEvent(t,{bubbles:!0,cancelable:!0,detail:r});return e.dispatchEvent(o),o}function T(e,t){if(!document.body){document.addEventListener("DOMContentLoaded",function(){T(e,t)}),console.warn("["+t+'] Script loaded before <body> — add "defer" to your <script> tag');return}e()}function L(e){return e.hasAttribute("data-ln-value")?e.getAttribute("data-ln-value"):e.tagName==="TIME"&&e.hasAttribute("datetime")?e.getAttribute("datetime"):e.tagName==="DATA"&&e.hasAttribute("value")?e.getAttribute("value"):e.textContent.trim()}const K={};function ne(e,t){K[e]=t}function re(e){return K[e]||{ingress:t=>t,egress:t=>t}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerDataMapper=ne,window.lnCore.getDataMapper=re);function oe(e){const t=e?e.closest("[lang]"):null,n=(t?t.getAttribute("lang")||t.lang:null)||(typeof document<"u"&&document.documentElement?document.documentElement.getAttribute("lang")||document.documentElement.lang:null)||(typeof navigator<"u"?navigator.language:null);return n?n.trim():"en-US"}function ie(){typeof window>"u"||(window.lnCore=window.lnCore||{},!window.lnCore._localeObserverBound&&(window.lnCore._localeObserverBound=!0,T(function(){new MutationObserver(function(){te(document,"ln-core:locale-change",{})}).observe(document.documentElement,{attributes:!0,attributeFilter:["lang"],subtree:!0})},"ln-core")))}const U={};function le(e,t){if(!e||typeof t!="object")return;const n=e.toLowerCase().split("-")[0];U[n]=t}function se(e){if(!e)return null;const t=e.toLowerCase().split("-")[0];return U[t]||null}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerLocaleFallback=le,window.lnCore.getLocaleFallback=se,window.lnCore.ensureLocaleObserver=ie);const x={};function ue(e,t){x[e]||(x[e]=document.querySelector('[data-ln-template="'+e+'"]'));const n=x[e];return n?n.content.cloneNode(!0):(console.warn("["+(t||"ln-core")+'] Template "'+e+'" not found'),null)}function P(e,t){if(!e||!t)return e;const n=e.querySelectorAll("[data-ln-field]");for(let l=0;l<n.length;l++){const u=n[l],a=u.getAttribute("data-ln-field");t[a]!=null&&(u.textContent=t[a])}const r=e.querySelectorAll("[data-ln-attr]");for(let l=0;l<r.length;l++){const u=r[l],a=u.getAttribute("data-ln-attr").split(",");for(let d=0;d<a.length;d++){const b=a[d].trim().split(":");if(b.length!==2)continue;const f=b[0].trim(),C=b[1].trim();t[C]!=null&&u.setAttribute(f,t[C])}}const o=e.querySelectorAll("[data-ln-show]");for(let l=0;l<o.length;l++){const u=o[l],a=u.getAttribute("data-ln-show");a in t&&u.classList.toggle("hidden",!t[a])}const i=e.querySelectorAll("[data-ln-class]");for(let l=0;l<i.length;l++){const u=i[l],a=u.getAttribute("data-ln-class").split(",");for(let d=0;d<a.length;d++){const b=a[d].trim().split(":");if(b.length!==2)continue;const f=b[0].trim(),C=b[1].trim();C in t&&u.classList.toggle(f,!!t[C])}}return e}function ae(e,t){e.matches&&e.matches("[data-ln-form], [data-ln-fillable]")&&(window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",e,t??null),e.dispatchEvent(new CustomEvent("ln-fill",{detail:t??null,bubbles:!0})));const n=e.querySelectorAll("[data-ln-form], [data-ln-fillable]");for(let r=0;r<n.length;r++)window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",n[r],t??null),n[r].dispatchEvent(new CustomEvent("ln-fill",{detail:t??null,bubbles:!0}));return e}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._fillBound||(window.lnCore._fillBound=!0,document.addEventListener("ln-fill",function(e){if(!(!e.target.matches||!e.target.matches("[data-ln-fillable]")))if(e.detail)P(e.target,e.detail);else{const t=e.target.querySelectorAll("[data-ln-field]");for(let n=0;n<t.length;n++)t[n].textContent=""}})));function Q(e,t){if(!e||!t)return e;const n=document.createTreeWalker(e,NodeFilter.SHOW_TEXT);for(;n.nextNode();){const i=n.currentNode;i.textContent.indexOf("{{")!==-1&&(i.textContent=i.textContent.replace(/\{\{\s*(\w+)\s*\}\}/g,function(l,u){return t[u]!==void 0?t[u]:""}))}const r=function(i,l){return t[l]!==void 0?t[l]:""},o=Array.from(e.querySelectorAll("*"));e.nodeType===1&&o.push(e);for(let i=0;i<o.length;i++){const l=o[i],u=l.attributes;for(let a=0;a<u.length;a++){const d=u[a];d.value.indexOf("{{")!==-1&&l.setAttribute(d.name,d.value.replace(/\{\{\s*(\w+)\s*\}\}/g,r))}}return e}function ce(e,t,n,r,o,i){const l={};for(let a=0;a<e.children.length;a++){const d=e.children[a],b=d.getAttribute("data-ln-render-key");b&&(l[b]=d)}const u=document.createDocumentFragment();for(let a=0;a<t.length;a++){const d=t[a],b=String(r(d));let f=l[b];if(f)o(f,d,a);else{const C=ue(n,i);if(!C||(Q(C,d),f=C.firstElementChild,!f))continue;f.setAttribute("data-ln-render-key",b),o(f,d,a)}u.appendChild(f)}e.textContent="",e.appendChild(u)}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.fillTemplate=Q,window.lnCore.fill=P,window.lnCore.lnFill=ae,window.lnCore.renderList=ce);function D(e,t,n){const r=e.getAttribute(t);return r===null?n:r}function de(e,t,n){const r=parseInt(e.getAttribute(t),10);return isNaN(r)?n:r}function fe(e,t,n=!1){const r=e.getAttribute(t);if(r===null)return!!n;const o=r.trim().toLowerCase();return!(o==="false"||o==="0")}function he(e,t){return(e.getAttribute(t)||"").split(",").map(n=>n.trim()).filter(Boolean)}const N=new Map;function we(e,t){const n=(e?e.join("|"):"")+"::"+t;if(N.has(n))return N.get(n);const r=new Set(e||[]),o=function(i,l){const u=i.getAttribute(l);return u!==null&&r.has(u)?u:t};return N.set(n,o),o}function be(e,t,n){const r=parseFloat(e.getAttribute(t));return isNaN(r)?n:r}function ge(e,t,n){const r=e.getAttribute(t);if(!r)return n;try{return JSON.parse(r)}catch{return n}}function z(e,t,n,r,o){if(!e||t===null)return!0;const i=r||"ln-component",l=e.type;if(l==="trigger"||l==="marker"||l==="string"||l==="list"||!l||t===""&&e.fallback!==void 0)return!0;const u=a=>{o?console.warn(a,o):console.warn(a)};if(l==="boolean"){const a=t.trim().toLowerCase();return a!==""&&a!=="true"&&a!=="false"&&a!=="1"&&a!=="0"?(u(`[${i}] Invalid value "${t}" for boolean attribute "${n}". Allowed: "true", "false", or presence-only.`),!1):!0}if(l==="enum"){const a=e.values||[];return a.includes(t)?!0:(u(`[${i}] Invalid value "${t}" for attribute "${n}". Allowed: ${a.join(", ")}. Fallback: "${e.fallback}".`),!1)}if(l==="integer"){if(!/^-?\d+$/.test(t))return u(`[${i}] Invalid integer "${t}" for attribute "${n}". Fallback: ${e.fallback}.`),!1;const a=parseInt(t,10);return e.min!==void 0&&a<e.min?(u(`[${i}] Value ${a} for attribute "${n}" is less than min (${e.min}).`),!1):e.max!==void 0&&a>e.max?(u(`[${i}] Value ${a} for attribute "${n}" is greater than max (${e.max}).`),!1):!0}if(l==="float")return isNaN(Number(t))?(u(`[${i}] Invalid float "${t}" for attribute "${n}". Fallback: ${e.fallback}.`),!1):!0;if(l==="json")try{return JSON.parse(t),!0}catch(a){return u(`[${i}] Invalid JSON for attribute "${n}": ${a.message}. Fallback: ${e.fallback}.`),!1}return!0}function pe(e,t,n){for(const r in n){const[o,i,l]=n[r];Object.defineProperty(e,r,{get:function(){return o(t,i,l)},enumerable:!0,configurable:!0})}return e}function me(e){const t={};for(const n in e){const r=e[n];if(!r||!r.prop)continue;let o=r.read;if(!o&&r.type)switch(r.type){case"enum":o=we(r.values,r.fallback);break;case"integer":o=de;break;case"float":o=be;break;case"boolean":o=fe;break;case"list":o=he;break;case"json":o=ge;break;case"string":default:o=D;break}o||(o=D),t[r.prop]=[o,n,r.fallback]}return t}function ye(e){const t={};for(const n in e){const r=e[n];r&&r.effect&&(t[n]=r.effect)}return Object.keys(t).length?t:null}function Ce(e){if(e.onAttrChange&&!e.declared)return null;const t=new Set;if(e.effects)for(const n in e.effects)t.add(n);if(e.onAttrChange&&e.declared)for(const n of e.declared)t.add(n);return t}function $(e,t,n,r){if(e.nodeType!==1)return;const i=t.indexOf("[")!==-1||t.indexOf(".")!==-1||t.indexOf("#")!==-1?t:"["+t+"]",l=Array.from(e.querySelectorAll(i));e.matches&&e.matches(i)&&l.push(e);for(const u of l)if(!u[n]){window.lnCore._persistSink&&u.hasAttribute("data-ln-persist")&&window.lnCore._persistSink(u,t);try{u[n]=new r(u)}catch(a){console.error("["+n+"] init failed",u,a)}}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._bootHolds=window.lnCore._bootHolds||0,window.lnCore._bootQueue=window.lnCore._bootQueue||[]);function Ae(){return typeof window<"u"&&window.lnCore&&window.lnCore._bootHolds||0}function q(e){typeof window<"u"?(window.lnCore=window.lnCore||{},window.lnCore._bootHolds=window.lnCore._bootHolds||0,window.lnCore._bootQueue=window.lnCore._bootQueue||[],window.lnCore._bootHolds>0?window.lnCore._bootQueue.push(e):setTimeout(e,0)):e()}function J(){window.lnCore=window.lnCore||{};const e=window.lnCore._attrRegistry=window.lnCore._attrRegistry||{byAttr:new Map,reactive:[],persist:[]};return e.byReactive=e.byReactive||new Map,e.reactiveWildcard=e.reactiveWildcard||[],e}function _e(e){const t=J(),n=e.observed||[];for(let r=0;r<n.length;r++){const o=n[r];t.byAttr.has(o)||t.byAttr.set(o,[]),t.byAttr.get(o).push(e)}if(t.byDeclaredAttr=t.byDeclaredAttr||new Map,e.attributes)for(const r in e.attributes){t.byDeclaredAttr.has(r)||t.byDeclaredAttr.set(r,[]);const o=t.byDeclaredAttr.get(r);o.some(i=>i.componentTag===e.componentTag)||o.push({spec:e.attributes[r],componentTag:e.componentTag})}if(e.onAttrChange||e.effects){t.reactive.push(e);const r=Ce(e);if(r===null)t.reactiveWildcard.push(e);else for(const o of r)t.byReactive.has(o)||t.byReactive.set(o,[]),t.byReactive.get(o).push(e)}e.persist&&t.persist.push(e)}function G(e,t,n,r){for(let o=0;o<e.length;o++){const i=e[o];if(!t[i.attribute])continue;const l=i.effects&&i.effects[n];l?l(t,n,r):i.onAttrChange&&(!i.declared||i.declared.has(n))&&i.onAttrChange(t,n,r)}}function Se(e){const t=e.target,n=e.attributeName;if(e.oldValue===t.getAttribute(n))return;const r=J(),o=r.byAttr.get(n);if(V()&&r.byDeclaredAttr&&r.byDeclaredAttr.has(n)&&O(t)){const i=r.byDeclaredAttr.get(n),l=t.getAttribute(n);for(let u=0;u<i.length;u++)z(i[u].spec,l,n,i[u].componentTag,t)}if(window.lnCore._debugSink&&(n.indexOf("data-ln-")===0||o)&&window.lnCore._debugSink("attr",n,t,{oldValue:e.oldValue,newValue:t.getAttribute(n)}),n.indexOf("data-ln-")===0){const i=r.byReactive.get(n);i&&G(i,t,n,e.oldValue),r.reactiveWildcard.length&&G(r.reactiveWildcard,t,n,e.oldValue)}if(o)for(let i=0;i<o.length;i++){const l=o[i];if(l.handler){l.handler(t,n,e.oldValue);continue}l.onAttributeChange&&t[l.attribute]?l.onAttributeChange(t,n):($(t,l.selector,l.attribute,l.ComponentFn),l.onInit&&l.onInit(t))}}function ve(){window.lnCore=window.lnCore||{},!window.lnCore._attrObserverBound&&(window.lnCore._attrObserverBound=!0,T(function(){new MutationObserver(function(t){for(let n=0;n<t.length;n++)try{Se(t[n])}catch(r){console.error("[ln-core] mutation handler failed",t[n].target,r)}}).observe(document.body,{attributes:!0,subtree:!0,attributeOldValue:!0})},"ln-core"))}function X(){return window.lnCore=window.lnCore||{},window.lnCore._lifecycleRegistry=window.lnCore._lifecycleRegistry||[]}function ke(e){const t=X();if(t.length){if(e.target)for(let n=0;n<t.length;n++){const r=t[n];if(r.onSubtreeChange){const o=r.query,i=e.target.nodeType===1?e.target.matches(o)?e.target:e.target.closest(o):e.target.parentElement?e.target.parentElement.closest(o):null;i&&r.onSubtreeChange(i,e)}}for(let n=0;n<e.addedNodes.length;n++){const r=e.addedNodes[n];if(r.nodeType===1)for(let o=0;o<t.length;o++){const i=t[o];$(r,i.selector,i.attribute,i.ComponentFn),i.onInit&&i.onInit(r)}}for(let n=0;n<e.removedNodes.length;n++){const r=e.removedNodes[n];if(r.nodeType===1)for(let o=0;o<t.length;o++){const i=t[o],l=i.query,u=Array.from(r.querySelectorAll(l));r.matches&&r.matches(l)&&u.push(r);for(let a=0;a<u.length;a++){const d=u[a];if(!document.contains(d)){const b=d[i.attribute];if(b&&typeof b.destroy=="function")try{b.destroy()}catch(f){console.error("["+i.attribute+"] destroy failed",d,f)}delete d[i.attribute]}}}}}}function Ee(){window.lnCore=window.lnCore||{},!window.lnCore._lifecycleObserverBound&&(window.lnCore._lifecycleObserverBound=!0,T(function(){new MutationObserver(function(t){for(let n=0;n<t.length;n++){const r=t[n];if(r.type==="childList")try{ke(r)}catch(o){console.error("[ln-core] lifecycle handler failed",r.target,o)}}}).observe(document.body,{childList:!0,subtree:!0})},"ln-core"))}function Te(e,t,n,r,o={}){const i=o.extraAttributes||[],l=o.onAttributeChange||null,u=o.onSubtreeChange||null,a=o.onInit||null,d=o.onAttrChange||null,b=o.effects||null,f=o.attributes||null,C=f?ye(f):b,c=f?new Set(Object.keys(f)):null,m=o.persist||null;function s(S){const w=S||document.body;if($(w,e,t,n),f&&V())for(const A in f){const j=f[A],v=Array.from(w.querySelectorAll("["+A+"]"));w.matches&&w.matches("["+A+"]")&&v.push(w);for(let k=0;k<v.length;k++){const E=v[k];O(E)&&z(j,E.getAttribute(A),A,r,E)}}a&&a(w)}const p=[];if(e.indexOf("[")!==-1){const S=/\[([\w-]+)/g;let w;for(;(w=S.exec(e))!==null;)p.push(w[1])}else p.push(e);_e({selector:e,attribute:t,componentTag:r,attributes:f,ComponentFn:n,onInit:a,observed:p.concat(i),onAttributeChange:l,onAttrChange:d,effects:C,declared:c,persist:m}),ve();const g=e.indexOf("[")!==-1||e.indexOf(".")!==-1||e.indexOf("#")!==-1?e:"["+e+"]";X().push({selector:e,attribute:t,ComponentFn:n,onInit:a,onSubtreeChange:u,query:g}),Ee(),window[t]=s;function y(){Ae()>0?q(function(){s(document.body)}):s(document.body)}return document.readyState==="loading"?document.addEventListener("DOMContentLoaded",y):y(),s}function Ie(e){let t=!1;for(let n=0;n<e.length;n++){const r=e[n];if(!(r===""||r==null)&&(t=!0,!Number.isFinite(Number(r))))return"string"}return t?"number":"string"}function Oe(e,t,n,r){if(n==="number"){const l=parseFloat(e),u=parseFloat(t);return(isNaN(l)?0:l)-(isNaN(u)?0:u)}const o=e!=null?String(e):"",i=t!=null?String(t):"";return r?r.compare(o,i):o<i?-1:o>i?1:0}function Y(e){return(e||"").replace(/^#/,"")}function R(e){const t=e===void 0?location.hash:e,n={},r=Y(t);if(!r)return n;const o=r.split("&");for(let i=0;i<o.length;i++){const l=o[i];if(!l)continue;const u=l.indexOf(":"),a=u>-1?l.slice(0,u):l,d=u>-1?l.slice(u+1):"";if(a)try{n[a]=decodeURIComponent(d)}catch{n[a]=d}}return n}function B(e){if(!e)return null;const t=R();return e in t?t[e]:null}function Z(e,t){if(!e)return;const n=R();t==null?delete n[e]:n[e]=String(t);const o=Object.keys(n).map(function(i){const l=n[i];return l===""?i:i+":"+encodeURIComponent(l)}).join("&");Y(location.hash)!==o&&(location.hash=o)}function Le(e){return e.button===1||e.ctrlKey||e.metaKey||e.shiftKey?!1:(e.preventDefault(),!0)}function I(e,t){if(!e||!e.hasAttribute("data-ln-hash"))return null;const n=e.getAttribute("data-ln-hash");if(n&&n.trim()!=="")return n.trim();const r=e.getAttribute("data-ln-sort")||e.getAttribute("data-ln-search-for")||e.getAttribute("data-ln-search")||e.getAttribute("data-ln-filter")||e.id;return r?t?r+"-"+t:r:t||null}function ee(e,t){return!t||t==="none"||e===null||e===void 0?null:String(e)+"."+t}function F(e){return!e||typeof e!="string"?null:e.endsWith(".asc")?{fieldOrColumn:e.slice(0,-4),direction:"asc"}:e.endsWith(".desc")?{fieldOrColumn:e.slice(0,-5),direction:"desc"}:null}function xe(e,t){return!e||!Array.isArray(t)||t.length===0?null:e+":"+t.map(encodeURIComponent).join(",")}function De(e){if(!e||typeof e!="string")return null;const t=e.indexOf(":");if(t===-1)return null;const n=e.slice(0,t),r=e.slice(t+1),o=r?r.split(",").map(function(i){try{return decodeURIComponent(i)}catch{return i}}).filter(Boolean):[];return{key:n,values:o}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.hashParse=R,window.lnCore.hashGet=B,window.lnCore.hashSet=Z,window.lnCore.hashLinkClick=Le,window.lnCore.resolveHashNamespace=I,window.lnCore.hashSortEncode=ee,window.lnCore.hashSortDecode=F,window.lnCore.hashFilterEncode=xe,window.lnCore.hashFilterDecode=De);function _(e){const t=String(e||"").trim().toLowerCase();return t==="asc"||t==="ascending"?"asc":t==="desc"||t==="descending"?"desc":"none"}function Ne(e){const t=_(e);return t==="asc"?"ascending":t==="desc"?"descending":"none"}function $e(e,t){return!e||!t?!1:e.field!==null&&e.field!==void 0&&t.field!==null&&t.field!==void 0?e.field===t.field:e.column!==null&&e.column!==void 0&&t.column!==null&&t.column!==void 0?String(e.column)===String(t.column):!1}function qe(e,t,n,r){const o=_(e);if(o==="none")return()=>0;const i=o==="desc"?-1:1,l=typeof r=="function"?r:u=>u;return function(u,a){const d=l(u),b=l(a);return Oe(d,b,t,n)*i}}function M(e){return!!(!e||typeof e!="object"||e.nodeType!==1||e.tagName==="TEMPLATE"||typeof e.hasAttribute=="function"&&(e.hasAttribute("data-ln-sort-exclude")||e.hasAttribute("hidden"))||e.classList&&e.classList.contains("hidden")||e.style&&e.style.display==="none"||typeof e.matches=="function"&&e.matches(".empty-state, .ln-table__empty, .ln-table__empty-state, [data-ln-empty], [data-ln-empty-state], [data-ln-table-empty]"))}function Re(e,t){if(!e||typeof e!="object"||e.nodeType!==1)return[];const n=t||(typeof e.getAttribute=="function"?e.getAttribute("data-ln-sort-items"):null)||null;if(n&&typeof e.querySelectorAll=="function")return Array.from(e.querySelectorAll(n));if(e.tagName==="TABLE"){const r=e.tBodies&&e.tBodies.length?e.tBodies[0]:typeof e.querySelector=="function"?e.querySelector("tbody"):null;if(r)return Array.from(r.children||[]);if(typeof e.querySelectorAll=="function")return Array.from(e.querySelectorAll("tbody tr, tr"))}return Array.from(e.children||[])}(function(){const e="data-ln-sort",t="lnSort",n="data-ln-sort-field",r="data-ln-sort-state",o="data-ln-sort-dir",i="data-ln-hash";if(window[t]!==void 0)return;function l(c,m){return c.getAttribute(m)||null}const u={"data-ln-sort":{prop:"targetId",type:"string",read:D,fallback:null,description:"Target table or list element ID to sort"},"data-ln-sort-field":{prop:"field",type:"string",read:l,effect:C,description:"Field name or column key to sort by"},"data-ln-sort-dir":{type:"enum",values:["asc","desc"],fallback:"asc",description:"Default or requested sort direction"},"data-ln-sort-items":{prop:"itemsSelector",type:"string",read:l,description:"CSS selector matching sortable child items"},"data-ln-sort-state":{type:"enum",values:["asc","desc","none"],fallback:"none",effect:C,description:"Active sort state applied to column or control"},"data-ln-hash":{type:"string",effect:C,description:"URL hash routing key for sort state persistence"}},a=me(u),d=new WeakMap;function b(c,m,s){if(m){const p=c.querySelector('[data-ln-field="'+m+'"]');return p?L(p):""}return s!=null&&c.cells&&c.cells[s]?L(c.cells[s]):L(c)}function f(c){this.dom=c,pe(this,c,a);const m=c.closest("th");this.column=!this.field&&m?m.cellIndex:null,this._state=_(c.getAttribute(r)),c.hasAttribute(r)||c.setAttribute(r,this._state),this._destroyed=!1,this.nsKey=I(c,"sort"),this.hashEnabled=!!this.nsKey;const s=this;this._onClick=function(h){const g=h.target.closest("["+o+"]");if(!g)return;const y=_(g.getAttribute(o));s._apply(y)},c.addEventListener("click",this._onClick),this._onSortChange=function(h){if(s._destroyed||!h.detail)return;const g=s._resolveTarget();if(!(g&&(h.target===g||g.contains(h.target))||h.detail.targetId&&h.detail.targetId===s.targetId))return;if($e({field:s.field,column:s.column},{field:h.detail.field,column:h.detail.column})){const w=_(h.detail.direction);w&&c.getAttribute(r)!==w&&(s._state=w,c.setAttribute(r,w),s._updateAriaSort(w));return}c.getAttribute(r)!=="none"&&(s._state="none",c.setAttribute(r,"none"),s._updateAriaSort("none"))},document.addEventListener("ln-sort:change",this._onSortChange),this._onHashChange=function(){if(s._destroyed||!s.hashEnabled)return;const h=B(s.nsKey),g=F(h);if(g)s.field!==null&&g.fieldOrColumn===s.field||s.column!==null&&String(s.column)===g.fieldOrColumn?s._state!==g.direction&&s._apply(g.direction,!0):s._state!=="none"&&(s._state="none",c.setAttribute(r,"none"),s._updateAriaSort("none"));else if(s._state!=="none"){s._state="none",c.setAttribute(r,"none"),s._updateAriaSort("none");const y=s._resolveTarget();y&&(W(y,"ln-sort:change",{field:s.field,column:s.column,direction:"none",targetId:s.targetId}).defaultPrevented||s._defaultSort(y,"none"))}},this.hashEnabled&&window.addEventListener("hashchange",this._onHashChange);let p=!1;if(this.hashEnabled){const h=B(this.nsKey),g=F(h);g&&((s.field!==null&&g.fieldOrColumn===s.field||s.column!==null&&String(s.column)===g.fieldOrColumn)&&q(function(){s._destroyed||s._apply(g.direction,!0)}),p=!0)}if(!p){const h=_(c.getAttribute(r));h&&h!=="none"&&q(function(){s._destroyed||s._apply(h,!0)})}return this}f.prototype._resolveTarget=function(){return document.getElementById(this.targetId)},f.prototype._updateAriaSort=function(c){const m=this.dom.closest("th");m&&m.setAttribute("aria-sort",Ne(c))},f.prototype._apply=function(c,m){if(this._destroyed)return;if(!this.field&&this.column===null){const y=this.dom.closest("th");y&&y.cellIndex!==void 0&&(this.column=y.cellIndex)}const s=_(c);this._state=s,this.dom.getAttribute(r)!==s&&this.dom.setAttribute(r,s),this._updateAriaSort(s);const p=this._resolveTarget();if(!p)return;const h={field:this.field,column:this.column,direction:s,targetId:this.targetId};if(!m&&this.hashEnabled){const y=ee(this.field!==null?this.field:this.column,s);Z(this.nsKey,y)}W(p,"ln-sort:change",h).defaultPrevented||this._defaultSort(p,s)},f.prototype._defaultSort=function(c,m){const s=Re(c,this.itemsSelector);if(!s.length)return;const p=s[0].parentNode,h=s.filter(function(w){return!M(w)});if(!h.length)return;d.has(c)||d.set(c,h.slice());let g;if(m==="none"){const w=d.get(c)||h;d.delete(c),g=w.filter(function(A){return A.parentNode===p&&!M(A)})}else{const w=this.field,A=this.column,j=h.map(function(H){return b(H,w,A)}),v=Ie(j),k=typeof Intl<"u"?new Intl.Collator(oe(this.dom),{sensitivity:"base",numeric:!0}):null,E=qe(m,v,k,function(H){return b(H,w,A)});g=h.slice().sort(E)}const y=document.createDocumentFragment();let S=0;for(let w=0;w<s.length;w++){const A=s[w];M(A)?y.appendChild(A):S<g.length&&y.appendChild(g[S++])}p.appendChild(y)},f.prototype.destroy=function(){this._destroyed||(this._destroyed=!0,this.dom.removeEventListener("click",this._onClick),document.removeEventListener("ln-sort:change",this._onSortChange),this.hashEnabled&&this._onHashChange&&window.removeEventListener("hashchange",this._onHashChange),delete this.dom[t])};function C(c,m){const s=c[t];if(!(!s||s._destroyed))if(m===n){const p=c.closest("th");s.column=!s.field&&p?p.cellIndex:null}else if(m===r){const p=_(c.getAttribute(r));p!==s._state&&s._apply(p)}else m===i&&(s.hashEnabled&&s._onHashChange&&window.removeEventListener("hashchange",s._onHashChange),s.nsKey=I(c,"sort"),s.hashEnabled=!!s.nsKey,s.hashEnabled&&window.addEventListener("hashchange",s._onHashChange))}Te(e,t,f,"ln-sort",{attributes:u,persist:{attr:r,hashActive:function(c){return!!I(c,"sort")}}})})()})();
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "This file is partly generated. The $comment, component, generator, and each attribute's direction, sources, type, values, fallback, and description keys are owned by the generator and synchronized from JS source code. All other keys are preserved and safe to hand-author. Regenerate with `npm run sync:ln-schemas`.",
|
|
3
|
+
"component": "ln-sort",
|
|
4
|
+
"generator": "scripts/sync-ln-schemas.mjs",
|
|
5
|
+
"attributes": {
|
|
6
|
+
"data-ln-debug": {
|
|
7
|
+
"direction": null,
|
|
8
|
+
"sources": [
|
|
9
|
+
"ln-sort-dev.scss"
|
|
10
|
+
]
|
|
11
|
+
},
|
|
12
|
+
"data-ln-empty": {
|
|
13
|
+
"direction": "author",
|
|
14
|
+
"sources": [
|
|
15
|
+
"src/sort-model.js"
|
|
16
|
+
]
|
|
17
|
+
},
|
|
18
|
+
"data-ln-empty-state": {
|
|
19
|
+
"direction": "author",
|
|
20
|
+
"sources": [
|
|
21
|
+
"src/sort-model.js"
|
|
22
|
+
]
|
|
23
|
+
},
|
|
24
|
+
"data-ln-field": {
|
|
25
|
+
"direction": "author",
|
|
26
|
+
"sources": [
|
|
27
|
+
"src/ln-sort.js"
|
|
28
|
+
]
|
|
29
|
+
},
|
|
30
|
+
"data-ln-hash": {
|
|
31
|
+
"direction": null,
|
|
32
|
+
"sources": [
|
|
33
|
+
"src/ln-sort.js"
|
|
34
|
+
],
|
|
35
|
+
"type": "string",
|
|
36
|
+
"description": "URL hash routing key for sort state persistence"
|
|
37
|
+
},
|
|
38
|
+
"data-ln-sort": {
|
|
39
|
+
"direction": null,
|
|
40
|
+
"sources": [
|
|
41
|
+
"ln-sort-dev.scss",
|
|
42
|
+
"src/ln-sort.js"
|
|
43
|
+
],
|
|
44
|
+
"type": "string",
|
|
45
|
+
"description": "Target table or list element ID to sort"
|
|
46
|
+
},
|
|
47
|
+
"data-ln-sort-dir": {
|
|
48
|
+
"direction": "author",
|
|
49
|
+
"sources": [
|
|
50
|
+
"src/ln-sort.js"
|
|
51
|
+
],
|
|
52
|
+
"type": "enum",
|
|
53
|
+
"values": [
|
|
54
|
+
"asc",
|
|
55
|
+
"desc"
|
|
56
|
+
],
|
|
57
|
+
"fallback": "asc",
|
|
58
|
+
"description": "Default or requested sort direction"
|
|
59
|
+
},
|
|
60
|
+
"data-ln-sort-exclude": {
|
|
61
|
+
"direction": "author",
|
|
62
|
+
"sources": [
|
|
63
|
+
"src/sort-model.js"
|
|
64
|
+
]
|
|
65
|
+
},
|
|
66
|
+
"data-ln-sort-field": {
|
|
67
|
+
"direction": null,
|
|
68
|
+
"sources": [
|
|
69
|
+
"src/ln-sort.js"
|
|
70
|
+
],
|
|
71
|
+
"type": "string",
|
|
72
|
+
"description": "Field name or column key to sort by"
|
|
73
|
+
},
|
|
74
|
+
"data-ln-sort-items": {
|
|
75
|
+
"direction": "author",
|
|
76
|
+
"sources": [
|
|
77
|
+
"src/ln-sort.js",
|
|
78
|
+
"src/sort-model.js"
|
|
79
|
+
],
|
|
80
|
+
"type": "string",
|
|
81
|
+
"description": "CSS selector matching sortable child items"
|
|
82
|
+
},
|
|
83
|
+
"data-ln-sort-state": {
|
|
84
|
+
"direction": "both",
|
|
85
|
+
"sources": [
|
|
86
|
+
"src/ln-sort.js"
|
|
87
|
+
],
|
|
88
|
+
"type": "enum",
|
|
89
|
+
"values": [
|
|
90
|
+
"asc",
|
|
91
|
+
"desc",
|
|
92
|
+
"none"
|
|
93
|
+
],
|
|
94
|
+
"fallback": "none",
|
|
95
|
+
"description": "Active sort state applied to column or control"
|
|
96
|
+
},
|
|
97
|
+
"data-ln-table-empty": {
|
|
98
|
+
"direction": "author",
|
|
99
|
+
"sources": [
|
|
100
|
+
"src/sort-model.js"
|
|
101
|
+
]
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|