@livenetworks/ashlar 2.0.7 → 2.0.9
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 -641
- package/components/COMPONENTS.md +1116 -1116
- package/components/index.js +81 -81
- package/components/ln-accordion/ln-accordion-dev.scss +8 -8
- package/components/ln-accordion/ln-accordion.js +1 -1
- package/components/ln-accordion/ln-accordion.schema.json +30 -30
- package/components/ln-ajax/ln-ajax-dev.scss +8 -8
- package/components/ln-ajax/ln-ajax.js +1 -1
- package/components/ln-ajax/ln-ajax.schema.json +30 -30
- package/components/ln-api-connector/ln-api-connector.js +1 -1
- package/components/ln-api-connector/ln-api-connector.schema.json +9 -0
- package/components/ln-api-connector/src/ln-api-connector.js +2 -0
- package/components/ln-api-queue/ln-api-queue.js +1 -1
- package/components/ln-api-queue/ln-api-queue.schema.json +34 -34
- package/components/ln-api-queue/src/ln-api-queue.js +3 -13
- package/components/ln-autoresize/ln-autoresize-dev.scss +8 -8
- package/components/ln-autoresize/ln-autoresize.js +1 -1
- package/components/ln-autoresize/ln-autoresize.schema.json +22 -22
- package/components/ln-autosave/ln-autosave-dev.scss +13 -13
- package/components/ln-autosave/ln-autosave.js +1 -1
- package/components/ln-autosave/ln-autosave.schema.json +48 -48
- package/components/ln-autosave/src/autosave-model.js +34 -34
- package/components/ln-chart/ln-chart.js +1 -1
- package/components/ln-chart/ln-chart.schema.json +146 -146
- package/components/ln-chart/src/chart-model.js +154 -154
- package/components/ln-circular-progress/ln-circular-progress.js +1 -1
- package/components/ln-circular-progress/ln-circular-progress.schema.json +42 -42
- package/components/ln-confirm/ln-confirm-dev.scss +24 -24
- package/components/ln-confirm/ln-confirm.js +1 -1
- package/components/ln-confirm/ln-confirm.schema.json +66 -66
- package/components/ln-confirm/src/ln-confirm.js +178 -178
- package/components/ln-core/attrs.js +13 -0
- package/components/ln-core/crypto.js +286 -265
- package/components/ln-core/dom.js +115 -115
- package/components/ln-core/form.js +146 -136
- package/components/ln-core/helpers.js +33 -33
- package/components/ln-core/http.js +48 -48
- package/components/ln-core/index.js +1 -1
- package/components/ln-core/lifecycle.js +5 -0
- package/components/ln-core/ln-core.schema.json +3 -2
- package/components/ln-core/locale.js +55 -55
- package/components/ln-core/matching.js +78 -78
- package/components/ln-core/number.js +125 -125
- package/components/ln-core/template.js +206 -206
- package/components/ln-couchdb-connector/ln-couchdb-connector.js +1 -1
- package/components/ln-couchdb-connector/ln-couchdb-connector.schema.json +50 -50
- package/components/ln-couchdb-connector/src/ln-couchdb-connector.js +1 -0
- package/components/ln-data-coordinator/README.md +9 -38
- package/components/ln-data-coordinator/ln-data-coordinator-dev.scss +8 -8
- package/components/ln-data-coordinator/ln-data-coordinator.js +1 -1
- package/components/ln-data-coordinator/ln-data-coordinator.schema.json +16 -16
- package/components/ln-data-coordinator/src/data-read-policy.js +0 -7
- package/components/ln-data-coordinator/src/ln-data-coordinator.js +432 -1308
- package/components/ln-data-store/ln-data-store-dev.scss +13 -13
- package/components/ln-data-store/ln-data-store.js +1 -1
- package/components/ln-data-store/ln-data-store.schema.json +84 -84
- package/components/ln-data-store/src/data-store-model.js +184 -184
- package/components/ln-data-store/src/ln-data-store.js +1 -1
- package/components/ln-date/ln-date.js +1 -1
- package/components/ln-date/ln-date.schema.json +92 -92
- package/components/ln-date/src/date-model.js +186 -186
- package/components/ln-debug/ln-debug.js +1 -1
- package/components/ln-debug/ln-debug.schema.json +28 -28
- package/components/ln-debug/src/console-sink.js +19 -19
- package/components/ln-debug/src/gate.js +95 -95
- package/components/ln-debug/src/generated-attributes.js +4 -2
- package/components/ln-dropdown/ln-dropdown-dev.scss +13 -13
- package/components/ln-dropdown/ln-dropdown.js +1 -1
- package/components/ln-dropdown/ln-dropdown.schema.json +90 -90
- package/components/ln-editor/ln-editor.js +1 -1
- package/components/ln-editor/ln-editor.schema.json +58 -58
- package/components/ln-external-links/ln-external-links.js +1 -1
- package/components/ln-external-links/ln-external-links.schema.json +18 -18
- package/components/ln-fill/ln-fill.js +1 -1
- package/components/ln-fill/ln-fill.schema.json +23 -23
- package/components/ln-filter/ln-filter.js +1 -1
- package/components/ln-filter/ln-filter.schema.json +153 -153
- package/components/ln-filter/src/filter-model.js +185 -185
- package/components/ln-form/ln-form-dev.scss +8 -8
- package/components/ln-form/ln-form.js +1 -1
- package/components/ln-form/ln-form.schema.json +6 -0
- package/components/ln-form/src/ln-form.js +21 -0
- package/components/ln-http/ln-http.js +1 -1
- package/components/ln-http/ln-http.schema.json +6 -6
- package/components/ln-icon/ln-icon.schema.json +6 -6
- package/components/ln-include/ln-include.js +1 -1
- package/components/ln-include/ln-include.schema.json +23 -23
- package/components/ln-key/ln-key-dev.scss +18 -18
- package/components/ln-key/ln-key.js +1 -1
- package/components/ln-key/ln-key.schema.json +56 -56
- package/components/ln-key/src/ln-key.js +10 -10
- package/components/ln-link/ln-link-dev.scss +8 -8
- package/components/ln-link/ln-link.js +1 -1
- package/components/ln-link/ln-link.schema.json +22 -22
- package/components/ln-list/README.md +152 -152
- package/components/ln-list/ln-list-dev.scss +8 -8
- package/components/ln-list/ln-list.js +1 -1
- package/components/ln-list/ln-list.schema.json +166 -166
- package/components/ln-modal/ln-modal.js +1 -1
- package/components/ln-modal/ln-modal.schema.json +65 -65
- package/components/ln-nav/ln-nav.js +1 -1
- package/components/ln-nav/ln-nav.schema.json +25 -25
- package/components/ln-number/ln-number.js +1 -1
- package/components/ln-number/ln-number.schema.json +63 -63
- package/components/ln-number/src/ln-number.js +26 -0
- package/components/ln-number/src/number-model.js +31 -31
- package/components/ln-obfuscator/README.md +60 -60
- package/components/ln-obfuscator/ln-obfuscator.js +1 -1
- package/components/ln-obfuscator/ln-obfuscator.schema.json +49 -49
- package/components/ln-obfuscator/src/ln-obfuscator.js +159 -159
- package/components/ln-obfuscator/src/obfuscator-model.js +250 -250
- package/components/ln-options/ln-options.js +1 -1
- package/components/ln-options/ln-options.schema.json +6 -0
- package/components/ln-options/src/ln-options.js +4 -4
- package/components/ln-persist/README.md +151 -151
- package/components/ln-persist/ln-persist.js +1 -1
- package/components/ln-persist/ln-persist.schema.json +28 -28
- package/components/ln-persist/src/ln-persist.js +83 -83
- package/components/ln-picklist/README.md +230 -230
- package/components/ln-picklist/ln-picklist-dev.scss +22 -22
- package/components/ln-picklist/ln-picklist.js +1 -1
- package/components/ln-picklist/ln-picklist.schema.json +49 -49
- package/components/ln-picklist/src/ln-picklist.js +228 -228
- package/components/ln-popover/ln-popover-dev.scss +13 -13
- package/components/ln-popover/ln-popover.js +1 -1
- package/components/ln-popover/ln-popover.schema.json +82 -82
- package/components/ln-progress/ln-progress-dev.scss +8 -8
- package/components/ln-progress/ln-progress.js +1 -1
- package/components/ln-progress/ln-progress.schema.json +40 -40
- package/components/ln-router/ln-router.js +1 -1
- package/components/ln-router/ln-router.schema.json +76 -76
- package/components/ln-scroll/README.md +45 -45
- package/components/ln-scroll/ln-scroll.js +1 -1
- package/components/ln-scroll/ln-scroll.schema.json +85 -85
- package/components/ln-scroll/src/ln-scroll.js +150 -150
- package/components/ln-search/README.md +188 -188
- package/components/ln-search/ln-search.js +1 -1
- package/components/ln-search/ln-search.schema.json +103 -103
- package/components/ln-slug/ln-slug.js +1 -1
- package/components/ln-slug/ln-slug.schema.json +23 -23
- package/components/ln-slug/src/ln-slug.js +25 -1
- package/components/ln-sort/ln-sort.js +1 -1
- package/components/ln-sort/ln-sort.schema.json +104 -104
- package/components/ln-sort/src/ln-sort.js +321 -321
- package/components/ln-sort/src/sort-model.js +117 -117
- package/components/ln-sortable/ln-sortable-dev.scss +13 -13
- package/components/ln-sortable/ln-sortable.js +1 -1
- package/components/ln-sortable/ln-sortable.schema.json +36 -36
- package/components/ln-stat/ln-stat-dev.scss +8 -8
- package/components/ln-stat/ln-stat.js +1 -1
- package/components/ln-stat/ln-stat.schema.json +32 -32
- package/components/ln-stat/src/stat-model.js +28 -28
- package/components/ln-table/ln-table.js +1 -1
- package/components/ln-table/ln-table.schema.json +211 -211
- package/components/ln-table/src/table-model.js +98 -98
- package/components/ln-table-coordinator/ln-table-coordinator.js +1 -1
- package/components/ln-table-coordinator/ln-table-coordinator.schema.json +93 -93
- package/components/ln-tabs/ln-tabs.js +1 -1
- package/components/ln-tabs/ln-tabs.schema.json +75 -75
- package/components/ln-tabs/src/ln-tabs.js +208 -208
- package/components/ln-tabs/src/tabs-model.js +82 -82
- package/components/ln-time/ln-time-dev.scss +13 -13
- package/components/ln-time/ln-time.js +1 -1
- package/components/ln-time/ln-time.schema.json +38 -38
- package/components/ln-toast/ln-toast.js +1 -1
- package/components/ln-toast/ln-toast.schema.json +65 -65
- package/components/ln-toggle/ln-toggle.js +1 -1
- package/components/ln-toggle/ln-toggle.schema.json +52 -52
- package/components/ln-tooltip/ln-tooltip.js +1 -1
- package/components/ln-tooltip/ln-tooltip.schema.json +86 -86
- package/components/ln-translations/ln-translations.js +1 -1
- package/components/ln-translations/ln-translations.schema.json +120 -120
- package/components/ln-ui-coordinator/README.md +62 -62
- package/components/ln-ui-coordinator/ln-ui-coordinator.js +1 -1
- package/components/ln-ui-coordinator/ln-ui-coordinator.schema.json +28 -28
- package/components/ln-ui-coordinator/src/ln-ui-coordinator.js +140 -140
- package/components/ln-upload/ln-upload.js +1 -1
- package/components/ln-upload/ln-upload.schema.json +193 -193
- package/components/ln-upload/src/upload-model.js +78 -78
- package/components/ln-validate/ln-validate.js +1 -1
- package/components/ln-validate/ln-validate.schema.json +50 -50
- package/components/ln-validate/src/validate-model.js +64 -64
- package/components/ln-websocket-connector/README.md +166 -166
- package/components/ln-websocket-connector/ln-websocket-connector.js +1 -1
- package/components/ln-websocket-connector/ln-websocket-connector.schema.json +29 -29
- package/components/ln-websocket-connector/src/ln-websocket-connector.js +283 -279
- package/ln-ashlar.html-data.json +15 -8
- package/package.json +85 -84
- package/theme/brand.css +73 -73
- package/theme/components/_confirm.scss +6 -6
- package/theme/components/_picklist.scss +3 -3
- package/theme/config/_palette.scss +274 -274
- package/theme/config/_theme.scss +292 -292
- package/theme/config/_tokens.scss +285 -285
- package/theme/config/mixins/_index.scss +62 -62
- package/theme/config/mixins/_picklist.scss +66 -66
- package/theme/ln-ashlar-dev.scss +66 -66
- package/theme/ln-ashlar-landing.scss +56 -56
- package/theme/ln-ashlar-theme.scss +63 -63
- package/theme/presentation/_bento.scss +151 -151
- package/theme/presentation/_cta.scss +111 -111
- package/theme/presentation/_effects.scss +216 -216
- package/theme/presentation/_features.scss +108 -108
- package/theme/presentation/_footer.scss +129 -129
- package/theme/presentation/_hero.scss +158 -158
- package/theme/presentation/_layout.scss +170 -170
- package/theme/presentation/_navbar.scss +140 -140
- package/theme/presentation/_pricing.scss +262 -262
- package/theme/presentation/_stats.scss +87 -87
- package/theme/presentation/_testimonials.scss +124 -124
- package/theme/presentation/_tokens.scss +39 -39
- package/theme/presentation/_typography.scss +163 -163
- package/web-types.json +26 -12
|
@@ -1,85 +1,85 @@
|
|
|
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-scroll",
|
|
4
|
-
"generator": "scripts/sync-ln-schemas.mjs",
|
|
5
|
-
"attributes": {
|
|
6
|
-
"data-ln-scroll": {
|
|
7
|
-
"direction": "author",
|
|
8
|
-
"sources": [
|
|
9
|
-
"src/ln-scroll.js"
|
|
10
|
-
],
|
|
11
|
-
"type": "string",
|
|
12
|
-
"description": "Target element ID or CSS selector to scroll into view"
|
|
13
|
-
},
|
|
14
|
-
"data-ln-scroll-behavior": {
|
|
15
|
-
"direction": "author",
|
|
16
|
-
"sources": [
|
|
17
|
-
"src/ln-scroll.js"
|
|
18
|
-
],
|
|
19
|
-
"type": "enum",
|
|
20
|
-
"values": [
|
|
21
|
-
"smooth",
|
|
22
|
-
"auto"
|
|
23
|
-
],
|
|
24
|
-
"fallback": "smooth",
|
|
25
|
-
"description": "Scroll animation behavior transition"
|
|
26
|
-
},
|
|
27
|
-
"data-ln-scroll-block": {
|
|
28
|
-
"direction": "author",
|
|
29
|
-
"sources": [
|
|
30
|
-
"src/ln-scroll.js"
|
|
31
|
-
],
|
|
32
|
-
"type": "enum",
|
|
33
|
-
"values": [
|
|
34
|
-
"start",
|
|
35
|
-
"center",
|
|
36
|
-
"end",
|
|
37
|
-
"nearest"
|
|
38
|
-
],
|
|
39
|
-
"fallback": "start",
|
|
40
|
-
"description": "Vertical alignment positioning of scrolled target"
|
|
41
|
-
},
|
|
42
|
-
"data-ln-scroll-delay": {
|
|
43
|
-
"direction": "author",
|
|
44
|
-
"sources": [
|
|
45
|
-
"src/ln-scroll.js"
|
|
46
|
-
],
|
|
47
|
-
"type": "integer",
|
|
48
|
-
"fallback": 450,
|
|
49
|
-
"min": 0,
|
|
50
|
-
"description": "Delay in milliseconds before shifting keyboard focus"
|
|
51
|
-
},
|
|
52
|
-
"data-ln-scroll-focus": {
|
|
53
|
-
"direction": "author",
|
|
54
|
-
"sources": [
|
|
55
|
-
"src/ln-scroll.js"
|
|
56
|
-
],
|
|
57
|
-
"type": "string",
|
|
58
|
-
"fallback": true,
|
|
59
|
-
"description": "CSS selector of element to focus after scroll, or "
|
|
60
|
-
},
|
|
61
|
-
"data-ln-scroll-set": {
|
|
62
|
-
"direction": "author",
|
|
63
|
-
"sources": [
|
|
64
|
-
"src/ln-scroll.js"
|
|
65
|
-
],
|
|
66
|
-
"type": "string",
|
|
67
|
-
"description": "Optional state attribute assignment on target after scroll (e.g. data-ln-toggle=open)"
|
|
68
|
-
},
|
|
69
|
-
"data-ln-scroll-update-hash": {
|
|
70
|
-
"direction": null,
|
|
71
|
-
"sources": [
|
|
72
|
-
"src/ln-scroll.js"
|
|
73
|
-
],
|
|
74
|
-
"type": "boolean",
|
|
75
|
-
"fallback": false,
|
|
76
|
-
"description": "Whether to update URL hash with target ID"
|
|
77
|
-
},
|
|
78
|
-
"data-ln-toggle": {
|
|
79
|
-
"direction": null,
|
|
80
|
-
"sources": [
|
|
81
|
-
"src/ln-scroll.js"
|
|
82
|
-
]
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
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-scroll",
|
|
4
|
+
"generator": "scripts/sync-ln-schemas.mjs",
|
|
5
|
+
"attributes": {
|
|
6
|
+
"data-ln-scroll": {
|
|
7
|
+
"direction": "author",
|
|
8
|
+
"sources": [
|
|
9
|
+
"src/ln-scroll.js"
|
|
10
|
+
],
|
|
11
|
+
"type": "string",
|
|
12
|
+
"description": "Target element ID or CSS selector to scroll into view"
|
|
13
|
+
},
|
|
14
|
+
"data-ln-scroll-behavior": {
|
|
15
|
+
"direction": "author",
|
|
16
|
+
"sources": [
|
|
17
|
+
"src/ln-scroll.js"
|
|
18
|
+
],
|
|
19
|
+
"type": "enum",
|
|
20
|
+
"values": [
|
|
21
|
+
"smooth",
|
|
22
|
+
"auto"
|
|
23
|
+
],
|
|
24
|
+
"fallback": "smooth",
|
|
25
|
+
"description": "Scroll animation behavior transition"
|
|
26
|
+
},
|
|
27
|
+
"data-ln-scroll-block": {
|
|
28
|
+
"direction": "author",
|
|
29
|
+
"sources": [
|
|
30
|
+
"src/ln-scroll.js"
|
|
31
|
+
],
|
|
32
|
+
"type": "enum",
|
|
33
|
+
"values": [
|
|
34
|
+
"start",
|
|
35
|
+
"center",
|
|
36
|
+
"end",
|
|
37
|
+
"nearest"
|
|
38
|
+
],
|
|
39
|
+
"fallback": "start",
|
|
40
|
+
"description": "Vertical alignment positioning of scrolled target"
|
|
41
|
+
},
|
|
42
|
+
"data-ln-scroll-delay": {
|
|
43
|
+
"direction": "author",
|
|
44
|
+
"sources": [
|
|
45
|
+
"src/ln-scroll.js"
|
|
46
|
+
],
|
|
47
|
+
"type": "integer",
|
|
48
|
+
"fallback": 450,
|
|
49
|
+
"min": 0,
|
|
50
|
+
"description": "Delay in milliseconds before shifting keyboard focus"
|
|
51
|
+
},
|
|
52
|
+
"data-ln-scroll-focus": {
|
|
53
|
+
"direction": "author",
|
|
54
|
+
"sources": [
|
|
55
|
+
"src/ln-scroll.js"
|
|
56
|
+
],
|
|
57
|
+
"type": "string",
|
|
58
|
+
"fallback": true,
|
|
59
|
+
"description": "CSS selector of element to focus after scroll, or "
|
|
60
|
+
},
|
|
61
|
+
"data-ln-scroll-set": {
|
|
62
|
+
"direction": "author",
|
|
63
|
+
"sources": [
|
|
64
|
+
"src/ln-scroll.js"
|
|
65
|
+
],
|
|
66
|
+
"type": "string",
|
|
67
|
+
"description": "Optional state attribute assignment on target after scroll (e.g. data-ln-toggle=open)"
|
|
68
|
+
},
|
|
69
|
+
"data-ln-scroll-update-hash": {
|
|
70
|
+
"direction": null,
|
|
71
|
+
"sources": [
|
|
72
|
+
"src/ln-scroll.js"
|
|
73
|
+
],
|
|
74
|
+
"type": "boolean",
|
|
75
|
+
"fallback": false,
|
|
76
|
+
"description": "Whether to update URL hash with target ID"
|
|
77
|
+
},
|
|
78
|
+
"data-ln-toggle": {
|
|
79
|
+
"direction": null,
|
|
80
|
+
"sources": [
|
|
81
|
+
"src/ln-scroll.js"
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -1,150 +1,150 @@
|
|
|
1
|
-
import { dispatch, dispatchCancelable, registerComponent, attrBool } from '../../ln-core';
|
|
2
|
-
|
|
3
|
-
(function () {
|
|
4
|
-
const DOM_SELECTOR = 'data-ln-scroll';
|
|
5
|
-
const DOM_ATTRIBUTE = 'lnScroll';
|
|
6
|
-
|
|
7
|
-
if (window[DOM_ATTRIBUTE] !== undefined) return;
|
|
8
|
-
|
|
9
|
-
// ─── Attribute Contract (SSOT) ──────────────────────────
|
|
10
|
-
const ATTRIBUTES = {
|
|
11
|
-
'data-ln-scroll': { effect: null, type: 'string', description: 'Target element ID or CSS selector to scroll into view' },
|
|
12
|
-
'data-ln-scroll-behavior': { effect: null, type: 'enum', values: ['smooth', 'auto'], fallback: 'smooth', description: 'Scroll animation behavior transition' },
|
|
13
|
-
'data-ln-scroll-block': { effect: null, type: 'enum', values: ['start', 'center', 'end', 'nearest'], fallback: 'start', description: 'Vertical alignment positioning of scrolled target' },
|
|
14
|
-
'data-ln-scroll-set': { effect: null, type: 'string', description: 'Optional state attribute assignment on target after scroll (e.g. data-ln-toggle=open)' },
|
|
15
|
-
'data-ln-scroll-focus': { effect: null, type: 'string', description: 'CSS selector of element to focus after scroll, or "false" to disable' },
|
|
16
|
-
'data-ln-scroll-delay': { effect: null, type: 'integer', fallback: 450, min: 0, description: 'Delay in milliseconds before shifting keyboard focus' },
|
|
17
|
-
'data-ln-scroll-update-hash': { effect: null, type: 'boolean', fallback: false, description: 'Whether to update URL hash with target ID' }
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
// ─── Component Constructor ───────────────────────────────
|
|
21
|
-
function _component(dom) {
|
|
22
|
-
if (dom[DOM_ATTRIBUTE]) return dom[DOM_ATTRIBUTE];
|
|
23
|
-
// Allow both <a> and <button> elements
|
|
24
|
-
if (!dom || (dom.tagName !== 'A' && dom.tagName !== 'BUTTON')) return;
|
|
25
|
-
|
|
26
|
-
dom[DOM_ATTRIBUTE] = this;
|
|
27
|
-
this.dom = dom;
|
|
28
|
-
this._handleClick = this._handleClick.bind(this);
|
|
29
|
-
this.dom.addEventListener('click', this._handleClick);
|
|
30
|
-
|
|
31
|
-
return this;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// ─── Click & Smooth Scroll Handler ───────────────────────
|
|
35
|
-
_component.prototype._handleClick = function (e) {
|
|
36
|
-
// Allow native navigation if modifier keys are pressed on <a> links
|
|
37
|
-
if (this.dom.tagName === 'A' && (e.ctrlKey || e.metaKey || e.shiftKey || e.altKey || e.button !== 0)) {
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// Target resolution: data-ln-scroll="#apply" takes priority, falls back to href
|
|
42
|
-
let targetSelector = (this.dom.getAttribute('data-ln-scroll') || '').trim();
|
|
43
|
-
if (!targetSelector) {
|
|
44
|
-
targetSelector = (this.dom.getAttribute('href') || '').trim();
|
|
45
|
-
}
|
|
46
|
-
if (!targetSelector || targetSelector === '#') {
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
// If provided as a raw ID without '#', normalize to ID selector
|
|
50
|
-
if (!targetSelector.startsWith('#') && !targetSelector.startsWith('.') && !targetSelector.startsWith('[')) {
|
|
51
|
-
targetSelector = '#' + targetSelector;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
let targetEl = null;
|
|
55
|
-
try {
|
|
56
|
-
targetEl = document.querySelector(targetSelector);
|
|
57
|
-
} catch (_) {
|
|
58
|
-
const id = targetSelector.replace(/^#/, '');
|
|
59
|
-
targetEl = document.getElementById(id);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
if (!targetEl) return;
|
|
63
|
-
|
|
64
|
-
e.preventDefault();
|
|
65
|
-
|
|
66
|
-
// Optional field preset: selector:value (e.g. data-ln-scroll-set="#opportunity_type:Company Driver")
|
|
67
|
-
const setAttr = this.dom.getAttribute('data-ln-scroll-set');
|
|
68
|
-
if (setAttr) {
|
|
69
|
-
const colonIdx = setAttr.indexOf(':');
|
|
70
|
-
if (colonIdx !== -1) {
|
|
71
|
-
const selector = setAttr.slice(0, colonIdx).trim();
|
|
72
|
-
const val = setAttr.slice(colonIdx + 1).trim();
|
|
73
|
-
try {
|
|
74
|
-
const field = document.querySelector(selector);
|
|
75
|
-
if (field) {
|
|
76
|
-
field.value = val;
|
|
77
|
-
field.dispatchEvent(new Event('input', { bubbles: true }));
|
|
78
|
-
field.dispatchEvent(new Event('change', { bubbles: true }));
|
|
79
|
-
}
|
|
80
|
-
} catch (_) {}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Dispatch cancelable before-scroll event
|
|
85
|
-
const beforeEvent = dispatchCancelable(this.dom, 'ln-scroll:before-scroll', {
|
|
86
|
-
target: targetEl,
|
|
87
|
-
link: this.dom,
|
|
88
|
-
href: targetSelector
|
|
89
|
-
});
|
|
90
|
-
if (beforeEvent.defaultPrevented) return;
|
|
91
|
-
|
|
92
|
-
// Perform smooth scroll
|
|
93
|
-
const behavior = this.dom.getAttribute('data-ln-scroll-behavior') || 'smooth';
|
|
94
|
-
const block = this.dom.getAttribute('data-ln-scroll-block') || 'start';
|
|
95
|
-
targetEl.scrollIntoView({ behavior: behavior, block: block });
|
|
96
|
-
|
|
97
|
-
// Optional URL hash update
|
|
98
|
-
const updateHash = attrBool(this.dom, 'data-ln-scroll-update-hash', false);
|
|
99
|
-
if (updateHash) {
|
|
100
|
-
try {
|
|
101
|
-
if (window.history && window.history.pushState) {
|
|
102
|
-
window.history.pushState(null, '', targetSelector);
|
|
103
|
-
}
|
|
104
|
-
} catch (_) {}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// Shift focus after scrolling to preserve keyboard flow
|
|
108
|
-
const focusTargetAttr = this.dom.getAttribute('data-ln-scroll-focus');
|
|
109
|
-
if (focusTargetAttr !== 'false' && focusTargetAttr !== '0') {
|
|
110
|
-
const rawDelay = parseInt(this.dom.getAttribute('data-ln-scroll-delay'), 10);
|
|
111
|
-
const delay = isNaN(rawDelay) ? 450 : rawDelay;
|
|
112
|
-
|
|
113
|
-
window.setTimeout(function () {
|
|
114
|
-
let focusEl = null;
|
|
115
|
-
if (focusTargetAttr && focusTargetAttr !== 'true' && focusTargetAttr !== '1') {
|
|
116
|
-
try {
|
|
117
|
-
focusEl = document.querySelector(focusTargetAttr);
|
|
118
|
-
} catch (_) {}
|
|
119
|
-
}
|
|
120
|
-
if (!focusEl) {
|
|
121
|
-
focusEl = targetEl.querySelector('input:not([type="hidden"]):not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), [tabindex]:not([tabindex="-1"])');
|
|
122
|
-
}
|
|
123
|
-
if (!focusEl && targetEl.getAttribute('tabindex') !== null) {
|
|
124
|
-
focusEl = targetEl;
|
|
125
|
-
}
|
|
126
|
-
if (focusEl && typeof focusEl.focus === 'function') {
|
|
127
|
-
focusEl.focus({ preventScroll: true });
|
|
128
|
-
}
|
|
129
|
-
}, delay);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// Dispatch post-scroll event
|
|
133
|
-
dispatch(this.dom, 'ln-scroll:scrolled', {
|
|
134
|
-
target: targetEl,
|
|
135
|
-
link: this.dom,
|
|
136
|
-
href: targetSelector
|
|
137
|
-
});
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
_component.prototype.destroy = function () {
|
|
141
|
-
if (!this.dom[DOM_ATTRIBUTE]) return;
|
|
142
|
-
this.dom.removeEventListener('click', this._handleClick);
|
|
143
|
-
delete this.dom[DOM_ATTRIBUTE];
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
// ─── Registration ─────────────────────────────────────────
|
|
147
|
-
registerComponent(DOM_SELECTOR, DOM_ATTRIBUTE, _component, 'ln-scroll', {
|
|
148
|
-
attributes: ATTRIBUTES
|
|
149
|
-
});
|
|
150
|
-
})();
|
|
1
|
+
import { dispatch, dispatchCancelable, registerComponent, attrBool } from '../../ln-core';
|
|
2
|
+
|
|
3
|
+
(function () {
|
|
4
|
+
const DOM_SELECTOR = 'data-ln-scroll';
|
|
5
|
+
const DOM_ATTRIBUTE = 'lnScroll';
|
|
6
|
+
|
|
7
|
+
if (window[DOM_ATTRIBUTE] !== undefined) return;
|
|
8
|
+
|
|
9
|
+
// ─── Attribute Contract (SSOT) ──────────────────────────
|
|
10
|
+
const ATTRIBUTES = {
|
|
11
|
+
'data-ln-scroll': { effect: null, type: 'string', description: 'Target element ID or CSS selector to scroll into view' },
|
|
12
|
+
'data-ln-scroll-behavior': { effect: null, type: 'enum', values: ['smooth', 'auto'], fallback: 'smooth', description: 'Scroll animation behavior transition' },
|
|
13
|
+
'data-ln-scroll-block': { effect: null, type: 'enum', values: ['start', 'center', 'end', 'nearest'], fallback: 'start', description: 'Vertical alignment positioning of scrolled target' },
|
|
14
|
+
'data-ln-scroll-set': { effect: null, type: 'string', description: 'Optional state attribute assignment on target after scroll (e.g. data-ln-toggle=open)' },
|
|
15
|
+
'data-ln-scroll-focus': { effect: null, type: 'string', description: 'CSS selector of element to focus after scroll, or "false" to disable' },
|
|
16
|
+
'data-ln-scroll-delay': { effect: null, type: 'integer', fallback: 450, min: 0, description: 'Delay in milliseconds before shifting keyboard focus' },
|
|
17
|
+
'data-ln-scroll-update-hash': { effect: null, type: 'boolean', fallback: false, description: 'Whether to update URL hash with target ID' }
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
// ─── Component Constructor ───────────────────────────────
|
|
21
|
+
function _component(dom) {
|
|
22
|
+
if (dom[DOM_ATTRIBUTE]) return dom[DOM_ATTRIBUTE];
|
|
23
|
+
// Allow both <a> and <button> elements
|
|
24
|
+
if (!dom || (dom.tagName !== 'A' && dom.tagName !== 'BUTTON')) return;
|
|
25
|
+
|
|
26
|
+
dom[DOM_ATTRIBUTE] = this;
|
|
27
|
+
this.dom = dom;
|
|
28
|
+
this._handleClick = this._handleClick.bind(this);
|
|
29
|
+
this.dom.addEventListener('click', this._handleClick);
|
|
30
|
+
|
|
31
|
+
return this;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// ─── Click & Smooth Scroll Handler ───────────────────────
|
|
35
|
+
_component.prototype._handleClick = function (e) {
|
|
36
|
+
// Allow native navigation if modifier keys are pressed on <a> links
|
|
37
|
+
if (this.dom.tagName === 'A' && (e.ctrlKey || e.metaKey || e.shiftKey || e.altKey || e.button !== 0)) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Target resolution: data-ln-scroll="#apply" takes priority, falls back to href
|
|
42
|
+
let targetSelector = (this.dom.getAttribute('data-ln-scroll') || '').trim();
|
|
43
|
+
if (!targetSelector) {
|
|
44
|
+
targetSelector = (this.dom.getAttribute('href') || '').trim();
|
|
45
|
+
}
|
|
46
|
+
if (!targetSelector || targetSelector === '#') {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
// If provided as a raw ID without '#', normalize to ID selector
|
|
50
|
+
if (!targetSelector.startsWith('#') && !targetSelector.startsWith('.') && !targetSelector.startsWith('[')) {
|
|
51
|
+
targetSelector = '#' + targetSelector;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
let targetEl = null;
|
|
55
|
+
try {
|
|
56
|
+
targetEl = document.querySelector(targetSelector);
|
|
57
|
+
} catch (_) {
|
|
58
|
+
const id = targetSelector.replace(/^#/, '');
|
|
59
|
+
targetEl = document.getElementById(id);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (!targetEl) return;
|
|
63
|
+
|
|
64
|
+
e.preventDefault();
|
|
65
|
+
|
|
66
|
+
// Optional field preset: selector:value (e.g. data-ln-scroll-set="#opportunity_type:Company Driver")
|
|
67
|
+
const setAttr = this.dom.getAttribute('data-ln-scroll-set');
|
|
68
|
+
if (setAttr) {
|
|
69
|
+
const colonIdx = setAttr.indexOf(':');
|
|
70
|
+
if (colonIdx !== -1) {
|
|
71
|
+
const selector = setAttr.slice(0, colonIdx).trim();
|
|
72
|
+
const val = setAttr.slice(colonIdx + 1).trim();
|
|
73
|
+
try {
|
|
74
|
+
const field = document.querySelector(selector);
|
|
75
|
+
if (field) {
|
|
76
|
+
field.value = val;
|
|
77
|
+
field.dispatchEvent(new Event('input', { bubbles: true }));
|
|
78
|
+
field.dispatchEvent(new Event('change', { bubbles: true }));
|
|
79
|
+
}
|
|
80
|
+
} catch (_) {}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Dispatch cancelable before-scroll event
|
|
85
|
+
const beforeEvent = dispatchCancelable(this.dom, 'ln-scroll:before-scroll', {
|
|
86
|
+
target: targetEl,
|
|
87
|
+
link: this.dom,
|
|
88
|
+
href: targetSelector
|
|
89
|
+
});
|
|
90
|
+
if (beforeEvent.defaultPrevented) return;
|
|
91
|
+
|
|
92
|
+
// Perform smooth scroll
|
|
93
|
+
const behavior = this.dom.getAttribute('data-ln-scroll-behavior') || 'smooth';
|
|
94
|
+
const block = this.dom.getAttribute('data-ln-scroll-block') || 'start';
|
|
95
|
+
targetEl.scrollIntoView({ behavior: behavior, block: block });
|
|
96
|
+
|
|
97
|
+
// Optional URL hash update
|
|
98
|
+
const updateHash = attrBool(this.dom, 'data-ln-scroll-update-hash', false);
|
|
99
|
+
if (updateHash) {
|
|
100
|
+
try {
|
|
101
|
+
if (window.history && window.history.pushState) {
|
|
102
|
+
window.history.pushState(null, '', targetSelector);
|
|
103
|
+
}
|
|
104
|
+
} catch (_) {}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Shift focus after scrolling to preserve keyboard flow
|
|
108
|
+
const focusTargetAttr = this.dom.getAttribute('data-ln-scroll-focus');
|
|
109
|
+
if (focusTargetAttr !== 'false' && focusTargetAttr !== '0') {
|
|
110
|
+
const rawDelay = parseInt(this.dom.getAttribute('data-ln-scroll-delay'), 10);
|
|
111
|
+
const delay = isNaN(rawDelay) ? 450 : rawDelay;
|
|
112
|
+
|
|
113
|
+
window.setTimeout(function () {
|
|
114
|
+
let focusEl = null;
|
|
115
|
+
if (focusTargetAttr && focusTargetAttr !== 'true' && focusTargetAttr !== '1') {
|
|
116
|
+
try {
|
|
117
|
+
focusEl = document.querySelector(focusTargetAttr);
|
|
118
|
+
} catch (_) {}
|
|
119
|
+
}
|
|
120
|
+
if (!focusEl) {
|
|
121
|
+
focusEl = targetEl.querySelector('input:not([type="hidden"]):not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), [tabindex]:not([tabindex="-1"])');
|
|
122
|
+
}
|
|
123
|
+
if (!focusEl && targetEl.getAttribute('tabindex') !== null) {
|
|
124
|
+
focusEl = targetEl;
|
|
125
|
+
}
|
|
126
|
+
if (focusEl && typeof focusEl.focus === 'function') {
|
|
127
|
+
focusEl.focus({ preventScroll: true });
|
|
128
|
+
}
|
|
129
|
+
}, delay);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Dispatch post-scroll event
|
|
133
|
+
dispatch(this.dom, 'ln-scroll:scrolled', {
|
|
134
|
+
target: targetEl,
|
|
135
|
+
link: this.dom,
|
|
136
|
+
href: targetSelector
|
|
137
|
+
});
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
_component.prototype.destroy = function () {
|
|
141
|
+
if (!this.dom[DOM_ATTRIBUTE]) return;
|
|
142
|
+
this.dom.removeEventListener('click', this._handleClick);
|
|
143
|
+
delete this.dom[DOM_ATTRIBUTE];
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
// ─── Registration ─────────────────────────────────────────
|
|
147
|
+
registerComponent(DOM_SELECTOR, DOM_ATTRIBUTE, _component, 'ln-scroll', {
|
|
148
|
+
attributes: ATTRIBUTES
|
|
149
|
+
});
|
|
150
|
+
})();
|