Skip to content

Commit

Permalink
fix(icons): make icon transform props work with IE11 (closes #4607) (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
tmorehouse authored Jan 12, 2020
1 parent defbec0 commit 899779f
Show file tree
Hide file tree
Showing 3 changed files with 318 additions and 22 deletions.
6 changes: 3 additions & 3 deletions src/icons/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ Vue.use(BootstrapVueIcons)
```

BootstrapVue icons SCSS/CSS does not depend on any Bootstrap SASS variables, mixins, functions or
CSS classes (other than the Bootstrap `text-{variant}` variant utility classes, if using the
CSS classes (other than the Bootstrap `text-{variant}` text color utility classes, if using the
`variant` prop). Please note that the icons CSS is _also_ included in the main BootstrapVue SCSS/CSS
files.

Expand Down Expand Up @@ -299,9 +299,9 @@ With the use of Bootstrap's border and background

## Transforms

BootstrapVue icons provide several props for applying basic CSS transforms to the `<svg>`. All
BootstrapVue icons provide several props for applying basic SVG transforms to the `<svg>`. All
transforms can be combined for added effect. Note that the transforms are applied to the `<svg>`
content, and not the `<svg>` bounding box.
_content_ and not the `<svg>` bounding box.

### Flipping

Expand Down
44 changes: 26 additions & 18 deletions src/icons/helpers/make-icon.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,35 +62,43 @@ const BVIconBase = {
...commonIconProps
},
render(h, { data, props }) {
const fontScale = toFloat(props.fontScale) || 1
const scale = toFloat(props.scale) || 1
const fontScale = Math.max(toFloat(props.fontScale) || 1, 0) || 1
const scale = Math.max(toFloat(props.scale) || 1, 0) || 1
const rotate = toFloat(props.rotate) || 0
const shiftH = toFloat(props.shiftH) || 0
const shiftV = toFloat(props.shiftV) || 0
const flipH = props.flipH
const flipV = props.flipV
// Compute the transforms. Note that order is important
// CSS transforms are applied in order from right to left
// and we want flipping to occur before rotation, and
// shifting is applied last
// Compute the transforms. Note that order is important as
// SVG transforms are applied in order from left to right
// and we want flipping/scale to occur before rotation.
// Note shifting is applied separately. Assumes that the
// viewbox is `0 0 20 20` (`10 10` is the center)
const hasScale = flipH || flipV || scale !== 1
const hasTransforms = hasScale || rotate
const hasShift = shiftH || shiftV
const transforms = [
shiftH ? `translateX(${(100 * shiftH) / 16}%)` : null,
shiftV ? `translateY(${(-100 * shiftV) / 16}%)` : null,
rotate ? `rotate(${rotate}deg)` : null,
flipH || flipV || scale !== 1
? `scale(${(flipH ? -1 : 1) * scale}, ${(flipV ? -1 : 1) * scale})`
: null
hasTransforms ? 'translate(10 10)' : null,
hasScale ? `scale(${(flipH ? -1 : 1) * scale} ${(flipV ? -1 : 1) * scale})` : null,
rotate ? `rotate(${rotate})` : null,
hasTransforms ? 'translate(-10 -10)' : null
].filter(identity)

// We wrap the content in a `<g>` for handling the transforms
const $inner = h('g', {
style: {
transform: transforms.join(' ') || null,
transformOrigin: transforms.length > 0 ? 'center' : null
},
// We wrap the content in a `<g>` for handling the transforms (except shift)
let $inner = h('g', {
attrs: { transform: transforms.join(' ') || null },
domProps: { innerHTML: props.content || '' }
})

// If needed, we wrap in an additional `<g>` in order to handle the shifting
if (hasShift) {
$inner = h(
'g',
{ attrs: { transform: `translate(${(20 * shiftH) / 16} ${(-20 * shiftV) / 16})` } },
[$inner]
)
}

return h(
'svg',
mergeData(
Expand Down
Loading

0 comments on commit 899779f

Please sign in to comment.