@stackoverflow/stacks 1.10.3 → 2.0.0-rc.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.
Files changed (90) hide show
  1. package/README.md +15 -0
  2. package/dist/css/stacks.css +7428 -4429
  3. package/dist/css/stacks.min.css +1 -1
  4. package/dist/js/stacks.js +110 -265
  5. package/dist/js/stacks.min.js +1 -1
  6. package/lib/atomic/__snapshots__/color-new.less.test.ts.snap +3015 -0
  7. package/lib/atomic/__snapshots__/color.less.test.ts.snap +2886 -0
  8. package/lib/atomic/border.less +0 -258
  9. package/lib/atomic/color.less +26 -200
  10. package/lib/atomic/color.less.test.ts +12 -0
  11. package/lib/atomic/misc.less +7 -6
  12. package/lib/atomic/typography.less +0 -7
  13. package/lib/atomic/v1/__snapshots__/border.less.test.ts.snap +552 -0
  14. package/lib/atomic/v1/__snapshots__/color.less.test.ts.snap +6756 -0
  15. package/lib/atomic/v1/__snapshots__/typography.less.test.ts.snap +22 -0
  16. package/lib/atomic/v1/border.less +210 -0
  17. package/lib/atomic/v1/border.less.test.ts +14 -0
  18. package/lib/atomic/v1/color.less +183 -0
  19. package/lib/atomic/v1/color.less.test.ts +14 -0
  20. package/lib/atomic/v1/typography.less +8 -0
  21. package/lib/atomic/v1/typography.less.test.ts +14 -0
  22. package/lib/components/activity-indicator/activity-indicator.a11y.test.ts +1 -10
  23. package/lib/components/activity-indicator/activity-indicator.less +4 -4
  24. package/lib/components/anchor/anchor.a11y.test.ts +0 -12
  25. package/lib/components/anchor/anchor.less +4 -4
  26. package/lib/components/anchor/anchor.visual.test.ts +1 -1
  27. package/lib/components/avatar/avatar.less +2 -2
  28. package/lib/components/award-bling/award-bling.less +3 -3
  29. package/lib/components/badge/badge.a11y.test.ts +2 -51
  30. package/lib/components/badge/badge.less +40 -40
  31. package/lib/components/banner/banner.a11y.test.ts +0 -14
  32. package/lib/components/block-link/block-link.a11y.test.ts +0 -14
  33. package/lib/components/block-link/block-link.less +8 -8
  34. package/lib/components/breadcrumbs/breadcrumbs.a11y.test.ts +0 -2
  35. package/lib/components/breadcrumbs/breadcrumbs.less +1 -1
  36. package/lib/components/button/button.a11y.test.ts +0 -134
  37. package/lib/components/button/button.less +40 -40
  38. package/lib/components/button/button.visual.test.ts +1 -1
  39. package/lib/components/card/card.a11y.test.ts +0 -6
  40. package/lib/components/check-control/check-control.a11y.test.ts +0 -13
  41. package/lib/components/check-control/check-control.visual.test.ts +1 -1
  42. package/lib/components/checkbox_radio/checkbox_radio.less +5 -5
  43. package/lib/components/checkbox_radio/checkbox_radio.visual.test.ts +1 -1
  44. package/lib/components/code-block/code-block.less +3 -3
  45. package/lib/components/description/description.a11y.test.ts +0 -5
  46. package/lib/components/description/description.visual.test.ts +1 -1
  47. package/lib/components/input-fill/input-fill.less +2 -2
  48. package/lib/components/input-icon/input-icon.less +2 -2
  49. package/lib/components/input-message/input-message.less +8 -8
  50. package/lib/components/input_textarea/input_textarea.less +6 -6
  51. package/lib/components/label/label.less +11 -11
  52. package/lib/components/link/link.a11y.test.ts +0 -21
  53. package/lib/components/link/link.less +8 -8
  54. package/lib/components/link-preview/link-preview.less +9 -9
  55. package/lib/components/menu/menu.less +3 -3
  56. package/lib/components/modal/modal.less +5 -4
  57. package/lib/components/navigation/navigation.less +11 -11
  58. package/lib/components/notice/notice.less +48 -48
  59. package/lib/components/pagination/pagination.less +3 -3
  60. package/lib/components/popover/popover.less +2 -2
  61. package/lib/components/popover/tooltip.test.ts +1 -1
  62. package/lib/components/post-summary/post-summary.less +40 -40
  63. package/lib/components/progress-bar/progress-bar.less +15 -15
  64. package/lib/components/prose/prose.less +15 -15
  65. package/lib/components/select/select.less +5 -5
  66. package/lib/components/sidebar-widget/sidebar-widget.less +12 -12
  67. package/lib/components/table/table.less +7 -7
  68. package/lib/components/tag/tag.less +25 -25
  69. package/lib/components/toggle-switch/toggle-switch.a11y.test.ts +0 -7
  70. package/lib/components/toggle-switch/toggle-switch.less +4 -4
  71. package/lib/components/topbar/topbar.less +34 -34
  72. package/lib/components/uploader/uploader.less +15 -15
  73. package/lib/components/user-card/user-card.less +7 -7
  74. package/lib/exports/__snapshots__/color-mixins.less.test.ts.snap +539 -0
  75. package/lib/exports/__snapshots__/color.less.test.ts.snap +762 -0
  76. package/lib/exports/color-mixins.less +280 -0
  77. package/lib/exports/color-mixins.less.test.ts +150 -0
  78. package/lib/exports/color-sets.less +620 -0
  79. package/lib/exports/color.less +57 -0
  80. package/lib/exports/color.less.test.ts +12 -0
  81. package/lib/exports/exports.less +2 -1
  82. package/lib/exports/mixins.less +17 -5
  83. package/lib/exports/theme.less +85 -0
  84. package/lib/exports/v1/__snapshots__/constants-colors.less.test.ts.snap +902 -0
  85. package/lib/exports/v1/constants-colors.less +893 -0
  86. package/lib/exports/v1/constants-colors.less.test.ts +12 -0
  87. package/lib/stacks-static.less +5 -0
  88. package/lib/test/less-test-utils.ts +28 -0
  89. package/package.json +13 -7
  90. package/lib/exports/constants-colors.less +0 -1100
package/dist/js/stacks.js CHANGED
@@ -81,7 +81,7 @@ __webpack_require__.d(__webpack_exports__, {
81
81
  ;// CONCATENATED MODULE: ./node_modules/@hotwired/stimulus/dist/stimulus.js
82
82
  /*
83
83
  Stimulus 3.2.1
84
- Copyright © 2023 Basecamp, LLC
84
+ Copyright © 2022 Basecamp, LLC
85
85
  */
86
86
  class EventListener {
87
87
  constructor(eventTarget, eventName, eventOptions) {
@@ -246,23 +246,23 @@ const defaultActionDescriptorFilters = {
246
246
  }
247
247
  },
248
248
  };
249
- const descriptorPattern = /^(?:(?:([^.]+?)\+)?(.+?)(?:\.(.+?))?(?:@(window|document))?->)?(.+?)(?:#([^:]+?))(?::(.+))?$/;
249
+ const descriptorPattern = /^(?:(.+?)(?:\.(.+?))?(?:@(window|document))?->)?(.+?)(?:#([^:]+?))(?::(.+))?$/;
250
250
  function parseActionDescriptorString(descriptorString) {
251
251
  const source = descriptorString.trim();
252
252
  const matches = source.match(descriptorPattern) || [];
253
- let eventName = matches[2];
254
- let keyFilter = matches[3];
253
+ let eventName = matches[1];
254
+ let keyFilter = matches[2];
255
255
  if (keyFilter && !["keydown", "keyup", "keypress"].includes(eventName)) {
256
256
  eventName += `.${keyFilter}`;
257
257
  keyFilter = "";
258
258
  }
259
259
  return {
260
- eventTarget: parseEventTarget(matches[4]),
260
+ eventTarget: parseEventTarget(matches[3]),
261
261
  eventName,
262
- eventOptions: matches[7] ? parseEventOptions(matches[7]) : {},
263
- identifier: matches[5],
264
- methodName: matches[6],
265
- keyFilter: matches[1] || keyFilter,
262
+ eventOptions: matches[6] ? parseEventOptions(matches[6]) : {},
263
+ identifier: matches[4],
264
+ methodName: matches[5],
265
+ keyFilter,
266
266
  };
267
267
  }
268
268
  function parseEventTarget(eventTargetName) {
@@ -303,14 +303,6 @@ function tokenize(value) {
303
303
  return value.match(/[^\s]+/g) || [];
304
304
  }
305
305
 
306
- function isSomething(object) {
307
- return object !== null && object !== undefined;
308
- }
309
- function hasProperty(object, property) {
310
- return Object.prototype.hasOwnProperty.call(object, property);
311
- }
312
-
313
- const allModifiers = ["meta", "ctrl", "alt", "shift"];
314
306
  class Action {
315
307
  constructor(element, index, descriptor, schema) {
316
308
  this.element = element;
@@ -331,33 +323,25 @@ class Action {
331
323
  const eventTarget = this.eventTargetName ? `@${this.eventTargetName}` : "";
332
324
  return `${this.eventName}${eventFilter}${eventTarget}->${this.identifier}#${this.methodName}`;
333
325
  }
334
- shouldIgnoreKeyboardEvent(event) {
326
+ isFilterTarget(event) {
335
327
  if (!this.keyFilter) {
336
328
  return false;
337
329
  }
338
- const filters = this.keyFilter.split("+");
339
- if (this.keyFilterDissatisfied(event, filters)) {
330
+ const filteres = this.keyFilter.split("+");
331
+ const modifiers = ["meta", "ctrl", "alt", "shift"];
332
+ const [meta, ctrl, alt, shift] = modifiers.map((modifier) => filteres.includes(modifier));
333
+ if (event.metaKey !== meta || event.ctrlKey !== ctrl || event.altKey !== alt || event.shiftKey !== shift) {
340
334
  return true;
341
335
  }
342
- const standardFilter = filters.filter((key) => !allModifiers.includes(key))[0];
336
+ const standardFilter = filteres.filter((key) => !modifiers.includes(key))[0];
343
337
  if (!standardFilter) {
344
338
  return false;
345
339
  }
346
- if (!hasProperty(this.keyMappings, standardFilter)) {
340
+ if (!Object.prototype.hasOwnProperty.call(this.keyMappings, standardFilter)) {
347
341
  error(`contains unknown key filter: ${this.keyFilter}`);
348
342
  }
349
343
  return this.keyMappings[standardFilter].toLowerCase() !== event.key.toLowerCase();
350
344
  }
351
- shouldIgnoreMouseEvent(event) {
352
- if (!this.keyFilter) {
353
- return false;
354
- }
355
- const filters = [this.keyFilter];
356
- if (this.keyFilterDissatisfied(event, filters)) {
357
- return true;
358
- }
359
- return false;
360
- }
361
345
  get params() {
362
346
  const params = {};
363
347
  const pattern = new RegExp(`^data-${this.identifier}-(.+)-param$`, "i");
@@ -376,10 +360,6 @@ class Action {
376
360
  get keyMappings() {
377
361
  return this.schema.keyMappings;
378
362
  }
379
- keyFilterDissatisfied(event, filters) {
380
- const [meta, ctrl, alt, shift] = allModifiers.map((modifier) => filters.includes(modifier));
381
- return event.metaKey !== meta || event.ctrlKey !== ctrl || event.altKey !== alt || event.shiftKey !== shift;
382
- }
383
363
  }
384
364
  const defaultEventNames = {
385
365
  a: () => "click",
@@ -426,9 +406,8 @@ class Binding {
426
406
  return this.context.identifier;
427
407
  }
428
408
  handleEvent(event) {
429
- const actionEvent = this.prepareActionEvent(event);
430
- if (this.willBeInvokedByEvent(event) && this.applyEventModifiers(actionEvent)) {
431
- this.invokeWithEvent(actionEvent);
409
+ if (this.willBeInvokedByEvent(event) && this.applyEventModifiers(event)) {
410
+ this.invokeWithEvent(event);
432
411
  }
433
412
  }
434
413
  get eventName() {
@@ -444,12 +423,11 @@ class Binding {
444
423
  applyEventModifiers(event) {
445
424
  const { element } = this.action;
446
425
  const { actionDescriptorFilters } = this.context.application;
447
- const { controller } = this.context;
448
426
  let passes = true;
449
427
  for (const [name, value] of Object.entries(this.eventOptions)) {
450
428
  if (name in actionDescriptorFilters) {
451
429
  const filter = actionDescriptorFilters[name];
452
- passes = passes && filter({ name, value, event, element, controller });
430
+ passes = passes && filter({ name, value, event, element });
453
431
  }
454
432
  else {
455
433
  continue;
@@ -457,13 +435,12 @@ class Binding {
457
435
  }
458
436
  return passes;
459
437
  }
460
- prepareActionEvent(event) {
461
- return Object.assign(event, { params: this.action.params });
462
- }
463
438
  invokeWithEvent(event) {
464
439
  const { target, currentTarget } = event;
465
440
  try {
466
- this.method.call(this.controller, event);
441
+ const { params } = this.action;
442
+ const actionEvent = Object.assign(event, { params });
443
+ this.method.call(this.controller, actionEvent);
467
444
  this.context.logDebugActivity(this.methodName, { event, target, currentTarget, action: this.methodName });
468
445
  }
469
446
  catch (error) {
@@ -474,10 +451,7 @@ class Binding {
474
451
  }
475
452
  willBeInvokedByEvent(event) {
476
453
  const eventTarget = event.target;
477
- if (event instanceof KeyboardEvent && this.action.shouldIgnoreKeyboardEvent(event)) {
478
- return false;
479
- }
480
- if (event instanceof MouseEvent && this.action.shouldIgnoreMouseEvent(event)) {
454
+ if (event instanceof KeyboardEvent && this.action.isFilterTarget(event)) {
481
455
  return false;
482
456
  }
483
457
  if (this.element === eventTarget) {
@@ -567,7 +541,8 @@ class ElementObserver {
567
541
  this.processAddedNodes(mutation.addedNodes);
568
542
  }
569
543
  }
570
- processAttributeChange(element, attributeName) {
544
+ processAttributeChange(node, attributeName) {
545
+ const element = node;
571
546
  if (this.elements.has(element)) {
572
547
  if (this.delegate.elementAttributeChanged && this.matchElement(element)) {
573
548
  this.delegate.elementAttributeChanged(element, attributeName);
@@ -783,8 +758,8 @@ class IndexedMultimap extends (/* unused pure expression or super */ null && (Mu
783
758
  }
784
759
 
785
760
  class SelectorObserver {
786
- constructor(element, selector, delegate, details) {
787
- this._selector = selector;
761
+ constructor(element, selector, delegate, details = {}) {
762
+ this.selector = selector;
788
763
  this.details = details;
789
764
  this.elementObserver = new ElementObserver(element, this);
790
765
  this.delegate = delegate;
@@ -793,13 +768,6 @@ class SelectorObserver {
793
768
  get started() {
794
769
  return this.elementObserver.started;
795
770
  }
796
- get selector() {
797
- return this._selector;
798
- }
799
- set selector(selector) {
800
- this._selector = selector;
801
- this.refresh();
802
- }
803
771
  start() {
804
772
  this.elementObserver.start();
805
773
  }
@@ -816,61 +784,39 @@ class SelectorObserver {
816
784
  return this.elementObserver.element;
817
785
  }
818
786
  matchElement(element) {
819
- const { selector } = this;
820
- if (selector) {
821
- const matches = element.matches(selector);
822
- if (this.delegate.selectorMatchElement) {
823
- return matches && this.delegate.selectorMatchElement(element, this.details);
824
- }
825
- return matches;
826
- }
827
- else {
828
- return false;
787
+ const matches = element.matches(this.selector);
788
+ if (this.delegate.selectorMatchElement) {
789
+ return matches && this.delegate.selectorMatchElement(element, this.details);
829
790
  }
791
+ return matches;
830
792
  }
831
793
  matchElementsInTree(tree) {
832
- const { selector } = this;
833
- if (selector) {
834
- const match = this.matchElement(tree) ? [tree] : [];
835
- const matches = Array.from(tree.querySelectorAll(selector)).filter((match) => this.matchElement(match));
836
- return match.concat(matches);
837
- }
838
- else {
839
- return [];
840
- }
794
+ const match = this.matchElement(tree) ? [tree] : [];
795
+ const matches = Array.from(tree.querySelectorAll(this.selector)).filter((match) => this.matchElement(match));
796
+ return match.concat(matches);
841
797
  }
842
798
  elementMatched(element) {
843
- const { selector } = this;
844
- if (selector) {
845
- this.selectorMatched(element, selector);
846
- }
799
+ this.selectorMatched(element);
847
800
  }
848
801
  elementUnmatched(element) {
849
- const selectors = this.matchesByElement.getKeysForValue(element);
850
- for (const selector of selectors) {
851
- this.selectorUnmatched(element, selector);
852
- }
802
+ this.selectorUnmatched(element);
853
803
  }
854
804
  elementAttributeChanged(element, _attributeName) {
855
- const { selector } = this;
856
- if (selector) {
857
- const matches = this.matchElement(element);
858
- const matchedBefore = this.matchesByElement.has(selector, element);
859
- if (matches && !matchedBefore) {
860
- this.selectorMatched(element, selector);
861
- }
862
- else if (!matches && matchedBefore) {
863
- this.selectorUnmatched(element, selector);
864
- }
805
+ const matches = this.matchElement(element);
806
+ const matchedBefore = this.matchesByElement.has(this.selector, element);
807
+ if (!matches && matchedBefore) {
808
+ this.selectorUnmatched(element);
865
809
  }
866
810
  }
867
- selectorMatched(element, selector) {
868
- this.delegate.selectorMatched(element, selector, this.details);
869
- this.matchesByElement.add(selector, element);
811
+ selectorMatched(element) {
812
+ if (this.delegate.selectorMatched) {
813
+ this.delegate.selectorMatched(element, this.selector, this.details);
814
+ this.matchesByElement.add(this.selector, element);
815
+ }
870
816
  }
871
- selectorUnmatched(element, selector) {
872
- this.delegate.selectorUnmatched(element, selector, this.details);
873
- this.matchesByElement.delete(selector, element);
817
+ selectorUnmatched(element) {
818
+ this.delegate.selectorUnmatched(element, this.selector, this.details);
819
+ this.matchesByElement.delete(this.selector, element);
874
820
  }
875
821
  }
876
822
 
@@ -1367,47 +1313,34 @@ function getOwnStaticObjectPairs(constructor, propertyName) {
1367
1313
 
1368
1314
  class OutletObserver {
1369
1315
  constructor(context, delegate) {
1370
- this.started = false;
1371
1316
  this.context = context;
1372
1317
  this.delegate = delegate;
1373
1318
  this.outletsByName = new Multimap();
1374
1319
  this.outletElementsByName = new Multimap();
1375
1320
  this.selectorObserverMap = new Map();
1376
- this.attributeObserverMap = new Map();
1377
1321
  }
1378
1322
  start() {
1379
- if (!this.started) {
1323
+ if (this.selectorObserverMap.size === 0) {
1380
1324
  this.outletDefinitions.forEach((outletName) => {
1381
- this.setupSelectorObserverForOutlet(outletName);
1382
- this.setupAttributeObserverForOutlet(outletName);
1325
+ const selector = this.selector(outletName);
1326
+ const details = { outletName };
1327
+ if (selector) {
1328
+ this.selectorObserverMap.set(outletName, new SelectorObserver(document.body, selector, this, details));
1329
+ }
1383
1330
  });
1384
- this.started = true;
1385
- this.dependentContexts.forEach((context) => context.refresh());
1331
+ this.selectorObserverMap.forEach((observer) => observer.start());
1386
1332
  }
1387
- }
1388
- refresh() {
1389
- this.selectorObserverMap.forEach((observer) => observer.refresh());
1390
- this.attributeObserverMap.forEach((observer) => observer.refresh());
1333
+ this.dependentContexts.forEach((context) => context.refresh());
1391
1334
  }
1392
1335
  stop() {
1393
- if (this.started) {
1394
- this.started = false;
1395
- this.disconnectAllOutlets();
1396
- this.stopSelectorObservers();
1397
- this.stopAttributeObservers();
1398
- }
1399
- }
1400
- stopSelectorObservers() {
1401
1336
  if (this.selectorObserverMap.size > 0) {
1337
+ this.disconnectAllOutlets();
1402
1338
  this.selectorObserverMap.forEach((observer) => observer.stop());
1403
1339
  this.selectorObserverMap.clear();
1404
1340
  }
1405
1341
  }
1406
- stopAttributeObservers() {
1407
- if (this.attributeObserverMap.size > 0) {
1408
- this.attributeObserverMap.forEach((observer) => observer.stop());
1409
- this.attributeObserverMap.clear();
1410
- }
1342
+ refresh() {
1343
+ this.selectorObserverMap.forEach((observer) => observer.refresh());
1411
1344
  }
1412
1345
  selectorMatched(element, _selector, { outletName }) {
1413
1346
  const outlet = this.getOutlet(element, outletName);
@@ -1422,33 +1355,8 @@ class OutletObserver {
1422
1355
  }
1423
1356
  }
1424
1357
  selectorMatchElement(element, { outletName }) {
1425
- const selector = this.selector(outletName);
1426
- const hasOutlet = this.hasOutlet(element, outletName);
1427
- const hasOutletController = element.matches(`[${this.schema.controllerAttribute}~=${outletName}]`);
1428
- if (selector) {
1429
- return hasOutlet && hasOutletController && element.matches(selector);
1430
- }
1431
- else {
1432
- return false;
1433
- }
1434
- }
1435
- elementMatchedAttribute(_element, attributeName) {
1436
- const outletName = this.getOutletNameFromOutletAttributeName(attributeName);
1437
- if (outletName) {
1438
- this.updateSelectorObserverForOutlet(outletName);
1439
- }
1440
- }
1441
- elementAttributeValueChanged(_element, attributeName) {
1442
- const outletName = this.getOutletNameFromOutletAttributeName(attributeName);
1443
- if (outletName) {
1444
- this.updateSelectorObserverForOutlet(outletName);
1445
- }
1446
- }
1447
- elementUnmatchedAttribute(_element, attributeName) {
1448
- const outletName = this.getOutletNameFromOutletAttributeName(attributeName);
1449
- if (outletName) {
1450
- this.updateSelectorObserverForOutlet(outletName);
1451
- }
1358
+ return (this.hasOutlet(element, outletName) &&
1359
+ element.matches(`[${this.context.application.schema.controllerAttribute}~=${outletName}]`));
1452
1360
  }
1453
1361
  connectOutlet(outlet, element, outletName) {
1454
1362
  var _a;
@@ -1476,33 +1384,9 @@ class OutletObserver {
1476
1384
  }
1477
1385
  }
1478
1386
  }
1479
- updateSelectorObserverForOutlet(outletName) {
1480
- const observer = this.selectorObserverMap.get(outletName);
1481
- if (observer) {
1482
- observer.selector = this.selector(outletName);
1483
- }
1484
- }
1485
- setupSelectorObserverForOutlet(outletName) {
1486
- const selector = this.selector(outletName);
1487
- const selectorObserver = new SelectorObserver(document.body, selector, this, { outletName });
1488
- this.selectorObserverMap.set(outletName, selectorObserver);
1489
- selectorObserver.start();
1490
- }
1491
- setupAttributeObserverForOutlet(outletName) {
1492
- const attributeName = this.attributeNameForOutletName(outletName);
1493
- const attributeObserver = new AttributeObserver(this.scope.element, attributeName, this);
1494
- this.attributeObserverMap.set(outletName, attributeObserver);
1495
- attributeObserver.start();
1496
- }
1497
1387
  selector(outletName) {
1498
1388
  return this.scope.outlets.getSelectorForOutletName(outletName);
1499
1389
  }
1500
- attributeNameForOutletName(outletName) {
1501
- return this.scope.schema.outletAttributeForScope(this.identifier, outletName);
1502
- }
1503
- getOutletNameFromOutletAttributeName(attributeName) {
1504
- return this.outletDefinitions.find((outletName) => this.attributeNameForOutletName(outletName) === attributeName);
1505
- }
1506
1390
  get outletDependencies() {
1507
1391
  const dependencies = new Multimap();
1508
1392
  this.router.modules.forEach((module) => {
@@ -1534,9 +1418,6 @@ class OutletObserver {
1534
1418
  get scope() {
1535
1419
  return this.context.scope;
1536
1420
  }
1537
- get schema() {
1538
- return this.context.schema;
1539
- }
1540
1421
  get identifier() {
1541
1422
  return this.context.identifier;
1542
1423
  }
@@ -2024,9 +1905,6 @@ class ScopeObserver {
2024
1905
  }
2025
1906
  parseValueForToken(token) {
2026
1907
  const { element, content: identifier } = token;
2027
- return this.parseValueForElementAndIdentifier(element, identifier);
2028
- }
2029
- parseValueForElementAndIdentifier(element, identifier) {
2030
1908
  const scopesByIdentifier = this.fetchScopesByIdentifierForElement(element);
2031
1909
  let scope = scopesByIdentifier.get(identifier);
2032
1910
  if (!scope) {
@@ -2098,7 +1976,7 @@ class Router {
2098
1976
  this.connectModule(module);
2099
1977
  const afterLoad = definition.controllerConstructor.afterLoad;
2100
1978
  if (afterLoad) {
2101
- afterLoad.call(definition.controllerConstructor, definition.identifier, this.application);
1979
+ afterLoad(definition.identifier, this.application);
2102
1980
  }
2103
1981
  }
2104
1982
  unloadIdentifier(identifier) {
@@ -2113,15 +1991,6 @@ class Router {
2113
1991
  return module.contexts.find((context) => context.element == element);
2114
1992
  }
2115
1993
  }
2116
- proposeToConnectScopeForElementAndIdentifier(element, identifier) {
2117
- const scope = this.scopeObserver.parseValueForElementAndIdentifier(element, identifier);
2118
- if (scope) {
2119
- this.scopeObserver.elementMatchedValue(scope.element, scope);
2120
- }
2121
- else {
2122
- console.error(`Couldn't find or create scope for identifier: "${identifier}" and element:`, element);
2123
- }
2124
- }
2125
1994
  handleError(error, message, detail) {
2126
1995
  this.application.handleError(error, message, detail);
2127
1996
  }
@@ -2160,7 +2029,7 @@ const defaultSchema = {
2160
2029
  targetAttribute: "data-target",
2161
2030
  targetAttributeForScope: (identifier) => `data-${identifier}-target`,
2162
2031
  outletAttributeForScope: (identifier, outlet) => `data-${identifier}-${outlet}-outlet`,
2163
- keyMappings: Object.assign(Object.assign({ enter: "Enter", tab: "Tab", esc: "Escape", space: " ", up: "ArrowUp", down: "ArrowDown", left: "ArrowLeft", right: "ArrowRight", home: "Home", end: "End", page_up: "PageUp", page_down: "PageDown" }, objectFromEntries("abcdefghijklmnopqrstuvwxyz".split("").map((c) => [c, c]))), objectFromEntries("0123456789".split("").map((n) => [n, n]))),
2032
+ keyMappings: Object.assign(Object.assign({ enter: "Enter", tab: "Tab", esc: "Escape", space: " ", up: "ArrowUp", down: "ArrowDown", left: "ArrowLeft", right: "ArrowRight", home: "Home", end: "End" }, objectFromEntries("abcdefghijklmnopqrstuvwxyz".split("").map((c) => [c, c]))), objectFromEntries("0123456789".split("").map((n) => [n, n]))),
2164
2033
  };
2165
2034
  function objectFromEntries(array) {
2166
2035
  return array.reduce((memo, [k, v]) => (Object.assign(Object.assign({}, memo), { [k]: v })), {});
@@ -2286,32 +2155,22 @@ function OutletPropertiesBlessing(constructor) {
2286
2155
  return Object.assign(properties, propertiesForOutletDefinition(outletDefinition));
2287
2156
  }, {});
2288
2157
  }
2289
- function getOutletController(controller, element, identifier) {
2290
- return controller.application.getControllerForElementAndIdentifier(element, identifier);
2291
- }
2292
- function getControllerAndEnsureConnectedScope(controller, element, outletName) {
2293
- let outletController = getOutletController(controller, element, outletName);
2294
- if (outletController)
2295
- return outletController;
2296
- controller.application.router.proposeToConnectScopeForElementAndIdentifier(element, outletName);
2297
- outletController = getOutletController(controller, element, outletName);
2298
- if (outletController)
2299
- return outletController;
2300
- }
2301
2158
  function propertiesForOutletDefinition(name) {
2302
2159
  const camelizedName = namespaceCamelize(name);
2303
2160
  return {
2304
2161
  [`${camelizedName}Outlet`]: {
2305
2162
  get() {
2306
- const outletElement = this.outlets.find(name);
2307
- const selector = this.outlets.getSelectorForOutletName(name);
2308
- if (outletElement) {
2309
- const outletController = getControllerAndEnsureConnectedScope(this, outletElement, name);
2310
- if (outletController)
2163
+ const outlet = this.outlets.find(name);
2164
+ if (outlet) {
2165
+ const outletController = this.application.getControllerForElementAndIdentifier(outlet, name);
2166
+ if (outletController) {
2311
2167
  return outletController;
2312
- throw new Error(`The provided outlet element is missing an outlet controller "${name}" instance for host controller "${this.identifier}"`);
2168
+ }
2169
+ else {
2170
+ throw new Error(`Missing "data-controller=${name}" attribute on outlet element for "${this.identifier}" controller`);
2171
+ }
2313
2172
  }
2314
- throw new Error(`Missing outlet element "${name}" for host controller "${this.identifier}". Stimulus couldn't find a matching outlet element using selector "${selector}".`);
2173
+ throw new Error(`Missing outlet element "${name}" for "${this.identifier}" controller`);
2315
2174
  },
2316
2175
  },
2317
2176
  [`${camelizedName}Outlets`]: {
@@ -2319,11 +2178,14 @@ function propertiesForOutletDefinition(name) {
2319
2178
  const outlets = this.outlets.findAll(name);
2320
2179
  if (outlets.length > 0) {
2321
2180
  return outlets
2322
- .map((outletElement) => {
2323
- const outletController = getControllerAndEnsureConnectedScope(this, outletElement, name);
2324
- if (outletController)
2325
- return outletController;
2326
- console.warn(`The provided outlet element is missing an outlet controller "${name}" instance for host controller "${this.identifier}"`, outletElement);
2181
+ .map((outlet) => {
2182
+ const controller = this.application.getControllerForElementAndIdentifier(outlet, name);
2183
+ if (controller) {
2184
+ return controller;
2185
+ }
2186
+ else {
2187
+ console.warn(`The provided outlet element is missing the outlet controller "${name}" for "${this.identifier}"`, outlet);
2188
+ }
2327
2189
  })
2328
2190
  .filter((controller) => controller);
2329
2191
  }
@@ -2332,13 +2194,12 @@ function propertiesForOutletDefinition(name) {
2332
2194
  },
2333
2195
  [`${camelizedName}OutletElement`]: {
2334
2196
  get() {
2335
- const outletElement = this.outlets.find(name);
2336
- const selector = this.outlets.getSelectorForOutletName(name);
2337
- if (outletElement) {
2338
- return outletElement;
2197
+ const outlet = this.outlets.find(name);
2198
+ if (outlet) {
2199
+ return outlet;
2339
2200
  }
2340
2201
  else {
2341
- throw new Error(`Missing outlet element "${name}" for host controller "${this.identifier}". Stimulus couldn't find a matching outlet element using selector "${selector}".`);
2202
+ throw new Error(`Missing outlet element "${name}" for "${this.identifier}" controller`);
2342
2203
  }
2343
2204
  },
2344
2205
  },
@@ -2470,67 +2331,51 @@ function parseValueTypeDefault(defaultValue) {
2470
2331
  return "object";
2471
2332
  }
2472
2333
  function parseValueTypeObject(payload) {
2473
- const { controller, token, typeObject } = payload;
2474
- const hasType = isSomething(typeObject.type);
2475
- const hasDefault = isSomething(typeObject.default);
2476
- const fullObject = hasType && hasDefault;
2477
- const onlyType = hasType && !hasDefault;
2478
- const onlyDefault = !hasType && hasDefault;
2479
- const typeFromObject = parseValueTypeConstant(typeObject.type);
2480
- const typeFromDefaultValue = parseValueTypeDefault(payload.typeObject.default);
2481
- if (onlyType)
2482
- return typeFromObject;
2483
- if (onlyDefault)
2484
- return typeFromDefaultValue;
2485
- if (typeFromObject !== typeFromDefaultValue) {
2486
- const propertyPath = controller ? `${controller}.${token}` : token;
2487
- throw new Error(`The specified default value for the Stimulus Value "${propertyPath}" must match the defined type "${typeFromObject}". The provided default value of "${typeObject.default}" is of type "${typeFromDefaultValue}".`);
2488
- }
2489
- if (fullObject)
2490
- return typeFromObject;
2334
+ const typeFromObject = parseValueTypeConstant(payload.typeObject.type);
2335
+ if (!typeFromObject)
2336
+ return;
2337
+ const defaultValueType = parseValueTypeDefault(payload.typeObject.default);
2338
+ if (typeFromObject !== defaultValueType) {
2339
+ const propertyPath = payload.controller ? `${payload.controller}.${payload.token}` : payload.token;
2340
+ throw new Error(`The specified default value for the Stimulus Value "${propertyPath}" must match the defined type "${typeFromObject}". The provided default value of "${payload.typeObject.default}" is of type "${defaultValueType}".`);
2341
+ }
2342
+ return typeFromObject;
2491
2343
  }
2492
2344
  function parseValueTypeDefinition(payload) {
2493
- const { controller, token, typeDefinition } = payload;
2494
- const typeObject = { controller, token, typeObject: typeDefinition };
2495
- const typeFromObject = parseValueTypeObject(typeObject);
2496
- const typeFromDefaultValue = parseValueTypeDefault(typeDefinition);
2497
- const typeFromConstant = parseValueTypeConstant(typeDefinition);
2345
+ const typeFromObject = parseValueTypeObject({
2346
+ controller: payload.controller,
2347
+ token: payload.token,
2348
+ typeObject: payload.typeDefinition,
2349
+ });
2350
+ const typeFromDefaultValue = parseValueTypeDefault(payload.typeDefinition);
2351
+ const typeFromConstant = parseValueTypeConstant(payload.typeDefinition);
2498
2352
  const type = typeFromObject || typeFromDefaultValue || typeFromConstant;
2499
2353
  if (type)
2500
2354
  return type;
2501
- const propertyPath = controller ? `${controller}.${typeDefinition}` : token;
2502
- throw new Error(`Unknown value type "${propertyPath}" for "${token}" value`);
2355
+ const propertyPath = payload.controller ? `${payload.controller}.${payload.typeDefinition}` : payload.token;
2356
+ throw new Error(`Unknown value type "${propertyPath}" for "${payload.token}" value`);
2503
2357
  }
2504
2358
  function defaultValueForDefinition(typeDefinition) {
2505
2359
  const constant = parseValueTypeConstant(typeDefinition);
2506
2360
  if (constant)
2507
2361
  return defaultValuesByType[constant];
2508
- const hasDefault = hasProperty(typeDefinition, "default");
2509
- const hasType = hasProperty(typeDefinition, "type");
2510
- const typeObject = typeDefinition;
2511
- if (hasDefault)
2512
- return typeObject.default;
2513
- if (hasType) {
2514
- const { type } = typeObject;
2515
- const constantFromType = parseValueTypeConstant(type);
2516
- if (constantFromType)
2517
- return defaultValuesByType[constantFromType];
2518
- }
2362
+ const defaultValue = typeDefinition.default;
2363
+ if (defaultValue !== undefined)
2364
+ return defaultValue;
2519
2365
  return typeDefinition;
2520
2366
  }
2521
2367
  function valueDescriptorForTokenAndTypeDefinition(payload) {
2522
- const { token, typeDefinition } = payload;
2523
- const key = `${dasherize(token)}-value`;
2368
+ const key = `${dasherize(payload.token)}-value`;
2524
2369
  const type = parseValueTypeDefinition(payload);
2525
2370
  return {
2526
2371
  type,
2527
2372
  key,
2528
2373
  name: camelize(key),
2529
2374
  get defaultValue() {
2530
- return defaultValueForDefinition(typeDefinition);
2375
+ return defaultValueForDefinition(payload.typeDefinition);
2531
2376
  },
2532
2377
  get hasCustomDefaultValue() {
2533
- return parseValueTypeDefault(typeDefinition) !== undefined;
2378
+ return parseValueTypeDefault(payload.typeDefinition) !== undefined;
2534
2379
  },
2535
2380
  reader: readers[type],
2536
2381
  writer: writers[type] || writers.default,
@@ -2559,7 +2404,7 @@ const readers = {
2559
2404
  return !(value == "0" || String(value).toLowerCase() == "false");
2560
2405
  },
2561
2406
  number(value) {
2562
- return Number(value.replace(/_/g, ""));
2407
+ return Number(value);
2563
2408
  },
2564
2409
  object(value) {
2565
2410
  const object = JSON.parse(value);
@@ -2624,7 +2469,7 @@ class Controller {
2624
2469
  }
2625
2470
  disconnect() {
2626
2471
  }
2627
- dispatch(eventName, { target = this.element, detail = {}, prefix = this.identifier, bubbles = true, cancelable = true, } = {}) {
2472
+ dispatch(eventName, { target = this.element, detail = {}, prefix = this.identifier, bubbles = true, cancelable = true } = {}) {
2628
2473
  const type = prefix ? `${prefix}:${eventName}` : eventName;
2629
2474
  const event = new CustomEvent(type, { detail, bubbles, cancelable });
2630
2475
  target.dispatchEvent(event);