@livenetworks/ashlar 1.6.1 → 2.0.1
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 +190 -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,196 +1,198 @@
|
|
|
1
|
-
# ln-toggle
|
|
2
|
-
|
|
3
|
-
>
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
- **The
|
|
37
|
-
- **The
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
- `data-ln-toggle
|
|
64
|
-
- `data-ln-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
|
77
|
-
|
|
78
|
-
| **`ln-toggle:
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
1
|
+
# ln-toggle
|
|
2
|
+
|
|
3
|
+
> Applied to any collapsible panel element via `data-ln-toggle`, with triggers bound from anywhere in the DOM via `data-ln-toggle-for="id"`.
|
|
4
|
+
> It listens for trigger clicks and reacts to direct attribute mutations to toggle binary `open`/`close` state. The `data-ln-toggle`
|
|
5
|
+
> attribute is the single source of truth — automatically keeping `aria-expanded` and the `.open` CSS class in sync with zero JS height calculations or shadow state.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. Philosophy & The Primitive Mindset
|
|
10
|
+
|
|
11
|
+
In `ln-ashlar`, the core design principle is **orthogonality**. Rather than creating heavy components that mix state, visual presentation, and layout, we separate them into isolated concerns:
|
|
12
|
+
|
|
13
|
+
1. **The State Machine (JavaScript)**: The `ln-toggle` component (145 lines) only manages binary `open` / `close` state in the DOM and synchronizes ARIA accessibility. It does not own animations or visual geometries.
|
|
14
|
+
2. **The Visual Presentation (CSS)**: Visual transitions are handled in Vanilla CSS. The component synchronizes the `.open` class and `[data-ln-toggle="open"]` on the panel. CSS reads these selectors and runs transitions (e.g. height collapse or sliding drawers).
|
|
15
|
+
3. **Decoupled Binding (HTML)**: Triggers and panels are matched purely by ID. They can live anywhere in the DOM. Multiple triggers pointing to a single panel are supported natively, and all triggers stay perfectly synchronized.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 2. Minimal Blueprint
|
|
20
|
+
|
|
21
|
+
Triggers and panels are bound via ID. A panel must have a unique `id` and the `data-ln-toggle` attribute.
|
|
22
|
+
|
|
23
|
+
```html
|
|
24
|
+
<!-- Trigger anywhere -->
|
|
25
|
+
<button data-ln-toggle-for="example-panel">Toggle Options</button>
|
|
26
|
+
|
|
27
|
+
<!-- Panel anywhere -->
|
|
28
|
+
<section id="example-panel" data-ln-toggle class="collapsible">
|
|
29
|
+
<article class="collapsible-body">
|
|
30
|
+
<p>This is smooth collapsible content.</p>
|
|
31
|
+
</article>
|
|
32
|
+
</section>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Key Anatomy Rules
|
|
36
|
+
- **The Panel (`data-ln-toggle`)**: The value `open` represents open; anything else (empty or `close`) represents closed.
|
|
37
|
+
- **The Trigger (`data-ln-toggle-for="id"`)**: Automatically intercepts clicks to toggle the panel.
|
|
38
|
+
- **The Close Trigger (`data-ln-toggle-action="close"`)**: Forces the trigger to only close the panel (e.g. an "X" button inside a sidebar drawer).
|
|
39
|
+
- **The Body (`.collapsible-body`)**: Holds all padding and margins. The parent `.collapsible` container must have zero padding so it can transition to exactly `0px` height cleanly.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## 3. The Declarative API & State Contract
|
|
44
|
+
|
|
45
|
+
There are no imperative JavaScript methods (like `open()` or `close()`) on the component instance. **The HTML attribute is the sole contract.**
|
|
46
|
+
|
|
47
|
+
Triggers, sibling components, external scripts, and manual DevTools edits all change state by writing the attribute:
|
|
48
|
+
|
|
49
|
+
```js
|
|
50
|
+
const panel = document.getElementById('example-panel');
|
|
51
|
+
|
|
52
|
+
// Open the panel
|
|
53
|
+
panel.setAttribute('data-ln-toggle', 'open');
|
|
54
|
+
|
|
55
|
+
// Close the panel
|
|
56
|
+
panel.setAttribute('data-ln-toggle', 'close');
|
|
57
|
+
|
|
58
|
+
// Read-only state query (committed state tracker)
|
|
59
|
+
panel.lnToggle.isOpen; // Returns true/false
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Attributes
|
|
63
|
+
- `data-ln-toggle`: Placed on the panel to create the toggle instance.
|
|
64
|
+
- `data-ln-toggle-for`: Placed on triggers referencing the panel ID.
|
|
65
|
+
- `data-ln-toggle-action="open|close"`: Forces a trigger button to only open or only close the target.
|
|
66
|
+
- `data-ln-persist`: Saves the panel state individually in `localStorage`.
|
|
67
|
+
- storage key: `ln:{id}:data-ln-toggle` (global by default).
|
|
68
|
+
- `data-ln-persist-scope="page"`: Opt-in, independent attribute. Scopes the storage key to the current pathname: `ln:{id}:{pagePath}:data-ln-toggle`. Same IDs on different pages then store separately.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## 4. Transition Events
|
|
73
|
+
|
|
74
|
+
All events bubble. `event.detail.target` is always the panel element.
|
|
75
|
+
|
|
76
|
+
| Event | Cancelable | Dispatched When |
|
|
77
|
+
|---|---|---|
|
|
78
|
+
| **`ln-toggle:before-open`** | **Yes** | After attribute flips to `"open"`, before transition starts. Calling `event.preventDefault()` cancels the transition and reverts the attribute. |
|
|
79
|
+
| **`ln-toggle:open`** | No | After panel is fully open, classes added, and ARIA synced. |
|
|
80
|
+
| **`ln-toggle:before-close`** | **Yes** | After attribute flips to `"close"`, before transition starts. Calling `event.preventDefault()` cancels the close and reverts the attribute. |
|
|
81
|
+
| **`ln-toggle:close`** | No | After panel is fully closed, classes removed, and ARIA synced. |
|
|
82
|
+
|
|
83
|
+
```js
|
|
84
|
+
// Example: Cancel open transition for unauthorized users
|
|
85
|
+
document.addEventListener('ln-toggle:before-open', (e) => {
|
|
86
|
+
if (e.detail.target.id === 'secure-panel' && !currentUser.isAdmin) {
|
|
87
|
+
e.preventDefault(); // Reverts attribute back to "close"
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## 5. Integration Patterns
|
|
95
|
+
|
|
96
|
+
### A. Sidebar Drawer
|
|
97
|
+
Combine the panel with the library's `@mixin sidebar-drawer` and add a close button inside the sidebar:
|
|
98
|
+
```html
|
|
99
|
+
<aside id="menu" data-ln-toggle data-ln-persist class="sidebar">
|
|
100
|
+
<button data-ln-toggle-for="menu" data-ln-toggle-action="close">×</button>
|
|
101
|
+
</aside>
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### B. Smooth Height Collapsible
|
|
105
|
+
Combine the panel with the library's `@mixin collapsible` and `.collapsible-body` wrapper to animate height cleanly:
|
|
106
|
+
```html
|
|
107
|
+
<section id="panel" data-ln-toggle class="collapsible">
|
|
108
|
+
<div class="collapsible-body">Content goes here...</div>
|
|
109
|
+
</section>
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### C. Dismissible Alert
|
|
113
|
+
Combine the alert card with `data-ln-persist` so that once the user closes the alert, it stays closed across page reloads:
|
|
114
|
+
```html
|
|
115
|
+
<div class="alert" id="promo-banner" data-ln-toggle="open" data-ln-persist>
|
|
116
|
+
<p>Promo code active!</p>
|
|
117
|
+
<button data-ln-toggle-for="promo-banner" data-ln-toggle-action="close">×</button>
|
|
118
|
+
</div>
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## 6. Integration & Source Files
|
|
124
|
+
|
|
125
|
+
- **Unified Bundle**: Loaded automatically with the main bundle:
|
|
126
|
+
```html
|
|
127
|
+
<script src="dist/ln-ashlar.iife.js" defer></script>
|
|
128
|
+
```
|
|
129
|
+
- **Standalone IIFE**: For lightweight pages, load the standalone, self-registering IIFE version:
|
|
130
|
+
```html
|
|
131
|
+
<script src="components/ln-toggle/ln-toggle.js" defer></script>
|
|
132
|
+
```
|
|
133
|
+
- **Active Source (ESM)**: Development source is located at [components/ln-toggle/src/ln-toggle.js](file:///c:/laragon/www/ln-ashlar/components/ln-toggle/src/ln-toggle.js).
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Related
|
|
138
|
+
- **[`ln-accordion`](../ln-accordion/README.md)** — Single-open coordinator for toggle panels.
|
|
139
|
+
- **[`ln-dropdown`](../ln-dropdown/README.md)** — Menu wrapper adding click-outside/top-layer promotion.
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## 🔧 Internals
|
|
144
|
+
|
|
145
|
+
Source: `components/ln-toggle/ln-toggle.js`. Imports `registerComponent`, `dispatch`, `dispatchCancelable` from `ln-core` — no other library component. Persistence is declared, not imported: `registerComponent(...)` is passed `persist: { attr: DOM_SELECTOR, hashActive: null }`, and `ln-persist` (a separate component) does the restoring/saving from outside.
|
|
146
|
+
|
|
147
|
+
### Instance state
|
|
148
|
+
|
|
149
|
+
| Field | Description |
|
|
150
|
+
|---|---|
|
|
151
|
+
| `dom` | The panel element |
|
|
152
|
+
| `isOpen` | Cache of the attribute, kept current by `_syncAttribute`; used only to skip no-op transitions and as a read-only convenience getter |
|
|
153
|
+
|
|
154
|
+
No cached trigger list, no saved previous-value for revert, no timer/queue — every attribute change runs the pipeline immediately. Triggers are re-queried document-wide on each state change; cheap because the matching set is typically 1-3 elements.
|
|
155
|
+
|
|
156
|
+
### Init
|
|
157
|
+
|
|
158
|
+
`registerComponent` scans for `[data-ln-toggle]`, watches `data-ln-toggle` mutations, and instantiates panels. Triggers are handled document-wide by a single delegated click listener. `_component(dom)`:
|
|
159
|
+
1. **Persistence restore already happened** — if `data-ln-persist` is present, `ln-persist`'s sink already wrote the saved value onto `data-ln-toggle` via `setAttribute`, synchronously, *before* this constructor runs (inside `findElements`, immediately before `el[attribute] = new ComponentClass(el)`). The mutation-delivery microtask for that write fires *after* the constructor has already set `el.lnToggle` and read `isOpen` from the (already-restored) attribute, so `_syncAttribute`'s `shouldBeOpen === instance.isOpen` guard finds them equal and no-ops — no spurious `:before-open`/`:open` during restore.
|
|
160
|
+
2. Reads the (possibly restored) attribute into `isOpen`, adds `.open` if true, calls `_syncTriggerAria` for the initial ARIA state.
|
|
161
|
+
|
|
162
|
+
No `:open`/`:close` event fires at init — the attribute is already in its final state; there's been no transition.
|
|
163
|
+
|
|
164
|
+
### Delegated trigger handling
|
|
165
|
+
|
|
166
|
+
A module-level `instances` Set tracks all initialized toggle panels. A single delegated `document` click listener (`_ensureClickListener`) intercepts clicks on `[data-ln-toggle-for]`: ignores modifier-key clicks, ignores disabled targets (`isTargetDisabled`), calls `preventDefault()`, resolves the target panel by ID, and writes `data-ln-toggle` — `"open"`/`"close"` for an explicit `data-ln-toggle-action`, or the inverse of the current value for the default toggle action. There are no per-trigger event listeners or stashed handlers.
|
|
167
|
+
|
|
168
|
+
### `_syncAttribute` — the transition pipeline
|
|
169
|
+
|
|
170
|
+
Runs only when the mutated element already has an `lnToggle` instance (a brand-new element getting the attribute takes the init/upgrade path instead, via `findElements`, not a transition). Order, for the "open" direction (close mirrors it):
|
|
171
|
+
|
|
172
|
+
1. `dispatchCancelable('ln-toggle:before-open')` — listeners see `isOpen` at its **pre-transition** value.
|
|
173
|
+
2. If canceled: revert the attribute to `'close'` and return. The revert re-fires the observer, but `isOpen` was never changed, so the second pass is a no-op — no loop, no duplicate event.
|
|
174
|
+
3. `isOpen = true`, `.open` class added.
|
|
175
|
+
4. `_syncTriggerAria(el, true)` — before the post-event, so `:open` listeners see settled ARIA.
|
|
176
|
+
5. `dispatch('ln-toggle:open')`.
|
|
177
|
+
|
|
178
|
+
Persistence is not a step in this pipeline — `ln-persist`'s save handler is wired separately via `observeAttributes([DOM_SELECTOR], ...)` and reacts to the `data-ln-toggle` mutation on its own, after this function returns.
|
|
179
|
+
|
|
180
|
+
### `_syncTriggerAria`
|
|
181
|
+
|
|
182
|
+
Document-scoped `querySelectorAll('[data-ln-toggle-for="<id>"]')`, sets `aria-expanded` on each match — document-scoped because triggers can live anywhere relative to their panel. Drives both screen-reader state and the CSS chevron rotation rule in `theme/components/_toggle.scss`. Called from init and every transition.
|
|
183
|
+
|
|
184
|
+
### Persistence
|
|
185
|
+
|
|
186
|
+
Key: `ln:{id}:data-ln-toggle` (global by default), or `ln:{id}:{pagePath}:data-ln-toggle` when `data-ln-persist-scope="page"` is present, so the same panel `id` on two routes can be made to store independently (`_resolveKey` in `ln-persist/src/ln-persist.js`). The sink wraps `localStorage` in `try/catch` and swallows failures silently (private browsing, quota, disabled storage) — toggle keeps working without persistence, no error surfaces.
|
|
187
|
+
|
|
188
|
+
### Destroy
|
|
189
|
+
|
|
190
|
+
Guards double-destroy, removes request listeners (`ln-toggle:request-open/close/toggle`), removes the instance from the module-level `instances` Set, unbinds the delegated `document` click listener if no instances remain (`_maybeRemoveClickListener`), and deletes `el.lnToggle`. Does **not** remove `data-ln-toggle` or the `.open` class — only the JS coupling is severed; the consumer removes markup state separately if a full teardown is wanted.
|
|
191
|
+
|
|
192
|
+
### What it deliberately does not do
|
|
193
|
+
|
|
194
|
+
No keyboard handling (ESC, Space/Enter on the panel), no outside-click, no focus management, no resize listener. Each is a separate concern owned by a wrapping component: `ln-dropdown` (outside-click/resize), `ln-modal` (focus trap), or project code.
|
|
195
|
+
|
|
196
|
+
### Cross-component contract
|
|
197
|
+
|
|
198
|
+
`ln-accordion` and `ln-dropdown` both reach in only through the public contract — listening for `ln-toggle:open`/`:close`, and writing `data-ln-toggle="..."` directly (never an instance method). `ln-accordion` writes `'close'` on siblings from its wrapper listener; `ln-dropdown` listens on its inner toggle and wires outside-click on `:open`, reverses on `:close`. Because the attribute is the only mutation path, cancelable events and persistence fire identically regardless of which caller changed the state — there is no private mutator to bypass the pipeline.
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
@use '../../
|
|
2
|
-
|
|
3
|
-
[data-ln-debug] {
|
|
4
|
-
// 1. Toggle Panel Missing ID: panels controlled by data-ln-toggle must have an id for triggering/ARIA linking
|
|
5
|
-
[data-ln-toggle]:not([id]) {
|
|
6
|
-
@include dev-dom-error("[data-ln-toggle] is missing a required 'id' attribute for trigger linking.");
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
// 2. Toggle Trigger Empty ID: trigger elements must point to a target panel ID
|
|
10
|
-
[data-ln-toggle-for=""] {
|
|
11
|
-
@include dev-inline-error("data-ln-toggle-for target ID cannot be empty");
|
|
12
|
-
}
|
|
13
|
-
}
|
|
1
|
+
@use '../../theme/config/mixins' as *;
|
|
2
|
+
|
|
3
|
+
[data-ln-debug] {
|
|
4
|
+
// 1. Toggle Panel Missing ID: panels controlled by data-ln-toggle must have an id for triggering/ARIA linking
|
|
5
|
+
[data-ln-toggle]:not([id]) {
|
|
6
|
+
@include dev-dom-error("[data-ln-toggle] is missing a required 'id' attribute for trigger linking.");
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// 2. Toggle Trigger Empty ID: trigger elements must point to a target panel ID
|
|
10
|
+
[data-ln-toggle-for=""] {
|
|
11
|
+
@include dev-inline-error("data-ln-toggle-for target ID cannot be empty");
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(){"use strict";function x(){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 A(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 o=null;for(let l=1;l<t.length;l++)if(t[l]&&t[l].nodeType===1){o=t[l];break}if(!A(o))return}e.apply(console,t)}}function _(e,t,n){const o=n||{};window.lnCore._debugSink&&window.lnCore._debugSink("event",t,e,o),e.dispatchEvent(new CustomEvent(t,{bubbles:!0,detail:o}))}function R(e,t,n){const o=n||{};window.lnCore._debugSink&&window.lnCore._debugSink("event",t,e,o);const l=new CustomEvent(t,{bubbles:!0,cancelable:!0,detail:o});return e.dispatchEvent(l),l}function y(e,t){if(!document.body){document.addEventListener("DOMContentLoaded",function(){y(e,t)}),console.warn("["+t+'] Script loaded before <body> — add "defer" to your <script> tag');return}e()}function H(e){return!!(!e||e.ctrlKey||e.metaKey||e.shiftKey||e.altKey||typeof e.button=="number"&&e.button!==0)}function K(e){return!!(!e||e.disabled||typeof e.getAttribute=="function"&&e.getAttribute("aria-disabled")==="true"||typeof e.closest=="function"&&e.closest("[inert]"))}const I={};function U(e,t){I[e]=t}function Q(e){return I[e]||{ingress:t=>t,egress:t=>t}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerDataMapper=U,window.lnCore.getDataMapper=Q);function G(){typeof window>"u"||(window.lnCore=window.lnCore||{},!window.lnCore._localeObserverBound&&(window.lnCore._localeObserverBound=!0,y(function(){new MutationObserver(function(){_(document,"ln-core:locale-change",{})}).observe(document.documentElement,{attributes:!0,attributeFilter:["lang"],subtree:!0})},"ln-core")))}const D={};function P(e,t){if(!e||typeof t!="object")return;const n=e.toLowerCase().split("-")[0];D[n]=t}function J(e){if(!e)return null;const t=e.toLowerCase().split("-")[0];return D[t]||null}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerLocaleFallback=P,window.lnCore.getLocaleFallback=J,window.lnCore.ensureLocaleObserver=G);const v={};function z(e,t){v[e]||(v[e]=document.querySelector('[data-ln-template="'+e+'"]'));const n=v[e];return n?n.content.cloneNode(!0):(console.warn("["+(t||"ln-core")+'] Template "'+e+'" not found'),null)}function $(e,t){if(!e||!t)return e;const n=e.querySelectorAll("[data-ln-field]");for(let r=0;r<n.length;r++){const u=n[r],s=u.getAttribute("data-ln-field");t[s]!=null&&(u.textContent=t[s])}const o=e.querySelectorAll("[data-ln-attr]");for(let r=0;r<o.length;r++){const u=o[r],s=u.getAttribute("data-ln-attr").split(",");for(let d=0;d<s.length;d++){const f=s[d].trim().split(":");if(f.length!==2)continue;const a=f[0].trim(),b=f[1].trim();t[b]!=null&&u.setAttribute(a,t[b])}}const l=e.querySelectorAll("[data-ln-show]");for(let r=0;r<l.length;r++){const u=l[r],s=u.getAttribute("data-ln-show");s in t&&u.classList.toggle("hidden",!t[s])}const i=e.querySelectorAll("[data-ln-class]");for(let r=0;r<i.length;r++){const u=i[r],s=u.getAttribute("data-ln-class").split(",");for(let d=0;d<s.length;d++){const f=s[d].trim().split(":");if(f.length!==2)continue;const a=f[0].trim(),b=f[1].trim();b in t&&u.classList.toggle(a,!!t[b])}}return e}function X(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 o=0;o<n.length;o++)window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",n[o],t??null),n[o].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)$(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 B(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(r,u){return t[u]!==void 0?t[u]:""}))}const o=function(i,r){return t[r]!==void 0?t[r]:""},l=Array.from(e.querySelectorAll("*"));e.nodeType===1&&l.push(e);for(let i=0;i<l.length;i++){const r=l[i],u=r.attributes;for(let s=0;s<u.length;s++){const d=u[s];d.value.indexOf("{{")!==-1&&r.setAttribute(d.name,d.value.replace(/\{\{\s*(\w+)\s*\}\}/g,o))}}return e}function Y(e,t,n,o,l,i){const r={};for(let s=0;s<e.children.length;s++){const d=e.children[s],f=d.getAttribute("data-ln-render-key");f&&(r[f]=d)}const u=document.createDocumentFragment();for(let s=0;s<t.length;s++){const d=t[s],f=String(o(d));let a=r[f];if(a)l(a,d,s);else{const b=z(n,i);if(!b||(B(b,d),a=b.firstElementChild,!a))continue;a.setAttribute("data-ln-render-key",f),l(a,d,s)}u.appendChild(a)}e.textContent="",e.appendChild(u)}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.fillTemplate=B,window.lnCore.fill=$,window.lnCore.lnFill=X,window.lnCore.renderList=Y);function F(e,t,n,o,l){if(!e||t===null)return!0;const i=o||"ln-component",r=e.type;if(r==="trigger"||r==="marker"||r==="string"||r==="list"||!r||t===""&&e.fallback!==void 0)return!0;const u=s=>{l?console.warn(s,l):console.warn(s)};if(r==="boolean"){const s=t.trim().toLowerCase();return s!==""&&s!=="true"&&s!=="false"&&s!=="1"&&s!=="0"?(u(`[${i}] Invalid value "${t}" for boolean attribute "${n}". Allowed: "true", "false", or presence-only.`),!1):!0}if(r==="enum"){const s=e.values||[];return s.includes(t)?!0:(u(`[${i}] Invalid value "${t}" for attribute "${n}". Allowed: ${s.join(", ")}. Fallback: "${e.fallback}".`),!1)}if(r==="integer"){if(!/^-?\d+$/.test(t))return u(`[${i}] Invalid integer "${t}" for attribute "${n}". Fallback: ${e.fallback}.`),!1;const s=parseInt(t,10);return e.min!==void 0&&s<e.min?(u(`[${i}] Value ${s} for attribute "${n}" is less than min (${e.min}).`),!1):e.max!==void 0&&s>e.max?(u(`[${i}] Value ${s} for attribute "${n}" is greater than max (${e.max}).`),!1):!0}if(r==="float")return isNaN(Number(t))?(u(`[${i}] Invalid float "${t}" for attribute "${n}". Fallback: ${e.fallback}.`),!1):!0;if(r==="json")try{return JSON.parse(t),!0}catch(s){return u(`[${i}] Invalid JSON for attribute "${n}": ${s.message}. Fallback: ${e.fallback}.`),!1}return!0}function Z(e){const t={};for(const n in e){const o=e[n];o&&o.effect&&(t[n]=o.effect)}return Object.keys(t).length?t:null}function ee(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 k(e,t,n,o){if(e.nodeType!==1)return;const i=t.indexOf("[")!==-1||t.indexOf(".")!==-1||t.indexOf("#")!==-1?t:"["+t+"]",r=Array.from(e.querySelectorAll(i));e.matches&&e.matches(i)&&r.push(e);for(const u of r)if(!u[n]){window.lnCore._persistSink&&u.hasAttribute("data-ln-persist")&&window.lnCore._persistSink(u,t);try{u[n]=new o(u)}catch(s){console.error("["+n+"] init failed",u,s)}}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._bootHolds=window.lnCore._bootHolds||0,window.lnCore._bootQueue=window.lnCore._bootQueue||[]);function te(){return typeof window<"u"&&window.lnCore&&window.lnCore._bootHolds||0}function ne(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 M(){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 oe(e){const t=M(),n=e.observed||[];for(let o=0;o<n.length;o++){const l=n[o];t.byAttr.has(l)||t.byAttr.set(l,[]),t.byAttr.get(l).push(e)}if(t.byDeclaredAttr=t.byDeclaredAttr||new Map,e.attributes)for(const o in e.attributes){t.byDeclaredAttr.has(o)||t.byDeclaredAttr.set(o,[]);const l=t.byDeclaredAttr.get(o);l.some(i=>i.componentTag===e.componentTag)||l.push({spec:e.attributes[o],componentTag:e.componentTag})}if(e.onAttrChange||e.effects){t.reactive.push(e);const o=ee(e);if(o===null)t.reactiveWildcard.push(e);else for(const l of o)t.byReactive.has(l)||t.byReactive.set(l,[]),t.byReactive.get(l).push(e)}e.persist&&t.persist.push(e)}function W(e,t,n,o){for(let l=0;l<e.length;l++){const i=e[l];if(!t[i.attribute])continue;const r=i.effects&&i.effects[n];r?r(t,n,o):i.onAttrChange&&(!i.declared||i.declared.has(n))&&i.onAttrChange(t,n,o)}}function re(e){const t=e.target,n=e.attributeName;if(e.oldValue===t.getAttribute(n))return;const o=M(),l=o.byAttr.get(n);if(x()&&o.byDeclaredAttr&&o.byDeclaredAttr.has(n)&&A(t)){const i=o.byDeclaredAttr.get(n),r=t.getAttribute(n);for(let u=0;u<i.length;u++)F(i[u].spec,r,n,i[u].componentTag,t)}if(window.lnCore._debugSink&&(n.indexOf("data-ln-")===0||l)&&window.lnCore._debugSink("attr",n,t,{oldValue:e.oldValue,newValue:t.getAttribute(n)}),n.indexOf("data-ln-")===0){const i=o.byReactive.get(n);i&&W(i,t,n,e.oldValue),o.reactiveWildcard.length&&W(o.reactiveWildcard,t,n,e.oldValue)}if(l)for(let i=0;i<l.length;i++){const r=l[i];if(r.handler){r.handler(t,n,e.oldValue);continue}r.onAttributeChange&&t[r.attribute]?r.onAttributeChange(t,n):(k(t,r.selector,r.attribute,r.ComponentFn),r.onInit&&r.onInit(t))}}function ie(){window.lnCore=window.lnCore||{},!window.lnCore._attrObserverBound&&(window.lnCore._attrObserverBound=!0,y(function(){new MutationObserver(function(t){for(let n=0;n<t.length;n++)try{re(t[n])}catch(o){console.error("[ln-core] mutation handler failed",t[n].target,o)}}).observe(document.body,{attributes:!0,subtree:!0,attributeOldValue:!0})},"ln-core"))}function N(){return window.lnCore=window.lnCore||{},window.lnCore._lifecycleRegistry=window.lnCore._lifecycleRegistry||[]}function le(e){const t=N();if(t.length){if(e.target)for(let n=0;n<t.length;n++){const o=t[n];if(o.onSubtreeChange){const l=o.query,i=e.target.nodeType===1?e.target.matches(l)?e.target:e.target.closest(l):e.target.parentElement?e.target.parentElement.closest(l):null;i&&o.onSubtreeChange(i,e)}}for(let n=0;n<e.addedNodes.length;n++){const o=e.addedNodes[n];if(o.nodeType===1)for(let l=0;l<t.length;l++){const i=t[l];k(o,i.selector,i.attribute,i.ComponentFn),i.onInit&&i.onInit(o)}}for(let n=0;n<e.removedNodes.length;n++){const o=e.removedNodes[n];if(o.nodeType===1)for(let l=0;l<t.length;l++){const i=t[l],r=i.query,u=Array.from(o.querySelectorAll(r));o.matches&&o.matches(r)&&u.push(o);for(let s=0;s<u.length;s++){const d=u[s];if(!document.contains(d)){const f=d[i.attribute];if(f&&typeof f.destroy=="function")try{f.destroy()}catch(a){console.error("["+i.attribute+"] destroy failed",d,a)}delete d[i.attribute]}}}}}}function se(){window.lnCore=window.lnCore||{},!window.lnCore._lifecycleObserverBound&&(window.lnCore._lifecycleObserverBound=!0,y(function(){new MutationObserver(function(t){for(let n=0;n<t.length;n++){const o=t[n];if(o.type==="childList")try{le(o)}catch(l){console.error("[ln-core] lifecycle handler failed",o.target,l)}}}).observe(document.body,{childList:!0,subtree:!0})},"ln-core"))}function ue(e,t,n,o,l={}){const i=l.extraAttributes||[],r=l.onAttributeChange||null,u=l.onSubtreeChange||null,s=l.onInit||null,d=l.onAttrChange||null,f=l.effects||null,a=l.attributes||null,b=a?Z(a):f,c=a?new Set(Object.keys(a)):null,g=l.persist||null;function h(L){const p=L||document.body;if(k(p,e,t,n),a&&x())for(const C in a){const pe=a[C],T=Array.from(p.querySelectorAll("["+C+"]"));p.matches&&p.matches("["+C+"]")&&T.push(p);for(let E=0;E<T.length;E++){const q=T[E];A(q)&&F(pe,q.getAttribute(C),C,o,q)}}s&&s(p)}const w=[];if(e.indexOf("[")!==-1){const L=/\[([\w-]+)/g;let p;for(;(p=L.exec(e))!==null;)w.push(p[1])}else w.push(e);oe({selector:e,attribute:t,componentTag:o,attributes:a,ComponentFn:n,onInit:s,observed:w.concat(i),onAttributeChange:r,onAttrChange:d,effects:b,declared:c,persist:g}),ie();const O=e.indexOf("[")!==-1||e.indexOf(".")!==-1||e.indexOf("#")!==-1?e:"["+e+"]";N().push({selector:e,attribute:t,ComponentFn:n,onInit:s,onSubtreeChange:u,query:O}),se(),window[t]=h;function V(){te()>0?ne(function(){h(document.body)}):h(document.body)}return document.readyState==="loading"?document.addEventListener("DOMContentLoaded",V):V(),h}function j(e){return(e||"").replace(/^#/,"")}function S(e){const t=e===void 0?location.hash:e,n={},o=j(t);if(!o)return n;const l=o.split("&");for(let i=0;i<l.length;i++){const r=l[i];if(!r)continue;const u=r.indexOf(":"),s=u>-1?r.slice(0,u):r,d=u>-1?r.slice(u+1):"";if(s)try{n[s]=decodeURIComponent(d)}catch{n[s]=d}}return n}function ce(e){if(!e)return null;const t=S();return e in t?t[e]:null}function de(e,t){if(!e)return;const n=S();t==null?delete n[e]:n[e]=String(t);const l=Object.keys(n).map(function(i){const r=n[i];return r===""?i:i+":"+encodeURIComponent(r)}).join("&");j(location.hash)!==l&&(location.hash=l)}function ae(e){return e.button===1||e.ctrlKey||e.metaKey||e.shiftKey?!1:(e.preventDefault(),!0)}function fe(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 o=e.getAttribute("data-ln-sort")||e.getAttribute("data-ln-search-for")||e.getAttribute("data-ln-search")||e.getAttribute("data-ln-filter")||e.id;return o?t?o+"-"+t:o:t||null}function ge(e,t){return!t||t==="none"||e===null||e===void 0?null:String(e)+"."+t}function we(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 be(e,t){return!e||!Array.isArray(t)||t.length===0?null:e+":"+t.map(encodeURIComponent).join(",")}function he(e){if(!e||typeof e!="string")return null;const t=e.indexOf(":");if(t===-1)return null;const n=e.slice(0,t),o=e.slice(t+1),l=o?o.split(",").map(function(i){try{return decodeURIComponent(i)}catch{return i}}).filter(Boolean):[];return{key:n,values:l}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.hashParse=S,window.lnCore.hashGet=ce,window.lnCore.hashSet=de,window.lnCore.hashLinkClick=ae,window.lnCore.resolveHashNamespace=fe,window.lnCore.hashSortEncode=ge,window.lnCore.hashSortDecode=we,window.lnCore.hashFilterEncode=be,window.lnCore.hashFilterDecode=he),(function(){const e="data-ln-toggle",t="lnToggle",n="data-ln-toggle-for",o="data-ln-toggle-action";if(window[t]!==void 0)return;const l={"data-ln-toggle":{effect:b,type:"enum",values:["open","close"],fallback:"close",description:"Visibility state of toggleable element"},"data-ln-toggle-for":{type:"string",description:"Target element ID to toggle on trigger click"},"data-ln-toggle-action":{type:"enum",values:["open","close","toggle"],fallback:"toggle",description:"Action performed on target element when trigger is clicked"}},i=new Set;let r=null;function u(c,g){return g==="open"?"open":g==="close"||c==="open"?"close":"open"}function s(){r||(r=function(c){if(H(c))return;const g=c.target.closest("["+n+"]");if(!g||K(g))return;const h=g.getAttribute(n);if(!h)return;const w=document.getElementById(h);if(!w||!w[t])return;c.preventDefault();const m=g.getAttribute(o)||"toggle",O=w.getAttribute(e);w.setAttribute(e,u(O,m))},document.addEventListener("click",r))}function d(){i.size>0||!r||(document.removeEventListener("click",r),r=null)}function f(c,g){if(!c||!c.id)return;const h=document.querySelectorAll("["+n+'="'+c.id+'"]');for(let w=0;w<h.length;w++)h[w].setAttribute("aria-expanded",g?"true":"false")}function a(c){this.dom=c;const g=this;return this._onRequestOpen=function(){g.open()},this._onRequestClose=function(){g.close()},this._onRequestToggle=function(){g.toggle()},this.dom.addEventListener("ln-toggle:request-open",this._onRequestOpen),this.dom.addEventListener("ln-toggle:request-close",this._onRequestClose),this.dom.addEventListener("ln-toggle:request-toggle",this._onRequestToggle),this.isOpen=c.getAttribute(e)==="open",this.isOpen&&c.classList.add("open"),f(c,this.isOpen),i.add(this),s(),this}a.prototype.open=function(){this.dom.setAttribute(e,"open")},a.prototype.close=function(){this.dom.setAttribute(e,"close")},a.prototype.toggle=function(){const c=this.dom.getAttribute(e);this.dom.setAttribute(e,u(c,"toggle"))},a.prototype.destroy=function(){this.dom[t]&&(this.dom.removeEventListener("ln-toggle:request-open",this._onRequestOpen),this.dom.removeEventListener("ln-toggle:request-close",this._onRequestClose),this.dom.removeEventListener("ln-toggle:request-toggle",this._onRequestToggle),i.delete(this),delete this.dom[t],d())};function b(c){const g=c[t];if(!g)return;const w=c.getAttribute(e)==="open";if(w!==g.isOpen)if(w){if(R(c,"ln-toggle:before-open",{target:c}).defaultPrevented){c.setAttribute(e,"close");return}g.isOpen=!0,c.classList.add("open"),f(c,!0),_(c,"ln-toggle:open",{target:c})}else{if(R(c,"ln-toggle:before-close",{target:c}).defaultPrevented){c.setAttribute(e,"open");return}g.isOpen=!1,c.classList.remove("open"),f(c,!1),_(c,"ln-toggle:close",{target:c})}}ue(e,t,a,"ln-toggle",{attributes:l,persist:{attr:e,hashActive:null}})})()})();
|
|
@@ -0,0 +1,52 @@
|
|
|
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-toggle",
|
|
4
|
+
"generator": "scripts/sync-ln-schemas.mjs",
|
|
5
|
+
"attributes": {
|
|
6
|
+
"data-ln-debug": {
|
|
7
|
+
"direction": null,
|
|
8
|
+
"sources": [
|
|
9
|
+
"ln-toggle-dev.scss"
|
|
10
|
+
]
|
|
11
|
+
},
|
|
12
|
+
"data-ln-toggle": {
|
|
13
|
+
"direction": "both",
|
|
14
|
+
"sources": [
|
|
15
|
+
"ln-toggle-dev.scss",
|
|
16
|
+
"ln-toggle.scss",
|
|
17
|
+
"src/ln-toggle.js"
|
|
18
|
+
],
|
|
19
|
+
"type": "enum",
|
|
20
|
+
"values": [
|
|
21
|
+
"open",
|
|
22
|
+
"close"
|
|
23
|
+
],
|
|
24
|
+
"fallback": "close",
|
|
25
|
+
"description": "Visibility state of toggleable element"
|
|
26
|
+
},
|
|
27
|
+
"data-ln-toggle-action": {
|
|
28
|
+
"direction": "author",
|
|
29
|
+
"sources": [
|
|
30
|
+
"src/ln-toggle.js"
|
|
31
|
+
],
|
|
32
|
+
"type": "enum",
|
|
33
|
+
"values": [
|
|
34
|
+
"open",
|
|
35
|
+
"close",
|
|
36
|
+
"toggle"
|
|
37
|
+
],
|
|
38
|
+
"fallback": "toggle",
|
|
39
|
+
"description": "Action performed on target element when trigger is clicked"
|
|
40
|
+
},
|
|
41
|
+
"data-ln-toggle-for": {
|
|
42
|
+
"direction": "author",
|
|
43
|
+
"sources": [
|
|
44
|
+
"ln-toggle-dev.scss",
|
|
45
|
+
"ln-toggle.scss",
|
|
46
|
+
"src/ln-toggle.js"
|
|
47
|
+
],
|
|
48
|
+
"type": "string",
|
|
49
|
+
"description": "Target element ID to toggle on trigger click"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// ==========================================================================
|
|
2
|
+
// ln-toggle — Functional Grid Collapse & Chevron Mechanics
|
|
3
|
+
// ==========================================================================
|
|
4
|
+
|
|
5
|
+
.collapsible {
|
|
6
|
+
display: grid;
|
|
7
|
+
grid-template-rows: 0fr;
|
|
8
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
9
|
+
transition: grid-template-rows 200ms ease;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
&.open,
|
|
13
|
+
&[data-ln-toggle="open"] {
|
|
14
|
+
grid-template-rows: 1fr;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
> * {
|
|
18
|
+
overflow: hidden;
|
|
19
|
+
min-height: 0;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.collapsible-body {
|
|
24
|
+
overflow: hidden;
|
|
25
|
+
min-height: 0;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
[data-ln-toggle-for] .ln-chevron {
|
|
29
|
+
flex-shrink: 0;
|
|
30
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
31
|
+
transition: transform 200ms ease;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
[data-ln-toggle-for][aria-expanded="true"] .ln-chevron {
|
|
36
|
+
transform: rotate(180deg);
|
|
37
|
+
}
|