mirror of
https://github.com/opf/openproject.git
synced 2026-06-14 03:30:14 +00:00
Merge remote-tracking branch 'origin/dev' into housekeeping/remove-angularjs
This commit is contained in:
+1
-1
@@ -37,7 +37,6 @@ dist: trusty
|
||||
cache:
|
||||
bundler: true
|
||||
directories:
|
||||
- frontend/node_modules/foundation-apps
|
||||
- public/assets
|
||||
- app/assets/javascripts/bundles
|
||||
- app/assets/javascripts/locales
|
||||
@@ -77,6 +76,7 @@ jobs:
|
||||
- stage: prepare cache
|
||||
name: 'Prepare cache'
|
||||
script:
|
||||
- bash script/ci/db_setup.sh
|
||||
- bash script/ci/cache_prepare.sh
|
||||
- stage: test
|
||||
name: 'npm'
|
||||
|
||||
@@ -251,7 +251,7 @@ group :development do
|
||||
end
|
||||
|
||||
group :development, :test do
|
||||
gem 'puma', '~> 3.12.0'
|
||||
gem 'puma', '~> 4.0.0'
|
||||
gem 'thin', '~> 1.7.2'
|
||||
|
||||
# Tracing and profiling gems
|
||||
@@ -285,7 +285,7 @@ platforms :mri, :mingw, :x64_mingw do
|
||||
end
|
||||
|
||||
group :opf_plugins do
|
||||
gem 'openproject-translations', git: 'https://github.com/opf/openproject-translations.git', branch: 'dev'
|
||||
gem 'openproject-translations', git: 'https://github.com/opf/openproject-translations.git', ref: 'e88f311daa95e8530686d3dafe2ffefc86f6c8bc'
|
||||
end
|
||||
|
||||
group :docker, optional: true do
|
||||
|
||||
+7
-7
@@ -58,8 +58,8 @@ GIT
|
||||
|
||||
GIT
|
||||
remote: https://github.com/opf/openproject-translations.git
|
||||
revision: 03086ece9d9c745d41c4af0bb236f5b15d58a19f
|
||||
branch: dev
|
||||
revision: e88f311daa95e8530686d3dafe2ffefc86f6c8bc
|
||||
ref: e88f311daa95e8530686d3dafe2ffefc86f6c8bc
|
||||
specs:
|
||||
openproject-translations (7.4.0)
|
||||
crowdin-api (~> 0.5.0)
|
||||
@@ -113,7 +113,7 @@ PATH
|
||||
remote: modules/backlogs
|
||||
specs:
|
||||
openproject-backlogs (1.0.0)
|
||||
acts_as_silent_list (~> 3.0.0)
|
||||
acts_as_list (~> 0.9.18)
|
||||
openproject-pdf_export
|
||||
|
||||
PATH
|
||||
@@ -293,9 +293,8 @@ GEM
|
||||
i18n (>= 0.7, < 2)
|
||||
minitest (~> 5.1)
|
||||
tzinfo (~> 1.1)
|
||||
acts_as_list (0.9.11)
|
||||
acts_as_list (0.9.19)
|
||||
activerecord (>= 3.0)
|
||||
acts_as_silent_list (3.0.0)
|
||||
acts_as_tree (2.8.0)
|
||||
activerecord (>= 3.0.0)
|
||||
addressable (2.6.0)
|
||||
@@ -648,7 +647,8 @@ GEM
|
||||
binding_of_caller (>= 0.7)
|
||||
pry (>= 0.9.11)
|
||||
public_suffix (3.0.3)
|
||||
puma (3.12.0)
|
||||
puma (4.0.0)
|
||||
nio4r (~> 2.0)
|
||||
rack (2.0.6)
|
||||
rack-accept (0.4.5)
|
||||
rack (>= 0.4)
|
||||
@@ -993,7 +993,7 @@ DEPENDENCIES
|
||||
pry-rails (~> 0.3.6)
|
||||
pry-rescue (~> 1.5.0)
|
||||
pry-stack_explorer (~> 0.4.9.2)
|
||||
puma (~> 3.12.0)
|
||||
puma (~> 4.0.0)
|
||||
rack-attack (~> 5.4.2)
|
||||
rack-mini-profiler
|
||||
rack-protection (~> 2.0.0)
|
||||
|
||||
@@ -27,6 +27,8 @@ $grid--header-width: 20px
|
||||
.widget-box
|
||||
height: 100%
|
||||
|
||||
&:hover icon-triggered-context-menu
|
||||
visibility: visible
|
||||
|
||||
&.-resizing
|
||||
border: 1px solid $primary-color
|
||||
@@ -38,6 +40,12 @@ $grid--header-width: 20px
|
||||
justify-content: center
|
||||
align-items: center
|
||||
|
||||
&.-placeholder
|
||||
pointer-events: none
|
||||
|
||||
&.-dragged
|
||||
display: none
|
||||
|
||||
.resizer
|
||||
margin-top: 0
|
||||
margin-left: auto
|
||||
@@ -47,6 +55,15 @@ $grid--header-width: 20px
|
||||
.cdk-drag-handle
|
||||
cursor: grab
|
||||
|
||||
.widget-box--header
|
||||
display: flex
|
||||
|
||||
.widget-box--header-title
|
||||
flex-grow: 1
|
||||
|
||||
icon-triggered-context-menu
|
||||
visibility: hidden
|
||||
|
||||
.grid--area-drag-handle
|
||||
margin-left: -19px
|
||||
padding-right: 1px
|
||||
@@ -147,3 +164,4 @@ $grid--header-width: 20px
|
||||
|
||||
&:last-of-type
|
||||
border-bottom: none
|
||||
|
||||
|
||||
@@ -34,5 +34,8 @@ div#search-results-counts
|
||||
a
|
||||
padding: 0 5px
|
||||
|
||||
.top-menu-search--wrapper
|
||||
float: left
|
||||
|
||||
.global-search--tabs
|
||||
margin-bottom: 1rem
|
||||
|
||||
@@ -224,6 +224,7 @@ thead.-sticky th
|
||||
.generic-table--empty-header
|
||||
padding: 0 6px
|
||||
height: $generic-table--header-height
|
||||
line-height: $generic-table--header-height
|
||||
border-bottom: 1px solid $table-row-border-color
|
||||
z-index: 1
|
||||
|
||||
|
||||
@@ -26,25 +26,9 @@
|
||||
// See docs/COPYRIGHT.rdoc for more details.
|
||||
//++
|
||||
|
||||
#watchers
|
||||
img
|
||||
vertical-align: middle
|
||||
margin-right: 7px
|
||||
|
||||
.delete
|
||||
vertical-align: sub
|
||||
|
||||
li
|
||||
list-style-type: none
|
||||
margin: 0 10px 0 0
|
||||
padding: 0
|
||||
float: left
|
||||
line-height: $user-avatar-mini-width
|
||||
|
||||
div#watchers
|
||||
margin-top: 25px
|
||||
> form > p
|
||||
margin-top: 5px
|
||||
.work-package--watchers
|
||||
user-avatar
|
||||
margin-right: 5px
|
||||
|
||||
.work-package--watchers.-read-only
|
||||
.remove-watcher-btn
|
||||
@@ -53,8 +37,3 @@ div#watchers
|
||||
// Fix margin for inplace-edit controls
|
||||
.work-package--watchers-lookup .dropdown-wrapper
|
||||
margin-bottom: 50px
|
||||
|
||||
// Position avatar-minis correctly in listing and typeahead
|
||||
#detail-panel-watchers
|
||||
img.avatar-mini
|
||||
float: inherit
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
float: left
|
||||
margin-right: 20px
|
||||
|
||||
&.-multi-line
|
||||
margin-bottom: 0
|
||||
line-height: 40px
|
||||
|
||||
input
|
||||
margin-top: 0px
|
||||
|
||||
@@ -19,5 +23,5 @@
|
||||
.ee-attribute-highlighting-upsale
|
||||
margin-bottom: 1.5rem
|
||||
|
||||
multi-toggled-select
|
||||
display: inline-block
|
||||
ng-select
|
||||
width: fit-content
|
||||
|
||||
@@ -154,7 +154,6 @@ body.-browser-edge
|
||||
height: 22px !important
|
||||
line-height: 22px !important
|
||||
|
||||
|
||||
.inplace-editing--container
|
||||
display: inline-block
|
||||
border: 1px solid transparent
|
||||
@@ -162,8 +161,10 @@ body.-browser-edge
|
||||
overflow: visible
|
||||
width: 100%
|
||||
|
||||
|
||||
// Special width rules for more or less fixed with fields
|
||||
.wp-table--cell-td.startDate,
|
||||
.wp-table--cell-td.dueDate
|
||||
width: 160px
|
||||
|
||||
.wp-table--cell-td img.thumbnail
|
||||
height: 40px
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
|
||||
// Highlight additional hierarchy table rows
|
||||
// that are not part of the normal result list
|
||||
body:not(.accessibility-mode)
|
||||
body
|
||||
.wp-table--hierarchy-aditional-row,
|
||||
.wp-table--hierarchy-aditional-row .wp-table--hierarchy-indicator-icon
|
||||
color: $table-row-hierarchies-row-font-color
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
body:not(.accessibility-mode )
|
||||
|
||||
body
|
||||
.wp-table--relations-aditional-row,
|
||||
.wp-table--relation-cell-td.-expanded
|
||||
background: $table-row-relations-row-background-color
|
||||
|
||||
@@ -163,7 +163,7 @@ i
|
||||
@supports (column-span: all)
|
||||
// Remove the outline on focus since that breaks the column in chrome
|
||||
// Chrome bug https://bugs.chromium.org/p/chromium/issues/detail?id=565116
|
||||
body:not(.accessibility-mode)
|
||||
body
|
||||
.attributes-key-value--value-container
|
||||
*:focus
|
||||
outline: 1px solid $gray
|
||||
|
||||
@@ -5,14 +5,6 @@
|
||||
float: left
|
||||
z-index: 0
|
||||
|
||||
.timeline-element--bg
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
&:hover:not(.-clamp-style)
|
||||
.leftHandle, .rightHandle
|
||||
background-color: rgba(1, 1, 1, 0.2)
|
||||
|
||||
.bar-label
|
||||
overflow: hidden
|
||||
padding: 0 0 0 5px
|
||||
@@ -34,14 +26,10 @@
|
||||
max-width: 20%
|
||||
height: 100%
|
||||
|
||||
&.-readonly
|
||||
cursor: not-allowed !important
|
||||
|
||||
.leftHandle
|
||||
cursor: not-allowed !important
|
||||
|
||||
.rightHandle
|
||||
cursor: not-allowed !important
|
||||
&:hover .timeline-element--bg:not(.-clamp-style)
|
||||
&~.leftHandle,
|
||||
&~.rightHandle
|
||||
background-color: rgba(1, 1, 1, 0.2)
|
||||
|
||||
&.-editable
|
||||
cursor: ew-resize
|
||||
@@ -52,6 +40,19 @@
|
||||
.rightHandle
|
||||
cursor: col-resize
|
||||
|
||||
.timeline-element--bg
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
&.-readonly
|
||||
cursor: not-allowed !important
|
||||
|
||||
&~.leftHandle
|
||||
cursor: not-allowed !important
|
||||
|
||||
&~.rightHandle
|
||||
cursor: not-allowed !important
|
||||
|
||||
.active-selection-mode
|
||||
|
||||
.timeline-element.bar.selection-start
|
||||
|
||||
@@ -20,6 +20,11 @@
|
||||
|
||||
#main
|
||||
background: #fff
|
||||
// This counters 'overflow: auto' active in the non print version
|
||||
// which will lead to only the first page being printed on some pages.
|
||||
// For whatever reasons, all the pages are displayed in the print rendering emulation
|
||||
// regardless of the overflow.
|
||||
overflow: initial
|
||||
|
||||
#content-wrapper
|
||||
width: 99%
|
||||
|
||||
@@ -29,11 +29,6 @@
|
||||
$hamburger-right: -3px
|
||||
$hamburger-width: 50px
|
||||
|
||||
// search bar has a min-width of 160px and should adapt to every screen size
|
||||
$search-input-width: calc(160px + 3vw)
|
||||
$search-input-width-expanded: calc(160px + 13vw)
|
||||
$search-input-height: 30px
|
||||
|
||||
%top-menu-hover-styles
|
||||
@include varprop(background, header-item-bg-hover-color)
|
||||
@include varprop(color, header-item-font-hover-color)
|
||||
@@ -169,121 +164,6 @@ $search-input-height: 30px
|
||||
left: 260px
|
||||
@include varprop(color, font-color-on-primary)
|
||||
|
||||
|
||||
.top-menu-search--wrapper
|
||||
float: left
|
||||
|
||||
.top-menu-search
|
||||
display: flex
|
||||
align-items: center
|
||||
position: relative
|
||||
height: $header-height
|
||||
line-height: $header-height
|
||||
margin: 0 15px
|
||||
|
||||
.top-menu-search--back-button
|
||||
display: none
|
||||
|
||||
.top-menu-search--button
|
||||
position: absolute
|
||||
right: 2px
|
||||
@include varprop(font-size, header-item-font-size)
|
||||
@include varprop(color, header-item-font-color)
|
||||
&:hover
|
||||
text-decoration: none
|
||||
&.-input-focused
|
||||
color: $header-search-field-font-color
|
||||
|
||||
.top-menu-search--loading
|
||||
top: $header-height - 11px // display directly under ng-input field
|
||||
height: 46px // ng-option height + 1px border
|
||||
z-index: 1051
|
||||
|
||||
#global-search-input
|
||||
width: $search-input-width
|
||||
font-size: 0.9rem
|
||||
-webkit-transition: width 0.2s ease-in-out
|
||||
transition: width 0.2s ease-in-out
|
||||
&::-ms-clear
|
||||
margin-right: 5px
|
||||
width: 20px
|
||||
|
||||
.ng-select-container
|
||||
background: transparent
|
||||
@include varprop(border-color, header-item-font-color)
|
||||
|
||||
.ng-arrow-wrapper
|
||||
display: none
|
||||
|
||||
.ng-clear-wrapper
|
||||
@include varprop(color, header-item-font-color)
|
||||
top: 1px
|
||||
width: 30px
|
||||
right: 25px
|
||||
text-align: center
|
||||
|
||||
.ng-input
|
||||
top: 0
|
||||
input
|
||||
@include varprop(color, header-item-font-color)
|
||||
height: $search-input-height
|
||||
cursor: text
|
||||
|
||||
.ng-placeholder
|
||||
@include varprop(color, header-item-font-color)
|
||||
|
||||
&.-expanded
|
||||
width: $search-input-width-expanded
|
||||
background: white
|
||||
border-radius: 4px
|
||||
color: $header-search-field-font-color
|
||||
|
||||
.ng-placeholder,
|
||||
.ng-clear-wrapper,
|
||||
input
|
||||
@include varprop(color, header-search-field-font-color)
|
||||
|
||||
.scroll-host
|
||||
@include styled-scroll-bar
|
||||
max-height: 80vh
|
||||
height: auto
|
||||
|
||||
.ng-option
|
||||
border-bottom: 1px solid #EAEAEA
|
||||
white-space: normal
|
||||
padding: 5px 10px
|
||||
&:last-child
|
||||
border-bottom: none
|
||||
&.ng-option-marked
|
||||
@include varprop(background-color, drop-down-hover-bg-color)
|
||||
@include varprop(color, header-drop-down-item-font-hover-color)
|
||||
&.ng-option-disabled
|
||||
display: none
|
||||
&.ng-option-selected
|
||||
@include varprop(background-color, drop-down-selected-bg-color)
|
||||
@include varprop(color, header-drop-down-item-font-hover-color)
|
||||
|
||||
.global-search--wp-id
|
||||
color: $gray-dark
|
||||
font-size: 13px
|
||||
white-space: nowrap
|
||||
|
||||
.global-search--option-wrapper
|
||||
padding: 5px 5px
|
||||
line-height: 25px
|
||||
min-height: 35px // line-height + padding
|
||||
word-break: break-word
|
||||
|
||||
.global-search--project-scope
|
||||
position: absolute
|
||||
right: 7px
|
||||
border: 1px solid $button--border-color
|
||||
font-size: 13px
|
||||
background: $button--background-color
|
||||
border-radius: 2px
|
||||
padding: 0 4px
|
||||
color: $body-font-color
|
||||
|
||||
#quick-search
|
||||
float: right
|
||||
|
||||
|
||||
@@ -29,27 +29,11 @@
|
||||
@include breakpoint(680px down)
|
||||
$hamburger-right: -3px
|
||||
$hamburger-width: 50px
|
||||
$search-input-height-mobile: 36px
|
||||
|
||||
#logo
|
||||
background-color: transparent
|
||||
|
||||
#top-menu
|
||||
&.-global-search-expanded
|
||||
#account-nav-right,
|
||||
#account-nav-left,
|
||||
#main-menu-toggle
|
||||
display: none
|
||||
|
||||
.top-menu-search
|
||||
width: 100vw
|
||||
margin: 0
|
||||
padding-right: 15px
|
||||
|
||||
.top-menu-search--button
|
||||
display: none
|
||||
@include varprop(color, header-item-font-color)
|
||||
|
||||
#nav-login-content
|
||||
float: none
|
||||
padding: 15px 20px
|
||||
@@ -81,49 +65,6 @@
|
||||
.nosidebar &
|
||||
left: 0px
|
||||
|
||||
#global-search-input
|
||||
display: none
|
||||
&.-expanded
|
||||
display: block
|
||||
width: calc(100vw - 50px)
|
||||
min-width: unset
|
||||
position: unset
|
||||
|
||||
.scroll-host
|
||||
max-height: calc(100vh - #{$header-height})
|
||||
|
||||
.ng-clear-wrapper
|
||||
width: 40px
|
||||
right: 0
|
||||
|
||||
.ng-select-bottom
|
||||
height: calc(100vh - #{$header-height})
|
||||
overflow-y: auto
|
||||
margin: 0
|
||||
|
||||
.ng-select-container
|
||||
height: $search-input-height-mobile !important
|
||||
border-radius: 4px
|
||||
|
||||
.ng-input input
|
||||
height: 36px
|
||||
// The font-size is necessary to avoid iOS to zoom in when being focused
|
||||
font-size: 16px
|
||||
|
||||
.top-menu-search--back-button
|
||||
display: initial
|
||||
width: 50px
|
||||
text-align: center
|
||||
@include varprop(color, header-item-font-color)
|
||||
&:hover, &:focus, &:active
|
||||
text-decoration: none
|
||||
|
||||
.top-menu-search--loading
|
||||
top: $header-height + 1px
|
||||
|
||||
.top-menu-search--button.-input-focused
|
||||
@include varprop(color, header-item-font-color)
|
||||
|
||||
#account-nav-right
|
||||
> li ul
|
||||
top: $header-height-mobile
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
Copyright (c) 2014 ZURB, inc.
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
GLOBAL
|
||||
------
|
||||
|
||||
Global styles and settings for Foundation for Apps are stored here. This file must always
|
||||
be imported, no matter what.
|
||||
|
||||
Includes:
|
||||
-
|
||||
*/
|
||||
|
||||
/// @Foundation.settings
|
||||
// Global Styles
|
||||
// This sets 1rem to be 16px
|
||||
$rem-base: 16px;
|
||||
|
||||
// The default font-size is set to 100% of the browser style sheet (usually 16px)
|
||||
// for compatibility with browser-based text zoom or user-set defaults.
|
||||
|
||||
// Since the typical default browser font-size is 16px, that makes the calculation for grid size.
|
||||
// If you want your base font-size to be different and not have it affect the grid breakpoints,
|
||||
// set $rem-base to $base-font-size and make sure $base-font-size is a px value.
|
||||
$base-font-size: 100% !default;
|
||||
|
||||
// $base-line-height is 24px while $base-font-size is 16px
|
||||
$base-line-height: 1.5 !default;
|
||||
|
||||
// Text selector helpers
|
||||
$headers: "h1,h2,h3,h4,h5,h6";
|
||||
|
||||
// We use these to define default font weights
|
||||
$font-weight-normal: normal !default;
|
||||
$font-weight-bold: bold !default;
|
||||
|
||||
// We use these to control various global styles
|
||||
$body-background: #fff !default;
|
||||
$body-font-color: #222 !default;
|
||||
$body-font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif !default;
|
||||
$body-font-weight: $font-weight-normal !default;
|
||||
$body-font-style: normal !default;
|
||||
$body-antialiased: true;
|
||||
|
||||
// Application Colors
|
||||
$primary-color: #00558b !default;
|
||||
$secondary-color: #f1f1f1 !default;
|
||||
$alert-color: #F04124 !default;
|
||||
$info-color: #A0D3E8 !default;
|
||||
$success-color: #43AC6A !default;
|
||||
$warning-color: #F08A24 !default;
|
||||
$dark-color: #232323 !default;
|
||||
$gray: #dfdfdf !default;
|
||||
$gray-dark: darken($gray, 8) !default;
|
||||
$gray-light: lighten($gray, 8) !default;
|
||||
|
||||
// We use these to make sure border radius matches unless we want it different.
|
||||
$global-radius: 4px !default;
|
||||
$global-rounded: 1000px !default;
|
||||
|
||||
// We use this for default spacing
|
||||
$global-padding: 1rem !default;
|
||||
$global-spacing: rem-calc(15) !default;
|
||||
///
|
||||
|
||||
// For internal use: a color map
|
||||
$foundation-colors: (
|
||||
primary: $primary-color,
|
||||
success: $success-color,
|
||||
warning: $warning-color,
|
||||
alert: $alert-color,
|
||||
dark: $dark-color,
|
||||
);
|
||||
|
||||
@include exports(global) {
|
||||
// Make extra sure we're using the whole window
|
||||
html, body {
|
||||
height: 100%;
|
||||
font-size: $base-font-size;
|
||||
}
|
||||
// Set box-sizing globally to handle padding and border widths
|
||||
html {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
*, *:before, *:after {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
// Default body styles
|
||||
body {
|
||||
background: $body-background;
|
||||
color: $body-font-color;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-family: $body-font-family;
|
||||
font-weight: $body-font-weight;
|
||||
font-style: $body-font-style;
|
||||
line-height: 1;
|
||||
position: relative;
|
||||
|
||||
@if $body-antialiased {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
// Grid Defaults to get images and embeds to work properly
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
-ms-interpolation-mode: bicubic;
|
||||
|
||||
// Get rid of gap under images by making them display: inline-block; by default
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
// Give all anchors and interactive directives the hover cusor
|
||||
a, [ui-sref], [zf-open], [zf-close], [zf-toggle] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#map_canvas,
|
||||
.map_canvas {
|
||||
img,
|
||||
embed,
|
||||
object { max-width: none !important; }
|
||||
}
|
||||
|
||||
.padding {
|
||||
padding: $global-padding;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,614 @@
|
||||
// FOUNDATION FOR APPS SETTINGS
|
||||
// ----------------------------
|
||||
//
|
||||
// Table of Contents:
|
||||
//
|
||||
// 1. CSS Exports
|
||||
// 2. Global Styles
|
||||
// 3. Breakpoints
|
||||
// 4. Typography
|
||||
// 5. Grid
|
||||
// 6. Button
|
||||
// 7. Accordion
|
||||
// 8. Action Sheet
|
||||
// 9. Block List
|
||||
// 10. Button Group
|
||||
// 11. Card
|
||||
// 12. Extras
|
||||
// 13. Forms
|
||||
// 14. Iconic
|
||||
// 15. Label
|
||||
// 16. Menu Bar
|
||||
// 17. Modal
|
||||
// 18. Motion UI
|
||||
// 19. Notification
|
||||
// 20. Off-canvas
|
||||
// 21. Panel
|
||||
// 22. Popup
|
||||
// 23. Switch
|
||||
// 24. Tabs
|
||||
// 25. Title Bar
|
||||
|
||||
@import "helpers/functions";
|
||||
|
||||
// 1. CSS Exports
|
||||
// - - - - - - - - - - - - - - -
|
||||
|
||||
// Change any value in this map from "true" to "false" to disable that component's CSS class output. You'll still be able to use the component's mixins, but none of our pre-written classes will be in your CSS.
|
||||
|
||||
// $include-css: (
|
||||
// accordion: true,
|
||||
// action-sheet: true,
|
||||
// block-list: true,
|
||||
// button: true,
|
||||
// button-group: true,
|
||||
// card: true,
|
||||
// coloring: true,
|
||||
// extras: true,
|
||||
// forms: true,
|
||||
// grid: true,
|
||||
// iconic: true,
|
||||
// label: true,
|
||||
// badge: true,
|
||||
// list: true,
|
||||
// menu-bar: true,
|
||||
// modal: true,
|
||||
// motion: true,
|
||||
// notification: true,
|
||||
// off-canvas: true,
|
||||
// panel: true,
|
||||
// popup: true,
|
||||
// switch: true,
|
||||
// tabs: true,
|
||||
// title-bar: true,
|
||||
// typography: true,
|
||||
// utilities: true,
|
||||
// );
|
||||
|
||||
// 2. Global Styles
|
||||
// - - - - - - - - - - - - - - -
|
||||
|
||||
// This sets 1rem to be 16px
|
||||
// $rem-base: 16px;
|
||||
|
||||
// The default font-size is set to 100% of the browser style sheet (usually 16px)
|
||||
// for compatibility with browser-based text zoom or user-set defaults.
|
||||
|
||||
// Since the typical default browser font-size is 16px, that makes the calculation for grid size.
|
||||
// If you want your base font-size to be different and not have it affect the grid breakpoints,
|
||||
// set $rem-base to $base-font-size and make sure $base-font-size is a px value.
|
||||
// $base-font-size: 100%;
|
||||
|
||||
// $base-line-height is 24px while $base-font-size is 16px
|
||||
// $base-line-height: 1.5;
|
||||
|
||||
// Text selector helpers
|
||||
// $headers: "h1,h2,h3,h4,h5,h6";
|
||||
|
||||
// We use these to define default font weights
|
||||
// $font-weight-normal: normal;
|
||||
// $font-weight-bold: bold;
|
||||
|
||||
// We use these to control various global styles
|
||||
// $body-background: #fff;
|
||||
// $body-font-color: #222;
|
||||
// $body-font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif;
|
||||
// $body-font-weight: $font-weight-normal;
|
||||
// $body-font-style: normal;
|
||||
// $body-antialiased: true;
|
||||
|
||||
// Application Colors
|
||||
// $primary-color: #00558b;
|
||||
// $secondary-color: #f1f1f1;
|
||||
// $alert-color: #F04124;
|
||||
// $info-color: #A0D3E8;
|
||||
// $success-color: #43AC6A;
|
||||
// $warning-color: #F08A24;
|
||||
// $dark-color: #232323;
|
||||
// $gray: #dfdfdf;
|
||||
// $gray-dark: darken($gray, 8);
|
||||
// $gray-light: lighten($gray, 8);
|
||||
|
||||
// We use these to make sure border radius matches unless we want it different.
|
||||
// $global-radius: 4px;
|
||||
// $global-rounded: 1000px;
|
||||
|
||||
// We use this for default spacing
|
||||
// $global-padding: 1rem;
|
||||
// $global-spacing: rem-calc(15);
|
||||
|
||||
// 3. Breakpoints
|
||||
// - - - - - - - - - - - - - - -
|
||||
|
||||
// These are our named breakpoints. You can use them in our breakpoint function like this: @include breakpoint(medium) { // Medium and larger styles }
|
||||
// $breakpoints: (
|
||||
// small: rem-calc(0),
|
||||
// medium: rem-calc(640),
|
||||
// large: rem-calc(1200),
|
||||
// xlarge: rem-calc(1440),
|
||||
// xxlarge: rem-calc(1920),
|
||||
// );
|
||||
|
||||
// All of the names in this list will be output as classes in your CSS, like small-12, medium-6, and so on.
|
||||
// $breakpoint-classes: (small medium large);
|
||||
|
||||
// 4. Typography
|
||||
// - - - - - - - - - - - - - - -
|
||||
|
||||
// We use these to control header font styles
|
||||
// $header-font-family: $body-font-family;
|
||||
// $header-font-weight: $font-weight-normal;
|
||||
// $header-font-style: $font-weight-normal;
|
||||
// $header-font-color: #222;
|
||||
// $header-line-height: 1.4;
|
||||
// $header-top-margin: .2rem;
|
||||
// $header-bottom-margin: .5rem;
|
||||
// $header-text-rendering: optimizeLegibility;
|
||||
|
||||
// We use these to control header font sizes
|
||||
// $h1-font-size: rem-calc(44);
|
||||
// $h2-font-size: rem-calc(37);
|
||||
// $h3-font-size: rem-calc(27);
|
||||
// $h4-font-size: rem-calc(23);
|
||||
// $h5-font-size: rem-calc(18);
|
||||
// $h6-font-size: 1rem;
|
||||
|
||||
// We use these to control header size reduction on small screens
|
||||
// $h1-font-reduction: rem-calc(10);
|
||||
// $h2-font-reduction: rem-calc(10);
|
||||
// $h3-font-reduction: rem-calc(5);
|
||||
// $h4-font-reduction: rem-calc(5);
|
||||
// $h5-font-reduction: 0;
|
||||
// $h6-font-reduction: 0;
|
||||
|
||||
// These control how subheaders are styled.
|
||||
// $subheader-line-height: 1.4;
|
||||
// $subheader-font-color: scale-color($header-font-color, $lightness: 35%);
|
||||
// $subheader-font-weight: $font-weight-normal;
|
||||
// $subheader-top-margin: .2rem;
|
||||
// $subheader-bottom-margin: .5rem;
|
||||
|
||||
// A general <small> styling
|
||||
// $small-font-size: 60%;
|
||||
// $small-font-color: scale-color($header-font-color, $lightness: 35%);
|
||||
|
||||
// We use these to style paragraphs
|
||||
// $paragraph-font-family: inherit;
|
||||
// $paragraph-font-weight: $font-weight-normal;
|
||||
// $paragraph-font-size: 1rem;
|
||||
// $paragraph-line-height: 1.6;
|
||||
// $paragraph-margin-bottom: rem-calc(20);
|
||||
// $paragraph-aside-font-size: rem-calc(14);
|
||||
// $paragraph-aside-line-height: 1.35;
|
||||
// $paragraph-aside-font-style: italic;
|
||||
// $paragraph-text-rendering: optimizeLegibility;
|
||||
|
||||
// We use these to style <code> tags
|
||||
// $code-color: grayscale($primary-color);
|
||||
// $code-font-family: Consolas, 'Liberation Mono', Courier, monospace;
|
||||
// $code-font-weight: $font-weight-normal;
|
||||
// $code-background-color: scale-color($secondary-color, $lightness: 70%);
|
||||
// $code-border-size: 1px;
|
||||
// $code-border-style: solid;
|
||||
// $code-border-color: scale-color($code-background-color, $lightness: -10%);
|
||||
// $code-padding: rem-calc(2) rem-calc(5) rem-calc(1);
|
||||
|
||||
// We use these to style anchors
|
||||
// $anchor-text-decoration: none;
|
||||
// $anchor-text-decoration-hover: none;
|
||||
// $anchor-font-color: $primary-color;
|
||||
// $anchor-font-color-hover: scale-color($anchor-font-color, $lightness: -14%);
|
||||
|
||||
// We use these to style the <hr> element
|
||||
// $hr-border-width: 1px;
|
||||
// $hr-border-style: solid;
|
||||
// $hr-border-color: #ddd;
|
||||
// $hr-margin: rem-calc(20);
|
||||
|
||||
// We use these to style lists
|
||||
// $list-font-family: $paragraph-font-family;
|
||||
// $list-font-size: $paragraph-font-size;
|
||||
// $list-line-height: $paragraph-line-height;
|
||||
// $list-margin-bottom: $paragraph-margin-bottom;
|
||||
// $list-style-position: outside;
|
||||
// $list-side-margin: 1.1rem;
|
||||
// $list-ordered-side-margin: 1.4rem;
|
||||
// $list-side-margin-no-bullet: 0;
|
||||
// $list-nested-margin: rem-calc(20);
|
||||
// $definition-list-header-weight: $font-weight-bold;
|
||||
// $definition-list-header-margin-bottom: .3rem;
|
||||
// $definition-list-margin-bottom: rem-calc(12);
|
||||
|
||||
// We use these to style blockquotes
|
||||
// $blockquote-font-color: scale-color($header-font-color, $lightness: 35%);
|
||||
// $blockquote-padding: rem-calc(9 20 0 19);
|
||||
// $blockquote-border: 1px solid #ddd;
|
||||
// $blockquote-cite-font-size: rem-calc(13);
|
||||
// $blockquote-cite-font-color: scale-color($header-font-color, $lightness: 23%);
|
||||
// $blockquote-cite-link-color: $blockquote-cite-font-color;
|
||||
|
||||
// Acronym styles
|
||||
// $acronym-underline: 1px dotted #ddd;
|
||||
|
||||
// 5. Grid
|
||||
// - - - - - - - - - - - - - - -
|
||||
|
||||
// $container-width: rem-calc(900);
|
||||
// $block-padding: $global-padding;
|
||||
// $total-columns: 12;
|
||||
// $block-grid-max-size: 6;
|
||||
|
||||
// 6. Button
|
||||
// - - - - - - - - - - - - - - -
|
||||
|
||||
// $button-padding: 0.85em 1em;
|
||||
// $button-margin: 0 $global-padding $global-padding 0;
|
||||
// $button-style: solid;
|
||||
// $button-background: $primary-color;
|
||||
// $button-background-hover: scale-color($button-background, $lightness: -15%);
|
||||
// $button-color: auto;
|
||||
// $button-radius: 0;
|
||||
// $button-sizes: (
|
||||
// tiny: 0.7,
|
||||
// small: 0.8,
|
||||
// medium: 1,
|
||||
// large: 1.3,
|
||||
// );
|
||||
// $button-font-size: 0.9rem;
|
||||
// $button-opacity-disabled: 0.5;
|
||||
// $button-tag-selector: false;
|
||||
|
||||
// 7. Accordion
|
||||
// - - - - - - - - - - - - - - -
|
||||
|
||||
// $accordion-border: 1px solid $gray-dark;
|
||||
|
||||
// $accordion-title-background: $gray-light;
|
||||
// $accordion-title-background-hover: smartscale($accordion-title-background, 5%);
|
||||
// $accordion-title-background-active: smartscale($accordion-title-background, 3%);
|
||||
// $accordion-title-color: isitlight($accordion-title-background);
|
||||
// $accordion-title-color-active: isitlight($accordion-title-background);
|
||||
|
||||
// $accordion-title-padding: $global-padding;
|
||||
// $accordion-content-padding: $global-padding;
|
||||
|
||||
// 8. Action Sheet
|
||||
// - - - - - - - - - - - - - - -
|
||||
|
||||
// $actionsheet-background: white;
|
||||
// $actionsheet-border-color: #ccc;
|
||||
// $actionsheet-animate: transform opacity;
|
||||
// $actionsheet-animation-speed: 0.25s;
|
||||
// $actionsheet-width: 300px;
|
||||
// $actionsheet-radius: 4px;
|
||||
// $actionsheet-shadow: 0 -3px 10px rgba(black, 0.25);
|
||||
// $actionsheet-padding: $global-padding;
|
||||
// $actionsheet-tail-size: 10px;
|
||||
|
||||
// $actionsheet-popup-shadow: 0 0 10px rgba(black, 0.25);
|
||||
|
||||
// $actionsheet-link-color: #000;
|
||||
// $actionsheet-link-background-hover: smartscale($actionsheet-background);
|
||||
|
||||
// 9. Block List
|
||||
// - - - - - - - - - - - - - - -
|
||||
|
||||
// $blocklist-background: #fff;
|
||||
// $blocklist-fullbleed: true;
|
||||
// $blocklist-fontsize: 1rem;
|
||||
|
||||
// $blocklist-item-padding: 0.8rem 1rem;
|
||||
// $blocklist-item-color: isitlight($blocklist-background, #000, #fff);
|
||||
// $blocklist-item-background-hover: smartscale($blocklist-background, 4.5%);
|
||||
// $blocklist-item-color-disabled: #999;
|
||||
// $blocklist-item-border: 1px solid smartscale($blocklist-background, 18.5%);
|
||||
|
||||
// $blocklist-item-label-color: scale-color($blocklist-item-color, $lightness: 60%);
|
||||
// $blocklist-item-icon-size: 0.8;
|
||||
|
||||
// $blocklist-header-fontsize: 0.8em;
|
||||
// $blocklist-header-color: smartscale($blocklist-item-color, 40%);
|
||||
// $blocklist-header-uppercase: true;
|
||||
|
||||
// $blocklist-check-icons: true;
|
||||
|
||||
// 10. Button Group
|
||||
// - - - - - - - - - - - - - - -
|
||||
|
||||
// $btngroup-background: $primary-color;
|
||||
// $btngroup-color: #fff;
|
||||
// $btngroup-radius: $button-radius;
|
||||
|
||||
// 11. Card
|
||||
// - - - - - - - - - - - - - - -
|
||||
|
||||
// $card-background: #fff;
|
||||
// $card-color: isitlight($card-background);
|
||||
// $card-border: 1px solid smartscale($card-background, 7%);
|
||||
// $card-radius: $global-radius;
|
||||
// $card-shadow: 0 1px 2px rgba(#000, 0.2);
|
||||
// $card-padding: $global-padding;
|
||||
// $card-margin: 0.5rem;
|
||||
|
||||
// $card-divider-background: smartscale($card-background, 7%);
|
||||
|
||||
// 12. Extras
|
||||
// - - - - - - - - - - - - - - -
|
||||
|
||||
// $closebutton-position: (top right);
|
||||
// $closebutton-size: 2em;
|
||||
// $closebutton-lineheight: 0.5;
|
||||
// $closebutton-color: #999;
|
||||
// $closebutton-color-hover: #333;
|
||||
|
||||
// $thumbnail-padding: 0.5rem;
|
||||
// $thumbnail-shadow: 0 3px 15px rgba(black, 0.25);
|
||||
|
||||
// 13. Forms
|
||||
// - - - - - - - - - - - - - - -
|
||||
|
||||
// Basic form variables
|
||||
// $form-fontsize: 1rem;
|
||||
// $form-padding: 0.5rem;
|
||||
|
||||
// Text fields
|
||||
// $input-color: #000;
|
||||
// $input-color-hover: $input-color;
|
||||
// $input-color-focus: $input-color;
|
||||
// $input-background: #fff;
|
||||
// $input-background-hover: $input-background;
|
||||
// $input-background-focus: $input-background;
|
||||
// $input-background-disabled: smartscale($input-background);
|
||||
// $input-border: 1px solid #ccc;
|
||||
// $input-border-hover: 1px solid #bbb;
|
||||
// $input-border-focus: 1px solid #999;
|
||||
// $input-cursor-disabled: not-allowed;
|
||||
|
||||
// Select menus
|
||||
// $select-color: #000;
|
||||
// $select-background: #fafafa;
|
||||
// $select-background-hover: smartscale($select-background, 4%);
|
||||
// $select-arrow: true;
|
||||
// $select-arrow-color: $select-color;
|
||||
|
||||
// Labels
|
||||
// $form-label-fontsize: 0.9rem;
|
||||
// $form-label-margin: 0.5rem;
|
||||
// $form-label-color: #333;
|
||||
|
||||
// Inline labels
|
||||
// $inlinelabel-color: #333;
|
||||
// $inlinelabel-background: #eee;
|
||||
// $inlinelabel-border: $input-border;
|
||||
|
||||
// Range slider
|
||||
// $slider-background: #ddd;
|
||||
// $slider-height: 1rem;
|
||||
// $slider-radius: 0px;
|
||||
// $slider-thumb-height: 1.5rem;
|
||||
// $slider-thumb-color: $primary-color;
|
||||
// $slider-thumb-radius: 0px;
|
||||
|
||||
// Progress and meter
|
||||
// $meter-height: 1.5rem;
|
||||
// $meter-background: #ccc;
|
||||
// $meter-fill: $primary-color;
|
||||
// $meter-fill-high: $success-color;
|
||||
// $meter-fill-medium: #e7cf00;
|
||||
// $meter-fill-low: $alert-color;
|
||||
// $meter-radius: 0;
|
||||
|
||||
// 14. Iconic
|
||||
// - - - - - - - - - - - - - - -
|
||||
|
||||
// $iconic-primary-fill: $primary-color;
|
||||
// $iconic-primary-stroke: $primary-color;
|
||||
// $iconic-accent-fill: $iconic-primary-fill;
|
||||
// $iconic-accent-stroke: $iconic-accent-fill;
|
||||
|
||||
// 15. Label
|
||||
// - - - - - - - - - - - - - - -
|
||||
|
||||
// $label-fontsize: 0.8rem;
|
||||
// $label-padding: ($global-padding / 3) ($global-padding / 2);
|
||||
// $label-radius: 0;
|
||||
// $label-background: $primary-color;
|
||||
// $label-color: isitlight($primary-color);
|
||||
|
||||
// $badge-fontsize: 0.8em;
|
||||
// $badge-diameter: 1.5rem;
|
||||
// $badge-background: $primary-color;
|
||||
// $badge-color: #fff;
|
||||
|
||||
// 16. Menu Bar
|
||||
// - - - - - - - - - - - - - - -
|
||||
|
||||
// $menubar-fontsize: 1rem;
|
||||
// $menubar-background: #fff;
|
||||
// $menubar-background-hover: smartscale($menubar-background, 7%);
|
||||
// $menubar-background-active: $menubar-background-hover;
|
||||
// $menubar-color: isitlight($menubar-background);
|
||||
// $menubar-color-hover: $menubar-color;
|
||||
// $menubar-color-active: $menubar-color-hover;
|
||||
|
||||
// $menubar-item-padding: $global-padding;
|
||||
// $menubar-icon-size: 25px;
|
||||
// $menubar-icon-spacing: $menubar-item-padding;
|
||||
|
||||
// 17. Modal
|
||||
// - - - - - - - - - - - - - - -
|
||||
|
||||
// $modal-background: #fff;
|
||||
// $modal-border: 0;
|
||||
// $modal-radius: 0px;
|
||||
// $modal-shadow: none;
|
||||
// $modal-zindex: 1000;
|
||||
// $modal-sizes: (
|
||||
// tiny: 300px,
|
||||
// small: 500px,
|
||||
// medium: 600px,
|
||||
// large: 800px,
|
||||
// );
|
||||
|
||||
// $modal-overlay-class: 'modal-overlay';
|
||||
// $modal-overlay-background: rgba(#333, 0.7);
|
||||
|
||||
// 18. Motion UI
|
||||
// - - - - - - - - - - - - - - -
|
||||
|
||||
// Classes to use when triggering in/out animations
|
||||
// $motion-class: (
|
||||
// in: "ng-enter",
|
||||
// out: "ng-leave",
|
||||
// );
|
||||
// $motion-class-active: (
|
||||
// in: "ng-enter-active",
|
||||
// out: "ng-leave-active",
|
||||
// );
|
||||
// $motion-class-stagger: (
|
||||
// in: "ng-enter-stagger",
|
||||
// out: "ng-leave-stagger",
|
||||
// );
|
||||
// $motion-class-showhide: (
|
||||
// in: "ng-hide-remove",
|
||||
// out: "ng-hide-add",
|
||||
// );
|
||||
// $motion-class-showhide-active: (
|
||||
// in: "ng-hide-remove-active",
|
||||
// out: "ng-hide-add-active",
|
||||
// );
|
||||
|
||||
// Set if movement-based transitions should also fade the element in and out
|
||||
// $motion-slide-and-fade: false;
|
||||
// $motion-hinge-and-fade: true;
|
||||
// $motion-scale-and-fade: true;
|
||||
// $motion-spin-and-fade: true;
|
||||
|
||||
// Default speed for transitions and animations
|
||||
// $motion-duration-default: 500ms;
|
||||
|
||||
// Slow and fast modifiders
|
||||
// $motion-duration-slow: 750ms;
|
||||
// $motion-duration-fast: 250ms;
|
||||
// $motion-stagger-duration-default: 150ms;
|
||||
// $motion-stagger-duration-short: 50ms;
|
||||
// $motion-stagger-duration-long: 300ms;
|
||||
|
||||
// Default timing function for transitions and animations
|
||||
// $motion-timing-default: ease;
|
||||
|
||||
// Built-in and custom easing functions
|
||||
// Every item in this map becomes a CSS class
|
||||
// $motion-timings: (
|
||||
// linear: linear,
|
||||
// ease: ease,
|
||||
// easeIn: ease-in,
|
||||
// easeOut: ease-out,
|
||||
// easeInOut: ease-in-out,
|
||||
// bounceIn: cubic-bezier(0.485, 0.155, 0.240, 1.245),
|
||||
// bounceOut: cubic-bezier(0.485, 0.155, 0.515, 0.845),
|
||||
// bounceInOut: cubic-bezier(0.760, -0.245, 0.240, 1.245),
|
||||
// );
|
||||
|
||||
// Default delay for all transitions and animations
|
||||
// $motion-delay-default: 0;
|
||||
// Short and long delay modifiers
|
||||
// $motion-delay-short: 300ms;
|
||||
// $motion-delay-long: 700ms;
|
||||
|
||||
// 19. Notification
|
||||
// - - - - - - - - - - - - - - -
|
||||
|
||||
// $notification-default-position: right top;
|
||||
// $notification-width: rem-calc(400);
|
||||
// $notification-offset: $global-padding;
|
||||
|
||||
// $notification-background: $primary-color;
|
||||
// $notification-color: white;
|
||||
// $notification-padding: $global-padding;
|
||||
// $notification-radius: 4px;
|
||||
|
||||
// $notification-icon-size: 60px;
|
||||
// $notification-icon-margin: $global-padding;
|
||||
// $notification-icon-align: top;
|
||||
|
||||
|
||||
// 20. Off-canvas
|
||||
// - - - - - - - - - - - - - - -
|
||||
|
||||
// $offcanvas-size-horizontal: 250px;
|
||||
// $offcanvas-size-vertical: 250px;
|
||||
|
||||
// $offcanvas-background: #fff;
|
||||
// $offcanvas-color: isitlight($offcanvas-background);
|
||||
// $offcanvas-padding: 0;
|
||||
// $offcanvas-shadow: 3px 0 10px rgba(black, 0.25);
|
||||
// $offcanvas-animation-speed: 0.25s;
|
||||
|
||||
// $offcanvas-frame-selector: '.grid-frame';
|
||||
|
||||
// 21. Panel
|
||||
// - - - - - - - - - - - - - - -
|
||||
|
||||
// $panel-size-horizontal: 300px;
|
||||
// $panel-size-vertical: 300px;
|
||||
// $panel-padding: 0;
|
||||
|
||||
// $panel-background: #fff;
|
||||
// $panel-shadow: 3px 0 10px rgba(black, 0.25);
|
||||
|
||||
// DEPRECATED: these variables will be removed in a future version.
|
||||
// $panel-animation-speed: 0.25s;
|
||||
|
||||
// 22. Popup
|
||||
// - - - - - - - - - - - - - - -
|
||||
|
||||
// $popup-width: rem-calc(300);
|
||||
// $popup-background: #fff;
|
||||
// $popup-border: 0;
|
||||
// $popup-radius: 0;
|
||||
// $popup-shadow: 0 0 10px rgba(#000, 0.25);
|
||||
|
||||
// 23. Switch
|
||||
// - - - - - - - - - - - - - - -
|
||||
|
||||
// $switch-width: rem-calc(50);
|
||||
// $switch-height: rem-calc(32);
|
||||
// $switch-background: #ccc;
|
||||
// $switch-background-active: $primary-color;
|
||||
// $switch-border: 0;
|
||||
// $switch-radius: 9999px;
|
||||
// $switch-animation-speed: 0.15s;
|
||||
|
||||
// $switch-paddle-color: white;
|
||||
// $switch-paddle-offset: 4px;
|
||||
|
||||
// 24. Tabs
|
||||
// - - - - - - - - - - - - - - -
|
||||
|
||||
// $tabstrip-background: transparent;
|
||||
|
||||
// $tab-title-background: $gray-light;
|
||||
// $tab-title-background-hover: smartscale($tab-title-background, 5%);
|
||||
// $tab-title-background-active: smartscale($tab-title-background, 3%);
|
||||
// $tab-title-color: isitlight($tab-title-background);
|
||||
// $tab-title-color-active: $tab-title-color;
|
||||
|
||||
// $tab-title-padding: $global-padding;
|
||||
// $tab-content-padding: $global-padding;
|
||||
|
||||
// 25. Title Bar
|
||||
// - - - - - - - - - - - - - - -
|
||||
|
||||
// $titlebar-center-width: 50%;
|
||||
// $titlebar-side-width: (100% - $titlebar-center-width) / 2;
|
||||
// $titlebar-background: #eee;
|
||||
// $titlebar-color: #000;
|
||||
// $titlebar-border: 1px solid #ccc;
|
||||
// $titlebar-padding: $global-padding;
|
||||
// $titlebar-item-classes: (
|
||||
// center: 'center',
|
||||
// left: 'left',
|
||||
// right: 'right',
|
||||
// title: 'title',
|
||||
// );
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
ACCORDION
|
||||
---------
|
||||
|
||||
The trusy accordion allows you to create a series of vertical tabs.
|
||||
*/
|
||||
|
||||
/// @Foundation.settings
|
||||
// Accordion
|
||||
$accordion-border: 1px solid $gray-dark !default;
|
||||
|
||||
$accordion-title-background: $gray-light !default;
|
||||
$accordion-title-background-hover: smartscale($accordion-title-background, 5%) !default;
|
||||
$accordion-title-background-active: smartscale($accordion-title-background, 3%) !default;
|
||||
$accordion-title-color: isitlight($accordion-title-background) !default;
|
||||
$accordion-title-color-active: isitlight($accordion-title-background) !default;
|
||||
|
||||
$accordion-title-padding: $global-padding !default;
|
||||
$accordion-content-padding: $global-padding !default;
|
||||
///
|
||||
|
||||
@mixin accordion-title(
|
||||
$background: $accordion-title-background,
|
||||
$background-hover: $accordion-title-background-hover,
|
||||
$background-active: $accordion-title-background-active,
|
||||
$color: $accordion-title-color,
|
||||
$color-active: $accordion-title-color-active,
|
||||
$padding: $accordion-title-padding
|
||||
) {
|
||||
padding: $padding;
|
||||
background: $background;
|
||||
color: $color;
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background: $background-hover;
|
||||
}
|
||||
|
||||
.is-active > & {
|
||||
background: $background-active;
|
||||
color: $color-active;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin accordion-content(
|
||||
$padding: $accordion-content-padding
|
||||
) {
|
||||
padding: $padding;
|
||||
|
||||
display: none;
|
||||
.is-active > & {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
@include exports(accordion) {
|
||||
.accordion {
|
||||
@if hasvalue($accordion-border) {
|
||||
border: $accordion-border;
|
||||
}
|
||||
}
|
||||
.accordion-item {
|
||||
|
||||
}
|
||||
.accordion-title {
|
||||
@include accordion-title;
|
||||
}
|
||||
.accordion-content {
|
||||
@include accordion-content;
|
||||
}
|
||||
}
|
||||
+265
@@ -0,0 +1,265 @@
|
||||
/*
|
||||
ACTION SHEET
|
||||
------------
|
||||
|
||||
A dropdown menu that sticks to the bottom of the screen on small devices, and becomes a dropdown menu on larger devices.
|
||||
*/
|
||||
|
||||
/// @Foundation.settings
|
||||
// Action Sheet
|
||||
$actionsheet-background: white !default;
|
||||
$actionsheet-border-color: #ccc !default;
|
||||
$actionsheet-animate: transform opacity !default;
|
||||
$actionsheet-animation-speed: 0.25s !default;
|
||||
$actionsheet-width: 300px !default;
|
||||
$actionsheet-radius: 4px !default;
|
||||
$actionsheet-shadow: 0 -3px 10px rgba(black, 0.25) !default;
|
||||
$actionsheet-padding: $global-padding !default;
|
||||
$actionsheet-tail-size: 10px !default;
|
||||
|
||||
$actionsheet-popup-shadow: 0 0 10px rgba(black, 0.25) !default;
|
||||
|
||||
$actionsheet-link-color: #000 !default;
|
||||
$actionsheet-link-background-hover: smartscale($actionsheet-background) !default;
|
||||
///
|
||||
|
||||
/*
|
||||
Styles for the list inside an action sheet.
|
||||
Don't include this mixin if you want to build custom controls inside the sheet.
|
||||
*/
|
||||
@mixin action-sheet-menu(
|
||||
$padding: $actionsheet-padding,
|
||||
$color: $actionsheet-link-color,
|
||||
$border-color: $actionsheet-border-color,
|
||||
$background-hover: $actionsheet-link-background-hover
|
||||
) {
|
||||
// Menu container
|
||||
ul {
|
||||
margin: -($padding);
|
||||
margin-top: 0;
|
||||
list-style-type: none;
|
||||
user-select: none;
|
||||
|
||||
// If the menu has no content above it
|
||||
&:first-child {
|
||||
margin-top: -$padding;
|
||||
|
||||
li:first-child {
|
||||
border-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Menu links
|
||||
a {
|
||||
display: block;
|
||||
padding: $padding * 0.8;
|
||||
line-height: 1;
|
||||
color: $color;
|
||||
border-top: 1px solid $border-color;
|
||||
|
||||
&:hover {
|
||||
color: $color;
|
||||
background: $background-hover;
|
||||
}
|
||||
}
|
||||
|
||||
.alert > a {
|
||||
color: $alert-color;
|
||||
}
|
||||
.disabled > a {
|
||||
pointer-events: none;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Styles for the action sheet container. Action sheets pin to the top or bottom of the screen.
|
||||
*/
|
||||
@mixin action-sheet(
|
||||
$position: bottom,
|
||||
$shadow: $actionsheet-shadow,
|
||||
$animate: $actionsheet-animate,
|
||||
$animation-speed: $actionsheet-animation-speed,
|
||||
$padding: $actionsheet-padding,
|
||||
$background: $actionsheet-background
|
||||
) {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
z-index: 1000;
|
||||
width: 100%;
|
||||
padding: $padding;
|
||||
background: $background;
|
||||
text-align: center;
|
||||
transition-property: $animate;
|
||||
transition-duration: $animation-speed;
|
||||
transition-timing-function: ease-out;
|
||||
|
||||
@if hasvalue($shadow) {
|
||||
box-shadow: $shadow;
|
||||
}
|
||||
|
||||
// Positions
|
||||
@if $position == bottom {
|
||||
bottom: 0;
|
||||
transform: translateY(100%);
|
||||
|
||||
&.is-active {
|
||||
transform: translateY(0%);
|
||||
}
|
||||
}
|
||||
// These two don't quite work as planned yet
|
||||
@else if $position == top {
|
||||
top: 0;
|
||||
transform: translateY(-100%);
|
||||
|
||||
&.is-active {
|
||||
transform: translateY(0%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin popup-menu(
|
||||
$position: bottom,
|
||||
$background: $actionsheet-background,
|
||||
$width: $actionsheet-width,
|
||||
$radius: $actionsheet-radius,
|
||||
$shadow: $actionsheet-popup-shadow,
|
||||
$tail-size: $actionsheet-tail-size
|
||||
) {
|
||||
/*
|
||||
Core styles
|
||||
*/
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
width: $width;
|
||||
border-radius: $radius;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
|
||||
/*
|
||||
Menu shadow
|
||||
*/
|
||||
@if hasvalue($shadow) {
|
||||
box-shadow: $shadow;
|
||||
}
|
||||
|
||||
/*
|
||||
Active state
|
||||
*/
|
||||
&.is-active {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
/*
|
||||
Menu tail
|
||||
*/
|
||||
&::before, &::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
display: block;
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
border-left: $tail-size solid transparent;
|
||||
border-right: $tail-size solid transparent;
|
||||
margin-left: -($tail-size);
|
||||
}
|
||||
|
||||
/*
|
||||
Positioning
|
||||
*/
|
||||
@if $position == bottom {
|
||||
top: auto;
|
||||
bottom: 0;
|
||||
transform: translateX(-50%) translateY(110%);
|
||||
&.is-active {
|
||||
transform: translateX(-50%) translateY(100%);
|
||||
}
|
||||
|
||||
&::before, &::after {
|
||||
top: -($tail-size);
|
||||
bottom: auto;
|
||||
border-top: 0;
|
||||
border-bottom: $tail-size solid $background;
|
||||
}
|
||||
&::before {
|
||||
top: -($tail-size + 2);
|
||||
border-bottom-color: rgba(black, 0.15);
|
||||
}
|
||||
|
||||
}
|
||||
@else if $position == top {
|
||||
top: 0;
|
||||
bottom: auto;
|
||||
transform: translateX(-50%) translateY(-120%);
|
||||
&.is-active {
|
||||
transform: translateX(-50%) translateY(-110%);
|
||||
}
|
||||
|
||||
&::before, &::after {
|
||||
top: auto;
|
||||
bottom: -($tail-size);
|
||||
border-top: $tail-size solid $background;
|
||||
border-bottom: 0;
|
||||
}
|
||||
&::before {
|
||||
bottom: -($tail-size + 2);
|
||||
border-top-color: rgba(black, 0.15);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include exports(action-sheet) {
|
||||
.action-sheet-container {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
|
||||
.button {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
.action-sheet {
|
||||
@include action-sheet;
|
||||
@include action-sheet-menu;
|
||||
|
||||
@include breakpoint(medium) {
|
||||
@include popup-menu;
|
||||
|
||||
&.top {
|
||||
@include popup-menu(top);
|
||||
}
|
||||
}
|
||||
|
||||
&.primary {
|
||||
background: $primary-color;
|
||||
color: isitlight($primary-color);
|
||||
border: 0;
|
||||
&::before { display: none; }
|
||||
&::before, &::after { border-top-color: $primary-color; }
|
||||
&.top::before, &.top::after { border-bottom-color: $primary-color; }
|
||||
|
||||
@include action-sheet-menu(
|
||||
$color: isitlight($primary-color),
|
||||
$border-color: smartscale($primary-color, 10%),
|
||||
$background-hover: smartscale($primary-color)
|
||||
);
|
||||
}
|
||||
&.dark {
|
||||
background: $dark-color;
|
||||
color: isitlight($dark-color);
|
||||
border: 0;
|
||||
&::before { display: none; }
|
||||
&::before, &::after { border-top-color: $dark-color; }
|
||||
&.top::before, &.top::after { border-bottom-color: $dark-color; }
|
||||
|
||||
@include action-sheet-menu(
|
||||
$color: isitlight($dark-color),
|
||||
$border-color: smartscale($dark-color, 10%),
|
||||
$background-hover: smartscale($dark-color)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
+350
@@ -0,0 +1,350 @@
|
||||
/*
|
||||
BLOCK LIST
|
||||
----------
|
||||
|
||||
A generic list component that can accomodate a variety of styles and controls.
|
||||
|
||||
Features:
|
||||
- Icons
|
||||
- Labels
|
||||
- Chevrons
|
||||
- Text fields
|
||||
- Dropdown menus
|
||||
- Checkbox/radio inputs
|
||||
*/
|
||||
|
||||
/// @Foundation.settings
|
||||
// Block List
|
||||
$blocklist-background: #fff !default;
|
||||
$blocklist-fullbleed: true !default;
|
||||
$blocklist-fontsize: 1rem !default;
|
||||
|
||||
$blocklist-item-padding: 0.8rem 1rem !default;
|
||||
$blocklist-item-color: isitlight($blocklist-background, #000, #fff) !default;
|
||||
$blocklist-item-background-hover: smartscale($blocklist-background, 4.5%) !default;
|
||||
$blocklist-item-color-disabled: #999 !default;
|
||||
$blocklist-item-border: 1px solid smartscale($blocklist-background, 18.5%) !default;
|
||||
|
||||
$blocklist-item-label-color: scale-color($blocklist-item-color, $lightness: 60%) !default;
|
||||
$blocklist-item-icon-size: 0.8 !default;
|
||||
|
||||
$blocklist-header-fontsize: 0.8em !default;
|
||||
$blocklist-header-color: smartscale($blocklist-item-color, 40%) !default;
|
||||
$blocklist-header-uppercase: true;
|
||||
|
||||
$blocklist-check-icons: true !default;
|
||||
///
|
||||
|
||||
/*
|
||||
Adds styles for a block list container.
|
||||
|
||||
$font-size: global font size for the list.
|
||||
$full-bleed: when "true", the margins of the list invert to line it up with the edge of a padded element.
|
||||
*/
|
||||
%block-list-container {
|
||||
margin-bottom: 1rem;
|
||||
line-height: 1;
|
||||
user-select: none;
|
||||
|
||||
&, ul {
|
||||
list-style-type: none;
|
||||
}
|
||||
ul {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
@mixin block-list-container(
|
||||
$font-size: $blocklist-fontsize,
|
||||
$full-bleed: $blocklist-fullbleed
|
||||
) {
|
||||
@extend %block-list-container;
|
||||
font-size: $font-size;
|
||||
|
||||
@if $full-bleed {
|
||||
margin-left: -$global-padding;
|
||||
margin-right: -$global-padding;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Styles block list headers on the selector you include this mixin in (normally a <header>).
|
||||
|
||||
$color - color of the header.
|
||||
$font-size - font size of the header.
|
||||
$offset - left margin to add to the header, to line it up with the list items.
|
||||
*/
|
||||
@mixin block-list-header(
|
||||
$color: $blocklist-header-color,
|
||||
$font-size: $blocklist-header-fontsize,
|
||||
$uppercase: $blocklist-header-uppercase,
|
||||
$offset: get-side($blocklist-item-padding, left)
|
||||
) {
|
||||
margin-top: 1em;
|
||||
color: $color;
|
||||
font-weight: bold;
|
||||
margin-bottom: 0.5em;
|
||||
margin-left: $offset;
|
||||
font-size: $font-size;
|
||||
cursor: default;
|
||||
@if $uppercase { text-transform: uppercase; }
|
||||
}
|
||||
|
||||
/*
|
||||
Styles block list items on the selector you include this mixin in (normally an <li>).
|
||||
|
||||
$color - color of items.
|
||||
$color-hover - color of items on hover.
|
||||
$background - background of items.
|
||||
$background-hover - background of items on hover.
|
||||
$border - border between items.
|
||||
$padding - padding on items.
|
||||
*/
|
||||
@mixin block-list-item(
|
||||
$color: $blocklist-item-color,
|
||||
$color-hover: $blocklist-item-color,
|
||||
$color-disabled: $blocklist-item-color-disabled,
|
||||
$background: transparent,
|
||||
$background-hover: $blocklist-item-background-hover,
|
||||
$border: $blocklist-item-border,
|
||||
$padding: $blocklist-item-padding
|
||||
) {
|
||||
position: relative;
|
||||
|
||||
@if hasvalue($border) {
|
||||
border-bottom: $border;
|
||||
&:first-child {
|
||||
border-top: $border;
|
||||
}
|
||||
}
|
||||
|
||||
// Inner elements share the same basic styles
|
||||
> a, > span, > label {
|
||||
display: block;
|
||||
padding: $padding;
|
||||
padding-left: get-side($padding, left);
|
||||
color: $color;
|
||||
line-height: 1;
|
||||
}
|
||||
> span {
|
||||
cursor: default;
|
||||
}
|
||||
> a, > label {
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: $color-hover;
|
||||
}
|
||||
}
|
||||
> a, > label, select {
|
||||
&:hover {
|
||||
background: $background-hover;
|
||||
}
|
||||
}
|
||||
|
||||
// Coloring classes
|
||||
&.caution > a {
|
||||
&, &:hover { color: $alert-color; }
|
||||
}
|
||||
&.disabled > a {
|
||||
cursor: default;
|
||||
&, &:hover { color: $color-disabled; }
|
||||
&:hover { background: transparent; }
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Adds label styles to the class you include this mixin in.
|
||||
|
||||
$color - color of the label.
|
||||
$left-class - extra class to flip the orientation of the label.
|
||||
$left-padding - left padding to use for left-hand labels.
|
||||
*/
|
||||
@mixin block-list-label(
|
||||
$color: $blocklist-item-label-color,
|
||||
$left-class: 'left',
|
||||
$left-padding: get-side($blocklist-item-padding, top)
|
||||
) {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
padding: 0;
|
||||
color: $color;
|
||||
pointer-events: none;
|
||||
|
||||
&.#{$left-class} {
|
||||
margin-left: $left-padding;
|
||||
float: none;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Adds support for chevrons, which appear on the right-hand side of the item.
|
||||
|
||||
$color - color of the chevron.
|
||||
$padding - include the global padding of block list items here.
|
||||
*/
|
||||
@mixin block-list-chevron(
|
||||
$color: $blocklist-header-color,
|
||||
$padding: $blocklist-item-padding,
|
||||
$label-class: 'block-list-label'
|
||||
) {
|
||||
// Chevrons are a pseudo-element
|
||||
&::after {
|
||||
content: '\203A';
|
||||
display: block;
|
||||
position: absolute;
|
||||
right: get-side($padding, right);
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
font-weight: bold;
|
||||
color: $color;
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
// Labels next to links move over to make room for the chevron
|
||||
// TODO: this selector needs to be customiable, but adding a setting just for it might be weird
|
||||
.#{$label-class} {
|
||||
padding-right: get-side($padding, right) * 1.5;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Adds icon styles. Call this mixin on a block list container.
|
||||
|
||||
$size - size of the icon as a percentage (decimal) of the list item's height.
|
||||
$item-selector - overrides the 'li' selector used for list items.
|
||||
*/
|
||||
@mixin block-list-icons(
|
||||
$size: $blocklist-item-icon-size,
|
||||
$item-selector: 'li'
|
||||
) {
|
||||
// PH - need a better solution
|
||||
$item-height:
|
||||
$blocklist-fontsize
|
||||
+ get-side($blocklist-item-padding, top)
|
||||
+ get-side($blocklist-item-padding, top);
|
||||
|
||||
$icon-height: $item-height * $blocklist-item-icon-size;
|
||||
$icon-offset: ($item-height - $icon-height) / 2;
|
||||
|
||||
#{$item-selector} {
|
||||
> a, > span, > label {
|
||||
padding-left: (get-side($blocklist-item-padding, left) * 2) + $blocklist-item-icon-size;
|
||||
}
|
||||
img, .iconic {
|
||||
position: absolute;
|
||||
top: $icon-offset;
|
||||
left: $icon-offset;
|
||||
width: $icon-height;
|
||||
height: $icon-height;
|
||||
border-radius: 8px;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Adds support for text fields, select menus, and checkbox/radio groups in block lists.
|
||||
|
||||
$color - color of select menu arrow.
|
||||
$background-hover - color of select menu when hovered over.
|
||||
$padding - include the global padding of block list items here.
|
||||
$dropdown-class - class to use for list items that contain a dropdown.
|
||||
$switch-class - class to use for switches inside list items.
|
||||
*/
|
||||
@mixin block-list-inputs(
|
||||
$color: $blocklist-item-color,
|
||||
$background: $blocklist-background,
|
||||
$background-hover: $blocklist-item-background-hover,
|
||||
$padding: $blocklist-item-padding,
|
||||
$icons: $blocklist-check-icons,
|
||||
$dropdown-class: 'with-dropdown',
|
||||
$switch-class: 'switch'
|
||||
) {
|
||||
// Text fields
|
||||
#{$text-input-selectors} {
|
||||
margin: 0;
|
||||
border: 0;
|
||||
line-height: 1;
|
||||
height: auto;
|
||||
padding: $padding;
|
||||
color: inherit;
|
||||
|
||||
&:hover, &:focus {
|
||||
border: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Multiple select
|
||||
li > input[type="checkbox"], li > input[type="radio"] {
|
||||
position: absolute;
|
||||
left: -9999px;
|
||||
|
||||
& + label {
|
||||
display: block;
|
||||
font-size: $blocklist-fontsize;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@if $icons == true {
|
||||
&:checked + label {
|
||||
&::before {
|
||||
@include image-checkmark($color);
|
||||
content: '';
|
||||
background-size: 100% 100%;
|
||||
width: 1.5em;
|
||||
height: 1.5em;
|
||||
color: $primary-color;
|
||||
float: right;
|
||||
pointer-events: none;
|
||||
margin-top: -0.25em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dropdowns
|
||||
.#{$dropdown-class} {
|
||||
color: inherit;
|
||||
|
||||
select {
|
||||
// Reset pesky <select> styles
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
outline: 0;
|
||||
background: 0;
|
||||
border: 0;
|
||||
height: auto;
|
||||
padding: $padding;
|
||||
margin: 0;
|
||||
font-size: 1em; // Same size as its parent
|
||||
line-height: 1;
|
||||
color: inherit;
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
// Switches
|
||||
.#{$switch-class} {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: get-side($padding, right);
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
}
|
||||
|
||||
@include exports(block-list) {
|
||||
.block-list {
|
||||
@include block-list-container;
|
||||
@include block-list-inputs;
|
||||
|
||||
&.with-icons { @include block-list-icons; }
|
||||
header { @include block-list-header; }
|
||||
|
||||
li {
|
||||
@include block-list-item;
|
||||
|
||||
&.with-chevron { @include block-list-chevron; }
|
||||
.block-list-label { @include block-list-label; }
|
||||
}
|
||||
}
|
||||
}
|
||||
+197
@@ -0,0 +1,197 @@
|
||||
/// @Foundation.settings
|
||||
// Button Group
|
||||
$btngroup-background: $primary-color !default;
|
||||
$btngroup-color: #fff !default;
|
||||
$btngroup-radius: $button-radius !default;
|
||||
///
|
||||
|
||||
$child-selectors: '> a, > label, > button';
|
||||
|
||||
%button-group {
|
||||
margin: 0;
|
||||
margin-bottom: 1rem;
|
||||
list-style-type: none;
|
||||
display: inline-flex;
|
||||
border-radius: $btngroup-radius;
|
||||
overflow: hidden;
|
||||
font-size: $button-font-size;
|
||||
|
||||
> li {
|
||||
flex: 0 0 auto;
|
||||
|
||||
// Links become buttons
|
||||
#{$child-selectors} {
|
||||
@extend %button;
|
||||
border-radius: 0;
|
||||
font-size: inherit;
|
||||
display: block;
|
||||
margin: 0;
|
||||
}
|
||||
> input + label {
|
||||
margin-left: 0;
|
||||
}
|
||||
// Add borders between items
|
||||
&:not(:last-child) {
|
||||
#{$child-selectors} {
|
||||
border-right: 1px solid scale-color($btngroup-background, $lightness: -25%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@if using(iconic) {
|
||||
.iconic {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
vertical-align: middle;
|
||||
margin-right: 0.25em;
|
||||
margin-top: -2px; // The icons are oddly misaligned
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
%button-group-segmented {
|
||||
border: 1px solid $primary-color;
|
||||
transition-property: background color;
|
||||
|
||||
> li {
|
||||
// Hide the radio button
|
||||
> input[type="radio"] {
|
||||
position: absolute;
|
||||
left: -9999px;
|
||||
}
|
||||
// This is the button
|
||||
#{$child-selectors} {
|
||||
margin-right: 0;
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin button-group-size($size: medium, $expand: false) {
|
||||
$size: $button-font-size * map-get($button-sizes, $size);
|
||||
font-size: $size;
|
||||
|
||||
@if $expand {
|
||||
@include button-group-expand;
|
||||
}
|
||||
}
|
||||
@mixin button-group-expand($stretch: true) {
|
||||
display: if($stretch, flex, inline-flex);
|
||||
|
||||
> li {
|
||||
flex: if($stretch, 1, 0 0 auto);
|
||||
|
||||
#{$child-selectors} {
|
||||
@if $stretch { @include button-expand; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@mixin button-group-style(
|
||||
$segmented: false,
|
||||
$background: $primary-color,
|
||||
$color: auto
|
||||
) {
|
||||
|
||||
@if not($segmented) {
|
||||
> li {
|
||||
#{$child-selectors} {
|
||||
@include button-style($background, auto, $color);
|
||||
border-color: scale-color($background, $lightness: -15%);
|
||||
}
|
||||
&.is-active {
|
||||
#{$child-selectors} {
|
||||
background: scale-color($background, $lightness: -15%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@else {
|
||||
@extend %button-group-segmented;
|
||||
$hover-color: rgba($background, 0.25);
|
||||
border-color: $background;
|
||||
|
||||
> li {
|
||||
// This is the button
|
||||
#{$child-selectors} {
|
||||
border-color: $background;
|
||||
color: $background;
|
||||
|
||||
// This is the button being hovered on
|
||||
&:hover {
|
||||
background: $hover-color;
|
||||
color: $background;
|
||||
}
|
||||
|
||||
@if using(iconic) {
|
||||
.iconic { @include color-icon($background); }
|
||||
}
|
||||
}
|
||||
|
||||
// This is the button when it's active
|
||||
&.is-active > a,
|
||||
> input:checked + label {
|
||||
&, &:hover {
|
||||
background: $background;
|
||||
color: isitlight($background);
|
||||
}
|
||||
|
||||
@if using(iconic) {
|
||||
.iconic { @include color-icon(isitlight($background)); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin button-group(
|
||||
$segmented: false,
|
||||
$expand: false,
|
||||
$background: $primary-color,
|
||||
$color: #fff
|
||||
) {
|
||||
@extend %button-group;
|
||||
@include button-group-expand($expand);
|
||||
@include button-group-style($segmented, $background, $color);
|
||||
border-radius: $btngroup-radius;
|
||||
}
|
||||
|
||||
@include exports(button-group) {
|
||||
.button-group {
|
||||
@include button-group;
|
||||
|
||||
// Colors
|
||||
&.secondary { @include button-group-style(false, $secondary-color); }
|
||||
&.success { @include button-group-style(false, $success-color); }
|
||||
&.warning { @include button-group-style(false, $warning-color); }
|
||||
&.alert { @include button-group-style(false, $alert-color); }
|
||||
|
||||
// Individual colors
|
||||
> li {
|
||||
&.secondary { #{$child-selectors} { @include button-style($secondary-color, auto, $btngroup: true); } }
|
||||
&.success { #{$child-selectors} { @include button-style($success-color, auto, $btngroup: true); } }
|
||||
&.warning { #{$child-selectors} { @include button-style($warning-color, auto, $btngroup: true); } }
|
||||
&.alert { #{$child-selectors} { @include button-style($alert-color, auto, $btngroup: true); } }
|
||||
}
|
||||
|
||||
// Segmented
|
||||
&.segmented { @include button-group-style(true);
|
||||
&.secondary { @include button-group-style(true, $secondary-color); }
|
||||
&.success { @include button-group-style(true, $success-color); }
|
||||
&.warning { @include button-group-style(true, $warning-color); }
|
||||
&.alert { @include button-group-style(true, $alert-color); }
|
||||
}
|
||||
|
||||
// Sizing
|
||||
&.tiny { @include button-group-size(tiny); }
|
||||
&.small { @include button-group-size(small); }
|
||||
&.large { @include button-group-size(large); }
|
||||
&.expand { @include button-group-expand; }
|
||||
|
||||
// Disabled
|
||||
li.disabled {
|
||||
#{$child-selectors} {
|
||||
@include button-disabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
/// @Foundation.settings
|
||||
// Button
|
||||
$button-padding: 0.85em 1em !default;
|
||||
$button-margin: 0 $global-padding $global-padding 0 !default;
|
||||
$button-style: solid !default;
|
||||
$button-background: $primary-color !default;
|
||||
$button-background-hover: scale-color($button-background, $lightness: -15%) !default;
|
||||
$button-color: auto !default;
|
||||
$button-radius: 0 !default;
|
||||
$button-sizes: (
|
||||
tiny: 0.7,
|
||||
small: 0.8,
|
||||
medium: 1,
|
||||
large: 1.3,
|
||||
) !default;
|
||||
$button-font-size: 0.9rem !default;
|
||||
$button-opacity-disabled: 0.5 !default;
|
||||
$button-tag-selector: false !default;
|
||||
///
|
||||
|
||||
%button {
|
||||
display: inline-block;
|
||||
border: 0;
|
||||
text-align: center;
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
-webkit-appearance: none;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
transition: background 0.25s ease-out;
|
||||
vertical-align: middle;
|
||||
|
||||
padding: $button-padding;
|
||||
margin: $button-margin;
|
||||
font-size: $button-font-size;
|
||||
border-radius: $button-radius;
|
||||
|
||||
// Dropdown arrow
|
||||
// TODO: Change to class and mixin because now the toggle is 'fa-open' which is too generic
|
||||
// &[data-popup-toggle] {
|
||||
// position: relative;
|
||||
// padding-right: 2em; // Placeholder
|
||||
|
||||
// &::after {
|
||||
// @include css-triangle(6px, black, top);
|
||||
// position: absolute;
|
||||
// right: 0.7em;
|
||||
// top: 50%;
|
||||
// margin-top: -3px;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
@mixin button-size($size: medium, $expand: false) {
|
||||
$size: $button-font-size * map-get($button-sizes, $size);
|
||||
font-size: $size;
|
||||
|
||||
@if $expand {
|
||||
@include button-expand;
|
||||
}
|
||||
|
||||
@if using(iconic) {
|
||||
.iconic {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
vertical-align: middle;
|
||||
margin-right: 0.25em;
|
||||
margin-top: -2px; // The icons are oddly misaligned
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin button-expand($expand: true) {
|
||||
@if $expand {
|
||||
display: block;
|
||||
width: 100%;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
@else {
|
||||
display: inline-block;
|
||||
width: auto;
|
||||
margin: $button-margin;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin button-style(
|
||||
$background: $button-background,
|
||||
$background-hover: $button-background-hover,
|
||||
$color: $button-color,
|
||||
$style: $button-style,
|
||||
$radius: $button-radius,
|
||||
$btngroup: false
|
||||
){
|
||||
@if $style == hollow {
|
||||
border: 1px solid $background;
|
||||
background: transparent;
|
||||
color: $background;
|
||||
|
||||
&:hover, &:focus {
|
||||
border-color: scale-color($background, $lightness: 25%);
|
||||
background: transparent;
|
||||
color: scale-color($background, $lightness: 25%);
|
||||
}
|
||||
}
|
||||
// Solid is the default
|
||||
@else {
|
||||
@if $color == auto {
|
||||
$color: isitlight($background);
|
||||
}
|
||||
|
||||
background: $background;
|
||||
color: $color;
|
||||
|
||||
&:hover, &:focus {
|
||||
@if $background-hover == auto {
|
||||
background: scale-color($background, $lightness: -15%);
|
||||
}
|
||||
@else {
|
||||
background: $background-hover;
|
||||
}
|
||||
color: $color;
|
||||
}
|
||||
}
|
||||
|
||||
@if $btngroup {
|
||||
border-color: $background;
|
||||
&:hover, &:focus {
|
||||
border-color: scale-color($background, $lightness: -25%);
|
||||
}
|
||||
}
|
||||
|
||||
@if using(iconic) {
|
||||
@if $style == hollow {
|
||||
.iconic {
|
||||
@include color-icon($background);
|
||||
}
|
||||
&:hover .iconic {
|
||||
@include color-icon(scale-color($background, $lightness: 25%));
|
||||
}
|
||||
}
|
||||
@else {
|
||||
.iconic {
|
||||
@include color-icon($color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin button-disabled() {
|
||||
opacity: $button-opacity-disabled;
|
||||
cursor: default;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@mixin button(
|
||||
$size: medium,
|
||||
$expand: false,
|
||||
$background: $button-background,
|
||||
$background-hover: $button-background-hover,
|
||||
$color: $button-color,
|
||||
$style: $button-style,
|
||||
$radius: $button-radius
|
||||
) {
|
||||
@extend %button;
|
||||
@include button-size($size);
|
||||
@include button-expand($expand);
|
||||
@include button-style($background, $background-hover, $color, $style);
|
||||
}
|
||||
|
||||
@include exports(button) {
|
||||
.button {
|
||||
@include button;
|
||||
|
||||
&.tiny { @include button-size(tiny); }
|
||||
&.small { @include button-size(small); }
|
||||
&.large { @include button-size(large); }
|
||||
&.expand { @include button-expand; }
|
||||
|
||||
&.secondary { @include button-style($secondary-color, auto) }
|
||||
&.success { @include button-style($success-color, auto) }
|
||||
&.warning { @include button-style($warning-color, auto) }
|
||||
&.alert { @include button-style($alert-color, auto) }
|
||||
&.info { @include button-style($info-color, auto) }
|
||||
&.dark { @include button-style($dark-color, auto) }
|
||||
|
||||
@if $button-style != hollow {
|
||||
&.hollow { @include button-style($style: hollow);
|
||||
&.secondary { @include button-style($secondary-color, $style: hollow); }
|
||||
&.success { @include button-style($success-color, $style: hollow); }
|
||||
&.warning { @include button-style($warning-color, $style: hollow); }
|
||||
&.alert { @include button-style($alert-color, $style: hollow); }
|
||||
&.info { @include button-style($info-color, $style: hollow); }
|
||||
&.dark { @include button-style($dark-color, $style: hollow); }
|
||||
}
|
||||
}
|
||||
|
||||
&.disabled { @include button-disabled; }
|
||||
}
|
||||
|
||||
@if $button-tag-selector {
|
||||
button {
|
||||
@extend .button;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
Cards
|
||||
|
||||
Structure:
|
||||
|
||||
titles
|
||||
lists
|
||||
*/
|
||||
|
||||
/// @Foundation.settings
|
||||
// Card
|
||||
$card-background: #fff !default;
|
||||
$card-color: isitlight($card-background) !default;
|
||||
$card-border: 1px solid smartscale($card-background, 7%) !default;
|
||||
$card-radius: $global-radius !default;
|
||||
$card-shadow: 0 1px 2px rgba(#000, 0.2) !default;
|
||||
$card-padding: $global-padding !default;
|
||||
$card-margin: 0.5rem !default;
|
||||
|
||||
$card-divider-background: smartscale($card-background, 7%) !default;
|
||||
///
|
||||
|
||||
@mixin card-container(
|
||||
$background: $card-background,
|
||||
$color: $card-color,
|
||||
$border: $card-border,
|
||||
$radius: $card-radius,
|
||||
$shadow: $card-shadow,
|
||||
$padding: $card-padding,
|
||||
$margin: $card-margin
|
||||
) {
|
||||
border: $border;
|
||||
margin-bottom: $margin;
|
||||
background: $background;
|
||||
color: $color;
|
||||
border-radius: $radius;
|
||||
box-shadow: $shadow;
|
||||
overflow: hidden;
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin card-divider(
|
||||
$background: $card-divider-background,
|
||||
$padding: $card-padding
|
||||
) {
|
||||
background: $background;
|
||||
padding: $padding;
|
||||
}
|
||||
|
||||
@mixin card-section(
|
||||
$padding: $card-padding
|
||||
) {
|
||||
padding: $padding;
|
||||
}
|
||||
|
||||
@include exports(card) {
|
||||
.card {
|
||||
@include card-container;
|
||||
|
||||
@each $color in map-keys($foundation-colors) {
|
||||
&.#{$color} {
|
||||
$color-value: map-get($foundation-colors, $color);
|
||||
@include card-container(
|
||||
$background: $color-value,
|
||||
$color: isitlight($color-value),
|
||||
$border: 0
|
||||
);
|
||||
.card-divider {
|
||||
@include card-divider(
|
||||
$background: smartscale($color-value, 7%)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.card-divider {
|
||||
@include card-divider;
|
||||
}
|
||||
.card-section {
|
||||
@include card-section;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
Odds and ends.
|
||||
*/
|
||||
|
||||
/// @Foundation.settings
|
||||
// Extras
|
||||
$closebutton-position: (top right) !default;
|
||||
$closebutton-size: 2em !default;
|
||||
$closebutton-lineheight: 0.5 !default;
|
||||
$closebutton-color: #999 !default;
|
||||
$closebutton-color-hover: #333 !default;
|
||||
|
||||
$thumbnail-padding: 0.5rem !default;
|
||||
$thumbnail-shadow: 0 3px 15px rgba(black, 0.25) !default;
|
||||
///
|
||||
|
||||
// A basic close button. They pin to the corner of the thing they're inside.
|
||||
%close-button {
|
||||
$x: nth($closebutton-position, 1);
|
||||
$y: nth($closebutton-position, 2);
|
||||
|
||||
position: absolute;
|
||||
color: $closebutton-color;
|
||||
#{$x}: $global-padding;
|
||||
#{$y}: $global-padding;
|
||||
font-size: $closebutton-size;
|
||||
line-height: $closebutton-lineheight;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: $closebutton-color-hover;
|
||||
}
|
||||
}
|
||||
|
||||
// Make your images fancy-like.
|
||||
%thumbnail {
|
||||
padding: $thumbnail-padding;
|
||||
box-shadow: $thumbnail-shadow;
|
||||
}
|
||||
|
||||
@include exports(extras) {
|
||||
.close-button {
|
||||
@extend %close-button;
|
||||
}
|
||||
.thumbnail {
|
||||
@extend %thumbnail;
|
||||
}
|
||||
ul.thumbnails > li {
|
||||
margin-bottom: 1rem;
|
||||
|
||||
a { display: block; }
|
||||
img { @extend %thumbnail; }
|
||||
}
|
||||
}
|
||||
+458
@@ -0,0 +1,458 @@
|
||||
/*
|
||||
FORMS
|
||||
-----
|
||||
|
||||
Our form styles include basic resets for text fields, select menus, and so on, along with some of our own custom components.
|
||||
|
||||
Includes:
|
||||
- Text fields
|
||||
- Text areas
|
||||
- Select menus
|
||||
- Checkboxes and radio buttons
|
||||
- Range slider
|
||||
- Progress bars and meters
|
||||
*/
|
||||
|
||||
/// @Foundation.settings
|
||||
// Forms
|
||||
// Basic form variables
|
||||
$form-fontsize: 1rem !default;
|
||||
$form-padding: 0.5rem !default;
|
||||
|
||||
// Text fields
|
||||
$input-color: #000 !default;
|
||||
$input-color-hover: $input-color !default;
|
||||
$input-color-focus: $input-color !default;
|
||||
$input-background: #fff !default;
|
||||
$input-background-hover: $input-background !default;
|
||||
$input-background-focus: $input-background !default;
|
||||
$input-background-disabled: smartscale($input-background) !default;
|
||||
$input-border: 1px solid #ccc !default;
|
||||
$input-border-hover: 1px solid #bbb !default;
|
||||
$input-border-focus: 1px solid #999 !default;
|
||||
$input-cursor-disabled: not-allowed !default;
|
||||
|
||||
// Select menus
|
||||
$select-color: #000 !default;
|
||||
$select-background: #fafafa !default;
|
||||
$select-background-hover: smartscale($select-background, 4%) !default;
|
||||
$select-arrow: true !default;
|
||||
$select-arrow-color: $select-color !default;
|
||||
|
||||
// Labels
|
||||
$form-label-fontsize: 0.9rem !default;
|
||||
$form-label-margin: 0.5rem !default;
|
||||
$form-label-color: #333 !default;
|
||||
|
||||
// Inline labels
|
||||
$inlinelabel-color: #333 !default;
|
||||
$inlinelabel-background: #eee !default;
|
||||
$inlinelabel-border: $input-border !default;
|
||||
|
||||
// Range slider
|
||||
$slider-background: #ddd !default;
|
||||
$slider-height: 1rem !default;
|
||||
$slider-radius: 0px !default;
|
||||
$slider-thumb-height: 1.5rem !default;
|
||||
$slider-thumb-color: $primary-color !default;
|
||||
$slider-thumb-radius: 0px !default;
|
||||
|
||||
// Progress and meter
|
||||
$meter-height: 1.5rem !default;
|
||||
$meter-background: #ccc !default;
|
||||
$meter-fill: $primary-color !default;
|
||||
$meter-fill-high: $success-color !default;
|
||||
$meter-fill-medium: #e7cf00 !default;
|
||||
$meter-fill-low: $alert-color !default;
|
||||
$meter-radius: 0 !default;
|
||||
///
|
||||
|
||||
// Disable OS-level styles
|
||||
@mixin no-appearance {
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
}
|
||||
|
||||
// Text fields
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
#{$text-input-selectors} {
|
||||
$top-padding: get-side($form-padding, top);
|
||||
$bottom-padding: get-side($form-padding, bottom);
|
||||
$height: ($form-fontsize * 1.4) + $top-padding + $bottom-padding;
|
||||
|
||||
@include no-appearance;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: $height;
|
||||
padding: $form-padding;
|
||||
margin: 0 0 $global-padding 0;
|
||||
border: $input-border;
|
||||
border-radius: 0;
|
||||
background: $input-background;
|
||||
color: $input-color;
|
||||
font-size: $form-fontsize;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
vertical-align: middle;
|
||||
|
||||
&:hover {
|
||||
border: $input-border-hover;
|
||||
background: $input-background-hover;
|
||||
color: $input-color-hover;
|
||||
}
|
||||
&:focus {
|
||||
outline: 0;
|
||||
border: $input-border-focus;
|
||||
background: $input-background-focus;
|
||||
color: $input-color-focus;
|
||||
}
|
||||
|
||||
label > & {
|
||||
margin-top: $form-label-margin;
|
||||
}
|
||||
}
|
||||
|
||||
// Override the content-box declaration set by Normalize
|
||||
input[type="search"] {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
// Disabled state
|
||||
input {
|
||||
&.disabled,
|
||||
&[disabled],
|
||||
&[readonly],
|
||||
fieldset[disabled] & {
|
||||
cursor: $input-cursor-disabled;
|
||||
|
||||
&, &:hover {
|
||||
background-color: $input-background-disabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Labels
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
label {
|
||||
display: block;
|
||||
font-size: $form-label-fontsize;
|
||||
margin-bottom: $form-label-margin;
|
||||
color: $form-label-color;
|
||||
|
||||
> input, > textarea {
|
||||
margin-top: $form-label-margin;
|
||||
}
|
||||
}
|
||||
|
||||
// Checkbox/radio buttons
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
input[type="checkbox"], input[type="radio"] {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
|
||||
// Input inside of a label
|
||||
label > & {
|
||||
margin-right: $form-padding * 0.5;
|
||||
}
|
||||
|
||||
// Input next to a label
|
||||
& + label {
|
||||
display: inline-block;
|
||||
margin-left: $form-padding;
|
||||
margin-right: $form-padding * 2;
|
||||
margin-bottom: 0;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
}
|
||||
|
||||
// Inline labels
|
||||
// Inline labels allow you to prefix or postfix special labels to inputs
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
.inline-label {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
align-items: stretch;
|
||||
margin-bottom: $global-padding;
|
||||
|
||||
// Imitates the top margin on normal inputs
|
||||
label > & {
|
||||
margin-top: $form-label-margin;
|
||||
}
|
||||
|
||||
// Inputs stretch all the way out
|
||||
> input, > select {
|
||||
flex: 1;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
// Inline labels and buttons shrink
|
||||
> .form-label {
|
||||
flex: 0 0 auto;
|
||||
background: $inlinelabel-background;
|
||||
color: $inlinelabel-color;
|
||||
border: $inlinelabel-border;
|
||||
padding: 0 $form-padding;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&:first-child { border-right: 0; }
|
||||
&:last-child { border-left: 0; }
|
||||
}
|
||||
// Buttons also shrink
|
||||
> a,
|
||||
> button,
|
||||
> input[type="button"],
|
||||
> input[type="submit"] {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
margin: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Text areas
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
textarea {
|
||||
height: auto;
|
||||
width: 100%;
|
||||
min-height: 50px;
|
||||
}
|
||||
|
||||
// Select menus
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
select {
|
||||
$top-padding: get-side($form-padding, top);
|
||||
$bottom-padding: get-side($form-padding, bottom);
|
||||
$height: ($form-fontsize * 1.4) + $top-padding + $bottom-padding;
|
||||
$color: isitlight($select-background);
|
||||
|
||||
@include no-appearance;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: $height;
|
||||
padding: $form-padding;
|
||||
margin: 0 0 $global-padding 0;
|
||||
font-size: $form-fontsize;
|
||||
color: $select-color;
|
||||
border-radius: 0;
|
||||
border: $input-border;
|
||||
|
||||
@if $select-arrow {
|
||||
background: $select-background url(image-triangle($select-arrow-color)) right 10px center no-repeat;
|
||||
background-size: 8px 8px;
|
||||
padding-right: rem-calc(18px) + $form-padding;
|
||||
}
|
||||
@else {
|
||||
background-color: $select-background
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: $select-background-hover;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
// Remove the dropdown arrow added in IE10/11
|
||||
&::-ms-expand {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
// Range slider
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
input[type="range"] {
|
||||
$margin: ($slider-thumb-height - $slider-height) / 2;
|
||||
|
||||
@include no-appearance;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
cursor: pointer;
|
||||
margin-top: $margin;
|
||||
margin-bottom: $margin;
|
||||
border: 0;
|
||||
line-height: 1;
|
||||
|
||||
@if hasvalue($slider-radius) {
|
||||
border-radius: $slider-radius;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
// Chrome/Safari
|
||||
&::-webkit-slider-runnable-track {
|
||||
height: $slider-height;
|
||||
background: $slider-background;
|
||||
}
|
||||
&::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
background: $slider-thumb-color;
|
||||
width: $slider-thumb-height;
|
||||
height: $slider-thumb-height;
|
||||
margin-top: -$margin;
|
||||
@if hasvalue($slider-thumb-radius) {
|
||||
border-radius: $slider-thumb-radius;
|
||||
}
|
||||
}
|
||||
// Firefox
|
||||
&::-moz-range-track {
|
||||
-moz-appearance: none;
|
||||
height: $slider-height;
|
||||
background: #ccc;
|
||||
}
|
||||
&::-moz-range-thumb {
|
||||
-moz-appearance: none;
|
||||
background: $slider-thumb-color;
|
||||
width: $slider-thumb-height;
|
||||
height: $slider-thumb-height;
|
||||
margin-top: -$margin;
|
||||
@if hasvalue($slider-thumb-radius) {
|
||||
border-radius: $slider-thumb-radius;
|
||||
}
|
||||
}
|
||||
// Internet Explorer
|
||||
&::-ms-track {
|
||||
height: $slider-height;
|
||||
background: $slider-background;
|
||||
color: transparent;
|
||||
border: 0;
|
||||
overflow: visible;
|
||||
border-top: $margin solid $body-background;
|
||||
border-bottom: $margin solid $body-background;
|
||||
}
|
||||
&::-ms-thumb {
|
||||
background: $slider-thumb-color;
|
||||
width: $slider-thumb-height;
|
||||
height: $slider-thumb-height;
|
||||
border: 0;
|
||||
@if hasvalue($slider-thumb-radius) {
|
||||
border-radius: $slider-thumb-radius;
|
||||
}
|
||||
}
|
||||
&::-ms-fill-lower, &::-ms-fill-upper {
|
||||
background: $slider-background;
|
||||
}
|
||||
}
|
||||
output {
|
||||
line-height: $slider-thumb-height;
|
||||
vertical-align: middle;
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
|
||||
// Number inputs
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
input[type="number"] {
|
||||
&::-webkit-inner-spin-button {
|
||||
|
||||
}
|
||||
&::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
background: $primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
// Progress and meter
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
progress, meter {
|
||||
@include no-appearance;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: $meter-height;
|
||||
margin-bottom: 1rem;
|
||||
|
||||
@if hasvalue($meter-radius) {
|
||||
border-radius: $meter-radius;
|
||||
}
|
||||
|
||||
// For Firefox
|
||||
background: $meter-background;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
progress {
|
||||
&::-webkit-progress-bar {
|
||||
background: $meter-background;
|
||||
@if hasvalue($meter-radius) {
|
||||
border-radius: $meter-radius;
|
||||
}
|
||||
}
|
||||
&::-webkit-progress-value {
|
||||
background: $meter-fill;
|
||||
@if hasvalue($meter-radius) {
|
||||
border-radius: $meter-radius;
|
||||
}
|
||||
}
|
||||
&::-moz-progress-bar {
|
||||
background: $meter-fill;
|
||||
@if hasvalue($meter-radius) {
|
||||
border-radius: $meter-radius;
|
||||
}
|
||||
}
|
||||
|
||||
@each $name, $color in (high: $meter-fill-high, medium: $meter-fill-medium, low: $meter-fill-low) {
|
||||
&.#{$name} {
|
||||
&::-webkit-progress-value {
|
||||
background: $color;
|
||||
}
|
||||
&::-moz-progress-bar {
|
||||
background: $color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
meter {
|
||||
// Chrome/Safari
|
||||
&::-webkit-meter-bar {
|
||||
background: $meter-background;
|
||||
@if hasvalue($meter-radius) {
|
||||
border-radius: $meter-radius;
|
||||
}
|
||||
}
|
||||
&::-webkit-meter-inner-element {
|
||||
@if hasvalue($meter-radius) {
|
||||
border-radius: $meter-radius;
|
||||
}
|
||||
}
|
||||
&::-webkit-meter-optimum-value {
|
||||
background: $meter-fill-high;
|
||||
@if hasvalue($meter-radius) {
|
||||
border-radius: $meter-radius;
|
||||
}
|
||||
}
|
||||
&::-webkit-meter-suboptimum-value {
|
||||
background: $meter-fill-medium;
|
||||
@if hasvalue($meter-radius) {
|
||||
border-radius: $meter-radius;
|
||||
}
|
||||
}
|
||||
&::-webkit-meter-even-less-good-value {
|
||||
background: $meter-fill-low;
|
||||
@if hasvalue($meter-radius) {
|
||||
border-radius: $meter-radius;
|
||||
}
|
||||
}
|
||||
|
||||
// Firefox
|
||||
background: $meter-background;
|
||||
&::-moz-meter-bar {
|
||||
background: $primary-color;
|
||||
@if hasvalue($meter-radius) {
|
||||
border-radius: $meter-radius;
|
||||
}
|
||||
}
|
||||
&:-moz-meter-optimum::-moz-meter-bar {
|
||||
background: $meter-fill-high;
|
||||
}
|
||||
&:-moz-meter-sub-optimum::-moz-meter-bar {
|
||||
background: $meter-fill-medium;
|
||||
}
|
||||
&:-moz-meter-sub-sub-optimum::-moz-meter-bar {
|
||||
background: $meter-fill-low;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,419 @@
|
||||
@import "panel";
|
||||
|
||||
/*
|
||||
THE GRID
|
||||
--------
|
||||
|
||||
Foundation's magical, flexbox-powered grid.
|
||||
|
||||
Features:
|
||||
- Horizontal or vertical grids
|
||||
- Auto-sizing or percentage width grid blocks
|
||||
- Independently-scrollable blocks
|
||||
- Column alignment
|
||||
- Source ordering
|
||||
- Offsets
|
||||
*/
|
||||
|
||||
/// @Foundation.settings
|
||||
// Grid
|
||||
$container-width: rem-calc(900) !default;
|
||||
$block-padding: $global-padding !default;
|
||||
$total-columns: 12 !default;
|
||||
$block-grid-max-size: 6 !default;
|
||||
///
|
||||
|
||||
/*
|
||||
Define the size of a grid block. Blocks are flex items. By default, they stretch to fill all available space, based on the size of sibling blocks. This is the "expand" behavior.
|
||||
|
||||
If set to "shrink", the block will contract and only fill as much space as it needs for its content.
|
||||
|
||||
If set to a number, the block will be given a percentage width, based on the total number of columns (12 by default). Percentage widths don't work if a block is inside a vertical grid.
|
||||
|
||||
@group grid
|
||||
|
||||
@param {number|string} $size - Sizing behavior of the block. Should be expand, shrink, or a number.
|
||||
|
||||
@output The flex-basis, flex-grow, and flex-shrink properties.
|
||||
*/
|
||||
@mixin grid-size($size: expand) {
|
||||
@if (type-of($size) == 'number') {
|
||||
$pct: percentage($size / $total-columns);
|
||||
flex: 0 0 $pct;
|
||||
// max-width prevents columns from wrapping early in IE10/11
|
||||
max-width: $pct;
|
||||
}
|
||||
@else if ($size == shrink) {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
@else if ($size == expand) {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
}
|
||||
/*
|
||||
Set the orientation of blocks within this block. The grid is re-oriented by changing the flex direction of the block.
|
||||
|
||||
@group grid
|
||||
|
||||
@param {string} $orientation - Direction of the grid, either horizontal or vertical.
|
||||
|
||||
@output A flex-flow property to match the direction given.
|
||||
*/
|
||||
@mixin grid-orient($orientation: horizontal) {
|
||||
@if ($orientation == vertical) {
|
||||
flex-flow: column nowrap;
|
||||
align-items: stretch;
|
||||
}
|
||||
@else {
|
||||
flex-flow: row wrap;
|
||||
}
|
||||
}
|
||||
/*
|
||||
Stretch a grid's child blocks across its cross-axis, making every column appear to have the same height.
|
||||
|
||||
@group grid
|
||||
|
||||
@param {bool} $stretch - Stretch blocks if true, or align blocks to top if false.
|
||||
|
||||
@output Sets align-items to "stretch" if $stretch is true, or "flex-start" (the default value) if false.
|
||||
*/
|
||||
@mixin grid-wrap($wrap: true) {
|
||||
@if $wrap {
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-start;
|
||||
}
|
||||
@else {
|
||||
flex-wrap: nowrap;
|
||||
align-items: stretch;
|
||||
}
|
||||
}
|
||||
/*
|
||||
Set the alignment of blocks within a grid.
|
||||
|
||||
left: Items align to the left.
|
||||
right: Items align to the right.
|
||||
center: Items align to the center.
|
||||
justify: Items are spaced equally apart so they occupy the space of the entire grid.
|
||||
spaced: Items are given equal space to their left and right.
|
||||
|
||||
@group grid
|
||||
|
||||
@param {string} $align - Alignment to use.
|
||||
|
||||
@output An appropriate justify-content value.
|
||||
*/
|
||||
@mixin grid-align($align: left) {
|
||||
$options: (
|
||||
left: flex-start,
|
||||
right: flex-end,
|
||||
center: center,
|
||||
justify: space-between,
|
||||
spaced: space-around,
|
||||
);
|
||||
justify-content: map-get($options, $align);
|
||||
}
|
||||
/*
|
||||
Set the source order of a block. Items with lower numbers appear first. If multiple items have the same number, the one in the HTML first will appear first.
|
||||
|
||||
@group grid
|
||||
|
||||
@param {number} $order - Position in source order.
|
||||
|
||||
@output An order property.
|
||||
*/
|
||||
@mixin grid-order($order: 0) {
|
||||
order: $order;
|
||||
}
|
||||
/*
|
||||
Collapse a content block by removing the padding.
|
||||
|
||||
@group grid
|
||||
|
||||
@param {bool} $collapse - Collapses the block if true.
|
||||
|
||||
@output A padding value.
|
||||
|
||||
@todo No way to reverse collapse using this mixin. Solution:
|
||||
- If true, add padding: 0;
|
||||
- If false, add padding: 1rem;
|
||||
- If null, add nothing, to cut down on CSS output
|
||||
- Make null the default value
|
||||
*/
|
||||
@mixin grid-collapse($collapse: true) {
|
||||
@if ($collapse) {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
/*
|
||||
Constrain the size of a block to the size of the average grid row, and center-align it. This imitates the behavior of ordinary Foundation rows.
|
||||
|
||||
@group grid
|
||||
|
||||
@param {bool} $container - Adds container styles if true.
|
||||
|
||||
@output A maximum width and the good old margin: 0 auto for center alignment.
|
||||
*/
|
||||
@mixin grid-container($width: $container-width, $align: center) {
|
||||
$margins: (
|
||||
left: 0 auto 0 0,
|
||||
right: 0 0 0 auto,
|
||||
center: 0 auto,
|
||||
);
|
||||
max-width: $width;
|
||||
margin: map-get($margins, $align);
|
||||
}
|
||||
/*
|
||||
Add negative margins to a block, equal to the padding of a content block. This aligns the edges of a block nested inside a content block.
|
||||
|
||||
@group grid
|
||||
|
||||
@param {bool} $nest - Adds negative margins if true.
|
||||
|
||||
@output Negative margin values.
|
||||
*/
|
||||
@mixin grid-nest($nest: true) {
|
||||
@if ($nest) {
|
||||
margin-left: -1rem;
|
||||
margin-right: -1rem;
|
||||
}
|
||||
}
|
||||
/*
|
||||
Offset a block by adding a left margin.
|
||||
|
||||
@group grid
|
||||
|
||||
@param {number | bool} $offset - If false, nothing is output. If a number, offsets the column by the specified number of columns.
|
||||
|
||||
@output A left margin based on the number of columns specified, and the global number of columns.
|
||||
*/
|
||||
@mixin grid-offset($offset: false) {
|
||||
@if ($offset != false) {
|
||||
margin-left: percentage($offset / $total-columns);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Resets styles set by panels. Use this when a panel transforms into a block on larger screens.
|
||||
|
||||
@group grid
|
||||
|
||||
@output Resets to transform, position, and a few visual styles.
|
||||
*/
|
||||
@mixin grid-panel-reset() {
|
||||
transform: none;
|
||||
position: relative;
|
||||
width: auto;
|
||||
height: auto;
|
||||
z-index: auto;
|
||||
box-shadow: none;
|
||||
background: transparent;
|
||||
top: auto;
|
||||
right: auto;
|
||||
bottom: auto;
|
||||
left: auto;
|
||||
}
|
||||
|
||||
/*
|
||||
Frames are containers that stretch to the full dimmensions of the browser window.
|
||||
*/
|
||||
@mixin grid-frame($size: expand, $orientation: horizontal, $wrap: false, $align: left, $order: 0) {
|
||||
display: flex;
|
||||
height: 100vh;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
@include grid-size($size);
|
||||
@include grid-orient($orientation);
|
||||
@include grid-wrap($wrap);
|
||||
@include grid-align($align);
|
||||
@include grid-order($order);
|
||||
}
|
||||
|
||||
/*
|
||||
Groups are collections of content items. They're the "rows" of Foundation for Apps.
|
||||
*/
|
||||
@mixin grid-block($size: expand, $orientation: horizontal, $wrap: false, $align: left, $order: 0) {
|
||||
@include grid-frame($size, $orientation, $wrap, $align, $order);
|
||||
|
||||
// Reset the height used by frames
|
||||
height: auto;
|
||||
|
||||
// Blocks will scroll by default if their content overflows
|
||||
@if ($orientation == vertical) {
|
||||
overflow-x: auto;
|
||||
}
|
||||
@else {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
// Add scrolling with inertia
|
||||
-webkit-overflow-scrolling: touch;
|
||||
-ms-overflow-style: -ms-autohiding-scrollbar;
|
||||
}
|
||||
|
||||
/*
|
||||
Blocks are containers for actual content. They're the "columns" of Foundation for Apps.
|
||||
*/
|
||||
@mixin grid-content($size: expand, $offset: null, $order: null) {
|
||||
// Content blocks are not flex items and have padding
|
||||
display: block;
|
||||
padding: 0 $block-padding;
|
||||
|
||||
// Add scrolling with inertia
|
||||
overflow-y: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
-ms-overflow-style: -ms-autohiding-scrollbar;
|
||||
|
||||
@include grid-size($size);
|
||||
@if $offset != null { @include grid-offset($offset); }
|
||||
@if $order != null { @include grid-order($order); }
|
||||
}
|
||||
|
||||
@mixin grid-layout($up) {
|
||||
flex-flow: row wrap;
|
||||
overflow: visible;
|
||||
list-style-type: none;
|
||||
|
||||
> li, > div, > section {
|
||||
padding: 0 1rem 1rem;
|
||||
flex: 0 0 percentage(1 / $up);
|
||||
}
|
||||
}
|
||||
|
||||
// CSS Output
|
||||
// - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
// Shared styles for frames and blocks (parent elements)
|
||||
%block-core {
|
||||
// Change the direction children flow
|
||||
&.vertical { @include grid-orient(vertical); }
|
||||
@each $size in $breakpoint-classes {
|
||||
@include breakpoint($size) {
|
||||
&.#{$size}-vertical { @include grid-orient(vertical); }
|
||||
&.#{$size}-horizontal { @include grid-orient(horizontal); }
|
||||
}
|
||||
}
|
||||
|
||||
// Align the children of a grid block
|
||||
&.align-right { @include grid-align(right); }
|
||||
&.align-center { @include grid-align(center); }
|
||||
&.align-justify { @include grid-align(justify); }
|
||||
&.align-spaced { @include grid-align(spaced); }
|
||||
|
||||
// Allow child elements to wrap
|
||||
&.wrap { @include grid-wrap(true); }
|
||||
}
|
||||
|
||||
// Shared styles for blocks and content blocks (child elements)
|
||||
%child-core {
|
||||
// Shrink a flex item so it only takes up the space it needs
|
||||
&.shrink { @include grid-size(shrink); }
|
||||
|
||||
// Prevent an element from scrolling
|
||||
&.noscroll { overflow: hidden; }
|
||||
}
|
||||
|
||||
@include exports(grid) {
|
||||
// The core grid elements:
|
||||
// - Frame
|
||||
// - Block
|
||||
// - Content block
|
||||
// - Container
|
||||
.grid-frame {
|
||||
@extend %block-core;
|
||||
@include grid-frame;
|
||||
}
|
||||
.grid-block {
|
||||
@extend %block-core;
|
||||
@extend %child-core;
|
||||
@include grid-block;
|
||||
}
|
||||
.grid-content {
|
||||
@extend %child-core;
|
||||
@include grid-content;
|
||||
|
||||
&.collapse {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
// Grids inside content blocks should wrap by default, so they mimic traditional float grids
|
||||
.grid-block {
|
||||
margin-left: -($block-padding);
|
||||
margin-right: -($block-padding);
|
||||
flex-wrap: wrap;
|
||||
overflow: visible;
|
||||
|
||||
// Reverse the above wrapping behavior
|
||||
&.nowrap {
|
||||
@include grid-wrap(false);
|
||||
}
|
||||
|
||||
.grid-content {
|
||||
overflow: visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
.grid-container {
|
||||
@include grid-container;
|
||||
|
||||
&.contain-left { @include grid-container($align: left); }
|
||||
&.contain-right { @include grid-container($align: right); }
|
||||
}
|
||||
|
||||
// Breakpoint classes for blocks
|
||||
@each $size in $breakpoint-classes {
|
||||
.#{$size}-grid-block {
|
||||
@extend %block-core;
|
||||
@extend %child-core;
|
||||
|
||||
@include breakpoint($size) {
|
||||
@include grid-block;
|
||||
|
||||
// Override panel styles
|
||||
&.panel { @include grid-panel-reset; }
|
||||
}
|
||||
}
|
||||
.#{$size}-grid-content {
|
||||
@extend %child-core;
|
||||
|
||||
@include breakpoint($size) {
|
||||
@include grid-content;
|
||||
|
||||
// Override panel styles
|
||||
&.panel { @include grid-panel-reset; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sizing and ordering classes
|
||||
@for $i from 1 through $total-columns {
|
||||
// Source ordering
|
||||
.order-#{$i} { @include grid-order($i); }
|
||||
}
|
||||
@each $size in $breakpoint-classes {
|
||||
@for $i from 1 through $total-columns {
|
||||
@include breakpoint($size) {
|
||||
// Block sizing
|
||||
.#{$size}-#{$i} {
|
||||
@include grid-size($i);
|
||||
}
|
||||
// Source ordering
|
||||
.#{$size}-order-#{$i} {
|
||||
@include grid-order($i);
|
||||
}
|
||||
// Offsets
|
||||
.#{$size}-offset-#{$i} {
|
||||
@include grid-offset($i);
|
||||
}
|
||||
// Parent sizing (block grids)
|
||||
.#{$size}-up-#{$i} {
|
||||
@include grid-layout($i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.grid-content .modal .grid-block {
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
Label
|
||||
*/
|
||||
|
||||
/// @Foundation.settings
|
||||
// Label
|
||||
$label-fontsize: 0.8rem !default;
|
||||
$label-padding: ($global-padding / 3) ($global-padding / 2) !default;
|
||||
$label-radius: 0 !default;
|
||||
$label-background: $primary-color !default;
|
||||
$label-color: isitlight($primary-color) !default;
|
||||
|
||||
$badge-fontsize: 0.8em !default;
|
||||
$badge-diameter: 1.5rem !default;
|
||||
$badge-background: $primary-color !default;
|
||||
$badge-color: #fff !default;
|
||||
///
|
||||
|
||||
%label {
|
||||
line-height: 1;
|
||||
white-space: nowrap;
|
||||
display: inline-block;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
@mixin label-layout(
|
||||
$fontsize: $label-fontsize,
|
||||
$padding: $label-padding
|
||||
) {
|
||||
font-size: $fontsize;
|
||||
padding: $padding;
|
||||
}
|
||||
|
||||
@mixin label-style(
|
||||
$background: $label-background,
|
||||
$color: $label-color,
|
||||
$radius: $label-radius
|
||||
) {
|
||||
background: $background;
|
||||
border-radius: $radius;
|
||||
|
||||
@if $color == auto {
|
||||
color: isitlight($background);
|
||||
}
|
||||
@else {
|
||||
color: $color;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin label(
|
||||
$background: $label-background,
|
||||
$color: $label-color,
|
||||
$radius: $label-radius,
|
||||
$fontsize: $label-fontsize,
|
||||
$padding: $label-padding
|
||||
) {
|
||||
@extend %label;
|
||||
@include label-layout($fontsize, $padding);
|
||||
@include label-style($background, $color, $radius);
|
||||
}
|
||||
|
||||
@include exports(label) {
|
||||
.label {
|
||||
@include label;
|
||||
|
||||
@each $color in map-keys($foundation-colors) {
|
||||
&.#{$color} {
|
||||
$color-value: map-get($foundation-colors, $color);
|
||||
@include label-style($color-value, auto);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Badge
|
||||
*/
|
||||
|
||||
%badge {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
display: inline-flex;
|
||||
border-radius: 1000px;
|
||||
}
|
||||
|
||||
@mixin badge-layout(
|
||||
$fontsize: $badge-fontsize,
|
||||
$diameter: $badge-diameter
|
||||
) {
|
||||
font-size: $fontsize;
|
||||
width: $diameter;
|
||||
height: $diameter;
|
||||
}
|
||||
|
||||
@mixin badge-style(
|
||||
$background: $badge-background,
|
||||
$color: $badge-font-color
|
||||
) {
|
||||
background: $background;
|
||||
|
||||
@if $color == auto {
|
||||
color: isitlight($background);
|
||||
}
|
||||
@else {
|
||||
color: $color;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin badge(
|
||||
$background: $badge-background,
|
||||
$color: $badge-color,
|
||||
$diameter: $badge-diameter,
|
||||
$fontsize: $badge-fontsize
|
||||
) {
|
||||
@extend %badge;
|
||||
@include badge-layout($fontsize, $diameter);
|
||||
@include badge-style($background, $color);
|
||||
}
|
||||
|
||||
@include exports(badge) {
|
||||
.badge {
|
||||
@include badge;
|
||||
|
||||
&.secondary {
|
||||
@include badge-style($secondary-color, auto);
|
||||
}
|
||||
@each $color in map-keys($foundation-colors) {
|
||||
&.#{$color} {
|
||||
$color-value: map-get($foundation-colors, $color);
|
||||
@include badge-style($color-value, auto);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
@mixin inline-list($alignment){
|
||||
list-style-type: none;
|
||||
text-align: $alignment;
|
||||
li, dt, dd {
|
||||
display: inline-block;
|
||||
margin-left: -2px;
|
||||
margin-right: -2px;
|
||||
}
|
||||
}
|
||||
|
||||
@include exports(list) {
|
||||
.inline-list {
|
||||
@include inline-list(left);
|
||||
li {
|
||||
margin-right: 1rem;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
+363
@@ -0,0 +1,363 @@
|
||||
/*
|
||||
MENU BAR
|
||||
--------
|
||||
|
||||
A generic, flexible menu component.
|
||||
|
||||
Features:
|
||||
- Orient horizontally and vertically
|
||||
- Change orientation at certain breakpoints
|
||||
- Items with icons above, below, or to the left or right
|
||||
- Text labels for vertical menus and badges for horizontal menus
|
||||
*/
|
||||
|
||||
/// @Foundation.settings
|
||||
// Menu Bar
|
||||
$menubar-fontsize: 1rem !default;
|
||||
$menubar-background: #fff !default;
|
||||
$menubar-background-hover: smartscale($menubar-background, 7%) !default;
|
||||
$menubar-background-active: $menubar-background-hover;
|
||||
$menubar-color: isitlight($menubar-background) !default;
|
||||
$menubar-color-hover: $menubar-color !default;
|
||||
$menubar-color-active: $menubar-color-hover;
|
||||
|
||||
$menubar-item-padding: $global-padding !default;
|
||||
$menubar-icon-size: 25px !default;
|
||||
$menubar-icon-spacing: $menubar-item-padding !default;
|
||||
///
|
||||
|
||||
// Menu bar container
|
||||
%menu-bar {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
margin: 0;
|
||||
list-style-type: none;
|
||||
|
||||
// Menu item
|
||||
> li {
|
||||
// This flex setting makes each item an equal width
|
||||
flex: 1 0 auto;
|
||||
align-items: center;
|
||||
|
||||
// Link inside menu item
|
||||
> a {
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
align-items: center;
|
||||
padding: $menubar-item-padding;
|
||||
font-size: $menubar-fontsize;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin menu-bar-layout (
|
||||
$orientation: horizontal,
|
||||
$stretch: true
|
||||
) {
|
||||
/*
|
||||
Orientation
|
||||
*/
|
||||
@if $orientation == horizontal {
|
||||
overflow-x: hidden;
|
||||
flex-flow: row nowrap;
|
||||
> li > a {
|
||||
flex-flow: column nowrap;
|
||||
}
|
||||
}
|
||||
@else {
|
||||
flex-flow: column nowrap;
|
||||
> li > a {
|
||||
flex-flow: row nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Stretch
|
||||
*/
|
||||
> li {
|
||||
@if $stretch == false {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin menu-bar-style(
|
||||
$background: $menubar-background,
|
||||
$background-hover: $menubar-background-hover,
|
||||
$background-active: $menubar-background-active,
|
||||
$color: $menubar-color,
|
||||
$color-hover: $menubar-color-hover,
|
||||
$color-active: $menubar-color-active,
|
||||
$autocolor: false
|
||||
) {
|
||||
// Autocoloring
|
||||
@if ($autocolor) {
|
||||
$background-hover: smartscale($background, 7%);
|
||||
$background-active: $background-hover;
|
||||
|
||||
$color: isitlight($background);
|
||||
$color-hover: $color;
|
||||
$color-active: $color;
|
||||
}
|
||||
|
||||
// Container
|
||||
background: $background;
|
||||
|
||||
// Items
|
||||
> li > a {
|
||||
color: $color;
|
||||
|
||||
&:hover {
|
||||
background: $background-hover;
|
||||
color: $color-hover;
|
||||
}
|
||||
}
|
||||
.is-active > a {
|
||||
background: $background-active;
|
||||
color: $color-active
|
||||
}
|
||||
|
||||
// Iconic
|
||||
@if using(iconic) {
|
||||
.iconic { @include color-icon($color); }
|
||||
}
|
||||
}
|
||||
|
||||
@mixin menu-bar-icons(
|
||||
$position: left,
|
||||
$size: $menubar-icon-size
|
||||
) {
|
||||
> li {
|
||||
// Sizing
|
||||
> img, > .iconic {
|
||||
margin: 0;
|
||||
@if $menubar-icon-size != false {
|
||||
width: $menubar-icon-size;
|
||||
height: $menubar-icon-size;
|
||||
}
|
||||
}
|
||||
|
||||
// Position
|
||||
@if $position == left {
|
||||
> a {
|
||||
flex-flow: row nowrap;
|
||||
align-items: center;
|
||||
> img, > .iconic { margin: 0 $menubar-icon-spacing 0 0; }
|
||||
}
|
||||
}
|
||||
@if $position == top {
|
||||
> a {
|
||||
flex-flow: column nowrap;
|
||||
> img, > .iconic { margin: 0 0 $menubar-icon-spacing 0; }
|
||||
}
|
||||
}
|
||||
@if $position == right {
|
||||
> a {
|
||||
flex-flow: row-reverse nowrap;
|
||||
> img, > .iconic { margin: 0 0 0 $menubar-icon-spacing; }
|
||||
}
|
||||
}
|
||||
@if $position == bottom {
|
||||
> a {
|
||||
flex-flow: column-reverse nowrap;
|
||||
> img, > .iconic { margin: $menubar-icon-spacing 0 0 0; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin menu-bar-labels(
|
||||
$x: right,
|
||||
$y: center,
|
||||
$offset: $menubar-item-padding,
|
||||
$size: 1.2rem,
|
||||
$background: red,
|
||||
$color: auto,
|
||||
$selector: '.menu-bar-label'
|
||||
) {
|
||||
> li {
|
||||
position: relative;
|
||||
|
||||
> a {
|
||||
@if $x == left or $x == right {
|
||||
padding-#{$x}: $size + $offset * 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#{$selector} {
|
||||
display: block;
|
||||
font-size: $size * 0.75;
|
||||
width: $size;
|
||||
height: $size;
|
||||
line-height: $size;
|
||||
text-align: center;
|
||||
border-radius: 1000px;
|
||||
background: $background;
|
||||
color: if($color == auto, isitlight($background), $color);
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
|
||||
@if $x == left or $x == right {
|
||||
#{$x}: $offset;
|
||||
}
|
||||
|
||||
@if $y == top or $y == bottom {
|
||||
#{$y}: $offset;
|
||||
}
|
||||
@else {
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Set the alignment of menu items (li) within a menu-bar
|
||||
|
||||
left: Items align to the left.
|
||||
right: Items align to the right.
|
||||
center: Items align to the center.
|
||||
justify: Items are spaced equally apart so they occupy the space of the entire grid.
|
||||
spaced: Items are given equal space to their left and right.
|
||||
|
||||
@group menu-bar
|
||||
|
||||
@param {string} $align - Alignment to use.
|
||||
|
||||
@output An appropriate justify-content value.
|
||||
*/
|
||||
@mixin menu-bar-align($align: left) {
|
||||
$options: (
|
||||
left: flex-start,
|
||||
right: flex-end,
|
||||
center: center,
|
||||
justify: space-between,
|
||||
spaced: space-around,
|
||||
);
|
||||
justify-content: map-get($options, $align);
|
||||
}
|
||||
|
||||
/*
|
||||
CSS output
|
||||
*/
|
||||
@include exports(menu-bar) {
|
||||
.menu-bar {
|
||||
@extend %menu-bar;
|
||||
@include menu-bar-style;
|
||||
|
||||
// Positioning
|
||||
&, &.horizontal { @include menu-bar-layout(horizontal); }
|
||||
&.vertical { @include menu-bar-layout(vertical); }
|
||||
|
||||
// Condensed bar
|
||||
&.condense {
|
||||
> li { flex: 0 0 auto; }
|
||||
}
|
||||
|
||||
// Align Menu Items
|
||||
&.align-right { @include menu-bar-align(right); }
|
||||
&.align-center { @include menu-bar-align(center); }
|
||||
&.align-justify { @include menu-bar-align(justify); }
|
||||
&.align-spaced { @include menu-bar-align(spaced); }
|
||||
|
||||
@each $size in $breakpoint-classes {
|
||||
@include breakpoint($size) {
|
||||
&.#{$size}-condense { li { flex: 0 0 auto; } }
|
||||
&.#{$size}-expand { li { flex: 1 0 auto; } }
|
||||
|
||||
// Responsive Alignment
|
||||
&.#{$size}-align-left { @include menu-bar-align(left); }
|
||||
&.#{$size}-align-right { @include menu-bar-align(right); }
|
||||
&.#{$size}-align-center { @include menu-bar-align(center); }
|
||||
&.#{$size}-align-justify { @include menu-bar-align(justify); }
|
||||
&.#{$size}-align-spaced { @include menu-bar-align(spaced); }
|
||||
}
|
||||
}
|
||||
|
||||
// Responsive positioning
|
||||
@each $size in $breakpoint-classes {
|
||||
@include breakpoint($size) {
|
||||
&.#{$size}-horizontal {
|
||||
@include menu-bar-layout(horizontal);
|
||||
}
|
||||
&.#{$size}-vertical {
|
||||
@include menu-bar-layout(vertical);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Icon positioning
|
||||
&, &.icon-top { @include menu-bar-icons(top); }
|
||||
&.icon-right { @include menu-bar-icons(right); }
|
||||
&.icon-bottom { @include menu-bar-icons(bottom); }
|
||||
&.icon-left { @include menu-bar-icons(left); }
|
||||
@each $size in $breakpoint-classes {
|
||||
@each $pos in (top, right, bottom, left) {
|
||||
@include breakpoint($size) {
|
||||
&.#{$size}-icon-#{$pos} { @include menu-bar-icons($pos); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Labels
|
||||
&.label-side { @include menu-bar-labels(right, center); }
|
||||
&.label-corner { @include menu-bar-labels(right, top); }
|
||||
|
||||
// Coloring
|
||||
&.primary {
|
||||
@include menu-bar-style($primary-color, $autocolor: true);
|
||||
}
|
||||
&.dark {
|
||||
@include menu-bar-style($dark-color, $autocolor: true);
|
||||
}
|
||||
|
||||
// Title
|
||||
> li.title {
|
||||
padding: $menubar-item-padding;
|
||||
cursor: default;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
// Menu groups
|
||||
.menu-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
|
||||
@include breakpoint(medium) {
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
> .menu-group-left, > .menu-group-right {
|
||||
flex: 1 1 100%;
|
||||
|
||||
@include breakpoint(medium) {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
// Menu bar is condensed
|
||||
.menu-bar {
|
||||
> li { flex: 0 0 auto; }
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
// Coloring class cascades down to the menu bar
|
||||
&.primary {
|
||||
background-color: $primary-color;
|
||||
.menu-bar {
|
||||
@include menu-bar-style($primary-color, $autocolor: true);
|
||||
}
|
||||
}
|
||||
&.dark {
|
||||
background-color: $dark-color;
|
||||
.menu-bar {
|
||||
@include menu-bar-style($dark-color, $autocolor: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
MODAL
|
||||
-----
|
||||
|
||||
The humble modal hides off-canvas until summoned with an fa-open directive. Modals appear over an overlay that darkens the rest of the page, and have a maxmimum width. You can construct a grid inside a modal, or attach panels to it.
|
||||
|
||||
Note that the modal overlay is hardcoded into the CSS, because whether or not you build your modal semantically, the overlay is always required and will always look the same.
|
||||
*/
|
||||
|
||||
/// @Foundation.settings
|
||||
// Modal
|
||||
$modal-background: #fff !default;
|
||||
$modal-border: 0 !default;
|
||||
$modal-radius: 0px !default;
|
||||
$modal-shadow: none !default;
|
||||
$modal-zindex: 1000 !default;
|
||||
$modal-sizes: (
|
||||
tiny: 300px,
|
||||
small: 500px,
|
||||
medium: 600px,
|
||||
large: 800px,
|
||||
) !default;
|
||||
|
||||
$modal-overlay-class: 'modal-overlay' !default;
|
||||
$modal-overlay-background: rgba(#333, 0.7) !default;
|
||||
///
|
||||
|
||||
%modal {
|
||||
position: relative;
|
||||
z-index: $modal-zindex + 1;
|
||||
background: $modal-background;
|
||||
flex: 0 0 auto;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
max-height: 100%;
|
||||
overflow: hidden;
|
||||
padding: $global-padding;
|
||||
|
||||
@include breakpoint(medium) {
|
||||
height: auto;
|
||||
max-width: map-get($modal-sizes, medium);
|
||||
}
|
||||
|
||||
.grid-content, .grid-block {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.close-button, [fa-close] {
|
||||
z-index: $modal-zindex + 1;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin modal-dialog() {
|
||||
height: auto;
|
||||
}
|
||||
@mixin modal-layout(
|
||||
$width: map-get($modal-sizes, medium),
|
||||
$dialog: false
|
||||
) {
|
||||
max-width: $width;
|
||||
}
|
||||
@mixin modal-style(
|
||||
$border: $modal-border,
|
||||
$radius: $modal-radius,
|
||||
$shadow: $modal-shadow
|
||||
) {
|
||||
@if $border != 0 {
|
||||
border: $border;
|
||||
}
|
||||
@if $radius != 0px {
|
||||
border-radius: $radius;
|
||||
}
|
||||
@if $shadow != none {
|
||||
box-shadow: $shadow;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin modal(
|
||||
$width: map-get($modal-sizes, medium),
|
||||
$border: $modal-border,
|
||||
$radius: $modal-radius,
|
||||
$shadow: $modal-shadow
|
||||
) {
|
||||
@extend %modal;
|
||||
@include modal-layout($width);
|
||||
@include modal-style($border, $radius, $shadow);
|
||||
}
|
||||
|
||||
@include exports(modal) {
|
||||
.modal {
|
||||
@include modal;
|
||||
|
||||
@each $size in map-keys($modal-sizes) {
|
||||
$width: map-get($modal-sizes, $size);
|
||||
@if $size != medium {
|
||||
.#{$size} > & { @include modal-layout($width); }
|
||||
}
|
||||
}
|
||||
|
||||
.dialog > & {
|
||||
@include modal-dialog;
|
||||
}
|
||||
.collapse > & {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.#{$modal-overlay-class} {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: $modal-zindex;
|
||||
display: none;
|
||||
background-color: $modal-overlay-background;
|
||||
|
||||
// Horizontally and vertically center the modal
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
&.is-active {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,524 @@
|
||||
// FOUNDATION MOTION UI
|
||||
// Table of Contents
|
||||
//
|
||||
// 0. Variables
|
||||
// 1. Base Transitions
|
||||
// a. Slide
|
||||
// b. Fade
|
||||
// c. Hinge
|
||||
// d. Scale
|
||||
// e. Spin
|
||||
// 2. Base Animations
|
||||
// a. Shake
|
||||
// b. Spinners
|
||||
// c. Wiggle
|
||||
// 3. HTML Attributes
|
||||
|
||||
// 0. Variables
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
/// @Foundation.settings
|
||||
// Motion UI
|
||||
// Classes to use when triggering in/out animations
|
||||
$motion-class: (
|
||||
in: "ng-enter",
|
||||
out: "ng-leave",
|
||||
) !default;
|
||||
$motion-class-active: (
|
||||
in: "ng-enter-active",
|
||||
out: "ng-leave-active",
|
||||
) !default;
|
||||
$motion-class-stagger: (
|
||||
in: "ng-enter-stagger",
|
||||
out: "ng-leave-stagger",
|
||||
) !default;
|
||||
$motion-class-showhide: (
|
||||
in: "ng-hide-remove",
|
||||
out: "ng-hide-add",
|
||||
);
|
||||
$motion-class-showhide-active: (
|
||||
in: "ng-hide-remove-active",
|
||||
out: "ng-hide-add-active",
|
||||
);
|
||||
|
||||
// Set if movement-based transitions should also fade the element in and out
|
||||
$motion-slide-and-fade: false !default;
|
||||
$motion-hinge-and-fade: true !default;
|
||||
$motion-scale-and-fade: true !default;
|
||||
$motion-spin-and-fade: true !default;
|
||||
|
||||
// Default speed for transitions and animations
|
||||
$motion-duration-default: 500ms !default;
|
||||
|
||||
// Slow and fast modifiders
|
||||
$motion-duration-slow: 750ms !default;
|
||||
$motion-duration-fast: 250ms !default;
|
||||
$motion-stagger-duration-default: 150ms !default;
|
||||
$motion-stagger-duration-short: 50ms !default;
|
||||
$motion-stagger-duration-long: 300ms !default;
|
||||
|
||||
// Default timing function for transitions and animations
|
||||
$motion-timing-default: ease !default;
|
||||
|
||||
// Built-in and custom easing functions
|
||||
// Every item in this map becomes a CSS class
|
||||
$motion-timings: (
|
||||
linear: linear,
|
||||
ease: ease,
|
||||
easeIn: ease-in,
|
||||
easeOut: ease-out,
|
||||
easeInOut: ease-in-out,
|
||||
bounceIn: cubic-bezier(0.485, 0.155, 0.240, 1.245),
|
||||
bounceOut: cubic-bezier(0.485, 0.155, 0.515, 0.845),
|
||||
bounceInOut: cubic-bezier(0.760, -0.245, 0.240, 1.245),
|
||||
) !default;
|
||||
|
||||
// Default delay for all transitions and animations
|
||||
$motion-delay-default: 0 !default;
|
||||
// Short and long delay modifiers
|
||||
$motion-delay-short: 300ms !default;
|
||||
$motion-delay-long: 700ms !default;
|
||||
///
|
||||
|
||||
// Looks for a timing function in the list of presets
|
||||
// If none are found, returns the value as-is.
|
||||
@function get-timing($timing) {
|
||||
@if map-has-key($motion-timings, $timing) {
|
||||
@return map-get($motion-timings, $timing);
|
||||
}
|
||||
@else {
|
||||
@return $timing;
|
||||
}
|
||||
}
|
||||
|
||||
// Applies transition settings common to all mixins
|
||||
@mixin transition-basics(
|
||||
$duration: $motion-duration-default,
|
||||
$timing: $motion-timing-default,
|
||||
$delay: $motion-delay-default
|
||||
) {
|
||||
transition-duration: $duration;
|
||||
transition-timing-function: get-timing($timing);
|
||||
transition-delay: $delay;
|
||||
}
|
||||
|
||||
// Wraps content in an enter/leave class, chained to the parent selector
|
||||
// Define the initial state of a transition here
|
||||
@mixin transition-start($dir) {
|
||||
$sel1: map-get($motion-class, $dir);
|
||||
$sel2: map-get($motion-class-showhide, $dir);
|
||||
|
||||
&.#{$sel1},
|
||||
&.#{$sel2} {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
// Wraps content in an enter/leave active class, chained to the matching
|
||||
// enter/leave class, chained to the parent selector
|
||||
// Define the end state of a transition here
|
||||
@mixin transition-end($dir) {
|
||||
$sel1: map-get($motion-class, $dir);
|
||||
$sel1A: map-get($motion-class-active, $dir);
|
||||
|
||||
$sel2: map-get($motion-class-showhide, $dir);
|
||||
$sel2A: map-get($motion-class-showhide-active, $dir);
|
||||
|
||||
&.#{$sel1}.#{$sel1A},
|
||||
&.#{$sel2}.#{$sel2A} {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin stagger($delay-amount) {
|
||||
transition-delay: $delay-amount;
|
||||
// this is to avoid accidental CSS inheritance
|
||||
transition-duration:0;
|
||||
}
|
||||
|
||||
|
||||
// 1. Base Transitions
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
// SLIDE
|
||||
@mixin slide (
|
||||
$dir: in,
|
||||
$from: left,
|
||||
$fade: $motion-slide-and-fade,
|
||||
$duration: $motion-duration-default,
|
||||
$timing: $motion-timing-default,
|
||||
$delay: $motion-delay-default
|
||||
) {
|
||||
$slideDirections: (
|
||||
top: translateY(-100%),
|
||||
right: translateX(100%),
|
||||
bottom: translateY(100%),
|
||||
left: translateX(-100%),
|
||||
);
|
||||
$start: '';
|
||||
$end: '';
|
||||
|
||||
@if $dir == in {
|
||||
$start: map-get($slideDirections, $from);
|
||||
$end: translateX(0) translateY(0);
|
||||
}
|
||||
@else {
|
||||
$start: translateX(0) translateY(0);
|
||||
$end: map-get($slideDirections, $from);
|
||||
}
|
||||
|
||||
// CSS Output
|
||||
@include transition-start($dir) {
|
||||
@include transition-basics($duration, $timing, $delay);
|
||||
transition-property: transform, opacity;
|
||||
backface-visibility: hidden;
|
||||
transform: $start;
|
||||
|
||||
@if $fade { opacity: if($dir == in, 0, 1); }
|
||||
}
|
||||
@include transition-end($dir) {
|
||||
transform: $end;
|
||||
|
||||
@if $fade { opacity: if($dir == in, 1, 0); }
|
||||
}
|
||||
}
|
||||
|
||||
// FADE
|
||||
@mixin fade(
|
||||
$dir: in,
|
||||
$from: 0,
|
||||
$to: 1,
|
||||
$duration: $motion-duration-default,
|
||||
$timing: $motion-timing-default,
|
||||
$delay: $motion-delay-default
|
||||
) {
|
||||
@include transition-start($dir) {
|
||||
@include transition-basics($duration, $timing, $delay);
|
||||
transition-property: opacity;
|
||||
opacity: $from;
|
||||
}
|
||||
@include transition-end($dir) {
|
||||
opacity: $to;
|
||||
}
|
||||
}
|
||||
|
||||
// HINGE
|
||||
@mixin hinge (
|
||||
$dir: in,
|
||||
$from: left,
|
||||
$axis: edge,
|
||||
$perspective: 2000px,
|
||||
$turn-origin: from-back,
|
||||
$fade: $motion-hinge-and-fade,
|
||||
$duration: $motion-duration-default,
|
||||
$timing: $motion-timing-default,
|
||||
$delay: $motion-delay-default
|
||||
) {
|
||||
|
||||
// Rotation directions when hinging from back vs. front
|
||||
$rotationAmount: 90deg;
|
||||
$rotationsBack: (
|
||||
top: rotateX($rotationAmount * -1),
|
||||
right: rotateY($rotationAmount * -1),
|
||||
bottom: rotateX($rotationAmount),
|
||||
left: rotateY($rotationAmount),
|
||||
);
|
||||
$rotationsFrom: (
|
||||
top: rotateX($rotationAmount),
|
||||
right: rotateY($rotationAmount),
|
||||
bottom: rotateX($rotationAmount * -1),
|
||||
left: rotateY($rotationAmount * -1),
|
||||
);
|
||||
|
||||
// Rotation origin
|
||||
$rotation: '';
|
||||
@if $turn-origin == from-front {
|
||||
$rotation: map-get($rotationsFrom, $from);
|
||||
}
|
||||
@else if $turn-origin == from-back {
|
||||
$rotation: map-get($rotationsBack, $from);
|
||||
}
|
||||
@else {
|
||||
@warn "`$turn-origin` must be either `from-back` or `from-front`";
|
||||
}
|
||||
|
||||
// Start and end state
|
||||
$start: '';
|
||||
$end: '';
|
||||
@if $dir == in {
|
||||
$start: perspective($perspective) $rotation;
|
||||
$end: rotate(0deg);
|
||||
}
|
||||
@else {
|
||||
$start: rotate(0deg);
|
||||
$end: perspective($perspective) $rotation;
|
||||
}
|
||||
|
||||
// Turn axis
|
||||
$origin: '';
|
||||
@if $axis == edge {
|
||||
$origin: $from;
|
||||
}
|
||||
@else {
|
||||
$origin: center;
|
||||
}
|
||||
|
||||
@include transition-start($dir) {
|
||||
@include transition-basics($duration, $timing, $delay);
|
||||
transition-property: transform, opacity;
|
||||
transform: $start;
|
||||
transform-origin: $origin;
|
||||
@if $fade { opacity: if($dir == in, 0, 1); }
|
||||
}
|
||||
@include transition-end($dir) {
|
||||
transform: $end;
|
||||
@if $fade { opacity: if($dir == in, 1, 0); }
|
||||
}
|
||||
}
|
||||
|
||||
// SCALE
|
||||
@mixin scale(
|
||||
$dir: in,
|
||||
$from: 1.5,
|
||||
$to: 1,
|
||||
$fade: $motion-scale-and-fade,
|
||||
$duration: $motion-duration-default,
|
||||
$timing: $motion-timing-default,
|
||||
$delay: $motion-delay-default
|
||||
) {
|
||||
@include transition-start($dir) {
|
||||
@include transition-basics($duration, $timing, $delay);
|
||||
transition-property: transform, property;
|
||||
transform: scale($from);
|
||||
@if $fade { opacity: if($dir == in, 0, 1) }
|
||||
}
|
||||
@include transition-end($dir) {
|
||||
transform: scale($to);
|
||||
@if $fade { opacity: if($dir == in, 1, 0) }
|
||||
}
|
||||
}
|
||||
|
||||
// SPIN
|
||||
@mixin spin(
|
||||
$dir: in,
|
||||
$amount: 0.75turn,
|
||||
$ccw: false,
|
||||
$fade: $motion-spin-and-fade,
|
||||
$duration: $motion-duration-default,
|
||||
$timing: $motion-timing-default,
|
||||
$delay: $motion-delay-default
|
||||
) {
|
||||
$amount: turn-to-deg($amount);
|
||||
$start: 0;
|
||||
$end: 0;
|
||||
|
||||
@if $dir == in {
|
||||
$start: if($ccw, $amount, $amount * -1);
|
||||
$end: 0;
|
||||
}
|
||||
@else {
|
||||
$start: 0;
|
||||
$end: if($ccw, $amount * -1, $amount);
|
||||
}
|
||||
|
||||
@include transition-start($dir) {
|
||||
transition-property: transform, opacity;
|
||||
transform: rotate($start);
|
||||
@if $fade { opacity: if($dir == in, 0, 1); }
|
||||
}
|
||||
@include transition-end($dir) {
|
||||
transform: rotate($end);
|
||||
@if $fade { opacity: if($dir == in, 1, 0); }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 2. Base Animations
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
// SHAKE
|
||||
@keyframes shake {
|
||||
0%, 10%, 20%, 30%, 40%, 50%, 60%, 70%, 80%, 90% {
|
||||
transform: translateX(7%);
|
||||
}
|
||||
5%, 15%, 25%, 35%, 45%, 55%, 65%, 75%, 85%, 95% {
|
||||
transform: translateX(-7%);
|
||||
}
|
||||
100% { transform: translateX(0); }
|
||||
}
|
||||
|
||||
// SPINNERS
|
||||
@keyframes spin-cw {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
@keyframes spin-ccw {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(-360deg); }
|
||||
}
|
||||
|
||||
// WIGGLE
|
||||
@keyframes wiggle {
|
||||
40%, 50%, 60% {
|
||||
transform: rotate(7deg);
|
||||
}
|
||||
35%, 45%, 55%, 65% {
|
||||
transform: rotate(-7deg);
|
||||
}
|
||||
0%, 30%, 70%, 100% { transform: rotate(0); }
|
||||
}
|
||||
|
||||
@mixin animation(
|
||||
$animation,
|
||||
$duration: $motion-duration-default,
|
||||
$timing: $motion-timing-default,
|
||||
$delay: $motion-delay-default,
|
||||
$iterations: null
|
||||
) {
|
||||
|
||||
animation-name: $animation;
|
||||
animation-duration: $duration;
|
||||
animation-timing-function: $timing;
|
||||
|
||||
backface-visibility: hidden;
|
||||
transform: translate3d(0,0,0);
|
||||
|
||||
@if $delay != null {
|
||||
animation-delay: $delay;
|
||||
}
|
||||
@if $iterations != null {
|
||||
animation-iteration-count: $iterations;
|
||||
}
|
||||
|
||||
@if $animation == null {
|
||||
@warn "Please include an animation name";
|
||||
}
|
||||
}
|
||||
|
||||
// 3. HTML Exports
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
@include exports(motion) {
|
||||
/*
|
||||
Transitions
|
||||
*/
|
||||
|
||||
// Slide
|
||||
.slideInDown { @include slide($from: top); }
|
||||
.slideInLeft { @include slide($from: right); }
|
||||
.slideInUp { @include slide($from: bottom); }
|
||||
.slideInRight { @include slide($from: left); }
|
||||
.slideOutBottom { @include slide($dir: out, $from: bottom); }
|
||||
.slideOutRight { @include slide($dir: out, $from: right); }
|
||||
.slideOutUp { @include slide($dir: out, $from: top); }
|
||||
.slideOutLeft { @include slide($dir: out, $from: left); }
|
||||
|
||||
// Fade
|
||||
.fadeIn { @include fade(in, 0, 1); }
|
||||
.fadeOut { @include fade(out, 1, 0); }
|
||||
|
||||
// Hinge
|
||||
.hingeInFromTop { @include hinge($dir: in, $from: top); }
|
||||
.hingeInFromRight { @include hinge($dir: in, $from: right); }
|
||||
.hingeInFromBottom { @include hinge($dir: in, $from: bottom); }
|
||||
.hingeInFromLeft { @include hinge($dir: in, $from: left); }
|
||||
.hingeInFromMiddleX { @include hinge($dir: in, $from: top, $axis: center); }
|
||||
.hingeInFromMiddleY { @include hinge($dir: in, $from: right, $axis: center); }
|
||||
.hingeOutFromTop { @include hinge($dir: out, $from: top); }
|
||||
.hingeOutFromRight { @include hinge($dir: out, $from: right); }
|
||||
.hingeOutFromBottom { @include hinge($dir: out, $from: bottom); }
|
||||
.hingeOutFromLeft { @include hinge($dir: out, $from: left); }
|
||||
.hingeOutFromMiddleX { @include hinge($dir: out, $from: top, $axis: center); }
|
||||
.hingeOutFromMiddleY { @include hinge($dir: out, $from: right, $axis: center); }
|
||||
|
||||
// Scale
|
||||
.zoomIn { @include scale(in, 1.5, 1); }
|
||||
.zoomOut { @include scale(out, 0.5, 1); }
|
||||
|
||||
// Spin
|
||||
.spinIn { @include spin(in, 0.75turn); }
|
||||
.spinOut { @include spin(out, 0.75turn); }
|
||||
.spinInCCW { @include spin(in, 0.75turn, true); }
|
||||
.spinOutCCW { @include spin(out, 0.75turn, true); }
|
||||
|
||||
/*
|
||||
Transition modifiers
|
||||
*/
|
||||
|
||||
// Duration
|
||||
.slow { transition-duration: $motion-duration-slow !important; }
|
||||
.fast { transition-duration: $motion-duration-fast !important; }
|
||||
|
||||
// Easing
|
||||
@each $easing in map-keys($motion-timings) {
|
||||
.#{$easing} {
|
||||
transition-timing-function: map-get($motion-timings, $easing) !important;
|
||||
}
|
||||
}
|
||||
|
||||
// Delay
|
||||
.delay { transition-delay: $motion-delay-short !important; }
|
||||
.long-delay { transition-delay: $motion-delay-long !important; }
|
||||
|
||||
/*
|
||||
Animations
|
||||
*/
|
||||
|
||||
.shake { @include animation(shake); }
|
||||
.spin-cw { @include animation(spin-cw); }
|
||||
.spin-ccw { @include animation(spin-ccw); }
|
||||
.wiggle { @include animation(wiggle); }
|
||||
|
||||
/*
|
||||
Animation modifiers
|
||||
*/
|
||||
|
||||
.shake,
|
||||
.spin-cw,
|
||||
.spin-ccw,
|
||||
.wiggle {
|
||||
// Repeat
|
||||
&.infinite { animation-iteration-count: infinite; }
|
||||
|
||||
// Easing
|
||||
@each $timing in map-keys($motion-timings) {
|
||||
&.#{$timing} {
|
||||
animation-timing-function: map-get($motion-timings, $timing) !important;
|
||||
}
|
||||
}
|
||||
|
||||
// Duration
|
||||
&.slow { animation-duration: $motion-duration-slow !important; }
|
||||
&.fast { animation-duration: $motion-duration-fast !important; }
|
||||
|
||||
// Delay
|
||||
&.delay { animation-delay: $motion-delay-short !important; }
|
||||
&.long-delay { animation-delay: $motion-delay-long !important; }
|
||||
}
|
||||
.stagger { @include stagger($motion-stagger-duration-default); }
|
||||
.stort-stagger { @include stagger($motion-stagger-duration-default); }
|
||||
.long-stagger { @include stagger($motion-stagger-duration-default); }
|
||||
}
|
||||
|
||||
// View animation classes
|
||||
// - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
// Applied to the immediate parent of the animating views
|
||||
.position-absolute {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
// Applied to the animating views
|
||||
.ui-animation {
|
||||
&.ng-enter-active, &.ng-leave-active {
|
||||
position: absolute !important;
|
||||
backface-visibility: hidden;
|
||||
-webkit-transform-style: preserve-3d;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
+207
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
NOTIFICATION
|
||||
------------
|
||||
|
||||
An alert that pins to the corner of the screen when triggered by JavaScript. It can be set to disappear after a certain period of time, or to stay put until the user clicks on it. A custom action can be asigned to a notification as well.
|
||||
|
||||
Optionally, the notifications directive can also tap into the browser's native notification support, if it exists.
|
||||
*/
|
||||
|
||||
/// @Foundation.settings
|
||||
// Notification
|
||||
$notification-default-position: right top !default;
|
||||
$notification-width: rem-calc(400) !default;
|
||||
$notification-offset: $global-padding !default;
|
||||
|
||||
$notification-background: $primary-color !default;
|
||||
$notification-color: white !default;
|
||||
$notification-padding: $global-padding !default;
|
||||
$notification-radius: 4px !default;
|
||||
|
||||
$notification-icon-size: 60px !default;
|
||||
$notification-icon-margin: $global-padding !default;
|
||||
$notification-icon-align: top !default;
|
||||
|
||||
///
|
||||
|
||||
%notification {
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
position: relative;
|
||||
margin-top: .5rem;
|
||||
margin-bottom: .5rem;
|
||||
display: none;
|
||||
|
||||
h1 {
|
||||
font-size: 1.25em;
|
||||
margin: 0;
|
||||
}
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
// Placeholder animation
|
||||
// transition: opacity 1s ease-out;
|
||||
|
||||
&.is-active {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.close-button {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
%notification-container {
|
||||
z-index: 3000;
|
||||
position: fixed;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
@mixin notification-layout(
|
||||
$x: nth($notification-default-position, 1),
|
||||
$y: nth($notification-default-position, 2),
|
||||
$size: $notification-width,
|
||||
$offset: $notification-offset
|
||||
) {
|
||||
width: $size;
|
||||
|
||||
@if $x == right {
|
||||
right: $offset;
|
||||
}
|
||||
@else if $x == left {
|
||||
left: $offset;
|
||||
}
|
||||
@else if $x == middle {
|
||||
left: 50%;
|
||||
margin-left: -($size / 2);
|
||||
}
|
||||
|
||||
@if $y == top {
|
||||
top: $offset;
|
||||
}
|
||||
@else if $y == bottom {
|
||||
top: auto;
|
||||
bottom: $offset;
|
||||
}
|
||||
|
||||
// On small screens, notifications are full width but maintain their vertical orientation
|
||||
@include breakpoint(small only) {
|
||||
width: auto;
|
||||
left: $offset;
|
||||
right: $offset;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
@mixin notification-style(
|
||||
$background: $notification-background,
|
||||
$color: $notification-color,
|
||||
$padding: $notification-padding,
|
||||
$radius: $notification-radius
|
||||
) {
|
||||
background: $background;
|
||||
padding: $padding;
|
||||
border-radius: $radius;
|
||||
|
||||
&, h1, h2, h3, h4, h5, h6 {
|
||||
color: $color;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin notification(
|
||||
$background: $notification-background,
|
||||
$color: $notification-color,
|
||||
$padding: $notification-padding,
|
||||
$radius: $notification-radius
|
||||
) {
|
||||
@extend %notification;
|
||||
@include notification-style($background, $color, $padding, $radius);
|
||||
}
|
||||
|
||||
@mixin notification-container(
|
||||
$x: nth($notification-default-position, 1),
|
||||
$y: nth($notification-default-position, 2),
|
||||
$size: $notification-width,
|
||||
$offset: $notification-offset
|
||||
) {
|
||||
@extend %notification-container;
|
||||
@include notification-layout($x, $y, $size, $offset);
|
||||
}
|
||||
|
||||
@mixin notification-icon(
|
||||
$size: $notification-icon-size,
|
||||
$margin: $notification-icon-margin,
|
||||
$align: $notification-icon-align
|
||||
) {
|
||||
$alignments: (
|
||||
top: flex-start,
|
||||
middle: middle,
|
||||
bottom: flex-end,
|
||||
);
|
||||
flex: 0 0 $size;
|
||||
margin-right: $global-padding;
|
||||
align-self: map-get($alignments, $align);
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
CSS Output
|
||||
*/
|
||||
|
||||
@include exports(notification) {
|
||||
.notification {
|
||||
@include notification;
|
||||
|
||||
&.success { @include notification-style($success-color) }
|
||||
&.warning { @include notification-style($warning-color) }
|
||||
&.alert { @include notification-style($alert-color) }
|
||||
&.dark { @include notification-style($dark-color, #fff) }
|
||||
|
||||
|
||||
}
|
||||
|
||||
.static-notification {
|
||||
@include notification;
|
||||
|
||||
position: fixed !important;
|
||||
|
||||
&.top-right { @include notification-layout(right, top); }
|
||||
&.top-left { @include notification-layout(left, top); }
|
||||
&.top-middle { @include notification-layout(middle, top); }
|
||||
|
||||
&.bottom-right { @include notification-layout(right, bottom); }
|
||||
&.bottom-left { @include notification-layout(left, bottom); }
|
||||
&.bottom-middle { @include notification-layout(middle, bottom); }
|
||||
|
||||
&.success { @include notification-style($success-color) }
|
||||
&.warning { @include notification-style($warning-color) }
|
||||
&.alert { @include notification-style($alert-color) }
|
||||
&.dark { @include notification-style($dark-color, #fff) }
|
||||
}
|
||||
|
||||
.notification-container {
|
||||
@include notification-container;
|
||||
|
||||
&.top-right { @include notification-layout(right, top); }
|
||||
&.top-left { @include notification-layout(left, top); }
|
||||
&.top-middle { @include notification-layout(middle, top); }
|
||||
|
||||
&.bottom-right { @include notification-layout(right, bottom); }
|
||||
&.bottom-left { @include notification-layout(left, bottom); }
|
||||
&.bottom-middle { @include notification-layout(middle, bottom); }
|
||||
}
|
||||
|
||||
.notification-icon {
|
||||
@include notification-icon;
|
||||
}
|
||||
.notification-content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
}
|
||||
+169
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
Off-canvas menu
|
||||
---------------
|
||||
|
||||
A generic container that stays fixed to the left, top, right, or bottom of the screen, and is summoned when needed. When an off-canvas panel is open, the app frame shifts over to reveal the menu.
|
||||
*/
|
||||
|
||||
/// @Foundation.settings
|
||||
// Off-canvas
|
||||
$offcanvas-size-horizontal: 250px !default;
|
||||
$offcanvas-size-vertical: 250px !default;
|
||||
|
||||
$offcanvas-background: #fff !default;
|
||||
$offcanvas-color: isitlight($offcanvas-background) !default;
|
||||
$offcanvas-padding: 0 !default;
|
||||
$offcanvas-shadow: 3px 0 10px rgba(black, 0.25) !default;
|
||||
$offcanvas-animation-speed: 0.25s !default;
|
||||
|
||||
$offcanvas-frame-selector: '.grid-frame' !default;
|
||||
///
|
||||
|
||||
%off-canvas {
|
||||
position: fixed;
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
transition: transform $offcanvas-animation-speed ease-out;
|
||||
z-index: 2;
|
||||
|
||||
// Active state
|
||||
&.is-active {
|
||||
transform: translate(0,0) !important;
|
||||
}
|
||||
|
||||
// Frame styles
|
||||
& ~ #{$offcanvas-frame-selector} {
|
||||
transform: translate(0,0,0);
|
||||
transition: transform 0.25s ease-out;
|
||||
backface-visibility: hidden;
|
||||
background: white;
|
||||
}
|
||||
}
|
||||
@mixin off-canvas-detached {
|
||||
z-index: 0;
|
||||
box-shadow: none;
|
||||
|
||||
&, &.is-active {
|
||||
transform: none;
|
||||
}
|
||||
|
||||
& ~ #{$offcanvas-frame-selector} {
|
||||
z-index: 1;
|
||||
box-shadow: 0 0 15px rgba(0,0,0,0.5);
|
||||
}
|
||||
}
|
||||
|
||||
@mixin off-canvas-layout(
|
||||
$position: left,
|
||||
$size: default,
|
||||
$shadow: $offcanvas-shadow
|
||||
) {
|
||||
/*
|
||||
Get shadow values for later use
|
||||
*/
|
||||
$shadow-length: '';
|
||||
$shadow-size: '';
|
||||
$shadow-color: '';
|
||||
@if hasvalue($shadow) {
|
||||
$shadow-length: get-shadow-value($shadow, x);
|
||||
$shadow-size: get-shadow-value($shadow, size);
|
||||
$shadow-color: get-shadow-value($shadow, color);
|
||||
}
|
||||
|
||||
/*
|
||||
Sizing
|
||||
*/
|
||||
@if $position == left or $position == right {
|
||||
@if $size == default {
|
||||
$size: $offcanvas-size-horizontal;
|
||||
}
|
||||
width: $size;
|
||||
height: 100%;
|
||||
}
|
||||
@else {
|
||||
@if $size == default {
|
||||
$size: $offcanvas-size-vertical;
|
||||
}
|
||||
height: $size;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/*
|
||||
Positioning
|
||||
*/
|
||||
@if $position == left {
|
||||
top: 0;
|
||||
left: 0;
|
||||
@if hasvalue($shadow) { box-shadow: inset (-$shadow-length) 0 $shadow-size $shadow-color; }
|
||||
transform: translateX(-100%);
|
||||
&.is-active {
|
||||
& ~ #{$offcanvas-frame-selector} { transform: translateX($size) !important; }
|
||||
}
|
||||
}
|
||||
@else if $position == right {
|
||||
left: auto;
|
||||
top: 0;
|
||||
right: 0;
|
||||
@if hasvalue($shadow) { box-shadow: inset $shadow-length 0 $shadow-size $shadow-color; }
|
||||
transform: translateX(100%);
|
||||
&.is-active {
|
||||
& ~ #{$offcanvas-frame-selector} { transform: translateX(-$size) !important; }
|
||||
}
|
||||
}
|
||||
@else if $position == top {
|
||||
top: 0;
|
||||
left: 0;
|
||||
transform: translateY(-100%);
|
||||
@if hasvalue($shadow) { box-shadow: inset 0 (-$shadow-length) $shadow-size $shadow-color; }
|
||||
&.is-active {
|
||||
& ~ #{$offcanvas-frame-selector} { transform: translateY($size) !important; }
|
||||
}
|
||||
}
|
||||
@else if $position == bottom {
|
||||
top: auto;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
transform: translateY(100%);
|
||||
@if hasvalue($shadow) { box-shadow: inset 0 $shadow-length $shadow-size $shadow-color; }
|
||||
&.is-active {
|
||||
& ~ #{$offcanvas-frame-selector} { transform: translateY(-$size) !important; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin off-canvas-style(
|
||||
$background: $offcanvas-background,
|
||||
$color: $offcanvas-color,
|
||||
$padding: $offcanvas-padding
|
||||
) {
|
||||
background: $background;
|
||||
|
||||
@if $color == auto {
|
||||
color: isitlight($background, #000, #fff);
|
||||
}
|
||||
@else {
|
||||
color: $color;
|
||||
}
|
||||
|
||||
@if hasvalue($padding) {
|
||||
padding: $padding;
|
||||
}
|
||||
}
|
||||
|
||||
@include exports(off-canvas) {
|
||||
.off-canvas {
|
||||
@extend %off-canvas;
|
||||
@include off-canvas-layout;
|
||||
@include off-canvas-style;
|
||||
|
||||
&.top { @include off-canvas-layout(top); }
|
||||
&.right { @include off-canvas-layout(right); }
|
||||
&.bottom { @include off-canvas-layout(bottom); }
|
||||
&.left { @include off-canvas-layout(left); }
|
||||
|
||||
&.detached { @include off-canvas-detached; }
|
||||
|
||||
&.primary { @include off-canvas-style($primary-color, auto); }
|
||||
&.dark { @include off-canvas-style($dark-color, auto); }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
PANEL
|
||||
-----
|
||||
|
||||
The friendly panel is an all-purpose container for hiding content off-screen.
|
||||
|
||||
Features:
|
||||
- Position at top, right, bottom, or left
|
||||
- Anchor to grid block or window
|
||||
- Define max width or height
|
||||
- Transform into grid block depending on screen size
|
||||
*/
|
||||
|
||||
/// @Foundation.settings
|
||||
// Panel
|
||||
$panel-size-horizontal: 300px !default;
|
||||
$panel-size-vertical: 300px !default;
|
||||
$panel-padding: 0 !default;
|
||||
|
||||
$panel-background: #fff !default;
|
||||
$panel-shadow: 3px 0 10px rgba(black, 0.25) !default;
|
||||
|
||||
// DEPRECATED: these variables will be removed in a future version.
|
||||
$panel-animation-speed: 0.25s !default;
|
||||
///
|
||||
|
||||
%panel-base {
|
||||
display: block;
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
overflow-y: auto;
|
||||
display: none;
|
||||
|
||||
&.is-active {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin panel-layout(
|
||||
$position: left,
|
||||
$size: default,
|
||||
$shadow: $panel-shadow
|
||||
) {
|
||||
@if $size == default {
|
||||
@if $position == left or $position == right {
|
||||
$size: $panel-size-horizontal;
|
||||
}
|
||||
@if $position == top or $position == bottom {
|
||||
$size: $panel-size-vertical;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Direction
|
||||
*/
|
||||
@if $position == top {
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
}
|
||||
@else if $position == right {
|
||||
top: 0;
|
||||
right: 0;
|
||||
height: 100%;
|
||||
}
|
||||
@else if $position == bottom {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
}
|
||||
@else if $position == left {
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/*
|
||||
Sizing
|
||||
*/
|
||||
// Horizontal panels are always all the way tall and have a set width
|
||||
@if $position == left or $position == right {
|
||||
@if unit($size) == '%' {
|
||||
width: $size;
|
||||
}
|
||||
@else {
|
||||
width: 100%;
|
||||
@include breakpoint($size) {
|
||||
width: $size;
|
||||
}
|
||||
}
|
||||
}
|
||||
// (For now) vertical panels don't change size
|
||||
@if $position == top or $position == bottom {
|
||||
height: $size;
|
||||
}
|
||||
|
||||
/*
|
||||
Shadows
|
||||
*/
|
||||
$shadow-distance: get-shadow-value($shadow, x);
|
||||
$shadow-size: get-shadow-value($shadow, size);
|
||||
$shadow-color: get-shadow-value($shadow, color);
|
||||
&.is-active {
|
||||
@if $position == left { box-shadow: $shadow-distance 0 $shadow-size $shadow-color; }
|
||||
@else if $position == right { box-shadow: (-$shadow-distance) 0 $shadow-size $shadow-color; }
|
||||
@else if $position == top { box-shadow: 0 $shadow-distance $shadow-size $shadow-color; }
|
||||
@else if $position == bottom { box-shadow: 2px (-$shadow-distance) $shadow-size $shadow-color; }
|
||||
}
|
||||
}
|
||||
|
||||
@mixin panel-style(
|
||||
$padding: $panel-padding,
|
||||
$background: $panel-background
|
||||
) {
|
||||
/*
|
||||
Basic styles
|
||||
*/
|
||||
padding: $padding;
|
||||
background: $background;
|
||||
}
|
||||
|
||||
@include exports(panel) {
|
||||
.panel {
|
||||
@extend %panel-base;
|
||||
@include panel-style;
|
||||
}
|
||||
|
||||
.panel-top { @include panel-layout(top); }
|
||||
.panel-right { @include panel-layout(right); }
|
||||
.panel-bottom { @include panel-layout(bottom); }
|
||||
.panel-left { @include panel-layout(left); }
|
||||
|
||||
.panel-fixed { position: fixed; }
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
POPUP
|
||||
-----
|
||||
|
||||
A floating container that can anchor to any other on-screen element, and contain any content, including grid blocks or panels.
|
||||
*/
|
||||
|
||||
/// @Foundation.settings
|
||||
// Popup
|
||||
$popup-width: rem-calc(300) !default;
|
||||
$popup-background: #fff !default;
|
||||
$popup-border: 0 !default;
|
||||
$popup-radius: 0 !default;
|
||||
$popup-shadow: 0 0 10px rgba(#000, 0.25) !default;
|
||||
///
|
||||
|
||||
%popup {
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
opacity: 0;
|
||||
overflow: hidden;
|
||||
transition: opacity 0.25s ease-out;
|
||||
pointer-events: none;
|
||||
|
||||
&.tether-enabled {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin popup-layout(
|
||||
$width: $popup-width
|
||||
) {
|
||||
width: $popup-width;
|
||||
}
|
||||
@mixin popup-style(
|
||||
$background: $popup-background,
|
||||
$color: #000,
|
||||
$radius: $popup-radius,
|
||||
$shadow: $popup-shadow,
|
||||
$border: $popup-border
|
||||
) {
|
||||
background: $background;
|
||||
border-radius: $radius;
|
||||
box-shadow: $shadow;
|
||||
border: $border;
|
||||
}
|
||||
|
||||
@mixin popup(
|
||||
$width: $popup-width,
|
||||
$background: $popup-background,
|
||||
$radius: $popup-radius,
|
||||
$shadow: $popup-shadow,
|
||||
$border: $popup-border
|
||||
) {
|
||||
@extend %popup;
|
||||
@include popup-layout($width);
|
||||
@include popup-style($background, isitlight($background), $radius, $shadow, $border);
|
||||
}
|
||||
|
||||
@include exports(popup) {
|
||||
.popup {
|
||||
@include popup;
|
||||
|
||||
&.dark { @include popup-style($dark-color, #fff); }
|
||||
&.primary { @include popup-style($primary-color, isitlight($primary-color)); }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
SWITCH
|
||||
------
|
||||
*/
|
||||
|
||||
/// @Foundation.settings
|
||||
// Switch
|
||||
$switch-width: rem-calc(50) !default;
|
||||
$switch-height: rem-calc(32) !default;
|
||||
$switch-background: #ccc !default;
|
||||
$switch-background-active: $primary-color !default;
|
||||
$switch-border: 0 !default;
|
||||
$switch-radius: 9999px !default;
|
||||
$switch-animation-speed: 0.15s !default;
|
||||
|
||||
$switch-paddle-color: white !default;
|
||||
$switch-paddle-offset: 4px !default;
|
||||
///
|
||||
|
||||
%switch {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
display: inline-block;
|
||||
|
||||
> input {
|
||||
position: absolute;
|
||||
left: -9999px;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
> label {
|
||||
-ms-touch-action: manipulation;
|
||||
touch-action: manipulation;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
margin: 0;
|
||||
|
||||
// Paddle
|
||||
&::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Defines the dimmensions of the switch.
|
||||
|
||||
$width - width of the switch.
|
||||
$height - height of the switch.
|
||||
*/
|
||||
@mixin switch-layout(
|
||||
$width: $switch-width,
|
||||
$height: $switch-height
|
||||
) {
|
||||
width: $width;
|
||||
height: $height;
|
||||
|
||||
> label {
|
||||
&::after {
|
||||
width: $height;
|
||||
height: $height;
|
||||
}
|
||||
}
|
||||
input:checked + label {
|
||||
&::after {
|
||||
left: $width - $height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin switch-style(
|
||||
$background: $switch-background,
|
||||
$background-active: $switch-background-active,
|
||||
$border: $switch-border,
|
||||
$radius: $switch-radius,
|
||||
$paddle-color: $switch-paddle-color,
|
||||
$paddle-offset: $switch-paddle-offset,
|
||||
$animation-speed: $switch-animation-speed
|
||||
) {
|
||||
@if hasvalue($border) {
|
||||
border: $border;
|
||||
}
|
||||
border-radius: $radius;
|
||||
|
||||
> label {
|
||||
background: $background;
|
||||
|
||||
&::after {
|
||||
background: $paddle-color;
|
||||
border-radius: $radius;
|
||||
transition: left $animation-speed ease-out;
|
||||
|
||||
@if hasvalue($paddle-offset) {
|
||||
border: $paddle-offset solid $background
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
input:checked + label {
|
||||
background: $background-active;
|
||||
margin: 0;
|
||||
|
||||
&::after {
|
||||
@if hasvalue($paddle-offset) {
|
||||
border-color: $background-active;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin switch() {
|
||||
@extend %switch;
|
||||
@include switch-layout;
|
||||
@include switch-style;
|
||||
}
|
||||
|
||||
@include exports(switch) {
|
||||
.switch {
|
||||
@include switch;
|
||||
|
||||
&.small { @include switch-layout(rem-calc(40), rem-calc(26)); }
|
||||
&.large { @include switch-layout(rem-calc(60), rem-calc(38)); }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
TABS
|
||||
----
|
||||
*/
|
||||
|
||||
/// @Foundation.settings
|
||||
// Tabs
|
||||
$tabstrip-background: transparent !default;
|
||||
|
||||
$tab-title-background: $gray-light !default;
|
||||
$tab-title-background-hover: smartscale($tab-title-background, 5%) !default;
|
||||
$tab-title-background-active: smartscale($tab-title-background, 3%) !default;
|
||||
$tab-title-color: isitlight($tab-title-background) !default;
|
||||
$tab-title-color-active: $tab-title-color !default;
|
||||
|
||||
$tab-title-padding: $global-padding !default;
|
||||
$tab-content-padding: $global-padding !default;
|
||||
///
|
||||
|
||||
@mixin tabstrip(
|
||||
$orientation: horizontal,
|
||||
$background: $tabstrip-background
|
||||
) {
|
||||
/*
|
||||
Container styles
|
||||
*/
|
||||
display: flex;
|
||||
background: $background;
|
||||
|
||||
@if $orientation == vertical {
|
||||
flex-flow: column nowrap;
|
||||
}
|
||||
@else {
|
||||
flex-flow: row wrap;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin tabstrip-item(
|
||||
$background: $tab-title-background,
|
||||
$background-hover: $tab-title-background-hover,
|
||||
$background-active: $tab-title-background-active,
|
||||
$color: $tab-title-color,
|
||||
$color-active: $tab-title-color-active,
|
||||
$padding: $tab-title-padding
|
||||
) {
|
||||
background: $background;
|
||||
padding: $padding;
|
||||
line-height: 1;
|
||||
margin: 0;
|
||||
flex: 0 1 auto;
|
||||
cursor: pointer;
|
||||
color: $color;
|
||||
|
||||
&.is-active {
|
||||
background: $background-active;
|
||||
color: $color-active;
|
||||
|
||||
&:hover {
|
||||
background: $background-hover;
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
background: $background-hover;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin tab-content(
|
||||
$padding: $tab-content-padding
|
||||
) {
|
||||
padding: $padding;
|
||||
}
|
||||
|
||||
@mixin tab-content-item {
|
||||
display: none;
|
||||
&.is-active {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
@include exports(tabs) {
|
||||
.tabs {
|
||||
@include tabstrip(horizontal);
|
||||
|
||||
&.vertical {
|
||||
@include tabstrip(vertical);
|
||||
}
|
||||
|
||||
.tab-item {
|
||||
@include tabstrip-item;
|
||||
}
|
||||
}
|
||||
|
||||
.tab-contents {
|
||||
@include tab-content;
|
||||
|
||||
.tab-content {
|
||||
@include tab-content-item;
|
||||
}
|
||||
}
|
||||
}
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
TITLE BAR
|
||||
---------
|
||||
|
||||
A navigational component which can display the current screen the user is on, along with additional controls or menu items.
|
||||
|
||||
The title bar includes classes to create center, left, and right sections, which can be used in any combination. However, in the markup, the sections must come in this order:
|
||||
- Center
|
||||
- Left
|
||||
- Right
|
||||
*/
|
||||
|
||||
/// @Foundation.settings
|
||||
// Title Bar
|
||||
$titlebar-center-width: 50% !default;
|
||||
$titlebar-side-width: (100% - $titlebar-center-width) / 2 !default;
|
||||
$titlebar-background: #eee !default;
|
||||
$titlebar-color: #000 !default;
|
||||
$titlebar-border: 1px solid #ccc !default;
|
||||
$titlebar-padding: $global-padding !default;
|
||||
$titlebar-item-classes: (
|
||||
center: 'center',
|
||||
left: 'left',
|
||||
right: 'right',
|
||||
title: 'title',
|
||||
) !default;
|
||||
///
|
||||
|
||||
%title-bar {
|
||||
$center: map-get($titlebar-item-classes, center);
|
||||
$left: map-get($titlebar-item-classes, left);
|
||||
$right: map-get($titlebar-item-classes, right);
|
||||
$title: map-get($titlebar-item-classes, title);
|
||||
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
overflow: visible;
|
||||
|
||||
// Denotes the title of the bar
|
||||
.#{$title} {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
// Denotes left, right, and center sections of the bar
|
||||
.#{$left}, .#{$center}, .#{$right} {
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
overflow: visible;
|
||||
|
||||
// If only one section is in use, stretch it all the way out
|
||||
&:first-child:last-child {
|
||||
flex: 1;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Left always comes first, then center, then right
|
||||
// The left and right sections have the same width
|
||||
.#{$left} {
|
||||
order: 1;
|
||||
flex: 0 0 $titlebar-side-width;
|
||||
}
|
||||
.#{$center} {
|
||||
order: 2;
|
||||
flex: 0 0 $titlebar-center-width;
|
||||
text-align: center;
|
||||
}
|
||||
.#{$right} {
|
||||
order: 3;
|
||||
flex: 0 0 $titlebar-side-width;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
// If only left and right are in use, stretch them both out equally
|
||||
.#{$left}:first-child {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
.#{$left}:first-child + .#{$right}:last-child {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
// If only center and right are in use, shift the center section into the right position
|
||||
.#{$center}:first-child:not(:last-child) {
|
||||
margin-left: $titlebar-side-width;
|
||||
}
|
||||
// If only center and left are in use, override the above style
|
||||
.#{$center} + .#{$left} {
|
||||
margin-right: -($titlebar-side-width);
|
||||
}
|
||||
}
|
||||
|
||||
@mixin title-bar-style(
|
||||
$background: $titlebar-background,
|
||||
$color: $titlebar-color,
|
||||
$border: $titlebar-border,
|
||||
$padding: $titlebar-padding
|
||||
) {
|
||||
background: $background;
|
||||
color: $color;
|
||||
padding: $padding;
|
||||
border-bottom: $border;
|
||||
}
|
||||
|
||||
@mixin title-bar(
|
||||
$background: $titlebar-background,
|
||||
$color: $titlebar-color,
|
||||
$border: $titlebar-border,
|
||||
$padding: $titlebar-padding
|
||||
) {
|
||||
@extend %title-bar;
|
||||
@include title-bar-style($background, $color, $border, $padding);
|
||||
}
|
||||
|
||||
@include exports(title-bar) {
|
||||
.title-bar {
|
||||
@include title-bar;
|
||||
|
||||
&.primary {
|
||||
@include title-bar-style($primary-color, isitlight($primary-color));
|
||||
a, a:hover { color: isitlight($primary-color); }
|
||||
@if using(iconic) { .iconic { @include color-icon(isitlight($primary-color)); } }
|
||||
}
|
||||
&.dark {
|
||||
@include title-bar-style($dark-color, #fff);
|
||||
a, a:hover { color: #fff; }
|
||||
@if using(iconic) { .iconic { @include color-icon(#fff); } }
|
||||
}
|
||||
}
|
||||
.title-bar-bottom {
|
||||
border-bottom: 0;
|
||||
border-top: $titlebar-border;
|
||||
}
|
||||
}
|
||||
+345
@@ -0,0 +1,345 @@
|
||||
/*
|
||||
TYPOGRAPHY
|
||||
----------
|
||||
|
||||
Includes typographic resets for many common elements, and a few helper classes.
|
||||
- Headers
|
||||
- Subheaders
|
||||
- Lead paragraphs
|
||||
- Ordered/unordered lists
|
||||
- Code samples
|
||||
- Anchors
|
||||
- Dividers
|
||||
- Blockquotes
|
||||
- Acronyms
|
||||
*/
|
||||
|
||||
/// @Foundation.settings
|
||||
// Typography
|
||||
// We use these to control header font styles
|
||||
$header-font-family: $body-font-family !default;
|
||||
$header-font-weight: $font-weight-normal !default;
|
||||
$header-font-style: $font-weight-normal !default;
|
||||
$header-font-color: #222 !default;
|
||||
$header-line-height: 1.4 !default;
|
||||
$header-top-margin: .2rem !default;
|
||||
$header-bottom-margin: .5rem !default;
|
||||
$header-text-rendering: optimizeLegibility !default;
|
||||
|
||||
// We use these to control header font sizes
|
||||
$h1-font-size: rem-calc(44) !default;
|
||||
$h2-font-size: rem-calc(37) !default;
|
||||
$h3-font-size: rem-calc(27) !default;
|
||||
$h4-font-size: rem-calc(23) !default;
|
||||
$h5-font-size: rem-calc(18) !default;
|
||||
$h6-font-size: 1rem !default;
|
||||
|
||||
// We use these to control header size reduction on small screens
|
||||
$h1-font-reduction: rem-calc(10) !default;
|
||||
$h2-font-reduction: rem-calc(10) !default;
|
||||
$h3-font-reduction: rem-calc(5) !default;
|
||||
$h4-font-reduction: rem-calc(5) !default;
|
||||
$h5-font-reduction: 0 !default;
|
||||
$h6-font-reduction: 0 !default;
|
||||
|
||||
// These control how subheaders are styled.
|
||||
$subheader-line-height: 1.4 !default;
|
||||
$subheader-font-color: scale-color($header-font-color, $lightness: 35%) !default;
|
||||
$subheader-font-weight: $font-weight-normal !default;
|
||||
$subheader-top-margin: .2rem !default;
|
||||
$subheader-bottom-margin: .5rem !default;
|
||||
|
||||
// A general <small> styling
|
||||
$small-font-size: 60% !default;
|
||||
$small-font-color: scale-color($header-font-color, $lightness: 35%) !default;
|
||||
|
||||
// We use these to style paragraphs
|
||||
$paragraph-font-family: inherit !default;
|
||||
$paragraph-font-weight: $font-weight-normal !default;
|
||||
$paragraph-font-size: 1rem !default;
|
||||
$paragraph-line-height: 1.6 !default;
|
||||
$paragraph-margin-bottom: rem-calc(20) !default;
|
||||
$paragraph-aside-font-size: rem-calc(14) !default;
|
||||
$paragraph-aside-line-height: 1.35 !default;
|
||||
$paragraph-aside-font-style: italic !default;
|
||||
$paragraph-text-rendering: optimizeLegibility !default;
|
||||
|
||||
// We use these to style <code> tags
|
||||
$code-color: grayscale($primary-color) !default;
|
||||
$code-font-family: Consolas, 'Liberation Mono', Courier, monospace !default;
|
||||
$code-font-weight: $font-weight-normal !default;
|
||||
$code-background-color: scale-color($secondary-color, $lightness: 70%) !default;
|
||||
$code-border-size: 1px !default;
|
||||
$code-border-style: solid !default;
|
||||
$code-border-color: scale-color($code-background-color, $lightness: -10%) !default;
|
||||
$code-padding: rem-calc(2) rem-calc(5) rem-calc(1) !default;
|
||||
|
||||
// We use these to style anchors
|
||||
$anchor-text-decoration: none !default;
|
||||
$anchor-text-decoration-hover: none !default;
|
||||
$anchor-font-color: $primary-color !default;
|
||||
$anchor-font-color-hover: scale-color($anchor-font-color, $lightness: -14%) !default;
|
||||
|
||||
// We use these to style the <hr> element
|
||||
$hr-border-width: 1px !default;
|
||||
$hr-border-style: solid !default;
|
||||
$hr-border-color: #ddd !default;
|
||||
$hr-margin: rem-calc(20) !default;
|
||||
|
||||
// We use these to style lists
|
||||
$list-font-family: $paragraph-font-family !default;
|
||||
$list-font-size: $paragraph-font-size !default;
|
||||
$list-line-height: $paragraph-line-height !default;
|
||||
$list-margin-bottom: $paragraph-margin-bottom !default;
|
||||
$list-style-position: outside !default;
|
||||
$list-side-margin: 1.1rem !default;
|
||||
$list-ordered-side-margin: 1.4rem !default;
|
||||
$list-side-margin-no-bullet: 0 !default;
|
||||
$list-nested-margin: rem-calc(20) !default;
|
||||
$definition-list-header-weight: $font-weight-bold !default;
|
||||
$definition-list-header-margin-bottom: .3rem !default;
|
||||
$definition-list-margin-bottom: rem-calc(12) !default;
|
||||
|
||||
// We use these to style blockquotes
|
||||
$blockquote-font-color: scale-color($header-font-color, $lightness: 35%) !default;
|
||||
$blockquote-padding: rem-calc(9 20 0 19) !default;
|
||||
$blockquote-border: 1px solid #ddd !default;
|
||||
$blockquote-cite-font-size: rem-calc(13) !default;
|
||||
$blockquote-cite-font-color: scale-color($header-font-color, $lightness: 23%) !default;
|
||||
$blockquote-cite-link-color: $blockquote-cite-font-color !default;
|
||||
|
||||
// Acronym styles
|
||||
$acronym-underline: 1px dotted #ddd !default;
|
||||
///
|
||||
|
||||
@mixin lead {
|
||||
font-size: $paragraph-font-size + rem-calc(3.5);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
@mixin subheader {
|
||||
line-height: $subheader-line-height;
|
||||
color: $subheader-font-color;
|
||||
font-weight: $subheader-font-weight;
|
||||
margin-top: $subheader-top-margin;
|
||||
margin-bottom: $subheader-bottom-margin;
|
||||
}
|
||||
|
||||
@include exports(typography) {
|
||||
/* Typography resets */
|
||||
div,
|
||||
dl,
|
||||
dt,
|
||||
dd,
|
||||
ul,
|
||||
ol,
|
||||
li,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
pre,
|
||||
form,
|
||||
p,
|
||||
blockquote,
|
||||
th,
|
||||
td {
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
/* Default Link Styles */
|
||||
a {
|
||||
color: $anchor-font-color;
|
||||
text-decoration: $anchor-text-decoration;
|
||||
line-height: inherit;
|
||||
|
||||
&[ui-sref] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: $anchor-font-color-hover;
|
||||
@if $anchor-text-decoration-hover != $anchor-text-decoration {
|
||||
text-decoration: $anchor-text-decoration-hover;
|
||||
}
|
||||
}
|
||||
|
||||
img { border:none; }
|
||||
}
|
||||
|
||||
/* Default paragraph styles */
|
||||
p {
|
||||
font-family: $paragraph-font-family;
|
||||
font-weight: $paragraph-font-weight;
|
||||
font-size: $paragraph-font-size;
|
||||
line-height: $paragraph-line-height;
|
||||
margin-bottom: $paragraph-margin-bottom;
|
||||
text-rendering: $paragraph-text-rendering;
|
||||
|
||||
&.lead { @include lead; }
|
||||
|
||||
& aside {
|
||||
font-size: $paragraph-aside-font-size;
|
||||
line-height: $paragraph-aside-line-height;
|
||||
font-style: $paragraph-aside-font-style;
|
||||
}
|
||||
}
|
||||
|
||||
/* Default header styles */
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-family: $header-font-family;
|
||||
font-weight: $header-font-weight;
|
||||
font-style: $header-font-style;
|
||||
color: $header-font-color;
|
||||
text-rendering: $header-text-rendering;
|
||||
margin-top: $header-top-margin;
|
||||
margin-bottom: $header-bottom-margin;
|
||||
line-height: $header-line-height;
|
||||
|
||||
small {
|
||||
font-size: $small-font-size;
|
||||
color: $small-font-color;
|
||||
line-height: 0;
|
||||
}
|
||||
}
|
||||
|
||||
h1 { font-size: $h1-font-size - $h1-font-reduction; }
|
||||
h2 { font-size: $h2-font-size - $h2-font-reduction; }
|
||||
h3 { font-size: $h3-font-size - $h3-font-reduction; }
|
||||
h4 { font-size: $h4-font-size - $h4-font-reduction; }
|
||||
h5 { font-size: $h5-font-size - $h5-font-reduction; }
|
||||
h6 { font-size: $h6-font-size - $h6-font-reduction; }
|
||||
|
||||
.subheader { @include subheader; }
|
||||
|
||||
hr {
|
||||
border: $hr-border-style $hr-border-color;
|
||||
border-width: $hr-border-width 0 0;
|
||||
clear: both;
|
||||
margin: $hr-margin 0 ($hr-margin - rem-calc($hr-border-width));
|
||||
height: 0;
|
||||
}
|
||||
|
||||
/* Helpful Typography Defaults */
|
||||
em,
|
||||
i {
|
||||
font-style: italic;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
strong,
|
||||
b {
|
||||
font-weight: $font-weight-bold;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
small {
|
||||
font-size: $small-font-size;
|
||||
color: $small-font-color;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: $code-font-family;
|
||||
font-weight: $code-font-weight;
|
||||
color: $code-color;
|
||||
background-color: $code-background-color;
|
||||
border-width: $code-border-size;
|
||||
border-style: $code-border-style;
|
||||
border-color: $code-border-color;
|
||||
padding: $code-padding;
|
||||
}
|
||||
|
||||
/* Lists */
|
||||
ul,
|
||||
ol,
|
||||
dl {
|
||||
font-size: $list-font-size;
|
||||
line-height: $list-line-height;
|
||||
margin-bottom: $list-margin-bottom;
|
||||
list-style-position: $list-style-position;
|
||||
font-family: $list-font-family;
|
||||
}
|
||||
|
||||
/* Lists */
|
||||
ul, ol {
|
||||
margin-left: $list-side-margin;
|
||||
li {
|
||||
ul,
|
||||
ol {
|
||||
margin-left: $list-nested-margin;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Lists without bullets */
|
||||
ul.no-bullet {
|
||||
&, li ul, li ol {
|
||||
list-style-type: none;
|
||||
}
|
||||
margin-left: $list-side-margin-no-bullet;
|
||||
}
|
||||
|
||||
/* Definition Lists */
|
||||
dl {
|
||||
dt {
|
||||
margin-bottom: $definition-list-header-margin-bottom;
|
||||
font-weight: $definition-list-header-weight;
|
||||
}
|
||||
dd { margin-bottom: $definition-list-margin-bottom; }
|
||||
}
|
||||
|
||||
/* Abbreviations */
|
||||
abbr,
|
||||
acronym {
|
||||
text-transform: uppercase;
|
||||
font-size: 90%;
|
||||
color: $body-font-color;
|
||||
border-bottom: $acronym-underline;
|
||||
cursor: help;
|
||||
}
|
||||
abbr {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
/* Blockquotes */
|
||||
blockquote {
|
||||
margin: 0 0 $paragraph-margin-bottom;
|
||||
padding: $blockquote-padding;
|
||||
border-left: $blockquote-border;
|
||||
|
||||
cite {
|
||||
display: block;
|
||||
font-size: $blockquote-cite-font-size;
|
||||
color: $blockquote-cite-font-color;
|
||||
&:before {
|
||||
content: "\2014 \0020";
|
||||
}
|
||||
|
||||
a,
|
||||
a:visited {
|
||||
color: $blockquote-cite-link-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
blockquote,
|
||||
blockquote p {
|
||||
line-height: $paragraph-line-height;
|
||||
color: $blockquote-font-color;
|
||||
}
|
||||
|
||||
@include breakpoint(medium) {
|
||||
h1,h2,h3,h4,h5,h6 { line-height: $header-line-height; }
|
||||
h1 { font-size: $h1-font-size; }
|
||||
h2 { font-size: $h2-font-size; }
|
||||
h3 { font-size: $h3-font-size; }
|
||||
h4 { font-size: $h4-font-size; }
|
||||
h5 { font-size: $h5-font-size; }
|
||||
h6 { font-size: $h6-font-size; }
|
||||
}
|
||||
}
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
UTILITIES
|
||||
---------
|
||||
|
||||
Responsive helper classes to assist you in quickly doing basic formatting and layout.
|
||||
|
||||
Features:
|
||||
- Vertical alignment
|
||||
- Visibility
|
||||
- Text alignment
|
||||
- Floating
|
||||
*/
|
||||
|
||||
$block-selector: '[class*="grid-block"]';
|
||||
|
||||
@mixin show-for($size, $prop: block) {
|
||||
&:not(.ng-hide) {
|
||||
display: none !important;
|
||||
@include breakpoint($size) {
|
||||
display: $prop !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin show-for-only($size, $prop: block) {
|
||||
&:not(.ng-hide) {
|
||||
display: none !important;
|
||||
@include breakpoint($size only) {
|
||||
display: $prop !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin hide-for($size, $prop: block) {
|
||||
&:not(.ng-hide) {
|
||||
display: $prop !important;
|
||||
@include breakpoint($size) {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin hide-for-only($size, $prop: block) {
|
||||
&:not(.ng-hide) {
|
||||
display: $prop !important;
|
||||
@include breakpoint($size only) {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include exports(utilities) {
|
||||
// Vertical alignment
|
||||
.v-align {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
$align-values: (
|
||||
'top': flex-start,
|
||||
'center': center,
|
||||
'bottom': flex-end,
|
||||
);
|
||||
|
||||
@each $orient in (top, center, bottom) {
|
||||
.align-#{$orient} {
|
||||
align-self: map-get($align-values, $orient);
|
||||
}
|
||||
}
|
||||
|
||||
@each $size in $breakpoint-classes {
|
||||
@each $orient in (top, center, bottom) {
|
||||
@include breakpoint($size) {
|
||||
.#{$size}-align-#{$orient} {
|
||||
align-self: map-get($align-values, $orient);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Visibility
|
||||
.hide { display: none !important; }
|
||||
|
||||
.invisible { visibility: hidden; }
|
||||
|
||||
@each $size in $breakpoint-classes {
|
||||
.hide-for-#{$size} {
|
||||
@include hide-for($size);
|
||||
&#{$block-selector} { @include hide-for($size, flex); }
|
||||
}
|
||||
|
||||
.show-for-#{$size} {
|
||||
@include show-for($size);
|
||||
&#{$block-selector} { @include show-for($size, flex); }
|
||||
}
|
||||
|
||||
.hide-for-#{$size}-only {
|
||||
@include hide-for-only($size);
|
||||
&#{$block-selector} { @include hide-for-only($size, flex); }
|
||||
}
|
||||
|
||||
.show-for-#{$size}-only {
|
||||
@include show-for-only($size);
|
||||
&#{$block-selector} { @include show-for-only($size, flex); }
|
||||
}
|
||||
}
|
||||
|
||||
@each $orientation in (portrait, landscape) {
|
||||
.hide-for-#{$orientation} {
|
||||
@include breakpoint($orientation) {
|
||||
display: none !important;
|
||||
&#{$block-selector} { display: flex !important; }
|
||||
}
|
||||
}
|
||||
|
||||
.show-for-#{$orientation} {
|
||||
display: none !important;
|
||||
|
||||
@include breakpoint($orientation) {
|
||||
display: block !important;
|
||||
&#{$block-selector} { display: flex !important; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Text alignment
|
||||
*/
|
||||
@each $align in (left, right, center, justify) {
|
||||
.text-#{$align} {
|
||||
text-align: $align;
|
||||
}
|
||||
|
||||
@each $size in $breakpoint-classes {
|
||||
@include breakpoint($size) {
|
||||
.#{$size}-text-#{$align} {
|
||||
text-align: $align;
|
||||
}
|
||||
}
|
||||
|
||||
@include breakpoint($size only) {
|
||||
.#{$size}-only-text-#{$align} {
|
||||
text-align: $align;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Floating
|
||||
*/
|
||||
.clearfix { @include clearfix; }
|
||||
|
||||
@each $float in (left, right, none) {
|
||||
.float-#{$float} {
|
||||
float: #{$float};
|
||||
}
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
// Foundation for Apps
|
||||
// by ZURB
|
||||
// foundation.zurb.com
|
||||
// Licensed under MIT Open Source
|
||||
|
||||
$foundation-version: '1.1.0';
|
||||
|
||||
// Make sure the charset is set appropriately
|
||||
@charset "UTF-8";
|
||||
|
||||
// Libraries (let's make Normalize an external dependency eventually)
|
||||
@import
|
||||
"vendor/normalize";
|
||||
|
||||
// Helpers
|
||||
@import
|
||||
"helpers/functions",
|
||||
"helpers/mixins",
|
||||
"helpers/breakpoints",
|
||||
"helpers/images";
|
||||
|
||||
// Global styles
|
||||
@import
|
||||
"global";
|
||||
|
||||
// Components
|
||||
@import
|
||||
"components/action-sheet",
|
||||
"components/block-list",
|
||||
"components/button",
|
||||
"components/button-group",
|
||||
"components/card",
|
||||
"components/extras",
|
||||
"components/forms",
|
||||
"components/grid",
|
||||
"components/title-bar",
|
||||
"components/label",
|
||||
"components/list",
|
||||
"components/menu-bar",
|
||||
"components/modal",
|
||||
"components/motion",
|
||||
"components/notification",
|
||||
"components/off-canvas",
|
||||
"components/popup",
|
||||
"components/switch",
|
||||
"components/tabs",
|
||||
"components/accordion",
|
||||
"components/typography",
|
||||
"components/utilities";
|
||||
+154
@@ -0,0 +1,154 @@
|
||||
// Foundation for Apps
|
||||
//
|
||||
// BREAKPOINTS
|
||||
// -----------
|
||||
// Foundation for Apps has three core breakpoints: small (> 0), medium (>= 640), and large (>= 1024).
|
||||
// There are two additional breakpoints, xlarge, and xxlarge, which (by default) do not output as sizing classes.
|
||||
// Access named breakpoints using the mixin breakpoint($size), where $size is a breakpoint value.
|
||||
// You can also pass an em, rem, or pixel value into this mixin to generate an em-based media query.
|
||||
// Create new named breakpoints using the $breakpoints map. Change which named breakpoints get their own classes by modifying the $breakpoint-classes map.
|
||||
// NOTE: If you change the $breakpoints map, know that all values must be ordered by width, smallest width first. So 0 is always your first value.
|
||||
|
||||
// 1. Variables
|
||||
// - - - - - - - - - - - - - - -
|
||||
|
||||
/// @Foundation.settings
|
||||
// Breakpoints
|
||||
// These are our named breakpoints. You can use them in our breakpoint function like this: @include breakpoint(medium) { // Medium and larger styles }
|
||||
$breakpoints: (
|
||||
small: rem-calc(0),
|
||||
medium: rem-calc(640),
|
||||
large: rem-calc(1200),
|
||||
xlarge: rem-calc(1440),
|
||||
xxlarge: rem-calc(1920),
|
||||
) !default;
|
||||
|
||||
// All of the names in this list will be output as classes in your CSS, like small-12, medium-6, and so on.
|
||||
$breakpoint-classes: (small medium large) !default;
|
||||
///
|
||||
|
||||
// 2. Mixins
|
||||
// - - - - - - - - - - - - - - -
|
||||
|
||||
/// Wraps a media query around the content you put inside the mixin. This mixin accepts a number of values:
|
||||
/// - If a string is passed, the mixin will look for it in the $breakpoints map, and use a media query there.
|
||||
/// - If a pixel value is passed, it will be converted to an em value using $rem-base.
|
||||
/// - If a rem value is passed, the unit will be changed to em.
|
||||
/// - If an em value is passed, the value will be used as-is.
|
||||
///
|
||||
/// @param {mixed} $val - Breakpoint name or px/em/rem value to process.
|
||||
///
|
||||
/// @output If the breakpoint is "0px and larger", outputs the content. Otherwise, outputs the content wrapped in a media query.
|
||||
@mixin breakpoint($val: small) {
|
||||
// Size or keyword
|
||||
$bp: nth($val, 1);
|
||||
// Value for max-width media queries
|
||||
$bpMax: 0;
|
||||
// Direction of media query (up, down, or only)
|
||||
$dir: if(length($val) > 1, nth($val, 2), up);
|
||||
// Eventual output
|
||||
$str: 'only screen';
|
||||
// Is it a named media query?
|
||||
$named: false;
|
||||
|
||||
// Orientation media queries have a unique syntax
|
||||
@if $bp == 'landscape' or $bp == 'portrait' {
|
||||
$str: $str + ' and (orientation: #{$bp})';
|
||||
}
|
||||
|
||||
@else {
|
||||
// Try to pull a named breakpoint out of the $breakpoints map
|
||||
@if type-of($bp) == 'string' {
|
||||
@if map-has-key($breakpoints, $bp) {
|
||||
@if $dir == 'only' {
|
||||
$next-bp: map-next($breakpoints, $bp);
|
||||
@if $next-bp == null {
|
||||
$bpMax: null;
|
||||
}
|
||||
@else {
|
||||
$bpMax: $next-bp - (1/16);
|
||||
}
|
||||
}
|
||||
$bp: map-get($breakpoints, $bp);
|
||||
$named: true;
|
||||
}
|
||||
@else {
|
||||
$bp: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Pixel and unitless values are converted to rems
|
||||
@if unit($bp) == 'px' or unit($bp) == '' {
|
||||
$bp: rem-calc($bp);
|
||||
}
|
||||
// Finally, the rem value is turned into an em value
|
||||
$bp: strip-unit($bp) * 1em;
|
||||
|
||||
// Skip media query creation if the input is "0 up" or "0 down"
|
||||
@if $bp > 0 or $dir == 'only' {
|
||||
// And lo, a media query was born
|
||||
@if $dir == 'only' {
|
||||
@if $named == true {
|
||||
$str: $str + ' and (min-width: #{$bp})';
|
||||
@if $bpMax != null {
|
||||
$str: $str + ' and (max-width: #{$bpMax})';
|
||||
}
|
||||
}
|
||||
@else {
|
||||
@debug 'ERROR: Only named media queries can have an "only" range.';
|
||||
}
|
||||
}
|
||||
@else if $dir == 'down' {
|
||||
$max: $bp - (1/16);
|
||||
$str: $str + ' and (max-width: #{$max})';
|
||||
}
|
||||
@else {
|
||||
$str: $str + ' and (min-width: #{$bp})';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Output
|
||||
@if $bp == 0em and $dir != 'only' {
|
||||
@content;
|
||||
}
|
||||
@else {
|
||||
@media #{$str} {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Prefixes selector $class with breakpoint keywords, allowing you to create a batch of breakpoint classes with one chunk of code. If you want to skip a breakpoint (like small, because mobile first and all that), add values to the $omit parameter.
|
||||
///
|
||||
/// @param {string} $class - Class to prefix with the breakpoint name and a hyphen.
|
||||
/// @param {list} $omit - Named breakpoints to skip. No class will be added with breakpoints in this list.
|
||||
@mixin each-breakpoint($class, $omit: ()) {
|
||||
// Iterate through breakpoint classes
|
||||
@each $size in $breakpoint-classes {
|
||||
// Only do something if the breakpoint is not in $omit
|
||||
@if index($omit, $size) == null {
|
||||
$val: map-get($breakpoints, $size);
|
||||
// Prefix $class with $size and a hyphen
|
||||
.#{$size + '-' + $class} {
|
||||
@include breakpoint($size) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. CSS Output
|
||||
// - - - - - - - - - - - - - - -
|
||||
|
||||
// Meta styles are included in all builds, as they are a dependancy of the Javascript.
|
||||
// Used to provide media query values for javascript components.
|
||||
// Forward slash placed around everything to convince PhantomJS to read the value.
|
||||
|
||||
meta.foundation-version {
|
||||
font-family: "#{$foundation-version}";
|
||||
}
|
||||
meta.foundation-mq {
|
||||
font-family: "#{map-serialize($breakpoints)}";
|
||||
}
|
||||
+343
@@ -0,0 +1,343 @@
|
||||
// Foundation for Apps ALPHA
|
||||
// by ZURB
|
||||
// foundation.zurb.com
|
||||
// Licensed under MIT Open Source
|
||||
|
||||
$include-css: () !default;
|
||||
$modules: () !default;
|
||||
$rem-base: 16px !default;
|
||||
|
||||
/// Checks if a module is in use.
|
||||
@function using($name) {
|
||||
// Import from global scope
|
||||
$include-css: $include-css !global;
|
||||
$module-key: map-get($include-css, $name);
|
||||
|
||||
@if $module-key == true or $module-key == null {
|
||||
@return true;
|
||||
}
|
||||
@else {
|
||||
@return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if a module's CSS has already been exported.
|
||||
@function imported($name) {
|
||||
// Import from global scope
|
||||
$modules: $modules !global;
|
||||
// Check if the module is already on the imported list
|
||||
@if type-of(index($modules, $name)) == 'number' {
|
||||
@return true;
|
||||
}
|
||||
@else {
|
||||
@return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// Outputs the chunk of content passed if component $name hasn't yet been output.
|
||||
/// This prevents code duplication by keeping track of which components have already been output.
|
||||
///
|
||||
/// @param {string} $name - Name of component to output
|
||||
///
|
||||
/// @output The content passed, if the component has not yet been exported.
|
||||
@mixin exports($name) {
|
||||
// Check if the module has already been imported
|
||||
@if not(imported($name)) {
|
||||
// Check if the module should be used
|
||||
@if using($name) {
|
||||
$modules: append($modules, $name) !global;
|
||||
@content;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Map Serialize
|
||||
/// Converts a Sass map to a URL-encoded string, like this: `key1=value1&key2=value2`. We use this function to encode the media queries in the `$breakpoints` variable, so it can be transferred to our JavaScript for use there.
|
||||
///
|
||||
/// @param {map} $map - Map to convert.
|
||||
///
|
||||
/// @return A string with a map converted to a string.
|
||||
@function map-serialize($map) {
|
||||
$str: '';
|
||||
@each $key, $value in $map {
|
||||
$str: $str + $key + '=' + $value + '&';
|
||||
}
|
||||
$str: str-slice($str, 1, -2);
|
||||
|
||||
@return $str;
|
||||
}
|
||||
|
||||
/// Map Next
|
||||
/// Find the next key in a map.
|
||||
///
|
||||
/// @param {map} $map - Map to traverse.
|
||||
/// @param {mixed} $key - Key to use as a starting point.
|
||||
///
|
||||
/// @return The value for the key after `$key` if `$key` was found. If `$key` was not found, or `$key` was the last value in the map, returns null.
|
||||
@function map-next($map, $key) {
|
||||
// Store the values of the map as a list, so we can access them with nth
|
||||
$values: map-values($map);
|
||||
|
||||
// Ghetto for loop
|
||||
$i: 1;
|
||||
$found: false;
|
||||
@each $val in map-keys($map) {
|
||||
@if $found == false {
|
||||
@if ($key == $val) {
|
||||
$found: true;
|
||||
}
|
||||
$i: $i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// If the key doesn't exist, or it's the last key in the map, return null
|
||||
@if $i > length($map) {
|
||||
@return null;
|
||||
}
|
||||
// Otherwise return the value
|
||||
@else {
|
||||
@return nth($values, $i);
|
||||
}
|
||||
}
|
||||
|
||||
/// Is It Light?
|
||||
/// Checks the lightness of $color, and if it passes the $threshold of lightness, it returns the `$yes` color. Otherwise, it returns the `$no` color. Use this function to dynamically output a foreground color based on a given background color.
|
||||
///
|
||||
/// @param {color} $color - Color to check the lightness of.
|
||||
/// @param {color} $yes - Color to return if $color is light.
|
||||
/// @param {color} $no - Color to return if $color is dark.
|
||||
/// @param {percentage} $threshold - Threshold of lightness to check against.
|
||||
///
|
||||
/// @return The $yes color or $no color.
|
||||
@function isitlight($color, $yes: #000, $no: #fff, $threshold: 60%) {
|
||||
@if (lightness($color) > $threshold) {
|
||||
@return $yes;
|
||||
}
|
||||
@else {
|
||||
@return $no;
|
||||
}
|
||||
}
|
||||
|
||||
/// Smart Scale
|
||||
/// Scales a color to be lighter if it's light, or darker if it's dark. Use this function to "fade" a color appropriate to its lightness.
|
||||
///
|
||||
/// @param {color} $color - Color to scale.
|
||||
/// @param {percentage} $scale - Amount to scale up or down.
|
||||
/// @param {percentage} $threshold - Threshold of lightness to check against.
|
||||
///
|
||||
/// @return A scaled color.
|
||||
@function smartscale($color, $scale: 5%, $threshold: 60%) {
|
||||
@if lightness($color) > $threshold {
|
||||
$scale: -$scale;
|
||||
}
|
||||
@return scale-color($color, $lightness: $scale);
|
||||
}
|
||||
|
||||
/// Has Value
|
||||
/// Returns true if a value is not 0, null, or none. Use this function to check for values like `border: 0` or `box-shadow: none`.
|
||||
///
|
||||
/// @param $val - Value to check.
|
||||
///
|
||||
/// @return True if `$val` is not 0, null, or none.
|
||||
@function hasvalue($val) {
|
||||
@if $val == null or $val == none {
|
||||
@return false;
|
||||
}
|
||||
@if type-of($val) == 'number' and strip-unit($val) == 0 {
|
||||
@return false;
|
||||
}
|
||||
@return true;
|
||||
}
|
||||
|
||||
/// Get Side
|
||||
/// Determine a top/right/bottom/right value on a padding, margin, etc. property, no matter how many values were passed in. Use this function if you need to know the specific side of a value, but don't know if the value is using shorthand.
|
||||
///
|
||||
/// @param {list|number} $val - Value to analyze. Should be a shorthand sizing property, e.g. "1em 2em 1em"
|
||||
/// @param {keyword} $side - Side to return. Should be top, right, bottom, or left.
|
||||
///
|
||||
/// @return A single value based on `$val` and `$side`.
|
||||
@function get-side($val, $side) {
|
||||
$length: length($val);
|
||||
|
||||
@if $length == 1 {
|
||||
@return $val;
|
||||
}
|
||||
@if $length == 2 {
|
||||
@return map-get((
|
||||
top: nth($val, 1),
|
||||
bottom: nth($val, 1),
|
||||
left: nth($val, 2),
|
||||
right: nth($val, 2),
|
||||
), $side);
|
||||
}
|
||||
@if $length == 3 {
|
||||
@return map-get((
|
||||
top: nth($val, 1),
|
||||
left: nth($val, 2),
|
||||
right: nth($val, 2),
|
||||
bottom: nth($val, 3),
|
||||
), $side);
|
||||
}
|
||||
@if $length == 4 {
|
||||
@return map-get((
|
||||
top: nth($val, 1),
|
||||
right: nth($val, 2),
|
||||
bottom: nth($val, 3),
|
||||
left: nth($val, 4),
|
||||
), $side);
|
||||
}
|
||||
}
|
||||
|
||||
/// Get Border Value
|
||||
/// Given border $val, find a specific element of the border, which is $elem. The possible values for $elem are width, style, and color.
|
||||
///
|
||||
/// @param {list} $val - Border value to find a value in.
|
||||
/// @param {keyword} $elem - Border component to extract.
|
||||
///
|
||||
/// @param If the value exists, returns the value. If the value is not in the border definition, the function will return a 0px width, solid style, or black border.
|
||||
@function get-border-value($val, $elem) {
|
||||
// Find the width, style, or color and return it
|
||||
@each $v in $val {
|
||||
$type: type-of($v);
|
||||
@if $elem == width and $type == 'number' {
|
||||
@return $v;
|
||||
}
|
||||
@if $elem == style and $type == 'string' {
|
||||
@return $v;
|
||||
}
|
||||
@if $elem == color and $type == 'color' {
|
||||
@return $v;
|
||||
}
|
||||
}
|
||||
|
||||
// Defaults
|
||||
$defaults: (
|
||||
width: 0,
|
||||
style: solid,
|
||||
color: black,
|
||||
);
|
||||
@return map-get($defaults, $elem);
|
||||
}
|
||||
|
||||
/// Get Shadow Value
|
||||
/// Given shadow value $val, find a specific element of the shadow, which is $elem. The possible values for $elem are x, y, size, spread, color, and inset.
|
||||
///
|
||||
/// @param {list} $val - Shadow value to find a value in.
|
||||
/// @param {keyword} $elem - Shadow component to extract.
|
||||
///
|
||||
/// @return If the value exists, returns the value. If the value is not set, returns false. If `$elem` is "inset", returns true, otherwise false.
|
||||
@function get-shadow-value($val, $elem) {
|
||||
// Return "none" if there's no shadow
|
||||
@if $val == none {
|
||||
@return none;
|
||||
}
|
||||
|
||||
// Inset and color are always at the beginning and end
|
||||
@if $elem == inset {
|
||||
@return nth($val, 1) == inset;
|
||||
}
|
||||
@if $elem == color {
|
||||
@if type-of(nth($val, -1)) == color {
|
||||
@return nth($val, -1);
|
||||
}
|
||||
@else {
|
||||
@return black;
|
||||
}
|
||||
}
|
||||
|
||||
// The rest of the values are located perilously in the middle
|
||||
$values: ();
|
||||
@each $v in $val {
|
||||
@if type-of($v) == 'number' {
|
||||
$values: append($values, $v);
|
||||
}
|
||||
}
|
||||
@if $elem == x {
|
||||
@if length($values) >= 1 {
|
||||
@return nth($values, 1);
|
||||
}
|
||||
@else {
|
||||
@return 0;
|
||||
}
|
||||
}
|
||||
@else if $elem == y {
|
||||
@if length($values) >= 2 {
|
||||
@return nth($values, 2);
|
||||
}
|
||||
@else {
|
||||
@return 0;
|
||||
}
|
||||
}
|
||||
@else if $elem == size {
|
||||
@if length($values) >= 3 {
|
||||
@return nth($values, 3);
|
||||
}
|
||||
@else {
|
||||
@return 0;
|
||||
}
|
||||
}
|
||||
@else if $elem == spread {
|
||||
@if length($values) >= 4 {
|
||||
@return nth($values, 4);
|
||||
}
|
||||
@else {
|
||||
@return 0;
|
||||
}
|
||||
}
|
||||
@else {
|
||||
@return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// Strip Unit
|
||||
/// Removes the unit (e.g. px, em, rem) from a value, returning the number only.
|
||||
///
|
||||
/// @param {number} $num - Number to strip unit from.
|
||||
///
|
||||
/// @return The same number, sans unit.
|
||||
@function strip-unit($num) {
|
||||
@return $num / ($num * 0 + 1);
|
||||
}
|
||||
|
||||
/// Turn to Degrees
|
||||
/// Converts a turn unit to the equivalent unit in degrees. 1turn is equal to 360 degrees. Not all browsers support turn, so this function allows us to use turns while outputting a value that all browsers understand.
|
||||
///
|
||||
/// @param {number} $value - Turn value to convert.
|
||||
///
|
||||
/// @return The same value, but in degrees.
|
||||
@function turn-to-deg($value) {
|
||||
@return strip-unit($value) * 360deg;
|
||||
}
|
||||
|
||||
/// Convert to Rem
|
||||
/// Converts a pixel value to matching rem value. *Any* value passed, regardless of unit, is assumed to be a pixel value. By default, the base pixel value used to calculate the rem value is taken from the `$rem-base` variable.
|
||||
///
|
||||
/// @param {number} $value - Pixel value to convert.
|
||||
///
|
||||
/// @return A number in rems, calculated based on the given value and the base pixel value.
|
||||
@function convert-to-rem($value, $base-value: $rem-base) {
|
||||
$value: strip-unit($value) / strip-unit($base-value) * 1rem;
|
||||
@if ($value == 0rem) { $value: 0; } // Turn 0rem into 0
|
||||
@return $value;
|
||||
}
|
||||
|
||||
/// Rem Calculator
|
||||
/// Converts one or more pixel values into matching rem values. This function works a lot like `convert-to-rem`, except it can convert more than one value at once, which is useful when setting multiple values on a `margin` or `padding` property.
|
||||
///
|
||||
/// @param {number|list} $values - One or more values to convert. Be sure to separate them with spaces and not commas. If you need to convert a comma-separated list, wrap the list in parentheses.
|
||||
///
|
||||
/// @return A list of converted values.
|
||||
@function rem-calc($values, $base-value: null) {
|
||||
@if $base-value == null {
|
||||
$base-value: $rem-base;
|
||||
}
|
||||
$max: length($values);
|
||||
|
||||
@if $max == 1 { @return convert-to-rem(nth($values, 1), $base-value); }
|
||||
|
||||
$remValues: ();
|
||||
@for $i from 1 through $max {
|
||||
$remValues: append($remValues, convert-to-rem(nth($values, $i), $base-value));
|
||||
}
|
||||
@return $remValues;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
@function image-triangle($color: #000) {
|
||||
$color: rgb(red($color), green($color), blue($color));
|
||||
@return 'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="32" height="24" viewBox="0 0 32 24"><polygon points="0,0 32,0 16,24" style="fill: #{$color}"></polygon></svg>';
|
||||
}
|
||||
|
||||
@mixin image-checkmark($color: #000) {
|
||||
$color: rgb(red($color), green($color), blue($color));
|
||||
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="32" height="32" viewBox="0 0 32 32"><path fill="#{$color}" d="M16 0c-8.837 0-16 7.163-16 16s7.163 16 16 16 16-7.163 16-16-7.163-16-16-16zm6.906 8.875l2.219 2.031-12.063 13.281-6.188-6.188 2.125-2.125 3.938 3.938 9.969-10.938z"/></svg>');
|
||||
|
||||
// IE10 fallback, since it doesn't support SVG data URLs
|
||||
@media screen and (min-width:0\0) {
|
||||
@if lightness($color) < 60% {
|
||||
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAdlJREFUeNrMl0FugzAQRY3TRZeoFyhVL0BOkGTXJezaHZwguUnECaCrdFd6gqQnCN11Uyk5QekNOlONJWMVGMCgfGlkEIY3HnsG2xFM3d96PjQB2AJsWdPtAPYOln+dTwXnuw4DHEGzBvNFN6EDCTiS9XIAwB40acNoucKoxODIie0AwAOCu8KOSnIiNx/MakK+A7sW9oTferxx3fP3T1nURoBG/irGVahHwjHm/Ggx7E3TMVdrQmoP0gngghhpZQ3QvG/EdPLUelARWI8Aycjq9Md0qMIdbcNhjmOKLoY7quk3l1Rebeqg4AwFkmq7LWGOh1pmNY0etZAWSq0OX8HoS4JvWuCopbSY26EGR/CW86K0BF+pwkLwlPuyHJhOCl5oe4ZtF++vOqST+GdOYwO+71pN2VNAjmQGPCe42weuHDg0PI8olUwnYrXTGQJH9gxq8l1LKvrQx4O6/YY32Kp/ugb3ey7gZ4xAzuhYiYTxB/UHZFAuaREVXZ2g6yFlvEC2yoKEmbsRZYNgVLk2JeaOaG+xLHN+WCszDWMqLGOrJFa1DlApjSdwoHJGqGzLIb0+cas0wh5Bh780ngswx8GJD7h8sHg2wLA/mfDLPZpdxOF0quP5rwADAAFIzSRvu1m5AAAAAElFTkSuQmCC');
|
||||
}
|
||||
@else {
|
||||
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAT9JREFUeNrMV4sRgyAMDU7gCI6AE7QjMILdoCO4Cd2g3aB2Ah2hG7Qb0ODRO2r98Anqu8txKvISII/AwBFKKY6NQDugHSe6NWgPtBtjrAMKIHGF1ip/6H+qGOIC7a7ioccofMkF2kvRQY8lfKY8FSqXyFPjZyaYvebYtGg5pMUbrcQseeqHzPogVyAHwyHXXPfZ/cCMA3rqOXGkF9NObbwOl6HsFS5BdNKaXTnTj2dGXinRYGQnx74CiNTOlt/cMfpeJSEh+dnlJyCU2iIkq4CInIemtIsDcmYth+Tc9xCDyHQSMeReDow4UVnv89Dj2yUNx5wYkreB+6dPw9pH2QbOxJBr1D5SLEccuEZmEP8O1Po64aByi8IVehxLAvL/8oz4TFjefHspyTYvSvdVlu/iYrKLq9mal1O29fX8I8AANpIQzC0hTdEAAAAASUVORK5CYII=');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
// Foundation for Apps
|
||||
//
|
||||
// Mixins
|
||||
// ------
|
||||
// The framework comes with a number of mixins that help you easily create common small components,
|
||||
// like triangles and menu icons.
|
||||
|
||||
/// CSS Triangle
|
||||
/// Creates a CSS triangle, which can be used for dropdown arrows, popup tails, and more. Use this mixin inside a `&::before` or `&::after` selector, to attach the triangle to an existing element.
|
||||
///
|
||||
/// @param {number} $triangle-size - Width of the triangle.
|
||||
/// @param {color} $triangle-color - Color of the triangle.
|
||||
/// @param {keyword} $triangle-direction - Direction the triangle points. Can be `top`, `right`, `bottom`, or `left`.
|
||||
@mixin css-triangle($triangle-size, $triangle-color, $triangle-direction) {
|
||||
content: "";
|
||||
display: block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border: inset $triangle-size;
|
||||
@if ($triangle-direction == top) {
|
||||
border-color: $triangle-color transparent transparent transparent;
|
||||
border-top-style: solid;
|
||||
}
|
||||
@if ($triangle-direction == bottom) {
|
||||
border-color: transparent transparent $triangle-color transparent;
|
||||
border-bottom-style: solid;
|
||||
}
|
||||
@if ($triangle-direction == left) {
|
||||
border-color: transparent transparent transparent $triangle-color;
|
||||
border-left-style: solid;
|
||||
}
|
||||
@if ($triangle-direction == right) {
|
||||
border-color: transparent $triangle-color transparent transparent;
|
||||
border-right-style: solid;
|
||||
}
|
||||
}
|
||||
|
||||
// @mixins
|
||||
//
|
||||
/// Hamburger
|
||||
/// Creates a three-line menu icon, affectionately referred to as the "hamburger icon".
|
||||
///
|
||||
/// @param {number} $width - Width of the icon, in rem units.
|
||||
/// @param {number|boolean} $left - Left offset of the icon. Set to `false` to center the icon horizontally.
|
||||
/// @param {number|boolean} $top - Top offset of the icon. Set to `false` to center the icon vertically.
|
||||
/// @param {number} $thickness - Height of each line in the icon.
|
||||
/// @param {number} $gap - Amount of space between each line.
|
||||
/// @param {color} $color - Color of the lines.
|
||||
/// @param {color} $hover-color - Color of the lines on hover.
|
||||
@mixin hamburger($width, $left, $top, $thickness, $gap, $color, $hover-color, $offcanvas) {
|
||||
span::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
display: block;
|
||||
height: 0;
|
||||
|
||||
@if $offcanvas {
|
||||
@if $top {
|
||||
top: $top;
|
||||
}
|
||||
@else {
|
||||
top: 50%;
|
||||
margin-top: -$width/2;
|
||||
}
|
||||
@if $left {
|
||||
left: $left;
|
||||
}
|
||||
@else {
|
||||
left: ($tabbar-menu-icon-width - $width)/2;
|
||||
}
|
||||
}
|
||||
@else {
|
||||
top: 50%;
|
||||
margin-top: -$width/2;
|
||||
#{$opposite-direction}: $topbar-link-padding;
|
||||
}
|
||||
|
||||
box-shadow:
|
||||
0 0px 0 $thickness $color,
|
||||
0 $gap + $thickness 0 $thickness $color,
|
||||
0 (2 * $gap + 2*$thickness) 0 $thickness $color;
|
||||
width: $width;
|
||||
}
|
||||
span:hover:after {
|
||||
box-shadow:
|
||||
0 0px 0 $thickness $hover-color,
|
||||
0 $gap + $thickness 0 $thickness $hover-color,
|
||||
0 (2 * $gap + 2*$thickness) 0 $thickness $hover-color;
|
||||
}
|
||||
}
|
||||
|
||||
/// Clearfix
|
||||
/// Uses the micro clearfix hack popularized by Nicolas Gallagher. Include this mixin on a container if its children are all floated, to give the container a proper height.
|
||||
///
|
||||
/// @see http://nicolasgallagher.com/micro-clearfix-hack/
|
||||
@mixin clearfix {
|
||||
&:before, &:after { content: " "; display: table; }
|
||||
&:after { clear: both; }
|
||||
}
|
||||
|
||||
/// Invisible Element
|
||||
/// Makes an element visually hidden, but accessible.
|
||||
///
|
||||
/// @see http://snook.ca/archives/html_and_css/hiding-content-for-accessibility
|
||||
@mixin element-invisible {
|
||||
position: absolute !important;
|
||||
height: 1px;
|
||||
width: 1px;
|
||||
overflow: hidden;
|
||||
clip: rect(1px, 1px, 1px, 1px);
|
||||
}
|
||||
|
||||
/// Invisible Element Off
|
||||
/// Reverses the CSS output by the `element-invisible()` mixin.
|
||||
@mixin element-invisible-off {
|
||||
position: static !important;
|
||||
height: auto;
|
||||
width: auto;
|
||||
overflow: visible;
|
||||
clip: auto;
|
||||
}
|
||||
|
||||
$text-input-selectors: 'input[type="text"], input[type="password"], input[type="date"], input[type="datetime"], input[type="datetime-local"], input[type="month"], input[type="week"], input[type="email"], input[type="number"], input[type="search"], input[type="tel"], input[type="time"], input[type="url"], input[type="color"], textarea';
|
||||
@@ -0,0 +1,425 @@
|
||||
/*! normalize.css v3.0.1 | MIT License | git.io/normalize */
|
||||
|
||||
/**
|
||||
* 1. Set default font family to sans-serif.
|
||||
* 2. Prevent iOS text size adjust after orientation change, without disabling
|
||||
* user zoom.
|
||||
*/
|
||||
|
||||
html {
|
||||
font-family: sans-serif; /* 1 */
|
||||
-ms-text-size-adjust: 100%; /* 2 */
|
||||
-webkit-text-size-adjust: 100%; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove default margin.
|
||||
*/
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* HTML5 display definitions
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Correct `block` display not defined for any HTML5 element in IE 8/9.
|
||||
* Correct `block` display not defined for `details` or `summary` in IE 10/11 and Firefox.
|
||||
* Correct `block` display not defined for `main` in IE 11.
|
||||
*/
|
||||
|
||||
article,
|
||||
aside,
|
||||
details,
|
||||
figcaption,
|
||||
figure,
|
||||
footer,
|
||||
header,
|
||||
hgroup,
|
||||
main,
|
||||
nav,
|
||||
section,
|
||||
summary {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct `inline-block` display not defined in IE 8/9.
|
||||
* 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
|
||||
*/
|
||||
|
||||
audio,
|
||||
canvas,
|
||||
progress,
|
||||
video {
|
||||
display: inline-block; /* 1 */
|
||||
vertical-align: baseline; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent modern browsers from displaying `audio` without controls.
|
||||
* Remove excess height in iOS 5 devices.
|
||||
*/
|
||||
|
||||
audio:not([controls]) {
|
||||
display: none;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Address `[hidden]` styling not present in IE 8/9/10.
|
||||
* Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.
|
||||
*/
|
||||
|
||||
[hidden],
|
||||
template {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Links
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Remove the gray background color from active links in IE 10.
|
||||
*/
|
||||
|
||||
a {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Improve readability when focused and also mouse hovered in all browsers.
|
||||
*/
|
||||
|
||||
a:active,
|
||||
a:hover {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
/* Text-level semantics
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Address styling not present in IE 8/9/10/11, Safari, and Chrome.
|
||||
*/
|
||||
|
||||
abbr[title] {
|
||||
border-bottom: 1px dotted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
|
||||
*/
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/**
|
||||
* Address styling not present in Safari and Chrome.
|
||||
*/
|
||||
|
||||
dfn {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Address variable `h1` font-size and margin within `section` and `article`
|
||||
* contexts in Firefox 4+, Safari, and Chrome.
|
||||
*/
|
||||
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
margin: 0.67em 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Address styling not present in IE 8/9.
|
||||
*/
|
||||
|
||||
mark {
|
||||
background: #ff0;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Address inconsistent and variable font size in all browsers.
|
||||
*/
|
||||
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent `sub` and `sup` affecting `line-height` in all browsers.
|
||||
*/
|
||||
|
||||
sub,
|
||||
sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
/* Embedded content
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Remove border when inside `a` element in IE 8/9/10.
|
||||
*/
|
||||
|
||||
img {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct overflow not hidden in IE 9/10/11.
|
||||
*/
|
||||
|
||||
svg:not(:root) {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Grouping content
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Address margin not present in IE 8/9 and Safari.
|
||||
*/
|
||||
|
||||
figure {
|
||||
margin: 1em 40px;
|
||||
}
|
||||
|
||||
/**
|
||||
* Address differences between Firefox and other browsers.
|
||||
*/
|
||||
|
||||
hr {
|
||||
-moz-box-sizing: content-box;
|
||||
box-sizing: content-box;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Contain overflow in all browsers.
|
||||
*/
|
||||
|
||||
pre {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/**
|
||||
* Address odd `em`-unit font size rendering in all browsers.
|
||||
*/
|
||||
|
||||
code,
|
||||
kbd,
|
||||
pre,
|
||||
samp {
|
||||
font-family: monospace, monospace;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
/* Forms
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Known limitation: by default, Chrome and Safari on OS X allow very limited
|
||||
* styling of `select`, unless a `border` property is set.
|
||||
*/
|
||||
|
||||
/**
|
||||
* 1. Correct color not being inherited.
|
||||
* Known issue: affects color of disabled elements.
|
||||
* 2. Correct font properties not being inherited.
|
||||
* 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
|
||||
*/
|
||||
|
||||
button,
|
||||
input,
|
||||
optgroup,
|
||||
select,
|
||||
textarea {
|
||||
color: inherit; /* 1 */
|
||||
font: inherit; /* 2 */
|
||||
margin: 0; /* 3 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Address `overflow` set to `hidden` in IE 8/9/10/11.
|
||||
*/
|
||||
|
||||
button {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
/**
|
||||
* Address inconsistent `text-transform` inheritance for `button` and `select`.
|
||||
* All other form control elements do not inherit `text-transform` values.
|
||||
* Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
|
||||
* Correct `select` style inheritance in Firefox.
|
||||
*/
|
||||
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
|
||||
* and `video` controls.
|
||||
* 2. Correct inability to style clickable `input` types in iOS.
|
||||
* 3. Improve usability and consistency of cursor style between image-type
|
||||
* `input` and others.
|
||||
*/
|
||||
|
||||
button,
|
||||
html input[type="button"], /* 1 */
|
||||
input[type="reset"],
|
||||
input[type="submit"] {
|
||||
-webkit-appearance: button; /* 2 */
|
||||
cursor: pointer; /* 3 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-set default cursor for disabled elements.
|
||||
*/
|
||||
|
||||
button[disabled],
|
||||
html input[disabled] {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove inner padding and border in Firefox 4+.
|
||||
*/
|
||||
|
||||
button::-moz-focus-inner,
|
||||
input::-moz-focus-inner {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Address Firefox 4+ setting `line-height` on `input` using `!important` in
|
||||
* the UA stylesheet.
|
||||
*/
|
||||
|
||||
input {
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
/**
|
||||
* It's recommended that you don't attempt to style these elements.
|
||||
* Firefox's implementation doesn't respect box-sizing, padding, or width.
|
||||
*
|
||||
* 1. Address box sizing set to `content-box` in IE 8/9/10.
|
||||
* 2. Remove excess padding in IE 8/9/10.
|
||||
*/
|
||||
|
||||
input[type="checkbox"],
|
||||
input[type="radio"] {
|
||||
box-sizing: border-box; /* 1 */
|
||||
padding: 0; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix the cursor style for Chrome's increment/decrement buttons. For certain
|
||||
* `font-size` values of the `input`, it causes the cursor style of the
|
||||
* decrement button to change from `default` to `text`.
|
||||
*/
|
||||
|
||||
input[type="number"]::-webkit-inner-spin-button,
|
||||
input[type="number"]::-webkit-outer-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Address `appearance` set to `searchfield` in Safari and Chrome.
|
||||
* 2. Address `box-sizing` set to `border-box` in Safari and Chrome
|
||||
* (include `-moz` to future-proof).
|
||||
*/
|
||||
|
||||
input[type="search"] {
|
||||
-webkit-appearance: textfield; /* 1 */
|
||||
-moz-box-sizing: content-box;
|
||||
-webkit-box-sizing: content-box; /* 2 */
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove inner padding and search cancel button in Safari and Chrome on OS X.
|
||||
* Safari (but not Chrome) clips the cancel button when the search input has
|
||||
* padding (and `textfield` appearance).
|
||||
*/
|
||||
|
||||
input[type="search"]::-webkit-search-cancel-button,
|
||||
input[type="search"]::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define consistent border, margin, and padding.
|
||||
*/
|
||||
|
||||
fieldset {
|
||||
border: 1px solid #c0c0c0;
|
||||
margin: 0 2px;
|
||||
padding: 0.35em 0.625em 0.75em;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct `color` not being inherited in IE 8/9/10/11.
|
||||
* 2. Remove padding so people aren't caught out if they zero out fieldsets.
|
||||
*/
|
||||
|
||||
legend {
|
||||
border: 0; /* 1 */
|
||||
padding: 0; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove default vertical scrollbar in IE 8/9/10/11.
|
||||
*/
|
||||
|
||||
textarea {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't inherit the `font-weight` (applied by a rule above).
|
||||
* NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
|
||||
*/
|
||||
|
||||
optgroup {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Tables
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Remove most spacing between table cells.
|
||||
*/
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
td,
|
||||
th {
|
||||
padding: 0;
|
||||
}
|
||||
@@ -36,7 +36,10 @@ module WorkPackages
|
||||
|
||||
attribute :subject
|
||||
attribute :description
|
||||
attribute :status_id
|
||||
attribute :status_id,
|
||||
writeable: ->(*) {
|
||||
!model.closed_version_and_status?
|
||||
}
|
||||
attribute :type_id
|
||||
attribute :priority_id
|
||||
attribute :category_id
|
||||
|
||||
@@ -73,13 +73,17 @@ class AdminController < ApplicationController
|
||||
|
||||
def info
|
||||
@db_adapter_name = ActiveRecord::Base.connection.adapter_name
|
||||
repository_writable = File.writable?(OpenProject::Configuration.attachments_storage_path)
|
||||
@checklist = [
|
||||
[:text_default_administrator_account_changed, User.default_admin_account_changed?],
|
||||
[:text_file_repository_writable, repository_writable],
|
||||
[:text_database_allows_tsv, OpenProject::Database.allows_tsv?]
|
||||
]
|
||||
|
||||
# Add local directory test if we're not using fog
|
||||
if OpenProject::Configuration.file_storage?
|
||||
repository_writable = File.writable?(OpenProject::Configuration.attachments_storage_path)
|
||||
@checklist << [:text_file_repository_writable, repository_writable]
|
||||
end
|
||||
|
||||
if OpenProject::Database.allows_tsv?
|
||||
@checklist += plaintext_extraction_checks
|
||||
end
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
#-- encoding: UTF-8
|
||||
#-- copyright
|
||||
# OpenProject is a project management system.
|
||||
# Copyright (C) 2012-2018 the OpenProject Foundation (OPF)
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License version 3.
|
||||
#
|
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
|
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang
|
||||
# Copyright (C) 2010-2013 the ChiliProject Team
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# See docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
class AttachmentsController < ApplicationController
|
||||
before_action :find_project
|
||||
before_action :file_readable, :read_authorize, except: :destroy
|
||||
before_action :delete_authorize, only: :destroy
|
||||
|
||||
def download
|
||||
url = @attachment.external_url
|
||||
|
||||
if url
|
||||
redirect_to url.to_s
|
||||
else
|
||||
serve_attachment @attachment
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
# Make sure association callbacks are called
|
||||
@attachment.container.attachments.delete(@attachment)
|
||||
|
||||
redirect_to url_for(destroy_response_url(@attachment.container))
|
||||
end
|
||||
|
||||
def fulltext
|
||||
render plain: @attachment.fulltext.to_s
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_project
|
||||
@attachment = Attachment.find(params[:id])
|
||||
# Show 404 if the filename in the url is wrong
|
||||
raise ActiveRecord::RecordNotFound if params[:filename] && params[:filename] != @attachment.filename
|
||||
@project = @attachment.project
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
|
||||
# Checks that the file exists and is readable
|
||||
def file_readable
|
||||
@attachment.readable? ? true : render_404
|
||||
end
|
||||
|
||||
def read_authorize
|
||||
@attachment.visible? ? true : deny_access
|
||||
end
|
||||
|
||||
def delete_authorize
|
||||
@attachment.deletable? ? true : deny_access
|
||||
end
|
||||
|
||||
def destroy_response_url(container)
|
||||
url_for(container.is_a?(WikiPage) ? [@project, container.wiki] : container)
|
||||
end
|
||||
|
||||
def serve_attachment(attachment)
|
||||
if attachment.container.is_a?(Version) || attachment.container.is_a?(Project)
|
||||
attachment.increment_download
|
||||
end
|
||||
|
||||
# browsers should not try to guess the content-type
|
||||
response.headers['X-Content-Type-Options'] = 'nosniff'
|
||||
|
||||
send_file attachment.diskfile, filename: filename_for_content_disposition(attachment.filename),
|
||||
type: attachment.content_type,
|
||||
disposition: attachment.content_disposition
|
||||
end
|
||||
end
|
||||
@@ -35,8 +35,9 @@ class HighlightingController < ApplicationController
|
||||
response.content_type = Mime[:css]
|
||||
request.format = :css
|
||||
|
||||
if stale?(last_modified: @last_modified_times.max, etag: cache_key, public: true)
|
||||
OpenProject::Cache.fetch(@last_modified_times.max) do
|
||||
expires_in 1.year, public: true, must_revalidate: false
|
||||
if stale?(last_modified: Time.zone.parse(@max_updated_at), etag: @highlight_version_tag, public: true)
|
||||
OpenProject::Cache.fetch('highlighting/styles', @highlight_version_tag) do
|
||||
render template: 'highlighting/styles', formats: [:css]
|
||||
end
|
||||
end
|
||||
@@ -44,15 +45,8 @@ class HighlightingController < ApplicationController
|
||||
|
||||
private
|
||||
|
||||
def cache_key
|
||||
OpenProject::Cache::CacheKey.expand @last_modified_times
|
||||
end
|
||||
|
||||
def determine_freshness
|
||||
@last_modified_times = [
|
||||
Status.maximum(:updated_at),
|
||||
IssuePriority.maximum(:updated_at),
|
||||
Type.maximum(:updated_at)
|
||||
].compact
|
||||
@max_updated_at = helpers.highlight_css_updated_at || Time.now.iso8601
|
||||
@highlight_version_tag = helpers.highlight_css_version_tag(@max_updated_at)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -53,8 +53,6 @@ class WikiController < ApplicationController
|
||||
history
|
||||
diff
|
||||
annotate
|
||||
add_attachment
|
||||
list_attachments
|
||||
destroy]
|
||||
before_action :build_wiki_page_and_content, only: %i[new create]
|
||||
|
||||
@@ -345,20 +343,6 @@ class WikiController < ApplicationController
|
||||
end
|
||||
end
|
||||
|
||||
def add_attachment
|
||||
return render_403 unless editable?
|
||||
@page.attach_files(permitted_params.attachments.to_h)
|
||||
@page.save
|
||||
redirect_to action: 'show', id: @page, project_id: @project
|
||||
end
|
||||
|
||||
def list_attachments
|
||||
respond_to do |format|
|
||||
format.json { render 'common/list_attachments', locals: { attachments: @page.attachments } }
|
||||
format.html
|
||||
end
|
||||
end
|
||||
|
||||
def current_menu_item_sym(page)
|
||||
page = page_for_menu_item(page)
|
||||
|
||||
|
||||
@@ -3,6 +3,10 @@ module AdditionalUrlHelpers
|
||||
|
||||
module_function
|
||||
|
||||
def fixed_home_url
|
||||
home_url(script_name: OpenProject::Configuration.rails_relative_url_root)
|
||||
end
|
||||
|
||||
def add_params_to_uri(uri, args = {})
|
||||
uri = URI.parse uri
|
||||
query = URI.decode_www_form String(uri.query)
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
module HighlightingHelper
|
||||
def highlight_css_version_tag(max_updated_at = highlight_css_updated_at)
|
||||
OpenProject::Cache::CacheKey.expand max_updated_at
|
||||
end
|
||||
|
||||
def highlight_css_updated_at
|
||||
ApplicationRecord.most_recently_changed Status, IssuePriority, Type
|
||||
end
|
||||
end
|
||||
@@ -1,3 +1,30 @@
|
||||
class ApplicationRecord < ActiveRecord::Base
|
||||
self.abstract_class = true
|
||||
|
||||
##
|
||||
# Get the newest recently changed resource for the given record classes
|
||||
#
|
||||
# e.g., +most_recently_changed(WorkPackage, Type, Status)+
|
||||
#
|
||||
# Returns the timestamp of the most recently updated value
|
||||
def self.most_recently_changed(*record_classes)
|
||||
queries = record_classes.map do |clz|
|
||||
column_name = clz.send(:timestamp_attributes_for_update_in_model)&.first || 'updated_at'
|
||||
"(SELECT MAX(#{column_name}) AS max_updated_at FROM #{clz.table_name})"
|
||||
end
|
||||
.join(" UNION ")
|
||||
|
||||
union_query = <<~SQL
|
||||
SELECT MAX(union_query.max_updated_at)
|
||||
FROM (#{queries})
|
||||
AS union_query
|
||||
SQL
|
||||
|
||||
ActiveRecord::Base
|
||||
.connection
|
||||
.select_all(union_query)
|
||||
.rows
|
||||
&.first # first result row
|
||||
&.first # max column
|
||||
end
|
||||
end
|
||||
|
||||
@@ -53,7 +53,7 @@ class CustomAction < ActiveRecord::Base
|
||||
ret
|
||||
end
|
||||
|
||||
def reload
|
||||
def reload(*args)
|
||||
@conditions = nil
|
||||
|
||||
super
|
||||
@@ -113,11 +113,7 @@ class CustomAction < ActiveRecord::Base
|
||||
availables.map do |available|
|
||||
existing = actual.detect { |a| a.key == available.key }
|
||||
|
||||
if existing
|
||||
existing
|
||||
else
|
||||
available.new
|
||||
end
|
||||
existing || available.new
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -30,8 +30,15 @@
|
||||
# Configures a Query on the Query model. This allows to
|
||||
# e.g get all queries that belong to a specific project or
|
||||
# all projects that are global
|
||||
|
||||
module Queries::Queries
|
||||
Queries::Register.filter Queries::Queries::QueryQuery, Queries::Queries::Filters::ProjectFilter
|
||||
Queries::Register.filter Queries::Queries::QueryQuery, Queries::Queries::Filters::ProjectIdentifierFilter
|
||||
Queries::Register.filter Queries::Queries::QueryQuery, Queries::Queries::Filters::HiddenFilter
|
||||
filters_ns = Queries::Queries::Filters
|
||||
query_ns = Queries::Queries::QueryQuery
|
||||
register = Queries::Register
|
||||
|
||||
register.filter query_ns, filters_ns::ProjectFilter
|
||||
register.filter query_ns, filters_ns::ProjectIdentifierFilter
|
||||
register.filter query_ns, filters_ns::HiddenFilter
|
||||
register.filter query_ns, filters_ns::UpdatedAtFilter
|
||||
register.filter query_ns, filters_ns::IdFilter
|
||||
end
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is a project management system.
|
||||
# Copyright (C) 2012-2018 the OpenProject Foundation (OPF)
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License version 3.
|
||||
#
|
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
|
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang
|
||||
# Copyright (C) 2010-2013 the ChiliProject Team
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# See docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
class Queries::Queries::Filters::IdFilter < Queries::Queries::Filters::QueryFilter
|
||||
def type
|
||||
:integer
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,35 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is a project management system.
|
||||
# Copyright (C) 2012-2018 the OpenProject Foundation (OPF)
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License version 3.
|
||||
#
|
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
|
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang
|
||||
# Copyright (C) 2010-2013 the ChiliProject Team
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# See docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
class Queries::Queries::Filters::UpdatedAtFilter < Queries::Queries::Filters::QueryFilter
|
||||
def type
|
||||
:datetime_past
|
||||
end
|
||||
end
|
||||
@@ -31,12 +31,12 @@
|
||||
class Status < ActiveRecord::Base
|
||||
extend Pagination::Model
|
||||
|
||||
default_scope { order('position ASC') }
|
||||
default_scope { order_by_position }
|
||||
before_destroy :check_integrity
|
||||
has_many :workflows, foreign_key: 'old_status_id'
|
||||
acts_as_list
|
||||
|
||||
belongs_to :color, class_name: 'Color', foreign_key: 'color_id'
|
||||
belongs_to :color, class_name: 'Color', foreign_key: 'color_id'
|
||||
|
||||
before_destroy :delete_workflows
|
||||
|
||||
@@ -57,7 +57,7 @@ class Status < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def self.where_default
|
||||
where(['is_default=?', true])
|
||||
where(is_default: true)
|
||||
end
|
||||
|
||||
# Update all the +Issues+ setting their done_ratio to the value of their +Status+
|
||||
@@ -107,6 +107,7 @@ class Status < ActiveRecord::Base
|
||||
|
||||
def is_readonly
|
||||
return false unless can_readonly?
|
||||
|
||||
super
|
||||
end
|
||||
alias :is_readonly? :is_readonly
|
||||
|
||||
@@ -165,20 +165,25 @@ module Type::AttributeGroups
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
##
|
||||
# Get the default attribute groups for this type.
|
||||
# If it has activated custom fields through +custom_field_ids=+,
|
||||
# it will put them into the other group.
|
||||
def work_package_attributes_by_default_group_key
|
||||
active_cfs = active_custom_field_attributes
|
||||
|
||||
work_package_attributes
|
||||
.keys
|
||||
.reject { |key| CustomField.custom_field_attribute?(key) && !active_cfs.include?(key) }
|
||||
.select { |key| default_attribute?(active_cfs, key) }
|
||||
.group_by { |key| default_group_key(key.to_sym) }
|
||||
end
|
||||
|
||||
##
|
||||
# Custom fields should not get included into the default form configuration.
|
||||
# This method might get patched by modules.
|
||||
def default_attribute?(active_cfs, key)
|
||||
!(CustomField.custom_field_attribute?(key) && !active_cfs.include?(key))
|
||||
end
|
||||
|
||||
def to_attribute_group_class(groups)
|
||||
groups.map do |group|
|
||||
attributes = group[1]
|
||||
|
||||
@@ -246,11 +246,14 @@ class WorkPackage < ActiveRecord::Base
|
||||
end
|
||||
|
||||
# Users/groups the work_package can be assigned to
|
||||
extend Forwardable
|
||||
def_delegator :project, :possible_assignees, :assignable_assignees
|
||||
def assignable_assignees
|
||||
project.possible_assignees
|
||||
end
|
||||
|
||||
# Users the work_package can be assigned to
|
||||
def_delegator :project, :possible_responsibles, :assignable_responsibles
|
||||
def assignable_responsibles
|
||||
project.possible_responsibles
|
||||
end
|
||||
|
||||
# Versions that the work_package can be assigned to
|
||||
# A work_package can be assigned to:
|
||||
@@ -279,13 +282,17 @@ class WorkPackage < ActiveRecord::Base
|
||||
status.present? && status.is_readonly?
|
||||
end
|
||||
|
||||
def closed_version_and_status?
|
||||
fixed_version&.closed? && status.is_closed?
|
||||
end
|
||||
|
||||
# Returns true if the work_package is overdue
|
||||
def overdue?
|
||||
!due_date.nil? && (due_date < Date.today) && !closed?
|
||||
end
|
||||
|
||||
def milestone?
|
||||
type && type.is_milestone?
|
||||
type&.is_milestone?
|
||||
end
|
||||
alias_method :is_milestone?, :milestone?
|
||||
|
||||
@@ -295,10 +302,12 @@ class WorkPackage < ActiveRecord::Base
|
||||
|
||||
current_status = Status.where(id: status_id)
|
||||
|
||||
return current_status if closed_version_and_status?
|
||||
|
||||
statuses = new_statuses_allowed_by_workflow_to(user)
|
||||
.or(current_status)
|
||||
|
||||
statuses = statuses.or(Status.where(id: Status.default.id)) if include_default
|
||||
statuses = statuses.or(Status.where_default) if include_default
|
||||
statuses = statuses.where(is_closed: false) if blocked?
|
||||
|
||||
statuses.order_by_position
|
||||
|
||||
@@ -30,7 +30,7 @@ module BasicData
|
||||
class WorkflowSeeder < Seeder
|
||||
def seed_data!
|
||||
colors = Color.all
|
||||
colors = colors.map { |c| { c.name => c.id } }.reduce({}, :merge)
|
||||
colors = colors.map { |c| { c.name => c.id } }.reduce({}, :merge)
|
||||
|
||||
if WorkPackage.where(type_id: nil).any? || Journal::WorkPackageJournal.where(type_id: nil).any?
|
||||
# Fixes work packages that do not have a type yet. They receive the standard type.
|
||||
@@ -76,18 +76,18 @@ module BasicData
|
||||
status_seeder_class.new.seed!
|
||||
|
||||
# Workflow - Each type has its own workflow
|
||||
workflows.each { |type_id, statuses_for_type|
|
||||
statuses_for_type.each { |old_status|
|
||||
statuses_for_type.each { |new_status|
|
||||
[manager.id, member.id].each { |role_id|
|
||||
workflows.each do |type_id, statuses_for_type|
|
||||
statuses_for_type.each do |old_status|
|
||||
statuses_for_type.each do |new_status|
|
||||
[manager.id, member.id].each do |role_id|
|
||||
Workflow.create type_id: type_id,
|
||||
role_id: role_id,
|
||||
old_status_id: old_status.id,
|
||||
new_status_id: new_status.id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@ module DemoData
|
||||
|
||||
Member.create!(
|
||||
project: project,
|
||||
user: user,
|
||||
principal: user,
|
||||
roles: [role]
|
||||
)
|
||||
end
|
||||
|
||||
@@ -34,6 +34,10 @@ module DemoData
|
||||
@url_helpers ||= OpenProject::StaticRouting::StaticRouter.new.url_helpers
|
||||
end
|
||||
|
||||
def api_url_helpers
|
||||
API::V3::Utilities::PathHelper::ApiV3Path
|
||||
end
|
||||
|
||||
def with_references(str, project)
|
||||
res = link_work_packages str, project
|
||||
res = link_queries res, project
|
||||
@@ -74,7 +78,7 @@ module DemoData
|
||||
if match.include?(".id")
|
||||
attachment.id
|
||||
else
|
||||
url_helpers.attachment_path id: attachment.id
|
||||
api_url_helpers.attachment_content attachment.id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -75,7 +75,6 @@ class BaseTypeService
|
||||
errors: errors,
|
||||
result: type)
|
||||
rescue => e
|
||||
binding.pry
|
||||
ServiceResult.new(success: false).tap do |result|
|
||||
result.errors.add(:base, e.message)
|
||||
end
|
||||
|
||||
@@ -58,7 +58,9 @@ module FileUploader
|
||||
end
|
||||
|
||||
def readable?
|
||||
file && File.readable?(local_file)
|
||||
return false unless file && local_file
|
||||
|
||||
File.readable?(local_file)
|
||||
end
|
||||
|
||||
# store! nil's the cache_id after it finishes so we need to remember it for deletion
|
||||
|
||||
@@ -67,6 +67,9 @@ See docs/COPYRIGHT.rdoc for more details.
|
||||
<%# Include CLI assets (development) or prod build assets %>
|
||||
<%= include_frontend_assets %>
|
||||
|
||||
<%# Render CSS highlighting %>
|
||||
<%= stylesheet_link_tag "/highlighting/styles/#{highlight_css_version_tag}", skip_pipeline: true %>
|
||||
|
||||
<%= javascript_include_tag 'application' %>
|
||||
<%= javascript_include_tag "locales/#{I18n.locale}" %>
|
||||
<!-- Text formatting specific includes -->
|
||||
@@ -122,7 +125,7 @@ See docs/COPYRIGHT.rdoc for more details.
|
||||
</a>
|
||||
<%= render_top_menu_left %>
|
||||
<div id="logo" class="hidden-for-mobile">
|
||||
<%= link_to(I18n.t('label_home'), home_url, class: 'home-link') %>
|
||||
<%= link_to(I18n.t('label_home'), fixed_home_url, class: 'home-link') %>
|
||||
</div>
|
||||
<%= call_hook :view_layouts_base_top_menu %>
|
||||
<div class="top-menu-items-right">
|
||||
|
||||
+39
-27
@@ -27,7 +27,7 @@
|
||||
"check_name": "RegexDoS",
|
||||
"message": "Model attribute used in regular expression",
|
||||
"file": "app/models/mail_handler.rb",
|
||||
"line": 309,
|
||||
"line": 307,
|
||||
"link": "https://brakemanscanner.org/docs/warning_types/denial_of_service/",
|
||||
"code": "/^(#{\"#{attr.to_s.humanize}|#{all_attribute_translations(user.language)[attr]}|#{all_attribute_translations(Setting.default_language)[attr]}\"})[ \\t]*:[ \\t]*(#{\".+\"})\\s*$/i",
|
||||
"render_path": null,
|
||||
@@ -130,7 +130,19 @@
|
||||
"line": 32,
|
||||
"link": "https://brakemanscanner.org/docs/warning_types/dynamic_render_path/",
|
||||
"code": "render(partial => Redmine::Plugin.find(params[:id]).settings[:partial], { :locals => ({ :settings => Setting[\"plugin_#{Redmine::Plugin.find(params[:id]).id}\"] }) })",
|
||||
"render_path": [{"type":"controller","class":"SettingsController","method":"plugin","line":71,"file":"app/controllers/settings_controller.rb","rendered":{"name":"settings/plugin","file":"/home/oliver/openproject/dev/app/views/settings/plugin.html.erb"}}],
|
||||
"render_path": [
|
||||
{
|
||||
"type": "controller",
|
||||
"class": "SettingsController",
|
||||
"method": "plugin",
|
||||
"line": 71,
|
||||
"file": "app/controllers/settings_controller.rb",
|
||||
"rendered": {
|
||||
"name": "settings/plugin",
|
||||
"file": "app/views/settings/plugin.html.erb"
|
||||
}
|
||||
}
|
||||
],
|
||||
"location": {
|
||||
"type": "template",
|
||||
"template": "settings/plugin"
|
||||
@@ -159,6 +171,26 @@
|
||||
"confidence": "Weak",
|
||||
"note": "version_projection is static"
|
||||
},
|
||||
{
|
||||
"warning_type": "SQL Injection",
|
||||
"warning_code": 0,
|
||||
"fingerprint": "9482cd863a566bce3c2fb623ba0fcb66c6850f2a2b1b9d3e0c25875a99376d1a",
|
||||
"check_name": "SQL",
|
||||
"message": "Possible SQL injection",
|
||||
"file": "app/models/application_record.rb",
|
||||
"line": 25,
|
||||
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
||||
"code": "ActiveRecord::Base.connection.select_all(\" SELECT MAX(union_query.max_updated_at)\\n FROM (#{record_classes.map do\n column_name = (clz.timestamp_attributes_for_update_in_model.first or \"updated_at\")\n\"(SELECT MAX(#{(clz.timestamp_attributes_for_update_in_model.first or \"updated_at\")}) AS max_updated_at FROM #{clz.table_name})\"\n end.join(\" UNION \")})\\n AS union_query\\n\")",
|
||||
"render_path": null,
|
||||
"location": {
|
||||
"type": "method",
|
||||
"class": "ApplicationRecord",
|
||||
"method": "ApplicationRecord.most_recently_changed"
|
||||
},
|
||||
"user_input": "record_classes.map do\n column_name = (clz.timestamp_attributes_for_update_in_model.first or \"updated_at\")\n\"(SELECT MAX(#{(clz.timestamp_attributes_for_update_in_model.first or \"updated_at\")}) AS max_updated_at FROM #{clz.table_name})\"\n end.join(\" UNION \")",
|
||||
"confidence": "Medium",
|
||||
"note": "Fixed internal references to columns and tables"
|
||||
},
|
||||
{
|
||||
"warning_type": "SQL Injection",
|
||||
"warning_code": 0,
|
||||
@@ -166,7 +198,7 @@
|
||||
"check_name": "SQL",
|
||||
"message": "Possible SQL injection",
|
||||
"file": "app/models/journal/aggregated_journal.rb",
|
||||
"line": 411,
|
||||
"line": 383,
|
||||
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
||||
"code": "self.class.query_aggregated_journals(:journable => journable).where(\"#{self.class.version_projection} > ?\", version)",
|
||||
"render_path": null,
|
||||
@@ -206,7 +238,7 @@
|
||||
"check_name": "SQL",
|
||||
"message": "Possible SQL injection",
|
||||
"file": "app/models/work_package.rb",
|
||||
"line": 520,
|
||||
"line": 529,
|
||||
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
||||
"code": "ActiveRecord::Base.connection.select_all(\"select s.id as status_id,\\n s.is_closed as closed,\\n i.project_id as project_id,\\n count(i.id) as total\\n from\\n #{WorkPackage.table_name} i, #{Status.table_name} s\\n where\\n i.status_id=s.id\\n and i.project_id IN (#{project.descendants.active.map(&:id).join(\",\")})\\n group by s.id, s.is_closed, i.project_id\")",
|
||||
"render_path": null,
|
||||
@@ -259,26 +291,6 @@
|
||||
"confidence": "Medium",
|
||||
"note": "Never called with user input"
|
||||
},
|
||||
{
|
||||
"warning_type": "Redirect",
|
||||
"warning_code": 18,
|
||||
"fingerprint": "cae51bc9c805a05a1490141ea53bb88e0a97d626336975aec5f0d36ade8493d5",
|
||||
"check_name": "Redirect",
|
||||
"message": "Possible unprotected redirect",
|
||||
"file": "app/controllers/attachments_controller.rb",
|
||||
"line": 39,
|
||||
"link": "https://brakemanscanner.org/docs/warning_types/redirect/",
|
||||
"code": "redirect_to(Attachment.find(params[:id]).external_url.to_s)",
|
||||
"render_path": null,
|
||||
"location": {
|
||||
"type": "method",
|
||||
"class": "AttachmentsController",
|
||||
"method": "download"
|
||||
},
|
||||
"user_input": "Attachment.find(params[:id]).external_url.to_s",
|
||||
"confidence": "High",
|
||||
"note": "external_url does not take in user input. Only user-provided ID is used to find attachment"
|
||||
},
|
||||
{
|
||||
"warning_type": "SQL Injection",
|
||||
"warning_code": 0,
|
||||
@@ -286,7 +298,7 @@
|
||||
"check_name": "SQL",
|
||||
"message": "Possible SQL injection",
|
||||
"file": "app/models/work_package.rb",
|
||||
"line": 616,
|
||||
"line": 625,
|
||||
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
||||
"code": "where(\"id IN (SELECT common_id FROM (#{[Relation.hierarchy.where(:from_id => Relation.where(:to => work_packages).hierarchy_or_follows.select(:from_id)).select(\"to_id common_id\"), Relation.where(:to => work_packages).hierarchy_or_follows.select(\"from_id common_id\")].map(&:to_sql).join(\" UNION \")}) following_relations)\")",
|
||||
"render_path": null,
|
||||
@@ -340,6 +352,6 @@
|
||||
"note": "Static SQL built from `project_condition`"
|
||||
}
|
||||
],
|
||||
"updated": "2019-04-30 09:36:52 +0200",
|
||||
"brakeman_version": "4.5.0"
|
||||
"updated": "2019-06-28 07:49:05 +0200",
|
||||
"brakeman_version": "4.5.1"
|
||||
}
|
||||
|
||||
@@ -30,4 +30,4 @@ if defined?(LivingStyleGuide)
|
||||
LivingStyleGuide.default_options[:scss_template] = OpenProject::LivingStyleGuide::Template
|
||||
end
|
||||
|
||||
Rails.application.config.sass.load_paths << Rails.root.join('frontend', 'node_modules', 'foundation-apps', 'scss')
|
||||
Rails.application.config.sass.load_paths << Rails.root.join('app', 'assets', 'stylesheets', 'vendor', 'foundation-apps', 'scss')
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+2158
-2515
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+2054
-2442
File diff suppressed because it is too large
Load Diff
+2078
-2526
File diff suppressed because it is too large
Load Diff
+2103
-2495
File diff suppressed because it is too large
Load Diff
+2061
-2445
File diff suppressed because it is too large
Load Diff
+2082
-2571
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+2077
-2564
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+2050
-2421
File diff suppressed because it is too large
Load Diff
+2079
-2575
File diff suppressed because it is too large
Load Diff
+2076
-2574
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+2089
-2491
File diff suppressed because it is too large
Load Diff
+2055
-2464
File diff suppressed because it is too large
Load Diff
+2044
-2449
File diff suppressed because it is too large
Load Diff
+2065
-2554
File diff suppressed because it is too large
Load Diff
+1978
-2102
File diff suppressed because it is too large
Load Diff
@@ -1,920 +0,0 @@
|
||||
---
|
||||
af:
|
||||
js:
|
||||
ajax:
|
||||
hide: Versteek
|
||||
loading: Loading ...
|
||||
attachments:
|
||||
draggable_hint: 'Drag on editor field to inline image or reference attachment.
|
||||
Closed editor fields will be opened while you keep dragging.
|
||||
|
||||
'
|
||||
autocomplete_select:
|
||||
placeholder:
|
||||
multi: Add "%{name}"
|
||||
single: Select "%{name}"
|
||||
remove: Remove %{name}
|
||||
active: Active %{label} %{name}
|
||||
close_popup_title: Close popup
|
||||
close_filter_title: Close filter
|
||||
close_form_title: Close form
|
||||
card:
|
||||
add_new: Add new card
|
||||
highlighting:
|
||||
inline: 'Highlight inline:'
|
||||
entire_card_by: Entire card by
|
||||
remove_from_list: Remove card from list
|
||||
clipboard:
|
||||
browser_error: Your browser doesn't support copying to clipboard. Please copy
|
||||
the selected text manually.
|
||||
copied_successful: Sucessfully copied to clipboard!
|
||||
button_add_watcher: Voeg kyker by
|
||||
button_back: Terug
|
||||
button_back_to_list_view: Back to list view
|
||||
button_cancel: Kanselleer
|
||||
button_close: Close
|
||||
button_check_all: Kontroleer almal
|
||||
button_configure-form: Configure form
|
||||
button_confirm: Confirm
|
||||
button_continue: Continue
|
||||
button_copy: Kopieer
|
||||
button_custom-fields: Pasgemaakte velde
|
||||
button_delete: Skrap
|
||||
button_delete_watcher: Delete watcher
|
||||
button_details_view: Details view
|
||||
button_duplicate: Dupliseer
|
||||
button_edit: Redigeer
|
||||
button_filter: Filtreer
|
||||
button_advanced_filter: Advanced filter
|
||||
button_list_view: List view
|
||||
button_show_view: Fullscreen view
|
||||
button_log_time: Log tyd
|
||||
button_more: Meer
|
||||
button_move: Skuif
|
||||
button_open_details: Open details view
|
||||
button_close_details: Close details view
|
||||
button_open_fullscreen: Maak volkermmodus oop
|
||||
button_quote: Haal aan
|
||||
button_save: Stoor
|
||||
button_settings: Instellings
|
||||
button_uncheck_all: Ontmerk almal
|
||||
button_update: Opdateer
|
||||
button_export-pdf: Download PDF
|
||||
button_export-atom: Download Atom
|
||||
calendar:
|
||||
title: Kalender
|
||||
too_many: There are more work packages (%{count}) than can be displayed by the
|
||||
calendar (%{max}). Add filters to focus on the relevant ones.
|
||||
description_available_columns: Kolomme beskikbaar
|
||||
description_current_position: 'You are here: '
|
||||
description_select_work_package: 'Kies werkspakket #%{id}'
|
||||
description_selected_columns: Geselekteerde kolomme
|
||||
description_subwork_package: 'Kind van werkspakket #%{id}'
|
||||
editor:
|
||||
preview: Toggle preview mode
|
||||
source_code: Toggle Markdown source mode
|
||||
error_saving_failed: 'Saving the document failed with the following error: %{error}'
|
||||
error_initialization_failed: Failed to initialize CKEditor!
|
||||
mode:
|
||||
manual: Switch to Markdown source
|
||||
wysiwyg: Switch to WYSIWYG editor
|
||||
macro:
|
||||
child_pages:
|
||||
button: Links to child pages
|
||||
include_parent: Include parent
|
||||
text: "[Placeholder] Links to child pages of"
|
||||
page: Wiki bladsy
|
||||
this_page: this page
|
||||
hint: 'Leave this field empty to list all child pages of the current page.
|
||||
If you want to reference a different page, provide its title or slug.
|
||||
|
||||
'
|
||||
code_block:
|
||||
button: Insert code snippet
|
||||
title: Insert / edit Code snippet
|
||||
language: Formatting language
|
||||
language_hint: Enter the formatting language that will be used for highlighting
|
||||
(if supported).
|
||||
dropdown:
|
||||
macros: Macros
|
||||
chose_macro: Chose macro
|
||||
toc: Table of contents
|
||||
toolbar_help: Click to select widget and show the toolbar. Double-click to
|
||||
edit widget
|
||||
wiki_page_include:
|
||||
button: Include content of another wiki page
|
||||
text: "[Placeholder] Included wiki page of"
|
||||
page: Wiki bladsy
|
||||
not_set: "(Page not yet set)"
|
||||
hint: |
|
||||
Include the content of another wiki page by specifying its title or slug.
|
||||
You can include the wiki page of another project by separating them with a colon like the following example.
|
||||
work_package_button:
|
||||
button: Insert create work package button
|
||||
type: Work package type
|
||||
button_style: Use button style
|
||||
button_style_hint: 'Optional: Check to make macro appear as a button, not
|
||||
as a link.'
|
||||
without_type: Create work package
|
||||
with_type: 'Create work package (Type: %{typename})'
|
||||
embedded_table:
|
||||
button: Embed work package table
|
||||
text: "[Placeholder] Embedded work package table"
|
||||
embedded_calendar:
|
||||
text: "[Placeholder] Embedded calendar"
|
||||
custom_actions:
|
||||
date:
|
||||
specific: 'on'
|
||||
current_date: Current date
|
||||
error:
|
||||
internal: An internal error has occurred.
|
||||
cannot_save_changes_with_message: 'Cannot save your changes due to the following
|
||||
error: %{error}'
|
||||
query_saving: The view could not be saved.
|
||||
embedded_table_loading: 'The embedded view could not be loaded: %{message}'
|
||||
filter:
|
||||
description:
|
||||
text_open_filter: Open this filter with 'ALT' and arrow keys.
|
||||
text_close_filter: To select an entry leave the focus for example by pressing
|
||||
enter. To leave without filter select the first (empty) entry.
|
||||
noneElement: "(none)"
|
||||
time_zone_converted:
|
||||
two_values: "%{from} - %{to} in your local time."
|
||||
only_start: From %{from} in your local time.
|
||||
only_end: Till %{to} in your local time.
|
||||
value_spacer: "-"
|
||||
sorting:
|
||||
criteria:
|
||||
one: First sorting criteria
|
||||
two: Second sorting criteria
|
||||
three: Third sorting criteria
|
||||
upsale_for_more: For more advanced filters, check out the
|
||||
upsale_link: Enterprise Edition.
|
||||
general_text_no: nee
|
||||
general_text_yes: ja
|
||||
general_text_No: Nee
|
||||
general_text_Yes: Ja
|
||||
grid:
|
||||
add_modal:
|
||||
choose_widget: Choose widget
|
||||
widgets:
|
||||
documents:
|
||||
title: Documents
|
||||
no_results: No documents yet.
|
||||
news:
|
||||
title: Nuus
|
||||
at: at
|
||||
no_results: Nothing new to report.
|
||||
time_entries_current_user:
|
||||
title: Spent time (last 7 days)
|
||||
no_results: No time entries for the last 7 days.
|
||||
work_packages_accountable:
|
||||
title: Work packages I am accountable for
|
||||
work_packages_assigned:
|
||||
title: Werkspakkette aan my toegeken
|
||||
work_packages_created:
|
||||
title: Work packages created by me
|
||||
work_packages_watched:
|
||||
title: Work packages watched by me
|
||||
work_packages_table:
|
||||
title: Werkspakkete
|
||||
work_packages_calendar:
|
||||
title: Kalender
|
||||
homescreen:
|
||||
blocks:
|
||||
new_features:
|
||||
text_new_features: Read about new features and product updates.
|
||||
current_new_feature_html: 'OpenProject contains a new <b>Boards view</b>
|
||||
for Agile project management. </br> To activate this new feature for your
|
||||
existing projects, please do the following steps: <ul><li>Activate the
|
||||
module Boards within existing projects'' settings.</li> <li>Configure
|
||||
your Boards in a project.</li> <li>Verify roles and permissions</li></ul>'
|
||||
image_alt_text: Board teaser image
|
||||
learn_about: Learn more about Agile Boards
|
||||
label_activate: Activate
|
||||
label_activity_no: Activity entry number %{activityNo}
|
||||
label_activity_with_comment_no: Activity entry number %{activityNo}. Has a user
|
||||
comment.
|
||||
label_add_column_after: Add column after
|
||||
label_add_column_before: Add column before
|
||||
label_add_columns: Add columns
|
||||
label_add_comment: Add comment
|
||||
label_add_comment_title: Comment and type @ to notify other people
|
||||
label_add_row_after: Add row after
|
||||
label_add_row_before: Add row before
|
||||
label_add_selected_columns: Voeg geselekteerde kolomme by
|
||||
label_added_by: added by
|
||||
label_added_time_by: Added by %{author} %{age}
|
||||
label_ago: dae gelede
|
||||
label_all: alle
|
||||
label_all_work_packages: all work packages
|
||||
label_and: and
|
||||
label_ascending: Stygende
|
||||
label_author: 'Author: %{user}'
|
||||
label_between: between
|
||||
label_board: Board
|
||||
label_board_locked: Gesluit
|
||||
label_board_plural: Boards
|
||||
label_board_sticky: Klewerig
|
||||
label_create: Skep
|
||||
label_create_work_package: Create new work package
|
||||
label_created_by: Created by
|
||||
label_date: Datum
|
||||
label_date_with_format: 'Tik die %{date_attribute} in die volgende formaat: %{format}'
|
||||
label_deactivate: Deactivate
|
||||
label_descending: Dalende
|
||||
label_description: Beskrywing
|
||||
label_cancel_comment: Kanselleer aanmerking
|
||||
label_closed_work_packages: gesluit
|
||||
label_collapse: Vou in
|
||||
label_collapsed: collapsed
|
||||
label_collapse_all: Vou almal op
|
||||
label_comment: Opmerking
|
||||
label_committed_at: "%{committed_revision_link} at %{date}"
|
||||
label_committed_link: committed revision %{revision_identifier}
|
||||
label_contains: bevat
|
||||
label_created_on: created on
|
||||
label_edit_comment: Edit this comment
|
||||
label_edit_status: Edit the status of the work package
|
||||
label_equals: is
|
||||
label_expand: Expand
|
||||
label_expanded: expanded
|
||||
label_expand_all: Vou almal uit
|
||||
label_expand_project_menu: Expand project menu
|
||||
label_export: Export
|
||||
label_filename: Lêer
|
||||
label_filesize: Grootte
|
||||
label_greater_or_equal: ">="
|
||||
label_group_by: Groepeer volgens
|
||||
label_hide_attributes: Wys minder
|
||||
label_hide_column: Hide column
|
||||
label_hide_project_menu: Collapse project menu
|
||||
label_in: in
|
||||
label_in_less_than: in minder as
|
||||
label_in_more_than: in meer as
|
||||
label_latest_activity: Latest activity
|
||||
label_last_updated_on: Last updated on
|
||||
label_less_or_equal: "<="
|
||||
label_less_than_ago: minder as dae gelede
|
||||
label_loading: Laai tans...
|
||||
label_me: ek
|
||||
label_menu_collapse: collapse
|
||||
label_menu_expand: expand
|
||||
label_more_than_ago: meer as dae gelede
|
||||
label_my_page: My bladsy
|
||||
label_next: Volgende
|
||||
label_no_color: No color
|
||||
label_no_data: Geen data om te wys
|
||||
label_no_due_date: no end date
|
||||
label_no_start_date: no start date
|
||||
label_none: geen
|
||||
label_not_contains: bevat nie
|
||||
label_not_equals: is nie
|
||||
label_on: 'on'
|
||||
label_open_menu: Maak kieslys oop
|
||||
label_open_context_menu: Open context menu
|
||||
label_open_work_packages: maak oop
|
||||
label_password: Wagwoord
|
||||
label_previous: Vorige
|
||||
label_per_page: 'Per page:'
|
||||
label_please_wait: Please wait
|
||||
label_visibility_settings: Visibility settings
|
||||
label_quote_comment: Quote this comment
|
||||
label_reset: Herstel
|
||||
label_remove_column: Remove column
|
||||
label_remove_columns: Remove selected columns
|
||||
label_remove_row: Remove row
|
||||
label_save_as: Save as
|
||||
label_select_watcher: Select a watcher...
|
||||
label_selected_filter_list: Selected filters
|
||||
label_show_attributes: Show all attributes
|
||||
label_show_in_menu: Show view in menu
|
||||
label_sort_by: Sort by
|
||||
label_sorted_by: sorted by
|
||||
label_sort_higher: Move up
|
||||
label_sort_lower: Skuif af
|
||||
label_sorting: Sorting
|
||||
label_star_query: Favored
|
||||
label_press_enter_to_save: Press enter to save.
|
||||
label_public_query: Openbaar
|
||||
label_sum_for: Sum for
|
||||
label_subject: Onderwerp
|
||||
label_this_week: vandeesweek
|
||||
label_today: vandag
|
||||
label_up: Up
|
||||
label_activity_show_only_comments: Show activities with comments only
|
||||
label_activity_show_all: Show all activities
|
||||
label_total_progress: "%{percent}% Total progress"
|
||||
label_total_amount: 'Total: %{amount}'
|
||||
label_updated_on: updated on
|
||||
label_warning: Warning
|
||||
label_work_package: Werkspakket
|
||||
label_work_package_plural: Werkspakkete
|
||||
label_watch: Hou dop
|
||||
label_watch_work_package: Watch work package
|
||||
label_watcher_added_successfully: Watcher successfully added!
|
||||
label_watcher_deleted_successfully: Watcher successfully deleted!
|
||||
label_work_package_details_you_are_here: You're on the %{tab} tab for %{type}
|
||||
%{subject}.
|
||||
label_unwatch: Hou op dophou
|
||||
label_unwatch_work_package: Unwatch work package
|
||||
label_uploaded_by: Uploaded by
|
||||
label_default_queries: Default views
|
||||
label_starred_queries: Favorite views
|
||||
label_global_queries: Public views
|
||||
label_custom_queries: Private views
|
||||
label_columns: Kolomme
|
||||
label_attachments: Lêers
|
||||
label_drop_files: Drop files here
|
||||
label_drop_files_hint: or click to add files
|
||||
label_drop_folders_hint: You cannot upload folders as an attachment. Please select
|
||||
single files.
|
||||
label_add_attachments: Add attachments
|
||||
label_formattable_attachment_hint: Attach and link files by dropping on this field,
|
||||
or pasting from the clipboard.
|
||||
label_remove_file: Delete %{fileName}
|
||||
label_remove_watcher: Remove watcher %{name}
|
||||
label_remove_all_files: Delete all files
|
||||
label_add_description: Add a description for %{file}
|
||||
label_upload_notification: Uploading files...
|
||||
label_work_package_upload_notification: 'Uploading files for Work package #%{id}:
|
||||
%{subject}'
|
||||
label_wp_id_added_by: "#%{id} added by %{author}"
|
||||
label_files_to_upload: 'These files will be uploaded:'
|
||||
label_rejected_files: 'These files cannot be uploaded:'
|
||||
label_rejected_files_reason: These files cannot be uploaded as their size is greater
|
||||
than %{maximumFilesize}
|
||||
label_wait: Please wait for configuration...
|
||||
label_upload_counter: "%{done} of %{count} files finished"
|
||||
label_validation_error: 'The work package could not be saved due to the following
|
||||
errors:'
|
||||
help_texts:
|
||||
show_modal: Show attribute help text entry
|
||||
onboarding:
|
||||
buttons:
|
||||
skip: Skip
|
||||
next: Volgende
|
||||
got_it: Got it
|
||||
steps:
|
||||
help_menu: In the <b>Help</b> menu you will find a user guide and additional
|
||||
help resources. <br> Enjoy your work with OpenProject!
|
||||
members: Invite new <b>Members</b> to join your project.
|
||||
project_selection: Please click on one of the projects with useful demo data
|
||||
to get started. <br> The <b>Demo project</b> suits best for classical project
|
||||
management, while the <b>Scrum project</b> is better for Agile project management.
|
||||
sidebar_arrow: With the arrow you can navigate back to the project's <b>Main
|
||||
menu</b>.
|
||||
welcome: Take a three minutes introduction tour to learn the most <b>important
|
||||
features</b>. <br> We recommend completing the steps until the end. You
|
||||
can restart the tour any time.
|
||||
wiki: Within the <b>Wiki</b> you can document and share knowledge together
|
||||
with your team.
|
||||
backlogs:
|
||||
overview: Manage your work in the <b>Backlogs</b> view. <br> On the right
|
||||
you have the Product Backlog or a Bug Backlog, on the left you will have
|
||||
the respective sprints. Here you can create <b>epics, user stories, and
|
||||
bugs</b>, prioritize via drag'n'drop and add them to a sprint.
|
||||
task_board_arrow: To see your <b>Task board</b>, open the Sprint drop-down...
|
||||
task_board_select: "... and select the <b>Task board</b> entry."
|
||||
task_board: The <b>Task board</b> visualizes the progress for this sprint.
|
||||
Add new tasks or impediments with the + icon next to a user story. Via
|
||||
drag'n'drop you can update the status.
|
||||
boards:
|
||||
overview: Manage your work within an intuitive <b>Boards</b> view.
|
||||
lists: You can create multiple lists (columns) within one Board view, e.g.
|
||||
to create a KANBAN board.
|
||||
add: Click the + will <b>add a new card</b> to the list within a Board.
|
||||
drag: Drag & Drop your cards within a list to re-order, or to another list.
|
||||
A double click will open the details view.
|
||||
wp:
|
||||
toggler: Now let's have a look at the <b>Work package</b> section, which
|
||||
gives you a more detailed view of your work.
|
||||
list: This is the <b>Work package</b> list with the important work within
|
||||
your project, such as tasks, features, milestones, bugs, and more. <br>
|
||||
You can create or edit a work package directly within this list. To see
|
||||
its details you can double click on a row.
|
||||
full_view: Within the <b>Work package details</b> you find all relevant
|
||||
information, such as description, status and priority, activities, dependencies
|
||||
or comments.
|
||||
back_button: With the arrow you can navigate back to the work package list.
|
||||
create_button: The <b>Create</b> button will add a new work package to your
|
||||
project.
|
||||
timeline_button: You can activate the <b>Gantt chart</b> to create a timeline
|
||||
for your project.
|
||||
timeline: Here you can edit your project plan. Create new phases, milestones,
|
||||
and add dependencies. All team members can see and update the latest plan
|
||||
at any time.
|
||||
password_confirmation:
|
||||
field_description: You need to enter your account password to confirm this change.
|
||||
title: Confirm your password to continue
|
||||
pagination:
|
||||
no_other_page: You are on the only page.
|
||||
pages:
|
||||
next: Forward to the next page
|
||||
previous: Back to the previous page
|
||||
placeholders:
|
||||
default: "-"
|
||||
subject: Enter subject here
|
||||
selection: Kies asseblief
|
||||
relation_description: Click to add description for this relation
|
||||
project:
|
||||
required_outside_context: 'Please choose a project to create the work package
|
||||
in to see all attributes. You can only select projects which have the type
|
||||
above activated.
|
||||
|
||||
'
|
||||
context: Project context
|
||||
work_package_belongs_to: This work package belongs to project %{projectname}.
|
||||
click_to_switch_context: Open this work package in that project.
|
||||
autocompleter:
|
||||
label: Project autocompletion
|
||||
text_are_you_sure: Are you sure?
|
||||
types:
|
||||
attribute_groups:
|
||||
error_duplicate_group_name: The name %{group} is used more than once. Group
|
||||
names must be unique.
|
||||
error_no_table_configured: Please configure a table for %{group}.
|
||||
reset_title: Reset form configuration
|
||||
confirm_reset: 'Warning: Are you sure you want to reset the form configuration?
|
||||
This will reset the attributes to their default group and disable ALL custom
|
||||
fields.
|
||||
|
||||
'
|
||||
upgrade_to_ee: Upgrade to Enterprise Edition
|
||||
upgrade_to_ee_text: Wow! If you need this feature you are a super pro! Would
|
||||
you mind supporting us OpenSource developers by becoming an Enterprise Edition
|
||||
client?
|
||||
more_information: More information
|
||||
nevermind: Nevermind
|
||||
filter_types:
|
||||
parent: being child of
|
||||
precedes: preceding
|
||||
follows: following
|
||||
relates: relating to
|
||||
duplicates: duplicating
|
||||
duplicated: gedupliseer deur
|
||||
blocks: blocking
|
||||
blocked: geblokkeer deur
|
||||
partof: being part of
|
||||
includes: including
|
||||
requires: requiring
|
||||
required: required by
|
||||
time_entry:
|
||||
activity: Aktiwiteit
|
||||
comment: Opmerking
|
||||
hours: Ure
|
||||
watchers:
|
||||
label_loading: loading watchers...
|
||||
label_error_loading: An error occurred while loading the watchers
|
||||
label_search_watchers: Search watchers
|
||||
label_add: Voeg dophouers by
|
||||
label_discard: Discard selection
|
||||
typeahead_placeholder: Search for possible watchers
|
||||
relation_labels:
|
||||
parent: Ouer
|
||||
children: Children
|
||||
relates: Related To
|
||||
duplicates: Duplicates
|
||||
duplicated: Duplicated by
|
||||
blocks: Blocks
|
||||
blocked: Blocked by
|
||||
precedes: Precedes
|
||||
follows: Follows
|
||||
includes: Includes
|
||||
partof: Part of
|
||||
requires: Requires
|
||||
required: Required by
|
||||
relation_type: relation type
|
||||
relations_hierarchy:
|
||||
parent_headline: Ouer
|
||||
hierarchy_headline: Hierarchy
|
||||
children_headline: Children
|
||||
relation_buttons:
|
||||
set_parent: Set parent
|
||||
change_parent: Change parent
|
||||
remove_parent: Remove parent
|
||||
group_by_wp_type: Group by work package type
|
||||
group_by_relation_type: Group by relation type
|
||||
add_parent: Add existing parent
|
||||
add_new_child: Create new child
|
||||
create_new: Create new
|
||||
add_existing: Add existing
|
||||
add_existing_child: Add existing child
|
||||
remove_child: Remove child
|
||||
add_new_relation: Create new relation
|
||||
add_existing_relation: Add existing relation
|
||||
update_description: Set or update description of this relation
|
||||
toggle_description: Toggle relation description
|
||||
update_relation: Klik om die verhoudingtipe te verander
|
||||
add_follower: Add follower
|
||||
add_predecessor: Add predecessor
|
||||
remove: Remove relation
|
||||
save: Save relation
|
||||
abort: Abort
|
||||
relations_autocomplete:
|
||||
placeholder: Type to search
|
||||
parent_placeholder: Choose new parent or press escape to cancel.
|
||||
repositories:
|
||||
select_tag: Select tag
|
||||
select_branch: Select branch
|
||||
field_value_enter_prompt: Enter a value for '%{field}'
|
||||
select2:
|
||||
input_too_short:
|
||||
one: Please enter one more character
|
||||
other: Please enter {{count}} more characters
|
||||
zero: Please enter more characters
|
||||
load_more: Loading more results ...
|
||||
no_matches: No matches found
|
||||
searching: Searching ...
|
||||
selection_too_big:
|
||||
one: You can only select one item
|
||||
other: You can only select {{limit}} items
|
||||
zero: You cannot select any items
|
||||
project_menu_details: Besonderhede
|
||||
sort:
|
||||
sorted_asc: 'Ascending sort applied, '
|
||||
sorted_dsc: 'Descending sort applied, '
|
||||
sorted_no: 'No sort applied, '
|
||||
sorting_disabled: sorting is disabled
|
||||
activate_asc: activate to apply an ascending sort
|
||||
activate_dsc: activate to apply a descending sort
|
||||
activate_no: activate to remove the sort
|
||||
text_work_packages_destroy_confirmation: Are you sure you want to delete the selected
|
||||
work package(s)?
|
||||
text_query_destroy_confirmation: Are you sure you want to delete the selected
|
||||
view?
|
||||
text_attachment_destroy_confirmation: Are you sure you want to delete the attachment?
|
||||
timelines:
|
||||
quarter_label: Q%{quarter_number}
|
||||
gantt_chart: Gantt chart
|
||||
labels:
|
||||
title: Label configuration
|
||||
bar: Bar labels
|
||||
left: Left
|
||||
right: Right
|
||||
farRight: Far right
|
||||
showNone: "-- No label --"
|
||||
description: 'Select the attributes you want to be shown in the respective
|
||||
positions of the Gantt chart at all times. Note that when hovering an element,
|
||||
its date labels will be shown instead of these attributes.
|
||||
|
||||
'
|
||||
button_activate: Show Gantt chart
|
||||
button_deactivate: Hide Gantt chart
|
||||
cancel: Kanselleer
|
||||
change: Change in planning
|
||||
due_date: Finish date
|
||||
empty: "(empty)"
|
||||
error: An error has occurred.
|
||||
errors:
|
||||
not_implemented: The timeline could not be rendered because it uses a feature
|
||||
that is not yet implemented.
|
||||
report_comparison: The timeline could not render the configured comparisons.
|
||||
Please check the appropriate section in the configuration, resetting it
|
||||
can help solve this problem.
|
||||
report_epicfail: The timeline could not be loaded due to an unexpected error.
|
||||
report_timeout: The timeline could not be loaded in a reasonable amount of
|
||||
time.
|
||||
filter:
|
||||
grouping_other: Ander
|
||||
noneSelection: "(none)"
|
||||
name: Naam
|
||||
outline: Reset Outline
|
||||
outlines:
|
||||
aggregation: Show aggregations only
|
||||
level1: Expand level 1
|
||||
level2: Expand level 2
|
||||
level3: Expand level 3
|
||||
level4: Expand level 4
|
||||
level5: Expand level 5
|
||||
all: Show all
|
||||
project_status: Projek status
|
||||
really_close_dialog: Do you really want to close the dialog and lose the entered
|
||||
data?
|
||||
responsible: Verantwoordelik
|
||||
save: Stoor
|
||||
start_date: Begindatum
|
||||
tooManyProjects: More than %{count} Projects. Please use a better filter!
|
||||
selection_mode:
|
||||
notification: Click on any highlighted work package to create the relation.
|
||||
Press escape to cancel.
|
||||
zoom:
|
||||
in: Zoom in
|
||||
out: Zoom out
|
||||
auto: Auto zoom
|
||||
days: Days
|
||||
weeks: Weeks
|
||||
months: Months
|
||||
quarters: Quarters
|
||||
years: Years
|
||||
slider: Zoom slider
|
||||
description: 'Select the initial zoom level that should be shown when autozoom
|
||||
is not available.
|
||||
|
||||
'
|
||||
tl_toolbar:
|
||||
zooms: Zoom level
|
||||
outlines: Hierarchy level
|
||||
upsale:
|
||||
ee_only: Enterprise Edition only feature
|
||||
wiki_formatting:
|
||||
strong: Strong
|
||||
italic: Italic
|
||||
underline: Underline
|
||||
deleted: Deleted
|
||||
code: Inline Code
|
||||
heading1: Heading 1
|
||||
heading2: Heading 2
|
||||
heading3: Heading 3
|
||||
unordered_list: Unordered List
|
||||
ordered_list: Ordered List
|
||||
quote: Haal aan
|
||||
unquote: Unquote
|
||||
preformatted_text: Preformatted Text
|
||||
wiki_link: Link to a Wiki page
|
||||
image: Image
|
||||
work_packages:
|
||||
bulk_actions:
|
||||
move: Bulk move
|
||||
edit: Bulk edit
|
||||
copy: Bulk copy
|
||||
delete: Bulk delete
|
||||
button_clear: Verwyder
|
||||
comment_added: The comment was successfully added.
|
||||
comment_send_failed: An error has occurred. Could not submit the comment.
|
||||
comment_updated: The comment was successfully updated.
|
||||
confirm_edit_cancel: Are you sure you want to cancel editing the work package?
|
||||
description_filter: Filtreer
|
||||
description_enter_text: Tik teks
|
||||
description_options_hide: Hide options
|
||||
description_options_show: Show options
|
||||
error:
|
||||
update_conflict_refresh: Click here to refresh the work package and update
|
||||
to the newest version.
|
||||
edit_prohibited: Redigering van %{attribute} is geblokkeer vir hierdie werkspakket.
|
||||
Hierdie eienskap is of afgelei van verhoudings (bv., kinders) of andersins
|
||||
nie veranderbaar nie.
|
||||
format:
|
||||
date: "%{attribute} is no valid date - YYYY-MM-DD expected."
|
||||
general: An error has occurred.
|
||||
edit_attribute: "%{attribute} - Edit"
|
||||
key_value: "%{key}: %{value}"
|
||||
label_enable_multi_select: Enable multiselect
|
||||
label_disable_multi_select: Disable multiselect
|
||||
label_filter_add: Voeg filter by
|
||||
label_filter_by_text: Filter by text
|
||||
label_options: Opsies
|
||||
label_column_multiselect: 'Combined dropdown field: Select with arrow keys,
|
||||
confirm selection with enter, delete with backspace'
|
||||
message_error_during_bulk_delete: An error occurred while trying to delete work
|
||||
packages.
|
||||
message_successful_bulk_delete: Successfully deleted work packages.
|
||||
message_successful_show_in_fullscreen: Klik hier om hierdie werkspakket in volskermmodus
|
||||
oop te maak.
|
||||
message_view_spent_time: Show spent time for this work package
|
||||
message_work_package_read_only: Work package is locked in this status. No attribute
|
||||
other than status can be altered.
|
||||
no_value: No value
|
||||
placeholder_filter_by_text: Subject, description, comments, ...
|
||||
inline_create:
|
||||
title: Klik hier om 'n nuwe werkspakket by hierdie lys te voeg
|
||||
create:
|
||||
title: Nuwe werkspakket
|
||||
header: New %{type}
|
||||
header_no_type: New work package (Type not yet set)
|
||||
header_with_parent: 'New %{type} (Child of %{parent_type} #%{id})'
|
||||
button: Skep
|
||||
copy:
|
||||
title: Copy work package
|
||||
hierarchy:
|
||||
show: Show hierarchy mode
|
||||
hide: Hide hierarchy mode
|
||||
toggle_button: Click to toggle hierarchy mode.
|
||||
leaf: Work package leaf at level %{level}.
|
||||
children_collapsed: Hierarchy level %{level}, collapsed. Click to show the
|
||||
filtered children
|
||||
children_expanded: Hierarchy level %{level}, expanded. Click to collapse the
|
||||
filtered children
|
||||
faulty_query:
|
||||
title: Work packages could not be loaded.
|
||||
description: Your view is erroneous and could not be processed.
|
||||
no_results:
|
||||
title: Geen werkspakkette om te wys.
|
||||
description: Geen geskep óf alle werkspakkette is uitgefiltreer.
|
||||
property_groups:
|
||||
details: Besonderhede
|
||||
people: People
|
||||
estimatesAndTime: Estimates & Time
|
||||
other: Ander
|
||||
properties:
|
||||
assignee: Gedelegeerde
|
||||
author: Outeur
|
||||
createdAt: Geskep op
|
||||
description: Beskrywing
|
||||
date: Datum
|
||||
dueDate: Finish date
|
||||
estimatedTime: Geraamde tyd
|
||||
spentTime: Tyd gespandeer
|
||||
category: Kategorie
|
||||
percentageDone: Percentage done
|
||||
priority: Prioriteit
|
||||
projectName: Projek
|
||||
responsible: Verantwoordelik
|
||||
startDate: Begindatum
|
||||
status: Status
|
||||
subject: Onderwerp
|
||||
title: Titel
|
||||
type: Soort
|
||||
updatedAt: Opgedateer op
|
||||
versionName: Weergawe
|
||||
version: Weergawe
|
||||
default_queries:
|
||||
latest_activity: Latest activity
|
||||
created_by_me: Created by me
|
||||
assigned_to_me: Assigned to me
|
||||
recently_created: Recently created
|
||||
all_open: All open
|
||||
summary: Opsomming
|
||||
jump_marks:
|
||||
pagination: Jump to table pagination
|
||||
label_pagination: Click here to skip over the work packages table and go to
|
||||
pagination
|
||||
content: Jump to content
|
||||
label_content: Click here to skip over the menu and go to the content
|
||||
placeholders:
|
||||
default: "-"
|
||||
description: Click to enter description...
|
||||
query:
|
||||
column_names: Kolomme
|
||||
group_by: Groepeer resultate by
|
||||
group: Groepeer volgens
|
||||
group_by_disabled_by_hierarchy: Group by is disabled due to the hierarchy
|
||||
mode being active.
|
||||
hierarchy_disabled_by_group_by: Hierarchy mode is disabled due to results
|
||||
being grouped by %{column}.
|
||||
sort_ascending: Sort ascending
|
||||
sort_descending: Sort descending
|
||||
move_column_left: Move column left
|
||||
move_column_right: Move column right
|
||||
hide_column: Hide column
|
||||
insert_columns: Insert columns ...
|
||||
filters: Filtreerders
|
||||
display_sums: Vertoon totale
|
||||
confirm_edit_cancel: Are you sure you want to cancel editing the name of this
|
||||
view? Title will be set back to previous value.
|
||||
click_to_edit_query_name: Click to edit title of this view.
|
||||
rename_query_placeholder: Name of this view
|
||||
errors:
|
||||
unretrievable_query: Unable to retrieve view from URL
|
||||
not_found: There is no such view
|
||||
duplicate_query_title: Name of this view already exists. Change anyway?
|
||||
text_no_results: No matching views were found.
|
||||
table:
|
||||
configure_button: Configure work package table
|
||||
summary: Table with rows of work package and columns of work package attributes.
|
||||
text_inline_edit: Most cells of this table are buttons that activate inline-editing
|
||||
functionality of that attribute.
|
||||
text_sort_hint: With the links in the table headers you can sort, group, reorder,
|
||||
remove and add table columns.
|
||||
text_select_hint: Select boxes should be opened with 'ALT' and arrow keys.
|
||||
table_configuration:
|
||||
button: Configure this work package table
|
||||
choose_display_mode: Display work packages as
|
||||
modal_title: Work package table configuration
|
||||
embedded_tab_disabled: This configuration tab is not available for the embedded
|
||||
view you're editing.
|
||||
default: default
|
||||
display_settings: Display settings
|
||||
default_mode: Flat list
|
||||
hierarchy_mode: Hierarchy
|
||||
hierarchy_hint: All filtered table results will be augmented with their ancestors.
|
||||
Hierarchies can be expanded and collapsed.
|
||||
display_sums_hint: Display sums of all summable attributes in a row below
|
||||
the table results.
|
||||
show_timeline_hint: Show an interactive gantt chart on the right side of the
|
||||
table. You can change its width by dragging the divider between table and
|
||||
gantt chart.
|
||||
highlighting: Highlighting
|
||||
highlighting_mode:
|
||||
description: Highlight with color
|
||||
none: No highlighting
|
||||
inline: Highlighted attribute(s)
|
||||
inline_all: All attributes
|
||||
entire_row_by: Entire row by
|
||||
status: Status
|
||||
priority: Prioriteit
|
||||
type: Soort
|
||||
columns_help_text: Use the input above to add or remove columns to your table
|
||||
view. You can drag and drop the columns to reorder them.
|
||||
upsale:
|
||||
attribute_highlighting: Need certain work packages to stand out from the
|
||||
mass?
|
||||
relation_columns: Need to see relations in the work package list?
|
||||
check_out_link: Check out the Enterprise Edition.
|
||||
relation_filters:
|
||||
first_part: Show all work packages
|
||||
second_part: the current work package
|
||||
tabs:
|
||||
overview: Oorsig
|
||||
activity: Aktiwiteit
|
||||
relations: Relations
|
||||
watchers: Dophouers
|
||||
attachments: Aanhegsels
|
||||
time_relative:
|
||||
days: dae
|
||||
weeks: weeks
|
||||
months: months
|
||||
toolbar:
|
||||
settings:
|
||||
configure_view: Configure view ...
|
||||
columns: Columns ...
|
||||
sort_by: Sort by ...
|
||||
group_by: Group by ...
|
||||
display_sums: Display sums
|
||||
display_hierarchy: Display hierarchy
|
||||
hide_hierarchy: Hide hierarchy
|
||||
hide_sums: Hide sums
|
||||
save: Stoor
|
||||
save_as: Save as ...
|
||||
export: Export ...
|
||||
visibility_settings: Visibility settings ...
|
||||
page_settings: Rename view ...
|
||||
delete: Skrap
|
||||
filter: Filtreer
|
||||
unselected_title: Werkspakket
|
||||
search_query_label: Search saved views
|
||||
search_query_title: Click to search saved views
|
||||
placeholder_query_title: Set a title for this view
|
||||
modals:
|
||||
label_settings: Rename view
|
||||
label_name: Naam
|
||||
label_delete_page: Delete current page
|
||||
button_apply: Pas toe
|
||||
button_save: Stoor
|
||||
button_submit: Dien in
|
||||
button_cancel: Kanselleer
|
||||
form_submit:
|
||||
title: Confirm to continue
|
||||
text: Are you sure you want to perform this action?
|
||||
destroy_work_package:
|
||||
title: Confirm deletion of %{label}
|
||||
text: Are you sure you want to delete the following %{label} ?
|
||||
has_children: 'The work package has %{childUnits}:'
|
||||
confirm_deletion_children: I acknowledge that ALL descendants of the listed
|
||||
work packages will be recursively removed.
|
||||
deletes_children: All child work packages and their descendants will also
|
||||
be recursively deleted.
|
||||
notice_no_results_to_display: No visible results to display.
|
||||
notice_successful_create: Successful creation.
|
||||
notice_successful_delete: Successful deletion.
|
||||
notice_successful_update: Successful update.
|
||||
notice_bad_request: Bad Request.
|
||||
relations:
|
||||
empty: No relation exists
|
||||
remove: Remove relation
|
||||
inplace:
|
||||
button_edit: "%{attribute}: Edit"
|
||||
button_save: "%{attribute}: Save"
|
||||
button_cancel: "%{attribute}: Cancel"
|
||||
button_save_all: Stoor
|
||||
button_cancel_all: Kanselleer
|
||||
link_formatting_help: Text formatting help
|
||||
btn_preview_enable: Voorskou
|
||||
btn_preview_disable: Disable preview
|
||||
null_value_label: No value
|
||||
clear_value_label: "-"
|
||||
errors:
|
||||
required: "%{field} cannot be empty"
|
||||
number: "%{field} is not a valid number"
|
||||
maxlength: "%{field} kan nie meer as %{maxLength} syfer(s) bevat nie"
|
||||
minlength: "%{field} kan nie minder as %{minLength} syfer(s) bevat nie"
|
||||
messages_on_field: 'This field is invalid: %{messages}'
|
||||
error_could_not_resolve_version_name: Couldn't resolve version name
|
||||
error_could_not_resolve_user_name: Couldn't resolve user name
|
||||
error_attachment_upload: 'File failed to upload: %{error}'
|
||||
error_attachment_upload_permission: You don't have the permission to upload files
|
||||
on this resource.
|
||||
units:
|
||||
workPackage:
|
||||
one: work package
|
||||
other: work packages
|
||||
child_work_packages:
|
||||
one: one child work package
|
||||
other: "%{count} work package children"
|
||||
hour:
|
||||
one: 1 hour
|
||||
other: "%{count} hours"
|
||||
zero: 0 hours
|
||||
zen_mode:
|
||||
button_activate: Activate zen mode
|
||||
button_deactivate: Deactivate zen mode
|
||||
global_search:
|
||||
all_projects: In all projects
|
||||
search: Search
|
||||
close_search: Close search
|
||||
current_project: In this project
|
||||
current_project_and_all_descendants: In this project + subprojects
|
||||
title:
|
||||
all_projects: all projects
|
||||
project_and_subprojects: and all subprojects
|
||||
search_for: Search for
|
||||
+669
-749
File diff suppressed because it is too large
Load Diff
@@ -1,922 +0,0 @@
|
||||
---
|
||||
az:
|
||||
js:
|
||||
ajax:
|
||||
hide: Hide
|
||||
loading: Yüklənir ...
|
||||
attachments:
|
||||
draggable_hint: 'Drag on editor field to inline image or reference attachment.
|
||||
Closed editor fields will be opened while you keep dragging.
|
||||
|
||||
'
|
||||
autocomplete_select:
|
||||
placeholder:
|
||||
multi: Add "%{name}"
|
||||
single: Select "%{name}"
|
||||
remove: Remove %{name}
|
||||
active: Active %{label} %{name}
|
||||
close_popup_title: Açılan pəncərəni bağla
|
||||
close_filter_title: Close filter
|
||||
close_form_title: Close form
|
||||
card:
|
||||
add_new: Add new card
|
||||
highlighting:
|
||||
inline: 'Highlight inline:'
|
||||
entire_card_by: Entire card by
|
||||
remove_from_list: Remove card from list
|
||||
clipboard:
|
||||
browser_error: Your browser doesn't support copying to clipboard. Please copy
|
||||
the selected text manually.
|
||||
copied_successful: Sucessfully copied to clipboard!
|
||||
button_add_watcher: Add watcher
|
||||
button_back: Back
|
||||
button_back_to_list_view: Back to list view
|
||||
button_cancel: Cancel
|
||||
button_close: Close
|
||||
button_check_all: Check all
|
||||
button_configure-form: Configure form
|
||||
button_confirm: Confirm
|
||||
button_continue: Continue
|
||||
button_copy: Copy
|
||||
button_custom-fields: Custom fields
|
||||
button_delete: Delete
|
||||
button_delete_watcher: İzləyicini sil
|
||||
button_details_view: Təfsilat baxışı
|
||||
button_duplicate: Duplicate
|
||||
button_edit: Edit
|
||||
button_filter: Filter
|
||||
button_advanced_filter: Advanced filter
|
||||
button_list_view: Siyahı baxışı
|
||||
button_show_view: Fullscreen view
|
||||
button_log_time: Log time
|
||||
button_more: More
|
||||
button_move: Move
|
||||
button_open_details: Təfsilat baxışını aç
|
||||
button_close_details: Close details view
|
||||
button_open_fullscreen: Open fullscreen view
|
||||
button_quote: Quote
|
||||
button_save: Save
|
||||
button_settings: Settings
|
||||
button_uncheck_all: Uncheck all
|
||||
button_update: Update
|
||||
button_export-pdf: Download PDF
|
||||
button_export-atom: Download Atom
|
||||
calendar:
|
||||
title: Calendar
|
||||
too_many: There are more work packages (%{count}) than can be displayed by the
|
||||
calendar (%{max}). Add filters to focus on the relevant ones.
|
||||
description_available_columns: Available Columns
|
||||
description_current_position: 'You are here: '
|
||||
description_select_work_package: 'Select work package #%{id}'
|
||||
description_selected_columns: Selected Columns
|
||||
description_subwork_package: 'Child of work package #%{id}'
|
||||
editor:
|
||||
preview: Toggle preview mode
|
||||
source_code: Toggle Markdown source mode
|
||||
error_saving_failed: 'Saving the document failed with the following error: %{error}'
|
||||
error_initialization_failed: Failed to initialize CKEditor!
|
||||
mode:
|
||||
manual: Switch to Markdown source
|
||||
wysiwyg: Switch to WYSIWYG editor
|
||||
macro:
|
||||
child_pages:
|
||||
button: Links to child pages
|
||||
include_parent: Include parent
|
||||
text: "[Placeholder] Links to child pages of"
|
||||
page: Wiki page
|
||||
this_page: this page
|
||||
hint: 'Leave this field empty to list all child pages of the current page.
|
||||
If you want to reference a different page, provide its title or slug.
|
||||
|
||||
'
|
||||
code_block:
|
||||
button: Insert code snippet
|
||||
title: Insert / edit Code snippet
|
||||
language: Formatting language
|
||||
language_hint: Enter the formatting language that will be used for highlighting
|
||||
(if supported).
|
||||
dropdown:
|
||||
macros: Macros
|
||||
chose_macro: Chose macro
|
||||
toc: Table of contents
|
||||
toolbar_help: Click to select widget and show the toolbar. Double-click to
|
||||
edit widget
|
||||
wiki_page_include:
|
||||
button: Include content of another wiki page
|
||||
text: "[Placeholder] Included wiki page of"
|
||||
page: Wiki page
|
||||
not_set: "(Page not yet set)"
|
||||
hint: |
|
||||
Include the content of another wiki page by specifying its title or slug.
|
||||
You can include the wiki page of another project by separating them with a colon like the following example.
|
||||
work_package_button:
|
||||
button: Insert create work package button
|
||||
type: Work package type
|
||||
button_style: Use button style
|
||||
button_style_hint: 'Optional: Check to make macro appear as a button, not
|
||||
as a link.'
|
||||
without_type: Create work package
|
||||
with_type: 'Create work package (Type: %{typename})'
|
||||
embedded_table:
|
||||
button: Embed work package table
|
||||
text: "[Placeholder] Embedded work package table"
|
||||
embedded_calendar:
|
||||
text: "[Placeholder] Embedded calendar"
|
||||
custom_actions:
|
||||
date:
|
||||
specific: 'on'
|
||||
current_date: Current date
|
||||
error:
|
||||
internal: An internal error has occurred.
|
||||
cannot_save_changes_with_message: 'Cannot save your changes due to the following
|
||||
error: %{error}'
|
||||
query_saving: The view could not be saved.
|
||||
embedded_table_loading: 'The embedded view could not be loaded: %{message}'
|
||||
filter:
|
||||
description:
|
||||
text_open_filter: Open this filter with 'ALT' and arrow keys.
|
||||
text_close_filter: To select an entry leave the focus for example by pressing
|
||||
enter. To leave without filter select the first (empty) entry.
|
||||
noneElement: "(none)"
|
||||
time_zone_converted:
|
||||
two_values: "%{from} - %{to} in your local time."
|
||||
only_start: From %{from} in your local time.
|
||||
only_end: Till %{to} in your local time.
|
||||
value_spacer: "-"
|
||||
sorting:
|
||||
criteria:
|
||||
one: First sorting criteria
|
||||
two: Second sorting criteria
|
||||
three: Third sorting criteria
|
||||
upsale_for_more: For more advanced filters, check out the
|
||||
upsale_link: Enterprise Edition.
|
||||
general_text_no: 'no'
|
||||
general_text_yes: 'yes'
|
||||
general_text_No: 'No'
|
||||
general_text_Yes: 'Yes'
|
||||
grid:
|
||||
add_modal:
|
||||
choose_widget: Choose widget
|
||||
widgets:
|
||||
documents:
|
||||
title: Documents
|
||||
no_results: No documents yet.
|
||||
news:
|
||||
title: News
|
||||
at: at
|
||||
no_results: Nothing new to report.
|
||||
time_entries_current_user:
|
||||
title: Spent time (last 7 days)
|
||||
no_results: No time entries for the last 7 days.
|
||||
work_packages_accountable:
|
||||
title: Work packages I am accountable for
|
||||
work_packages_assigned:
|
||||
title: Work packages assigned to me
|
||||
work_packages_created:
|
||||
title: Work packages created by me
|
||||
work_packages_watched:
|
||||
title: Work packages watched by me
|
||||
work_packages_table:
|
||||
title: Work packages
|
||||
work_packages_calendar:
|
||||
title: Calendar
|
||||
homescreen:
|
||||
blocks:
|
||||
new_features:
|
||||
text_new_features: Read about new features and product updates.
|
||||
current_new_feature_html: 'OpenProject contains a new <b>Boards view</b>
|
||||
for Agile project management. </br> To activate this new feature for your
|
||||
existing projects, please do the following steps: <ul><li>Activate the
|
||||
module Boards within existing projects'' settings.</li> <li>Configure
|
||||
your Boards in a project.</li> <li>Verify roles and permissions</li></ul>'
|
||||
image_alt_text: Board teaser image
|
||||
learn_about: Learn more about Agile Boards
|
||||
label_activate: Activate
|
||||
label_activity_no: Activity entry number %{activityNo}
|
||||
label_activity_with_comment_no: Activity entry number %{activityNo}. Has a user
|
||||
comment.
|
||||
label_add_column_after: Add column after
|
||||
label_add_column_before: Add column before
|
||||
label_add_columns: Add columns
|
||||
label_add_comment: Rəy bildir
|
||||
label_add_comment_title: Comment and type @ to notify other people
|
||||
label_add_row_after: Add row after
|
||||
label_add_row_before: Add row before
|
||||
label_add_selected_columns: Add selected columns
|
||||
label_added_by: əlavə edən
|
||||
label_added_time_by: "%{author} %{age} tərəfindən əlavə edildi"
|
||||
label_ago: days ago
|
||||
label_all: all
|
||||
label_all_work_packages: bütün iş paketləri
|
||||
label_and: and
|
||||
label_ascending: Ascending
|
||||
label_author: 'Author: %{user}'
|
||||
label_between: between
|
||||
label_board: Board
|
||||
label_board_locked: Locked
|
||||
label_board_plural: Boards
|
||||
label_board_sticky: Sticky
|
||||
label_create: Create
|
||||
label_create_work_package: Create new work package
|
||||
label_created_by: Created by
|
||||
label_date: Date
|
||||
label_date_with_format: 'Enter the %{date_attribute} using the following format:
|
||||
%{format}'
|
||||
label_deactivate: Söndür
|
||||
label_descending: Descending
|
||||
label_description: Description
|
||||
label_cancel_comment: Cancel comment
|
||||
label_closed_work_packages: closed
|
||||
label_collapse: Collapse
|
||||
label_collapsed: collapsed
|
||||
label_collapse_all: Collapse all
|
||||
label_comment: Comment
|
||||
label_committed_at: "%{committed_revision_link} at %{date}"
|
||||
label_committed_link: committed revision %{revision_identifier}
|
||||
label_contains: contains
|
||||
label_created_on: created on
|
||||
label_edit_comment: Edit this comment
|
||||
label_edit_status: Edit the status of the work package
|
||||
label_equals: is
|
||||
label_expand: Genişləndir
|
||||
label_expanded: genişləndirilmiş
|
||||
label_expand_all: Expand all
|
||||
label_expand_project_menu: Expand project menu
|
||||
label_export: İxrac et
|
||||
label_filename: File
|
||||
label_filesize: Size
|
||||
label_greater_or_equal: ">="
|
||||
label_group_by: Group by
|
||||
label_hide_attributes: Show less
|
||||
label_hide_column: Sütunu gizlət
|
||||
label_hide_project_menu: Collapse project menu
|
||||
label_in: in
|
||||
label_in_less_than: in less than
|
||||
label_in_more_than: in more than
|
||||
label_latest_activity: Latest activity
|
||||
label_last_updated_on: Son yenilənmə
|
||||
label_less_or_equal: "<="
|
||||
label_less_than_ago: less than days ago
|
||||
label_loading: Loading...
|
||||
label_me: me
|
||||
label_menu_collapse: collapse
|
||||
label_menu_expand: genişləndir
|
||||
label_more_than_ago: more than days ago
|
||||
label_my_page: My page
|
||||
label_next: Next
|
||||
label_no_color: No color
|
||||
label_no_data: No data to display
|
||||
label_no_due_date: bitmə tarixi yoxdur
|
||||
label_no_start_date: başlama tarixi yoxdur
|
||||
label_none: none
|
||||
label_not_contains: doesn't contain
|
||||
label_not_equals: is not
|
||||
label_on: 'on'
|
||||
label_open_menu: Open menu
|
||||
label_open_context_menu: Open context menu
|
||||
label_open_work_packages: open
|
||||
label_password: Password
|
||||
label_previous: Previous
|
||||
label_per_page: 'Səhifə başına:'
|
||||
label_please_wait: Please wait
|
||||
label_visibility_settings: Visibility settings
|
||||
label_quote_comment: Quote this comment
|
||||
label_reset: Reset
|
||||
label_remove_column: Remove column
|
||||
label_remove_columns: Remove selected columns
|
||||
label_remove_row: Remove row
|
||||
label_save_as: Fərqli saxla
|
||||
label_select_watcher: İzləyici seç...
|
||||
label_selected_filter_list: Seçilmiş filtrlər
|
||||
label_show_attributes: Show all attributes
|
||||
label_show_in_menu: Show view in menu
|
||||
label_sort_by: Sort by
|
||||
label_sorted_by: sıralama
|
||||
label_sort_higher: Move up
|
||||
label_sort_lower: Move down
|
||||
label_sorting: Sıralama
|
||||
label_star_query: Favored
|
||||
label_press_enter_to_save: Press enter to save.
|
||||
label_public_query: Public
|
||||
label_sum_for: Sum for
|
||||
label_subject: Subject
|
||||
label_this_week: this week
|
||||
label_today: today
|
||||
label_up: Up
|
||||
label_activity_show_only_comments: Show activities with comments only
|
||||
label_activity_show_all: Show all activities
|
||||
label_total_progress: "%{percent}% Total progress"
|
||||
label_total_amount: 'Total: %{amount}'
|
||||
label_updated_on: updated on
|
||||
label_warning: Warning
|
||||
label_work_package: Work package
|
||||
label_work_package_plural: Work packages
|
||||
label_watch: Watch
|
||||
label_watch_work_package: Watch work package
|
||||
label_watcher_added_successfully: Watcher successfully added!
|
||||
label_watcher_deleted_successfully: Watcher successfully deleted!
|
||||
label_work_package_details_you_are_here: You're on the %{tab} tab for %{type}
|
||||
%{subject}.
|
||||
label_unwatch: Unwatch
|
||||
label_unwatch_work_package: Unwatch work package
|
||||
label_uploaded_by: Uploaded by
|
||||
label_default_queries: Default views
|
||||
label_starred_queries: Favorite views
|
||||
label_global_queries: Public views
|
||||
label_custom_queries: Private views
|
||||
label_columns: Columns
|
||||
label_attachments: Files
|
||||
label_drop_files: Drop files here
|
||||
label_drop_files_hint: or click to add files
|
||||
label_drop_folders_hint: You cannot upload folders as an attachment. Please select
|
||||
single files.
|
||||
label_add_attachments: Add attachments
|
||||
label_formattable_attachment_hint: Attach and link files by dropping on this field,
|
||||
or pasting from the clipboard.
|
||||
label_remove_file: Delete %{fileName}
|
||||
label_remove_watcher: Remove watcher %{name}
|
||||
label_remove_all_files: Delete all files
|
||||
label_add_description: Add a description for %{file}
|
||||
label_upload_notification: Uploading files...
|
||||
label_work_package_upload_notification: 'Uploading files for Work package #%{id}:
|
||||
%{subject}'
|
||||
label_wp_id_added_by: "#%{id} added by %{author}"
|
||||
label_files_to_upload: 'These files will be uploaded:'
|
||||
label_rejected_files: 'These files cannot be uploaded:'
|
||||
label_rejected_files_reason: These files cannot be uploaded as their size is greater
|
||||
than %{maximumFilesize}
|
||||
label_wait: Please wait for configuration...
|
||||
label_upload_counter: "%{done} of %{count} files finished"
|
||||
label_validation_error: 'The work package could not be saved due to the following
|
||||
errors:'
|
||||
help_texts:
|
||||
show_modal: Show attribute help text entry
|
||||
onboarding:
|
||||
buttons:
|
||||
skip: Skip
|
||||
next: Next
|
||||
got_it: Got it
|
||||
steps:
|
||||
help_menu: In the <b>Help</b> menu you will find a user guide and additional
|
||||
help resources. <br> Enjoy your work with OpenProject!
|
||||
members: Invite new <b>Members</b> to join your project.
|
||||
project_selection: Please click on one of the projects with useful demo data
|
||||
to get started. <br> The <b>Demo project</b> suits best for classical project
|
||||
management, while the <b>Scrum project</b> is better for Agile project management.
|
||||
sidebar_arrow: With the arrow you can navigate back to the project's <b>Main
|
||||
menu</b>.
|
||||
welcome: Take a three minutes introduction tour to learn the most <b>important
|
||||
features</b>. <br> We recommend completing the steps until the end. You
|
||||
can restart the tour any time.
|
||||
wiki: Within the <b>Wiki</b> you can document and share knowledge together
|
||||
with your team.
|
||||
backlogs:
|
||||
overview: Manage your work in the <b>Backlogs</b> view. <br> On the right
|
||||
you have the Product Backlog or a Bug Backlog, on the left you will have
|
||||
the respective sprints. Here you can create <b>epics, user stories, and
|
||||
bugs</b>, prioritize via drag'n'drop and add them to a sprint.
|
||||
task_board_arrow: To see your <b>Task board</b>, open the Sprint drop-down...
|
||||
task_board_select: "... and select the <b>Task board</b> entry."
|
||||
task_board: The <b>Task board</b> visualizes the progress for this sprint.
|
||||
Add new tasks or impediments with the + icon next to a user story. Via
|
||||
drag'n'drop you can update the status.
|
||||
boards:
|
||||
overview: Manage your work within an intuitive <b>Boards</b> view.
|
||||
lists: You can create multiple lists (columns) within one Board view, e.g.
|
||||
to create a KANBAN board.
|
||||
add: Click the + will <b>add a new card</b> to the list within a Board.
|
||||
drag: Drag & Drop your cards within a list to re-order, or to another list.
|
||||
A double click will open the details view.
|
||||
wp:
|
||||
toggler: Now let's have a look at the <b>Work package</b> section, which
|
||||
gives you a more detailed view of your work.
|
||||
list: This is the <b>Work package</b> list with the important work within
|
||||
your project, such as tasks, features, milestones, bugs, and more. <br>
|
||||
You can create or edit a work package directly within this list. To see
|
||||
its details you can double click on a row.
|
||||
full_view: Within the <b>Work package details</b> you find all relevant
|
||||
information, such as description, status and priority, activities, dependencies
|
||||
or comments.
|
||||
back_button: With the arrow you can navigate back to the work package list.
|
||||
create_button: The <b>Create</b> button will add a new work package to your
|
||||
project.
|
||||
timeline_button: You can activate the <b>Gantt chart</b> to create a timeline
|
||||
for your project.
|
||||
timeline: Here you can edit your project plan. Create new phases, milestones,
|
||||
and add dependencies. All team members can see and update the latest plan
|
||||
at any time.
|
||||
password_confirmation:
|
||||
field_description: You need to enter your account password to confirm this change.
|
||||
title: Confirm your password to continue
|
||||
pagination:
|
||||
no_other_page: You are on the only page.
|
||||
pages:
|
||||
next: Forward to the next page
|
||||
previous: Back to the previous page
|
||||
placeholders:
|
||||
default: "-"
|
||||
subject: Enter subject here
|
||||
selection: Please select
|
||||
relation_description: Click to add description for this relation
|
||||
project:
|
||||
required_outside_context: 'Please choose a project to create the work package
|
||||
in to see all attributes. You can only select projects which have the type
|
||||
above activated.
|
||||
|
||||
'
|
||||
context: Project context
|
||||
work_package_belongs_to: This work package belongs to project %{projectname}.
|
||||
click_to_switch_context: Open this work package in that project.
|
||||
autocompleter:
|
||||
label: Project autocompletion
|
||||
text_are_you_sure: Are you sure?
|
||||
types:
|
||||
attribute_groups:
|
||||
error_duplicate_group_name: The name %{group} is used more than once. Group
|
||||
names must be unique.
|
||||
error_no_table_configured: Please configure a table for %{group}.
|
||||
reset_title: Reset form configuration
|
||||
confirm_reset: 'Warning: Are you sure you want to reset the form configuration?
|
||||
This will reset the attributes to their default group and disable ALL custom
|
||||
fields.
|
||||
|
||||
'
|
||||
upgrade_to_ee: Upgrade to Enterprise Edition
|
||||
upgrade_to_ee_text: Wow! If you need this feature you are a super pro! Would
|
||||
you mind supporting us OpenSource developers by becoming an Enterprise Edition
|
||||
client?
|
||||
more_information: More information
|
||||
nevermind: Nevermind
|
||||
filter_types:
|
||||
parent: being child of
|
||||
precedes: preceding
|
||||
follows: following
|
||||
relates: relating to
|
||||
duplicates: duplicating
|
||||
duplicated: duplicated by
|
||||
blocks: blocking
|
||||
blocked: blocked by
|
||||
partof: being part of
|
||||
includes: including
|
||||
requires: requiring
|
||||
required: required by
|
||||
time_entry:
|
||||
activity: Activity
|
||||
comment: Comment
|
||||
hours: Hours
|
||||
watchers:
|
||||
label_loading: loading watchers...
|
||||
label_error_loading: An error occurred while loading the watchers
|
||||
label_search_watchers: Search watchers
|
||||
label_add: Add watchers
|
||||
label_discard: Discard selection
|
||||
typeahead_placeholder: Search for possible watchers
|
||||
relation_labels:
|
||||
parent: Parent
|
||||
children: Children
|
||||
relates: Related To
|
||||
duplicates: Duplicates
|
||||
duplicated: Duplicated by
|
||||
blocks: Blocks
|
||||
blocked: Blocked by
|
||||
precedes: Precedes
|
||||
follows: Follows
|
||||
includes: Includes
|
||||
partof: Part of
|
||||
requires: Requires
|
||||
required: Required by
|
||||
relation_type: relation type
|
||||
relations_hierarchy:
|
||||
parent_headline: Parent
|
||||
hierarchy_headline: Hierarchy
|
||||
children_headline: Children
|
||||
relation_buttons:
|
||||
set_parent: Set parent
|
||||
change_parent: Change parent
|
||||
remove_parent: Remove parent
|
||||
group_by_wp_type: Group by work package type
|
||||
group_by_relation_type: Group by relation type
|
||||
add_parent: Add existing parent
|
||||
add_new_child: Create new child
|
||||
create_new: Create new
|
||||
add_existing: Add existing
|
||||
add_existing_child: Add existing child
|
||||
remove_child: Remove child
|
||||
add_new_relation: Create new relation
|
||||
add_existing_relation: Add existing relation
|
||||
update_description: Set or update description of this relation
|
||||
toggle_description: Toggle relation description
|
||||
update_relation: Click to change the relation type
|
||||
add_follower: Add follower
|
||||
add_predecessor: Add predecessor
|
||||
remove: Remove relation
|
||||
save: Save relation
|
||||
abort: Abort
|
||||
relations_autocomplete:
|
||||
placeholder: Type to search
|
||||
parent_placeholder: Choose new parent or press escape to cancel.
|
||||
repositories:
|
||||
select_tag: Select tag
|
||||
select_branch: Select branch
|
||||
field_value_enter_prompt: Enter a value for '%{field}'
|
||||
select2:
|
||||
input_too_short:
|
||||
one: Please enter one more character
|
||||
other: Please enter {{count}} more characters
|
||||
zero: Please enter more characters
|
||||
load_more: Loading more results ...
|
||||
no_matches: No matches found
|
||||
searching: Searching ...
|
||||
selection_too_big:
|
||||
one: You can only select one item
|
||||
other: You can only select {{limit}} items
|
||||
zero: You cannot select any items
|
||||
project_menu_details: Details
|
||||
sort:
|
||||
sorted_asc: 'Ascending sort applied, '
|
||||
sorted_dsc: 'Descending sort applied, '
|
||||
sorted_no: 'No sort applied, '
|
||||
sorting_disabled: sorting is disabled
|
||||
activate_asc: activate to apply an ascending sort
|
||||
activate_dsc: activate to apply a descending sort
|
||||
activate_no: activate to remove the sort
|
||||
text_work_packages_destroy_confirmation: Are you sure you want to delete the selected
|
||||
work package(s)?
|
||||
text_query_destroy_confirmation: Are you sure you want to delete the selected
|
||||
view?
|
||||
text_attachment_destroy_confirmation: Are you sure you want to delete the attachment?
|
||||
timelines:
|
||||
quarter_label: Q%{quarter_number}
|
||||
gantt_chart: Gantt chart
|
||||
labels:
|
||||
title: Label configuration
|
||||
bar: Bar labels
|
||||
left: Left
|
||||
right: Right
|
||||
farRight: Far right
|
||||
showNone: "-- No label --"
|
||||
description: 'Select the attributes you want to be shown in the respective
|
||||
positions of the Gantt chart at all times. Note that when hovering an element,
|
||||
its date labels will be shown instead of these attributes.
|
||||
|
||||
'
|
||||
button_activate: Show Gantt chart
|
||||
button_deactivate: Hide Gantt chart
|
||||
cancel: Cancel
|
||||
change: Change in planning
|
||||
due_date: Finish date
|
||||
empty: "(empty)"
|
||||
error: An error has occurred.
|
||||
errors:
|
||||
not_implemented: The timeline could not be rendered because it uses a feature
|
||||
that is not yet implemented.
|
||||
report_comparison: The timeline could not render the configured comparisons.
|
||||
Please check the appropriate section in the configuration, resetting it
|
||||
can help solve this problem.
|
||||
report_epicfail: The timeline could not be loaded due to an unexpected error.
|
||||
report_timeout: The timeline could not be loaded in a reasonable amount of
|
||||
time.
|
||||
filter:
|
||||
grouping_other: Other
|
||||
noneSelection: "(none)"
|
||||
name: Name
|
||||
outline: Reset Outline
|
||||
outlines:
|
||||
aggregation: Show aggregations only
|
||||
level1: Expand level 1
|
||||
level2: Expand level 2
|
||||
level3: Expand level 3
|
||||
level4: Expand level 4
|
||||
level5: Expand level 5
|
||||
all: Show all
|
||||
project_status: Project status
|
||||
really_close_dialog: Do you really want to close the dialog and lose the entered
|
||||
data?
|
||||
responsible: Responsible
|
||||
save: Save
|
||||
start_date: Start date
|
||||
tooManyProjects: More than %{count} Projects. Please use a better filter!
|
||||
selection_mode:
|
||||
notification: Click on any highlighted work package to create the relation.
|
||||
Press escape to cancel.
|
||||
zoom:
|
||||
in: Zoom in
|
||||
out: Zoom out
|
||||
auto: Auto zoom
|
||||
days: Days
|
||||
weeks: Weeks
|
||||
months: Months
|
||||
quarters: Quarters
|
||||
years: Years
|
||||
slider: Zoom slider
|
||||
description: 'Select the initial zoom level that should be shown when autozoom
|
||||
is not available.
|
||||
|
||||
'
|
||||
tl_toolbar:
|
||||
zooms: Zoom level
|
||||
outlines: Hierarchy level
|
||||
upsale:
|
||||
ee_only: Enterprise Edition only feature
|
||||
wiki_formatting:
|
||||
strong: Strong
|
||||
italic: Italic
|
||||
underline: Underline
|
||||
deleted: Deleted
|
||||
code: Inline Code
|
||||
heading1: Heading 1
|
||||
heading2: Heading 2
|
||||
heading3: Heading 3
|
||||
unordered_list: Unordered List
|
||||
ordered_list: Ordered List
|
||||
quote: Quote
|
||||
unquote: Unquote
|
||||
preformatted_text: Preformatted Text
|
||||
wiki_link: Link to a Wiki page
|
||||
image: Image
|
||||
work_packages:
|
||||
bulk_actions:
|
||||
move: Bulk move
|
||||
edit: Bulk edit
|
||||
copy: Bulk copy
|
||||
delete: Bulk delete
|
||||
button_clear: Clear
|
||||
comment_added: The comment was successfully added.
|
||||
comment_send_failed: An error has occurred. Could not submit the comment.
|
||||
comment_updated: The comment was successfully updated.
|
||||
confirm_edit_cancel: Are you sure you want to cancel editing the work package?
|
||||
description_filter: Filter
|
||||
description_enter_text: Enter text
|
||||
description_options_hide: Hide options
|
||||
description_options_show: Show options
|
||||
error:
|
||||
update_conflict_refresh: Click here to refresh the work package and update
|
||||
to the newest version.
|
||||
edit_prohibited: Editing %{attribute} is blocked for this work package. Either
|
||||
this attribute is derived from relations (e.g, children) or otherwise not
|
||||
configurable.
|
||||
format:
|
||||
date: "%{attribute} is no valid date - YYYY-MM-DD expected."
|
||||
general: An error has occurred.
|
||||
edit_attribute: "%{attribute} - Edit"
|
||||
key_value: "%{key}: %{value}"
|
||||
label_enable_multi_select: Enable multiselect
|
||||
label_disable_multi_select: Disable multiselect
|
||||
label_filter_add: Add filter
|
||||
label_filter_by_text: Filter by text
|
||||
label_options: Options
|
||||
label_column_multiselect: 'Combined dropdown field: Select with arrow keys,
|
||||
confirm selection with enter, delete with backspace'
|
||||
message_error_during_bulk_delete: An error occurred while trying to delete work
|
||||
packages.
|
||||
message_successful_bulk_delete: Successfully deleted work packages.
|
||||
message_successful_show_in_fullscreen: Click here to open this work package
|
||||
in fullscreen view.
|
||||
message_view_spent_time: Show spent time for this work package
|
||||
message_work_package_read_only: Work package is locked in this status. No attribute
|
||||
other than status can be altered.
|
||||
no_value: No value
|
||||
placeholder_filter_by_text: Subject, description, comments, ...
|
||||
inline_create:
|
||||
title: Click here to add a new work package to this list
|
||||
create:
|
||||
title: New work package
|
||||
header: New %{type}
|
||||
header_no_type: New work package (Type not yet set)
|
||||
header_with_parent: 'New %{type} (Child of %{parent_type} #%{id})'
|
||||
button: Create
|
||||
copy:
|
||||
title: Copy work package
|
||||
hierarchy:
|
||||
show: Show hierarchy mode
|
||||
hide: Hide hierarchy mode
|
||||
toggle_button: Click to toggle hierarchy mode.
|
||||
leaf: Work package leaf at level %{level}.
|
||||
children_collapsed: Hierarchy level %{level}, collapsed. Click to show the
|
||||
filtered children
|
||||
children_expanded: Hierarchy level %{level}, expanded. Click to collapse the
|
||||
filtered children
|
||||
faulty_query:
|
||||
title: Work packages could not be loaded.
|
||||
description: Your view is erroneous and could not be processed.
|
||||
no_results:
|
||||
title: No work packages to display.
|
||||
description: Either none have been created or all work packages are filtered
|
||||
out.
|
||||
property_groups:
|
||||
details: Details
|
||||
people: People
|
||||
estimatesAndTime: Estimates & Time
|
||||
other: Other
|
||||
properties:
|
||||
assignee: Assignee
|
||||
author: Author
|
||||
createdAt: Created on
|
||||
description: Description
|
||||
date: Date
|
||||
dueDate: Finish date
|
||||
estimatedTime: Estimated time
|
||||
spentTime: Spent time
|
||||
category: Category
|
||||
percentageDone: Percentage done
|
||||
priority: Priority
|
||||
projectName: Project
|
||||
responsible: Responsible
|
||||
startDate: Start date
|
||||
status: Status
|
||||
subject: Subject
|
||||
title: Title
|
||||
type: Type
|
||||
updatedAt: Updated on
|
||||
versionName: Version
|
||||
version: Version
|
||||
default_queries:
|
||||
latest_activity: Latest activity
|
||||
created_by_me: Created by me
|
||||
assigned_to_me: Assigned to me
|
||||
recently_created: Recently created
|
||||
all_open: All open
|
||||
summary: Summary
|
||||
jump_marks:
|
||||
pagination: Jump to table pagination
|
||||
label_pagination: Click here to skip over the work packages table and go to
|
||||
pagination
|
||||
content: Jump to content
|
||||
label_content: Click here to skip over the menu and go to the content
|
||||
placeholders:
|
||||
default: "-"
|
||||
description: Click to enter description...
|
||||
query:
|
||||
column_names: Columns
|
||||
group_by: Group results by
|
||||
group: Group by
|
||||
group_by_disabled_by_hierarchy: Group by is disabled due to the hierarchy
|
||||
mode being active.
|
||||
hierarchy_disabled_by_group_by: Hierarchy mode is disabled due to results
|
||||
being grouped by %{column}.
|
||||
sort_ascending: Sort ascending
|
||||
sort_descending: Sort descending
|
||||
move_column_left: Move column left
|
||||
move_column_right: Move column right
|
||||
hide_column: Sütunu gizlət
|
||||
insert_columns: Insert columns ...
|
||||
filters: Filters
|
||||
display_sums: Display Sums
|
||||
confirm_edit_cancel: Are you sure you want to cancel editing the name of this
|
||||
view? Title will be set back to previous value.
|
||||
click_to_edit_query_name: Click to edit title of this view.
|
||||
rename_query_placeholder: Name of this view
|
||||
errors:
|
||||
unretrievable_query: Unable to retrieve view from URL
|
||||
not_found: There is no such view
|
||||
duplicate_query_title: Name of this view already exists. Change anyway?
|
||||
text_no_results: No matching views were found.
|
||||
table:
|
||||
configure_button: Configure work package table
|
||||
summary: Table with rows of work package and columns of work package attributes.
|
||||
text_inline_edit: Most cells of this table are buttons that activate inline-editing
|
||||
functionality of that attribute.
|
||||
text_sort_hint: With the links in the table headers you can sort, group, reorder,
|
||||
remove and add table columns.
|
||||
text_select_hint: Select boxes should be opened with 'ALT' and arrow keys.
|
||||
table_configuration:
|
||||
button: Configure this work package table
|
||||
choose_display_mode: Display work packages as
|
||||
modal_title: Work package table configuration
|
||||
embedded_tab_disabled: This configuration tab is not available for the embedded
|
||||
view you're editing.
|
||||
default: default
|
||||
display_settings: Display settings
|
||||
default_mode: Flat list
|
||||
hierarchy_mode: Hierarchy
|
||||
hierarchy_hint: All filtered table results will be augmented with their ancestors.
|
||||
Hierarchies can be expanded and collapsed.
|
||||
display_sums_hint: Display sums of all summable attributes in a row below
|
||||
the table results.
|
||||
show_timeline_hint: Show an interactive gantt chart on the right side of the
|
||||
table. You can change its width by dragging the divider between table and
|
||||
gantt chart.
|
||||
highlighting: Highlighting
|
||||
highlighting_mode:
|
||||
description: Highlight with color
|
||||
none: No highlighting
|
||||
inline: Highlighted attribute(s)
|
||||
inline_all: All attributes
|
||||
entire_row_by: Entire row by
|
||||
status: Status
|
||||
priority: Priority
|
||||
type: Type
|
||||
columns_help_text: Use the input above to add or remove columns to your table
|
||||
view. You can drag and drop the columns to reorder them.
|
||||
upsale:
|
||||
attribute_highlighting: Need certain work packages to stand out from the
|
||||
mass?
|
||||
relation_columns: Need to see relations in the work package list?
|
||||
check_out_link: Check out the Enterprise Edition.
|
||||
relation_filters:
|
||||
first_part: Show all work packages
|
||||
second_part: the current work package
|
||||
tabs:
|
||||
overview: Overview
|
||||
activity: Activity
|
||||
relations: Relations
|
||||
watchers: Watchers
|
||||
attachments: Attachments
|
||||
time_relative:
|
||||
days: days
|
||||
weeks: weeks
|
||||
months: months
|
||||
toolbar:
|
||||
settings:
|
||||
configure_view: Configure view ...
|
||||
columns: Columns ...
|
||||
sort_by: Sort by ...
|
||||
group_by: Group by ...
|
||||
display_sums: Display sums
|
||||
display_hierarchy: Display hierarchy
|
||||
hide_hierarchy: Hide hierarchy
|
||||
hide_sums: Hide sums
|
||||
save: Save
|
||||
save_as: Save as ...
|
||||
export: Export ...
|
||||
visibility_settings: Visibility settings ...
|
||||
page_settings: Rename view ...
|
||||
delete: Delete
|
||||
filter: Filter
|
||||
unselected_title: Work package
|
||||
search_query_label: Search saved views
|
||||
search_query_title: Click to search saved views
|
||||
placeholder_query_title: Set a title for this view
|
||||
modals:
|
||||
label_settings: Rename view
|
||||
label_name: Name
|
||||
label_delete_page: Delete current page
|
||||
button_apply: Apply
|
||||
button_save: Save
|
||||
button_submit: Submit
|
||||
button_cancel: Cancel
|
||||
form_submit:
|
||||
title: Confirm to continue
|
||||
text: Are you sure you want to perform this action?
|
||||
destroy_work_package:
|
||||
title: Confirm deletion of %{label}
|
||||
text: Are you sure you want to delete the following %{label} ?
|
||||
has_children: 'The work package has %{childUnits}:'
|
||||
confirm_deletion_children: I acknowledge that ALL descendants of the listed
|
||||
work packages will be recursively removed.
|
||||
deletes_children: All child work packages and their descendants will also
|
||||
be recursively deleted.
|
||||
notice_no_results_to_display: No visible results to display.
|
||||
notice_successful_create: Successful creation.
|
||||
notice_successful_delete: Successful deletion.
|
||||
notice_successful_update: Successful update.
|
||||
notice_bad_request: Bad Request.
|
||||
relations:
|
||||
empty: No relation exists
|
||||
remove: Remove relation
|
||||
inplace:
|
||||
button_edit: "%{attribute}: Edit"
|
||||
button_save: "%{attribute}: Save"
|
||||
button_cancel: "%{attribute}: Cancel"
|
||||
button_save_all: Save
|
||||
button_cancel_all: Cancel
|
||||
link_formatting_help: Text formatting help
|
||||
btn_preview_enable: Preview
|
||||
btn_preview_disable: Disable preview
|
||||
null_value_label: No value
|
||||
clear_value_label: "-"
|
||||
errors:
|
||||
required: "%{field} cannot be empty"
|
||||
number: "%{field} is not a valid number"
|
||||
maxlength: "%{field} cannot contain more than %{maxLength} digit(s)"
|
||||
minlength: "%{field} cannot contain less than %{minLength} digit(s)"
|
||||
messages_on_field: 'This field is invalid: %{messages}'
|
||||
error_could_not_resolve_version_name: Couldn't resolve version name
|
||||
error_could_not_resolve_user_name: Couldn't resolve user name
|
||||
error_attachment_upload: 'File failed to upload: %{error}'
|
||||
error_attachment_upload_permission: You don't have the permission to upload files
|
||||
on this resource.
|
||||
units:
|
||||
workPackage:
|
||||
one: work package
|
||||
other: work packages
|
||||
child_work_packages:
|
||||
one: one child work package
|
||||
other: "%{count} work package children"
|
||||
hour:
|
||||
one: 1 hour
|
||||
other: "%{count} hours"
|
||||
zero: 0 hours
|
||||
zen_mode:
|
||||
button_activate: Activate zen mode
|
||||
button_deactivate: Deactivate zen mode
|
||||
global_search:
|
||||
all_projects: In all projects
|
||||
search: Search
|
||||
close_search: Close search
|
||||
current_project: In this project
|
||||
current_project_and_all_descendants: In this project + subprojects
|
||||
title:
|
||||
all_projects: all projects
|
||||
project_and_subprojects: and all subprojects
|
||||
search_for: Search for
|
||||
+654
-748
File diff suppressed because it is too large
Load Diff
+654
-750
File diff suppressed because it is too large
Load Diff
+665
-756
File diff suppressed because it is too large
Load Diff
+656
-745
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user