@@ -319,6 +319,8 @@ export default class Trigger extends PluginBase {
319
319
'oneof' ,
320
320
'allof' ,
321
321
'focus' ,
322
+ 'within' ,
323
+ 'notWithin' ,
322
324
] . includes ( condition . name . toLowerCase ( ) ) ) ;
323
325
}
324
326
@@ -386,6 +388,12 @@ export default class Trigger extends PluginBase {
386
388
this . createFocusedCondition ( trigger ) ,
387
389
) ;
388
390
break ;
391
+ case 'within' :
392
+ case 'notWithin' :
393
+ trigger . get ( 'conditionCallbacks' ) . push (
394
+ this . createWithinCondition ( trigger , ( condition . name === 'within' ) , ...condition . parameters ) ,
395
+ ) ;
396
+ break ;
389
397
default :
390
398
}
391
399
} ) ;
@@ -648,7 +656,47 @@ export default class Trigger extends PluginBase {
648
656
this . addEvent ( element , trigger , 'blur' ) ;
649
657
} ) ;
650
658
651
- return ( ) => Array . from ( supportedElements ) . some ( ( element ) => document . activeElement === element ) ;
659
+ return Array . from ( supportedElements ) . some ( ( element ) => document . activeElement === element ) ;
660
+ }
661
+
662
+ /**
663
+ * Creates a trigger that fires when all supported elements are within a specific element(s).
664
+ *
665
+ * @param {TriggerEntity } trigger
666
+ * @param {boolean } isWithin If the elements must be within the selector.
667
+ * @param {string } selector The selector to check if the elements are within.
668
+ */
669
+ createWithinCondition ( trigger , isWithin , selector ) {
670
+ const supportedElements = new Set ( ) ;
671
+
672
+ trigger . get ( 'elements' ) . forEach ( ( element ) => {
673
+ // All elements are supported (technically)
674
+ supportedElements . add ( element ) ;
675
+ } ) ;
676
+
677
+ supportedElements . forEach ( ( element ) => {
678
+ this . addEvent ( element , trigger , 'click' ) ;
679
+ this . addEvent ( element , trigger , 'change' ) ;
680
+ this . addEvent ( element , trigger , 'focus' ) ;
681
+ this . addEvent ( element , trigger , 'blur' ) ;
682
+ } ) ;
683
+
684
+ return Array . from ( supportedElements ) . every (
685
+ ( element ) => {
686
+ let within = false ;
687
+
688
+ document . querySelectorAll ( selector ) . forEach ( ( parent ) => {
689
+ if ( within === true ) {
690
+ return ;
691
+ }
692
+ if ( parent . contains ( element ) ) {
693
+ within = true ;
694
+ }
695
+ } ) ;
696
+
697
+ return within === isWithin ;
698
+ } ,
699
+ ) ;
652
700
}
653
701
654
702
/**
0 commit comments