Code Monkey home page Code Monkey logo

Comments (2)

Nness avatar Nness commented on June 4, 2024

The report issue is also happen to dropdown and popover. From the code I can see preventOverflow has been added as default.

ng-bootstrap utilize popper lite, which popper lite doesn't include preventOverflow, where you have to import in to make it work. Which ng-bootstrap did.

export function getPopperOptions({ placement, baseClass }: PositioningOptions, rtl: NgbRTL): Partial<Options> {
let placementVals: Array<Placement> = Array.isArray(placement)
? placement
: (placement.split(placementSeparator) as Array<Placement>);
// No need to consider left and right here, as start and end are enough, and it is used for 'auto' placement only
const allowedPlacements = [
'top',
'bottom',
'start',
'end',
'top-start',
'top-end',
'bottom-start',
'bottom-end',
'start-top',
'start-bottom',
'end-top',
'end-bottom',
];
// replace auto placement with other placements
let hasAuto = placementVals.findIndex((val) => val === 'auto');
if (hasAuto >= 0) {
allowedPlacements.forEach(function (obj) {
if (placementVals.find((val) => val.search('^' + obj) !== -1) == null) {
placementVals.splice(hasAuto++, 1, obj as Placement);
}
});
}
const popperPlacements = placementVals.map((_placement) => {
return getPopperClassPlacement(_placement, rtl.isRTL());
});
let mainPlacement = popperPlacements.shift();
const bsModifier: Partial<Modifier<any, any>> = {
name: 'bootstrapClasses',
enabled: !!baseClass,
phase: 'write',
fn({ state }) {
const bsClassRegExp = new RegExp(baseClass + '(-[a-z]+)*', 'gi');
const popperElement: HTMLElement = state.elements.popper as HTMLElement;
const popperPlacement = state.placement;
let className = popperElement.className;
// Remove old bootstrap classes
className = className.replace(bsClassRegExp, '');
// Add current placements
className += ` ${getBootstrapBaseClassPlacement(baseClass!, popperPlacement)}`;
// Remove multiple spaces
className = className.trim().replace(spacesRegExp, ' ');
// Reassign
popperElement.className = className;
},
};
return {
placement: mainPlacement,
modifiers: [
bsModifier,
flip,
preventOverflow,
arrow,
{
enabled: true,
name: 'flip',
options: {
fallbackPlacements: popperPlacements,
},
},
{
enabled: true,
name: 'preventOverflow',
phase: 'main',
fn: function () {},
},
],
};
}

bootstrap also has preventOverflow, but they use popper instead of popper lite.

https://github.com/twbs/bootstrap/blob/24cc552343c817b0d13201639c635a778d55da09/js/src/tooltip.js#L399-L437

Personally, this has been struggling me for a while as well.

from ng-bootstrap.

Nness avatar Nness commented on June 4, 2024

I have found out the issue. The following code cause preventOverflow to not functional. The goal of the code was suppose to provide additional option and to be merged with popper's preventOverflow modifier. But it actually setup fn.

{
enabled: true,
name: 'preventOverflow',
phase: 'main',
fn: function () {},
},

If we compare the option bootstrap has added and ng-bootstrap's code.

// bootstrap
{
   name: 'preventOverflow',
   options: {
      boundary: this._config.boundary
   }
}

// ng-bootstrap
{
  enabled: true,
  name: 'preventOverflow',
  phase: 'main',
  fn: function () {},
}

If we either remove ng-bootstrap's modifier or swap with bootstrap's modifier. In both case works.

Following is popperOptions function I use to debug ng-bootstrap. The logic is to check how many preventOverflow has been added. If more than one, remove last one. @Ste35 you can give it a try.

  
  popperOptions(options: Partial<Options>): Partial<Options> {
    const target = options.modifiers?.filter(m => m.name === 'preventOverflow');
    if (!target || target.length <= 1) {
      return options;
    }

    const last = target.at(-1);
    if (options.modifiers && last) {
      options.modifiers = options.modifiers.filter(m => m !== last);
    }

    console.log('popper options', options);

    return options;
  }

@maxokorokov The second preventOverflow that ng-bootstrap added, I feels not necessary. Bootstrap use it to setup boundary, where ng-bootstrap setup nothing. We can potentially remove it.

from ng-bootstrap.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.