From f21bb80035d36914b1a62f9880be2af363a8d7c3 Mon Sep 17 00:00:00 2001 From: Marcos Moura Date: Wed, 11 Jan 2017 00:01:34 -0200 Subject: [PATCH] Components/md speed dial (#318) #286 --- build/webpack/prod-lib.js | 8 +- docs/src/App.vue | 4 + docs/src/pages/components/SpeedDial.vue | 202 +++++++++++++++++++ docs/src/routes.js | 6 + src/components/mdButton/mdButton.scss | 100 ++++----- src/components/mdSpeedDial/index.js | 8 + src/components/mdSpeedDial/mdSpeedDial.scss | 142 +++++++++++++ src/components/mdSpeedDial/mdSpeedDial.theme | 5 + src/components/mdSpeedDial/mdSpeedDial.vue | 76 +++++++ src/index.js | 2 + 10 files changed, 504 insertions(+), 49 deletions(-) create mode 100644 docs/src/pages/components/SpeedDial.vue create mode 100644 src/components/mdSpeedDial/index.js create mode 100644 src/components/mdSpeedDial/mdSpeedDial.scss create mode 100644 src/components/mdSpeedDial/mdSpeedDial.theme create mode 100644 src/components/mdSpeedDial/mdSpeedDial.vue diff --git a/build/webpack/prod-lib.js b/build/webpack/prod-lib.js index 743fc07..2d2812c 100644 --- a/build/webpack/prod-lib.js +++ b/build/webpack/prod-lib.js @@ -47,7 +47,13 @@ export default merge(baseConfig, { ] }, externals: { - vue: 'vue' + vue: { + commonjs: 'vue', + commonjs2: 'vue', + amd: 'vue', + root: 'Vue', + var: 'Vue' + } }, plugins: [ new webpack.optimize.DedupePlugin(), diff --git a/docs/src/App.vue b/docs/src/App.vue index 7fdbee4..4d360b0 100644 --- a/docs/src/App.vue +++ b/docs/src/App.vue @@ -119,6 +119,10 @@ Snackbar + + Speed Dial + + Spinner diff --git a/docs/src/pages/components/SpeedDial.vue b/docs/src/pages/components/SpeedDial.vue new file mode 100644 index 0000000..9a4d255 --- /dev/null +++ b/docs/src/pages/components/SpeedDial.vue @@ -0,0 +1,202 @@ + + + + + diff --git a/docs/src/routes.js b/docs/src/routes.js index 4f6f6d3..2a4afa8 100644 --- a/docs/src/routes.js +++ b/docs/src/routes.js @@ -26,6 +26,7 @@ const Radio = (resolve) => require(['./pages/components/Radio'], resolve); const Select = (resolve) => require(['./pages/components/Select'], resolve); const Sidenav = (resolve) => require(['./pages/components/Sidenav'], resolve); const Snackbar = (resolve) => require(['./pages/components/Snackbar'], resolve); +const SpeedDial = (resolve) => require(['./pages/components/SpeedDial'], resolve); const Spinner = (resolve) => require(['./pages/components/Spinner'], resolve); const Subheader = (resolve) => require(['./pages/components/Subheader'], resolve); const Switch = (resolve) => require(['./pages/components/Switch'], resolve); @@ -172,6 +173,11 @@ const components = [ name: 'components:snackbar', component: Snackbar }, + { + path: '/components/speed-dial', + name: 'components:speed-dial', + component: SpeedDial + }, { path: '/components/spinner', name: 'components:spinner', diff --git a/src/components/mdButton/mdButton.scss b/src/components/mdButton/mdButton.scss index cf8220d..fca4a68 100644 --- a/src/components/mdButton/mdButton.scss +++ b/src/components/mdButton/mdButton.scss @@ -6,6 +6,7 @@ $button-radius: 2px; $button-fab-size: 56px; $button-fab-size-mini: 40px; +$button-fab-space: 24px; $button-dense-height: 32px; @@ -78,11 +79,11 @@ $button-icon-size: 40px; &.md-icon-button, &.md-fab { .md-icon { - margin-top: 1px; position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); + top: 1px; + right: 0; + bottom: 0; + left: 0; } } @@ -129,6 +130,7 @@ $button-icon-size: 40px; &.md-fab { width: $button-fab-size; height: $button-fab-size; + padding: 0; min-width: 0; overflow: hidden; box-shadow: $material-shadow-2dp; @@ -145,50 +147,6 @@ $button-icon-size: 40px; box-shadow: $material-shadow-5dp; } - &.md-fab-top-left { - position: absolute; - top: 16px; - left: 16px; - z-index: 10; - } - - &.md-fab-top-center { - position: absolute; - top: 16px; - left: 50%; - z-index: 10; - transform: translateX(-50%); - } - - &.md-fab-top-right { - position: absolute; - top: 16px; - right: 16px; - z-index: 10; - } - - &.md-fab-bottom-left { - position: absolute; - bottom: 16px; - left: 16px; - z-index: 10; - } - - &.md-fab-bottom-center { - position: absolute; - bottom: 16px; - left: 50%; - transform: translateX(-50%); - z-index: 10; - } - - &.md-fab-bottom-right { - position: absolute; - right: 16px; - bottom: 16px; - z-index: 10; - } - &.md-mini { width: $button-fab-size-mini; height: $button-fab-size-mini; @@ -232,6 +190,52 @@ $button-icon-size: 40px; } } +.md-fab, +.md-speed-dial { + &.md-fab-top-left, + &.md-fab-top-center, + &.md-fab-top-right, + &.md-fab-bottom-left, + &.md-fab-bottom-center, + &.md-fab-bottom-right { + margin: 0; + position: absolute; + z-index: 10; + } + + &.md-fab-top-left { + top: $button-fab-space; + left: $button-fab-space; + } + + &.md-fab-top-center { + top: $button-fab-space; + left: 50%; + transform: translateX(-50%); + } + + &.md-fab-top-right { + top: $button-fab-space; + right: $button-fab-space; + } + + &.md-fab-bottom-left { + bottom: $button-fab-space; + left: $button-fab-space; + } + + &.md-fab-bottom-center { + bottom: $button-fab-space; + left: 50%; + transform: translateX(-50%); + } + + &.md-fab-bottom-right { + right: $button-fab-space; + bottom: $button-fab-space; + } +} + .md-button-tooltip { &.md-tooltip-top { margin-top: -8px; diff --git a/src/components/mdSpeedDial/index.js b/src/components/mdSpeedDial/index.js new file mode 100644 index 0000000..1dd3699 --- /dev/null +++ b/src/components/mdSpeedDial/index.js @@ -0,0 +1,8 @@ +import mdSpeedDial from './mdSpeedDial.vue'; +import mdSpeedDialTheme from './mdSpeedDial.theme'; + +export default function install(Vue) { + Vue.component('md-speed-dial', Vue.extend(mdSpeedDial)); + + Vue.material.styles.push(mdSpeedDialTheme); +} diff --git a/src/components/mdSpeedDial/mdSpeedDial.scss b/src/components/mdSpeedDial/mdSpeedDial.scss new file mode 100644 index 0000000..b45a371 --- /dev/null +++ b/src/components/mdSpeedDial/mdSpeedDial.scss @@ -0,0 +1,142 @@ +@import '../../core/stylesheets/variables.scss'; + +.md-speed-dial { + display: flex; + flex-direction: column-reverse; + align-items: center; + + &.md-direction-top { + &.md-mode-fling { + [md-fab-trigger] ~ .md-button { + transform: scale(.95) translate3D(0, 80%, 0); + } + } + + [md-fab-trigger] { + margin-top: 8px; + + ~ .md-button { + margin-bottom: 16px; + } + } + } + + &.md-direction-right { + flex-direction: row; + justify-content: center; + + &.md-mode-fling { + [md-fab-trigger] ~ .md-button { + transform: scale(.95) translate3D(-80%, 0, 0); + } + } + + [md-fab-trigger] { + margin-right: 8px; + + ~ .md-button { + margin-left: 16px; + } + } + } + + &.md-direction-bottom { + flex-direction: column; + + &.md-mode-fling { + [md-fab-trigger] ~ .md-button { + transform: scale(.95) translate3D(0, -80%, 0); + } + } + + [md-fab-trigger] { + margin-bottom: 8px; + + ~ .md-button { + margin-top: 16px; + } + } + } + + &.md-direction-left { + flex-direction: row-reverse; + justify-content: center; + + &.md-mode-fling { + [md-fab-trigger] ~ .md-button { + transform: scale(.95) translate3D(80%, 0, 0); + } + } + + [md-fab-trigger] { + margin-left: 8px; + + ~ .md-button { + margin-right: 16px; + } + } + } + + &.md-mode-scale { + [md-fab-trigger] ~ .md-button { + transform: scale(.6); + } + } + + &.md-active { + [md-fab-trigger] { + ~ .md-button { + opacity: 1; + transform: translate3D(0, 0, 0) !important; + + @for $i from 1 through 10 { + &:nth-child(#{$i + 1}) { + transition-delay: $i * .05s; + } + } + } + + [md-icon-morph] { + transform: rotateZ(0); + opacity: 1; + + + .md-icon { + transform: rotateZ(90deg) scale(.8); + opacity: 0; + } + } + } + } + + .md-button { + margin: 0; + } + + [md-fab-trigger] { + position: relative; + z-index: 2; + + ~ .md-button { + position: relative; + z-index: 1; + opacity: 0; + transition: $swift-ease-out; + + @for $i from 1 through 10 { + &:nth-last-child(#{$i + 1}) { + transition-delay: $i * .05s; + } + } + } + } + + [md-icon-morph] + .md-icon, + [md-icon-morph] { + transition: $swift-ease-out; + } + + [md-icon-morph] { + opacity: 0; + transform: rotateZ(-90deg) scale(.8); + } +} diff --git a/src/components/mdSpeedDial/mdSpeedDial.theme b/src/components/mdSpeedDial/mdSpeedDial.theme new file mode 100644 index 0000000..8b5f450 --- /dev/null +++ b/src/components/mdSpeedDial/mdSpeedDial.theme @@ -0,0 +1,5 @@ +.THEME_NAME { + &.md-speed-dial { + + } +} diff --git a/src/components/mdSpeedDial/mdSpeedDial.vue b/src/components/mdSpeedDial/mdSpeedDial.vue new file mode 100644 index 0000000..fbcb82c --- /dev/null +++ b/src/components/mdSpeedDial/mdSpeedDial.vue @@ -0,0 +1,76 @@ + + + + + diff --git a/src/index.js b/src/index.js index a8d3d89..dd40658 100644 --- a/src/index.js +++ b/src/index.js @@ -21,6 +21,7 @@ import MdRadio from './components/mdRadio'; import MdSelect from './components/mdSelect'; import MdSidenav from './components/mdSidenav'; import MdSnackbar from './components/mdSnackbar'; +import MdSpeedDial from './components/mdSpeedDial'; import MdSpinner from './components/mdSpinner'; import MdSubheader from './components/mdSubheader'; import MdSwitch from './components/mdSwitch'; @@ -54,6 +55,7 @@ const options = { MdSelect, MdSidenav, MdSnackbar, + MdSpeedDial, MdSpinner, MdSubheader, MdSwitch,