Ned Zimmerman
7 years ago
18 changed files with 4327 additions and 0 deletions
@ -0,0 +1,65 @@
|
||||
module.exports = function( grunt ) { |
||||
'use strict'; |
||||
|
||||
grunt.initConfig({ |
||||
|
||||
// Setting folder templates.
|
||||
dirs: { |
||||
css: 'scss' |
||||
}, |
||||
|
||||
// Compile all .scss files.
|
||||
sass: { |
||||
compile: { |
||||
options: { |
||||
sourcemap: 'none', |
||||
loadPath: require( 'node-bourbon' ).includePaths |
||||
}, |
||||
files: [{ |
||||
expand: true, |
||||
cwd: '<%= dirs.css %>/', |
||||
src: ['*.scss'], |
||||
dest: './', |
||||
ext: '.css' |
||||
}] |
||||
} |
||||
}, |
||||
|
||||
// Minify all .css files.
|
||||
cssmin: { |
||||
minify: { |
||||
expand: true, |
||||
cwd: './', |
||||
src: [ |
||||
'*.css', |
||||
'!*.min.css' |
||||
], |
||||
dest: './', |
||||
ext: '.min.css' |
||||
} |
||||
}, |
||||
|
||||
// Watch changes for assets.
|
||||
watch: { |
||||
css: { |
||||
files: ['<%= dirs.css %>/*.scss'], |
||||
tasks: ['sass', 'cssmin'] |
||||
} |
||||
} |
||||
}); |
||||
|
||||
// Load NPM tasks to be used here
|
||||
grunt.loadNpmTasks( 'grunt-contrib-sass' ); |
||||
grunt.loadNpmTasks( 'grunt-contrib-cssmin' ); |
||||
grunt.loadNpmTasks( 'grunt-contrib-watch' ); |
||||
|
||||
// Register tasks
|
||||
grunt.registerTask( 'default', [ |
||||
'css' |
||||
]); |
||||
|
||||
grunt.registerTask( 'css', [ |
||||
'sass', |
||||
'cssmin' |
||||
]); |
||||
}; |
@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE |
||||
Version 2, June 1991 |
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/> |
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
Everyone is permitted to copy and distribute verbatim copies |
||||
of this license document, but changing it is not allowed. |
||||
|
||||
Preamble |
||||
|
||||
The licenses for most software are designed to take away your |
||||
freedom to share and change it. By contrast, the GNU General Public |
||||
License is intended to guarantee your freedom to share and change free |
||||
software--to make sure the software is free for all its users. This |
||||
General Public License applies to most of the Free Software |
||||
Foundation's software and to any other program whose authors commit to |
||||
using it. (Some other Free Software Foundation software is covered by |
||||
the GNU Lesser General Public License instead.) You can apply it to |
||||
your programs, too. |
||||
|
||||
When we speak of free software, we are referring to freedom, not |
||||
price. Our General Public Licenses are designed to make sure that you |
||||
have the freedom to distribute copies of free software (and charge for |
||||
this service if you wish), that you receive source code or can get it |
||||
if you want it, that you can change the software or use pieces of it |
||||
in new free programs; and that you know you can do these things. |
||||
|
||||
To protect your rights, we need to make restrictions that forbid |
||||
anyone to deny you these rights or to ask you to surrender the rights. |
||||
These restrictions translate to certain responsibilities for you if you |
||||
distribute copies of the software, or if you modify it. |
||||
|
||||
For example, if you distribute copies of such a program, whether |
||||
gratis or for a fee, you must give the recipients all the rights that |
||||
you have. You must make sure that they, too, receive or can get the |
||||
source code. And you must show them these terms so they know their |
||||
rights. |
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and |
||||
(2) offer you this license which gives you legal permission to copy, |
||||
distribute and/or modify the software. |
||||
|
||||
Also, for each author's protection and ours, we want to make certain |
||||
that everyone understands that there is no warranty for this free |
||||
software. If the software is modified by someone else and passed on, we |
||||
want its recipients to know that what they have is not the original, so |
||||
that any problems introduced by others will not reflect on the original |
||||
authors' reputations. |
||||
|
||||
Finally, any free program is threatened constantly by software |
||||
patents. We wish to avoid the danger that redistributors of a free |
||||
program will individually obtain patent licenses, in effect making the |
||||
program proprietary. To prevent this, we have made it clear that any |
||||
patent must be licensed for everyone's free use or not licensed at all. |
||||
|
||||
The precise terms and conditions for copying, distribution and |
||||
modification follow. |
||||
|
||||
GNU GENERAL PUBLIC LICENSE |
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION |
||||
|
||||
0. This License applies to any program or other work which contains |
||||
a notice placed by the copyright holder saying it may be distributed |
||||
under the terms of this General Public License. The "Program", below, |
||||
refers to any such program or work, and a "work based on the Program" |
||||
means either the Program or any derivative work under copyright law: |
||||
that is to say, a work containing the Program or a portion of it, |
||||
either verbatim or with modifications and/or translated into another |
||||
language. (Hereinafter, translation is included without limitation in |
||||
the term "modification".) Each licensee is addressed as "you". |
||||
|
||||
Activities other than copying, distribution and modification are not |
||||
covered by this License; they are outside its scope. The act of |
||||
running the Program is not restricted, and the output from the Program |
||||
is covered only if its contents constitute a work based on the |
||||
Program (independent of having been made by running the Program). |
||||
Whether that is true depends on what the Program does. |
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's |
||||
source code as you receive it, in any medium, provided that you |
||||
conspicuously and appropriately publish on each copy an appropriate |
||||
copyright notice and disclaimer of warranty; keep intact all the |
||||
notices that refer to this License and to the absence of any warranty; |
||||
and give any other recipients of the Program a copy of this License |
||||
along with the Program. |
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and |
||||
you may at your option offer warranty protection in exchange for a fee. |
||||
|
||||
2. You may modify your copy or copies of the Program or any portion |
||||
of it, thus forming a work based on the Program, and copy and |
||||
distribute such modifications or work under the terms of Section 1 |
||||
above, provided that you also meet all of these conditions: |
||||
|
||||
a) You must cause the modified files to carry prominent notices |
||||
stating that you changed the files and the date of any change. |
||||
|
||||
b) You must cause any work that you distribute or publish, that in |
||||
whole or in part contains or is derived from the Program or any |
||||
part thereof, to be licensed as a whole at no charge to all third |
||||
parties under the terms of this License. |
||||
|
||||
c) If the modified program normally reads commands interactively |
||||
when run, you must cause it, when started running for such |
||||
interactive use in the most ordinary way, to print or display an |
||||
announcement including an appropriate copyright notice and a |
||||
notice that there is no warranty (or else, saying that you provide |
||||
a warranty) and that users may redistribute the program under |
||||
these conditions, and telling the user how to view a copy of this |
||||
License. (Exception: if the Program itself is interactive but |
||||
does not normally print such an announcement, your work based on |
||||
the Program is not required to print an announcement.) |
||||
|
||||
These requirements apply to the modified work as a whole. If |
||||
identifiable sections of that work are not derived from the Program, |
||||
and can be reasonably considered independent and separate works in |
||||
themselves, then this License, and its terms, do not apply to those |
||||
sections when you distribute them as separate works. But when you |
||||
distribute the same sections as part of a whole which is a work based |
||||
on the Program, the distribution of the whole must be on the terms of |
||||
this License, whose permissions for other licensees extend to the |
||||
entire whole, and thus to each and every part regardless of who wrote it. |
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest |
||||
your rights to work written entirely by you; rather, the intent is to |
||||
exercise the right to control the distribution of derivative or |
||||
collective works based on the Program. |
||||
|
||||
In addition, mere aggregation of another work not based on the Program |
||||
with the Program (or with a work based on the Program) on a volume of |
||||
a storage or distribution medium does not bring the other work under |
||||
the scope of this License. |
||||
|
||||
3. You may copy and distribute the Program (or a work based on it, |
||||
under Section 2) in object code or executable form under the terms of |
||||
Sections 1 and 2 above provided that you also do one of the following: |
||||
|
||||
a) Accompany it with the complete corresponding machine-readable |
||||
source code, which must be distributed under the terms of Sections |
||||
1 and 2 above on a medium customarily used for software interchange; or, |
||||
|
||||
b) Accompany it with a written offer, valid for at least three |
||||
years, to give any third party, for a charge no more than your |
||||
cost of physically performing source distribution, a complete |
||||
machine-readable copy of the corresponding source code, to be |
||||
distributed under the terms of Sections 1 and 2 above on a medium |
||||
customarily used for software interchange; or, |
||||
|
||||
c) Accompany it with the information you received as to the offer |
||||
to distribute corresponding source code. (This alternative is |
||||
allowed only for noncommercial distribution and only if you |
||||
received the program in object code or executable form with such |
||||
an offer, in accord with Subsection b above.) |
||||
|
||||
The source code for a work means the preferred form of the work for |
||||
making modifications to it. For an executable work, complete source |
||||
code means all the source code for all modules it contains, plus any |
||||
associated interface definition files, plus the scripts used to |
||||
control compilation and installation of the executable. However, as a |
||||
special exception, the source code distributed need not include |
||||
anything that is normally distributed (in either source or binary |
||||
form) with the major components (compiler, kernel, and so on) of the |
||||
operating system on which the executable runs, unless that component |
||||
itself accompanies the executable. |
||||
|
||||
If distribution of executable or object code is made by offering |
||||
access to copy from a designated place, then offering equivalent |
||||
access to copy the source code from the same place counts as |
||||
distribution of the source code, even though third parties are not |
||||
compelled to copy the source along with the object code. |
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program |
||||
except as expressly provided under this License. Any attempt |
||||
otherwise to copy, modify, sublicense or distribute the Program is |
||||
void, and will automatically terminate your rights under this License. |
||||
However, parties who have received copies, or rights, from you under |
||||
this License will not have their licenses terminated so long as such |
||||
parties remain in full compliance. |
||||
|
||||
5. You are not required to accept this License, since you have not |
||||
signed it. However, nothing else grants you permission to modify or |
||||
distribute the Program or its derivative works. These actions are |
||||
prohibited by law if you do not accept this License. Therefore, by |
||||
modifying or distributing the Program (or any work based on the |
||||
Program), you indicate your acceptance of this License to do so, and |
||||
all its terms and conditions for copying, distributing or modifying |
||||
the Program or works based on it. |
||||
|
||||
6. Each time you redistribute the Program (or any work based on the |
||||
Program), the recipient automatically receives a license from the |
||||
original licensor to copy, distribute or modify the Program subject to |
||||
these terms and conditions. You may not impose any further |
||||
restrictions on the recipients' exercise of the rights granted herein. |
||||
You are not responsible for enforcing compliance by third parties to |
||||
this License. |
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent |
||||
infringement or for any other reason (not limited to patent issues), |
||||
conditions are imposed on you (whether by court order, agreement or |
||||
otherwise) that contradict the conditions of this License, they do not |
||||
excuse you from the conditions of this License. If you cannot |
||||
distribute so as to satisfy simultaneously your obligations under this |
||||
License and any other pertinent obligations, then as a consequence you |
||||
may not distribute the Program at all. For example, if a patent |
||||
license would not permit royalty-free redistribution of the Program by |
||||
all those who receive copies directly or indirectly through you, then |
||||
the only way you could satisfy both it and this License would be to |
||||
refrain entirely from distribution of the Program. |
||||
|
||||
If any portion of this section is held invalid or unenforceable under |
||||
any particular circumstance, the balance of the section is intended to |
||||
apply and the section as a whole is intended to apply in other |
||||
circumstances. |
||||
|
||||
It is not the purpose of this section to induce you to infringe any |
||||
patents or other property right claims or to contest validity of any |
||||
such claims; this section has the sole purpose of protecting the |
||||
integrity of the free software distribution system, which is |
||||
implemented by public license practices. Many people have made |
||||
generous contributions to the wide range of software distributed |
||||
through that system in reliance on consistent application of that |
||||
system; it is up to the author/donor to decide if he or she is willing |
||||
to distribute software through any other system and a licensee cannot |
||||
impose that choice. |
||||
|
||||
This section is intended to make thoroughly clear what is believed to |
||||
be a consequence of the rest of this License. |
||||
|
||||
8. If the distribution and/or use of the Program is restricted in |
||||
certain countries either by patents or by copyrighted interfaces, the |
||||
original copyright holder who places the Program under this License |
||||
may add an explicit geographical distribution limitation excluding |
||||
those countries, so that distribution is permitted only in or among |
||||
countries not thus excluded. In such case, this License incorporates |
||||
the limitation as if written in the body of this License. |
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions |
||||
of the General Public License from time to time. Such new versions will |
||||
be similar in spirit to the present version, but may differ in detail to |
||||
address new problems or concerns. |
||||
|
||||
Each version is given a distinguishing version number. If the Program |
||||
specifies a version number of this License which applies to it and "any |
||||
later version", you have the option of following the terms and conditions |
||||
either of that version or of any later version published by the Free |
||||
Software Foundation. If the Program does not specify a version number of |
||||
this License, you may choose any version ever published by the Free Software |
||||
Foundation. |
||||
|
||||
10. If you wish to incorporate parts of the Program into other free |
||||
programs whose distribution conditions are different, write to the author |
||||
to ask for permission. For software which is copyrighted by the Free |
||||
Software Foundation, write to the Free Software Foundation; we sometimes |
||||
make exceptions for this. Our decision will be guided by the two goals |
||||
of preserving the free status of all derivatives of our free software and |
||||
of promoting the sharing and reuse of software generally. |
||||
|
||||
NO WARRANTY |
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY |
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN |
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES |
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED |
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS |
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE |
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, |
||||
REPAIR OR CORRECTION. |
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING |
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR |
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, |
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING |
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED |
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY |
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER |
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE |
||||
POSSIBILITY OF SUCH DAMAGES. |
||||
|
||||
END OF TERMS AND CONDITIONS |
||||
|
||||
How to Apply These Terms to Your New Programs |
||||
|
||||
If you develop a new program, and you want it to be of the greatest |
||||
possible use to the public, the best way to achieve this is to make it |
||||
free software which everyone can redistribute and change under these terms. |
||||
|
||||
To do so, attach the following notices to the program. It is safest |
||||
to attach them to the start of each source file to most effectively |
||||
convey the exclusion of warranty; and each file should have at least |
||||
the "copyright" line and a pointer to where the full notice is found. |
||||
|
||||
{description} |
||||
Copyright (C) {year} {fullname} |
||||
|
||||
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. |
||||
|
||||
Also add information on how to contact you by electronic and paper mail. |
||||
|
||||
If the program is interactive, make it output a short notice like this |
||||
when it starts in an interactive mode: |
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author |
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. |
||||
This is free software, and you are welcome to redistribute it |
||||
under certain conditions; type `show c' for details. |
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate |
||||
parts of the General Public License. Of course, the commands you use may |
||||
be called something other than `show w' and `show c'; they could even be |
||||
mouse-clicks or menu items--whatever suits your program. |
||||
|
||||
You should also get your employer (if you work as a programmer) or your |
||||
school, if any, to sign a "copyright disclaimer" for the program, if |
||||
necessary. Here is a sample; alter the names: |
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program |
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker. |
||||
|
||||
{signature of Ty Coon}, 1 April 1989 |
||||
Ty Coon, President of Vice |
||||
|
||||
This General Public License does not permit incorporating your program into |
||||
proprietary programs. If your program is a subroutine library, you may |
||||
consider it more useful to permit linking proprietary applications with the |
||||
library. If this is what you want to do, use the GNU Lesser General |
||||
Public License instead of this License. |
@ -0,0 +1,69 @@
|
||||
# Who? |
||||
_huh_ was dreamt up by [secret pizza party](https://secretpizza.party) and brought to life by the amazing [Dan Hauk](https://danhauk.com/). Seriously, Dan is the best. He took a broad idea and really brought it to life like only he could. The SPP offices are open on Christmas Day but we close on May 5th (Dan's birthday) as it's a company wide holiday. |
||||
|
||||
# What? |
||||
_huh_ is the best way to offer in dashboard documentation for all your WordPress projects. The content is generated from a markdown file which makes it super quick & easy to update your documentation whenever you want. You can learn more from the launch post [here](https://secretpizza.party/huh-making-documentation-easier/). |
||||
|
||||
# Where? |
||||
We think _huh_ is awesome and we really want you to use it in all your projects. It's totally free/open source and you can find it on [github](https://github.com/secretpizzaparty/huh/). |
||||
|
||||
## Wanna Contribute? |
||||
If you found a bug, [report it here](https://github.com/secretpizzaparty/huh/issues/new). If you're a developer, we welcome pull requests of all types! |
||||
|
||||
### Development Workflow |
||||
1. Make sure you have `git`, `node`, and `npm` installed and a working WordPress installation. |
||||
2. Clone this repository inside your theme directory. |
||||
|
||||
``` |
||||
$ git clone https://github.com/secretpizzaparty/huh.git |
||||
$ cd huh |
||||
``` |
||||
|
||||
3. Watch the front-end CSS/Sass for changes and rebuild accordingly with [Grunt](https://github.com/gruntjs/grunt). Please only modify the Sass files to keep the CSS consistent and clean. |
||||
|
||||
``` |
||||
$ npm install |
||||
$ grunt watch |
||||
``` |
||||
|
||||
4. Open `/wp-admin/` in your browser. |
||||
5. Have fun! |
||||
|
||||
|
||||
# Why? |
||||
[secret pizza party](https://secretpizza.party) is in the process of developing a bunch of new WordPress themes and while they are quite simple there is still a need for a wee bit of documentation. External documentation is dumb and everything should be contained in the dashboard. We created _huh_ to make that happen. |
||||
|
||||
# How? |
||||
Adding _huh_ to your theme is incredibly easy. |
||||
|
||||
## Formatting your markdown |
||||
_huh_ pulls all of your `<h1>` tags to use as a table of contents. Each section of your documentation will be contained between these `<h1>` tags. For example: |
||||
|
||||
``` |
||||
# First section |
||||
The content of the first section of your documentation would go here. You can include links, bullets, images, anything! |
||||
|
||||
# Second section |
||||
This would be the next section. |
||||
|
||||
## You can even use subheadings |
||||
It will all be formatted correctly, but only the first-level headings will show on the table of contents. |
||||
``` |
||||
|
||||
## Adding _huh_ to your theme |
||||
Once you have your documentation formatted correctly, adding _huh_ to your theme is simple. |
||||
|
||||
Just download the zipped plugin and extract it to your theme directory. At the bottom of your theme's `functions.php` file add the following lines: |
||||
|
||||
``` php |
||||
require get_stylesheet_directory() . '/huh/huh.php'; |
||||
function secretpizzaparty_huh() { |
||||
// Enter the URL of your markdown file below |
||||
$markdown_url = 'https://raw.githubusercontent.com/secretpizzaparty/huh/master/README.md'; |
||||
$huh = new WP_Huh(); |
||||
$huh->init( $markdown_url ); |
||||
} |
||||
add_action( 'admin_init', 'secretpizzaparty_huh' ); |
||||
``` |
||||
|
||||
Make sure you change the URL of the `$markdown_url` variable to point to your markdown file. It's that easy! |
@ -0,0 +1,262 @@
|
||||
@keyframes popIn { |
||||
0% { |
||||
opacity: 0; |
||||
transform: scale(0); } |
||||
55% { |
||||
opacity: 0; |
||||
transform: scale(0); } |
||||
75% { |
||||
opacity: 1; |
||||
transform: scale(1.1); } |
||||
90% { |
||||
opacity: 1; |
||||
transform: scale(0.9); } |
||||
100% { |
||||
opacity: 1; |
||||
transform: scale(1); } } |
||||
@keyframes sonarEffect { |
||||
0% { |
||||
opacity: 1; } |
||||
40% { |
||||
opacity: 0.5; |
||||
box-shadow: 0 0 4px 2px rgba(0, 0, 0, 0.2); } |
||||
100% { |
||||
box-shadow: 0 0 4px 2px rgba(0, 0, 0, 0.2); |
||||
transform: scale(1.5); |
||||
opacity: 0; } } |
||||
@keyframes fadeIn { |
||||
0% { |
||||
opacity: 0; |
||||
transform: translateY(20px); } |
||||
100% { |
||||
opacity: 1; |
||||
transform: translateY(0); } } |
||||
.huh-launcher { |
||||
animation: popIn 0.8s ease-in-out; |
||||
bottom: 30px; |
||||
position: fixed; |
||||
right: 20px; |
||||
z-index: 500001; } |
||||
|
||||
.huh-launcher--button { |
||||
-webkit-appearance: none; |
||||
background: #009688; |
||||
border: none; |
||||
border-radius: 50px; |
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); |
||||
box-sizing: border-box; |
||||
cursor: pointer; |
||||
height: 50px; |
||||
padding: 0; |
||||
position: relative; |
||||
transition: transform ease-out 0.1s; |
||||
width: 50px; |
||||
z-index: 1; } |
||||
.huh-launcher--button svg { |
||||
fill: #fff; |
||||
float: right; |
||||
height: 50px; |
||||
left: 0; |
||||
position: absolute; |
||||
top: 0; |
||||
transition: transform 0.2s; |
||||
width: 50px; } |
||||
.huh-launcher--button .huh-launcher--icon-close { |
||||
height: 30px; |
||||
opacity: 0; |
||||
padding: 10px; |
||||
transform: scale(0.2); |
||||
width: 30px; } |
||||
.huh-launcher--button.active .huh-launcher--icon-enable { |
||||
opacity: 0; |
||||
transform: scale(0.2); } |
||||
.huh-launcher--button.active .huh-launcher--icon-close { |
||||
opacity: 1; |
||||
transform: scale(1); } |
||||
.huh-launcher--button::after, .huh-launcher--button::before { |
||||
border-radius: 50%; |
||||
box-sizing: content-box; |
||||
content: ''; |
||||
left: 0; |
||||
height: 100%; |
||||
pointer-events: none; |
||||
position: absolute; |
||||
top: 0; |
||||
transform: scale(0.9); |
||||
width: 100%; } |
||||
.huh-launcher--button:hover, .huh-launcher--button:focus { |
||||
outline: none; |
||||
transform: scale(0.9); } |
||||
.huh-launcher--button:hover::after, .huh-launcher--button:focus::after { |
||||
animation: sonarEffect 1.3s ease-out; } |
||||
|
||||
.huh-launcher--label { |
||||
display: block; |
||||
font-size: 0; |
||||
height: 0; |
||||
width: 0; } |
||||
|
||||
.huh-container { |
||||
background: #fff; |
||||
border-radius: 4px; |
||||
bottom: 90px; |
||||
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.15); |
||||
display: none; |
||||
height: calc( 100% - 150px ); |
||||
max-height: 550px; |
||||
max-width: 350px; |
||||
position: fixed; |
||||
right: 20px; |
||||
width: 100%; |
||||
z-index: 500001; } |
||||
.huh-container.open { |
||||
animation: fadeIn 0.3s ease-in-out; |
||||
display: flex; |
||||
flex-direction: column; } |
||||
@media screen and (max-width: 600px) { |
||||
.huh-container { |
||||
bottom: 0; |
||||
border-radius: 0; |
||||
height: 100%; |
||||
max-width: none; |
||||
right: 0; |
||||
top: 46px; } } |
||||
|
||||
.huh-container--head { |
||||
background: #009688; |
||||
border-radius: 4px 4px 0 0; |
||||
height: 60px; |
||||
flex-shrink: 0; |
||||
overflow: hidden; |
||||
position: relative; |
||||
transition: background 0.3s; } |
||||
@media screen and (max-width: 600px) { |
||||
.huh-container--head { |
||||
border-radius: 0; } } |
||||
.huh-container--head.with-content { |
||||
background: #f5f5f5 !important; |
||||
border-bottom: 1px solid #ddd; } |
||||
.huh-container--head.with-content .huh-container--heading { |
||||
transform: translateX(-100%); } |
||||
.huh-container--head.with-content .huh-container--back { |
||||
transform: translateX(0); } |
||||
|
||||
.huh-container--heading, |
||||
.huh-container--back { |
||||
box-sizing: border-box; |
||||
font-size: 16px; |
||||
left: 0; |
||||
line-height: 60px; |
||||
margin: 0; |
||||
padding: 0 20px; |
||||
position: absolute; |
||||
top: 0; |
||||
transition: transform 0.2s; |
||||
width: 100%; } |
||||
|
||||
.huh-container--heading { |
||||
color: #fff; |
||||
font-weight: 400; |
||||
text-align: center; |
||||
transform: translateX(0); |
||||
width: 100%; } |
||||
@media all and (max-width: 600px) { |
||||
.huh-container--heading { |
||||
text-align: left; } } |
||||
|
||||
.huh-container--back { |
||||
text-decoration: none; |
||||
transform: translateX(100%); } |
||||
.huh-container--back > svg { |
||||
display: inline-block; |
||||
fill: #444; |
||||
height: 16px; |
||||
position: relative; |
||||
top: 2px; |
||||
width: 16px; } |
||||
|
||||
.huh-container--content { |
||||
overflow: scroll; |
||||
padding: 0 20px 20px; } |
||||
.huh-container--content::after { |
||||
background: -moz-linear-gradient(top, rgba(255, 255, 255, 0) 0%, #fff 55%, #fff 100%); |
||||
background: -webkit-linear-gradient(top, rgba(255, 255, 255, 0) 0%, #fff 55%, #fff 100%); |
||||
background: linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, #fff 55%, #fff 100%); |
||||
bottom: 0; |
||||
content: ''; |
||||
display: block; |
||||
height: 20px; |
||||
left: 0; |
||||
position: absolute; |
||||
width: 100%; } |
||||
.huh-container--content p, |
||||
.huh-container--content ul, |
||||
.huh-container--content ol { |
||||
font-size: 14px; } |
||||
.huh-container--content img { |
||||
max-width: 100%; } |
||||
.huh-container--content code, |
||||
.huh-container--content pre { |
||||
max-width: 100%; |
||||
overflow: scroll; |
||||
white-space: pre-wrap; |
||||
word-wrap: break-word; } |
||||
|
||||
.huh-container--close-mobile { |
||||
cursor: pointer; |
||||
display: none; |
||||
fill: #fff; |
||||
height: 24px; |
||||
padding: 17px 10px; |
||||
position: absolute; |
||||
right: 0; |
||||
top: 0; |
||||
width: 24px; } |
||||
@media all and (max-width: 600px) { |
||||
.huh-container--close-mobile { |
||||
display: block; } } |
||||
|
||||
.huh-toc--trigger { |
||||
border-bottom: 1px solid #eee; |
||||
cursor: pointer; |
||||
display: block; |
||||
font-size: 16px; |
||||
font-weight: 600; |
||||
margin: 0 -20px; |
||||
padding: 20px; |
||||
position: relative; |
||||
transition: background 0.3s, box-shadow 0.1s; } |
||||
.huh-toc--trigger > span { |
||||
color: #666; |
||||
float: right; |
||||
opacity: 0; |
||||
transform: translateX(10px); |
||||
transition: opacity 0.3s, transform 0.3s; } |
||||
.huh-toc--trigger:hover { |
||||
background: #f9f9f9; } |
||||
.huh-toc--trigger:hover > span { |
||||
opacity: 1; |
||||
transform: translateX(0); } |
||||
.huh-toc--trigger.hidden { |
||||
display: none; } |
||||
.huh-toc--trigger.current { |
||||
animation: fadeIn 0.3s ease-in-out; |
||||
border: 0; |
||||
color: #222; |
||||
cursor: auto; |
||||
display: block; |
||||
font-size: 18px; |
||||
padding-bottom: 0; } |
||||
.huh-toc--trigger.current > span { |
||||
display: none; } |
||||
.huh-toc--trigger.current:hover { |
||||
background: 0; |
||||
box-shadow: none; } |
||||
.huh-toc--trigger.show { |
||||
animation: fadeIn 0.3s ease-in-out; } |
||||
|
||||
.huh-toc--content { |
||||
display: none; } |
||||
.huh-toc--content.open { |
||||
animation: fadeIn 0.3s ease-in-out; |
||||
display: block; } |
@ -0,0 +1 @@
|
||||
@keyframes popIn{0%,55%{opacity:0;transform:scale(0)}75%{opacity:1;transform:scale(1.1)}90%{opacity:1;transform:scale(.9)}100%{opacity:1;transform:scale(1)}}@keyframes sonarEffect{0%{opacity:1}40%{opacity:.5;box-shadow:0 0 4px 2px rgba(0,0,0,.2)}100%{box-shadow:0 0 4px 2px rgba(0,0,0,.2);transform:scale(1.5);opacity:0}}@keyframes fadeIn{0%{opacity:0;transform:translateY(20px)}100%{opacity:1;transform:translateY(0)}}.huh-launcher{animation:popIn .8s ease-in-out;bottom:30px;position:fixed;right:20px;z-index:500001}.huh-launcher--button{-webkit-appearance:none;background:#009688;border:none;border-radius:50px;box-shadow:0 2px 10px rgba(0,0,0,.2);box-sizing:border-box;cursor:pointer;height:50px;padding:0;position:relative;transition:transform ease-out .1s;width:50px;z-index:1}.huh-launcher--button svg{fill:#fff;float:right;height:50px;left:0;position:absolute;top:0;transition:transform .2s;width:50px}.huh-launcher--button .huh-launcher--icon-close{height:30px;opacity:0;padding:10px;transform:scale(.2);width:30px}.huh-launcher--button.active .huh-launcher--icon-enable{opacity:0;transform:scale(.2)}.huh-launcher--button.active .huh-launcher--icon-close{opacity:1;transform:scale(1)}.huh-launcher--button::after,.huh-launcher--button::before{border-radius:50%;box-sizing:content-box;content:'';left:0;height:100%;pointer-events:none;position:absolute;top:0;transform:scale(.9);width:100%}.huh-launcher--button:focus,.huh-launcher--button:hover{outline:0;transform:scale(.9)}.huh-launcher--button:focus::after,.huh-launcher--button:hover::after{animation:sonarEffect 1.3s ease-out}.huh-container.open,.huh-toc--content.open,.huh-toc--trigger.current,.huh-toc--trigger.show{animation:fadeIn .3s ease-in-out}.huh-launcher--label{display:block;font-size:0;height:0;width:0}.huh-container{background:#fff;border-radius:4px;bottom:90px;box-shadow:0 5px 20px rgba(0,0,0,.15);display:none;height:calc(100% - 150px);max-height:550px;max-width:350px;position:fixed;right:20px;width:100%;z-index:500001}.huh-container.open{display:flex;flex-direction:column}@media screen and (max-width:600px){.huh-container{bottom:0;border-radius:0;height:100%;max-width:none;right:0;top:46px}}.huh-container--head{background:#009688;border-radius:4px 4px 0 0;height:60px;flex-shrink:0;overflow:hidden;position:relative;transition:background .3s}@media screen and (max-width:600px){.huh-container--head{border-radius:0}}.huh-container--head.with-content{background:#f5f5f5!important;border-bottom:1px solid #ddd}.huh-container--head.with-content .huh-container--heading{transform:translateX(-100%)}.huh-container--head.with-content .huh-container--back,.huh-container--heading{transform:translateX(0)}.huh-container--back,.huh-container--heading{box-sizing:border-box;font-size:16px;left:0;line-height:60px;margin:0;padding:0 20px;position:absolute;top:0;transition:transform .2s;width:100%}.huh-container--heading{color:#fff;font-weight:400;text-align:center;width:100%}.huh-container--back{text-decoration:none;transform:translateX(100%)}.huh-container--back>svg{display:inline-block;fill:#444;height:16px;position:relative;top:2px;width:16px}.huh-container--content{overflow:scroll;padding:0 20px 20px}.huh-container--content::after{background:-moz-linear-gradient(top,rgba(255,255,255,0) 0,#fff 55%,#fff 100%);background:-webkit-linear-gradient(top,rgba(255,255,255,0) 0,#fff 55%,#fff 100%);background:linear-gradient(to bottom,rgba(255,255,255,0) 0,#fff 55%,#fff 100%);bottom:0;content:'';display:block;height:20px;left:0;position:absolute;width:100%}.huh-container--content ol,.huh-container--content p,.huh-container--content ul{font-size:14px}.huh-container--content img{max-width:100%}.huh-container--content code,.huh-container--content pre{max-width:100%;overflow:scroll;white-space:pre-wrap;word-wrap:break-word}.huh-container--close-mobile{cursor:pointer;display:none;fill:#fff;height:24px;padding:17px 10px;position:absolute;right:0;top:0;width:24px}@media all and (max-width:600px){.huh-container--heading{text-align:left}.huh-container--close-mobile{display:block}}.huh-toc--trigger{border-bottom:1px solid #eee;cursor:pointer;display:block;font-size:16px;font-weight:600;margin:0 -20px;padding:20px;position:relative;transition:background .3s,box-shadow .1s}.huh-toc--trigger>span{color:#666;float:right;opacity:0;transform:translateX(10px);transition:opacity .3s,transform .3s}.huh-toc--trigger:hover{background:#f9f9f9}.huh-toc--trigger:hover>span{opacity:1;transform:translateX(0)}.huh-toc--trigger.hidden{display:none}.huh-toc--trigger.current{border:0;color:#222;cursor:auto;display:block;font-size:18px;padding-bottom:0}.huh-toc--content,.huh-toc--trigger.current>span{display:none}.huh-toc--trigger.current:hover{background:0;box-shadow:none}.huh-toc--content.open{display:block} |
@ -0,0 +1,88 @@
|
||||
<?php |
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) { |
||||
exit; |
||||
} |
||||
|
||||
/** |
||||
* Main huh class. |
||||
*/ |
||||
class WP_Huh { |
||||
public $markdown_doc_url = null; |
||||
|
||||
/** |
||||
* Constructor. |
||||
*/ |
||||
public function __construct() {} |
||||
|
||||
/** |
||||
* Initialize. |
||||
* @param string $markdown_doc_url URL of the raw markdown file. |
||||
*/ |
||||
public function init( $markdown_doc_url ) { |
||||
$this->markdown_doc_url = $markdown_doc_url; |
||||
|
||||
if ( is_admin() || is_customize_preview() ) { |
||||
add_action( 'admin_enqueue_scripts', array( $this, 'huh_load_scripts' ) ); |
||||
add_action( 'admin_footer', array( $this, 'display_huh' ) ); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Enqueue CSS and JS. |
||||
*/ |
||||
public function huh_load_scripts() { |
||||
wp_register_style( 'huh_admin_css', get_theme_file_uri().'/lib/huh/huh.css', false ); |
||||
wp_enqueue_style( 'huh_admin_css' ); |
||||
|
||||
wp_register_script( 'huh_admin_js', get_theme_file_uri().'/lib/huh/js/huh.js', false ); |
||||
wp_enqueue_script( 'huh_admin_js' ); |
||||
|
||||
wp_register_script( 'huh_markdown_js', get_theme_file_uri().'/lib/huh/js/marked.js', false ); |
||||
wp_enqueue_script( 'huh_markdown_js' ); |
||||
} |
||||
|
||||
/** |
||||
* Get admin color scheme. |
||||
*/ |
||||
public function huh_get_admin_colors() { |
||||
global $_wp_admin_css_colors; |
||||
$current_color_scheme = get_user_meta( get_current_user_id(), 'admin_color', true ); |
||||
$colors = $_wp_admin_css_colors[ $current_color_scheme ]->colors; |
||||
|
||||
return $colors; |
||||
} |
||||
|
||||
/** |
||||
* Display the HTML. |
||||
* @param $markdown_doc_url URL of the raw markdown file. |
||||
*/ |
||||
public function display_huh() { |
||||
$colors = $this->huh_get_admin_colors(); |
||||
$huh_accent_color = $colors[1]; |
||||
|
||||
?> |
||||
<script type="text/javascript">var huhDocUrl = <?php echo json_encode( $this->markdown_doc_url ); ?>;</script>
|
||||
<div class="huh-launcher"> |
||||
<button class="huh-launcher--button" id="huh-launcher--button" data-accent-color="<?php echo esc_attr( $huh_accent_color ); ?>">
|
||||
<svg class="huh-launcher--icon-enable" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" viewBox="0 0 100 100" style="enable-background:new 0 0 100 100;" xml:space="preserve"><g><circle cx="50" cy="63.5" r="3"></circle><g><path d="M88.6,50c0-21.3-17.3-38.6-38.6-38.6S11.4,28.7,11.4,50S28.7,88.6,50,88.6S88.6,71.3,88.6,50z M15.6,50 c0-18.9,15.4-34.4,34.4-34.4S84.4,31.1,84.4,50S68.9,84.4,50,84.4S15.6,68.9,15.6,50z"></path><path d="M55.8,42.1c0.1,2.5-1.4,4.8-3.7,5.7c-2.6,1-4.3,3.6-4.3,6.5v1.4h4.2v-1.4c0-1.1,0.7-2.2,1.6-2.6c4-1.6,6.5-5.5,6.3-9.8 c-0.2-5.1-4.5-9.4-9.6-9.6C47.7,32.1,45,33.1,43,35c-2,1.9-3.1,4.5-3.1,7.3h4.2c0-1.6,0.6-3.1,1.8-4.2c1.2-1.1,2.7-1.7,4.3-1.6 C53.3,36.6,55.7,39.1,55.8,42.1z"></path></g></g></svg> |
||||
<svg class="huh-launcher--icon-close" xmlns="https://www.w3.org/2000/svg" viewBox="0 0 24 24"><g id="plus"><path d="M18.36,19.78L12,13.41,5.64,19.78,4.22,18.36,10.59,12,4.22,5.64,5.64,4.22,12,10.59l6.36-6.36,1.41,1.41L13.41,12l6.36,6.36Z"/></g></svg> |
||||
<span class="huh-launcher--label">Need help?</span> |
||||
</button> |
||||
</div> |
||||
|
||||
<div class="huh-container" id="huh-container"> |
||||
<div class="huh-container--head" id="huh-header"> |
||||
<h4 class="huh-container--heading">Need help?</h4> |
||||
<a href="javascript:;" class="huh-container--back" id="huh-back-to-toc"> |
||||
<svg xmlns="https://www.w3.org/2000/svg" viewBox="0 0 24 24"><rect x="0" fill="none" width="24" height="24"/><g><path d="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z"/></g></svg> |
||||
Back |
||||
</a> |
||||
<svg class="huh-container--close-mobile" id="huh-mobile-close" xmlns="https://www.w3.org/2000/svg" viewBox="0 0 24 24"><g id="plus"><path d="M18.36,19.78L12,13.41,5.64,19.78,4.22,18.36,10.59,12,4.22,5.64,5.64,4.22,12,10.59l6.36-6.36,1.41,1.41L13.41,12l6.36,6.36Z"/></g></svg> |
||||
</div> |
||||
<div class="huh-container--content" id="huh-content"></div> |
||||
</div> |
||||
<?php |
||||
} |
||||
|
||||
} |
@ -0,0 +1,139 @@
|
||||
// const docUrl = 'https://raw.githubusercontent.com/secretpizzaparty/huh/master/README.md';
|
||||
|
||||
let huhLauncher = '', |
||||
huhMobileClose = '', |
||||
huhContainer = '', |
||||
huhContent = '', |
||||
huhHeader = '', |
||||
huhBackButton = '', |
||||
huhAccentColor = '', |
||||
huhTocTriggers = ''; |
||||
|
||||
// init
|
||||
function huhInit() { |
||||
huhLauncher = document.querySelector( '#huh-launcher--button' ); |
||||
huhMobileClose = document.querySelector( '#huh-mobile-close' ); |
||||
huhContainer = document.querySelector( '#huh-container' ); |
||||
huhContent = document.querySelector( '#huh-content' ); |
||||
huhHeader = document.querySelector( '#huh-header'); |
||||
huhBackButton = document.querySelector( '#huh-back-to-toc' ); |
||||
huhAccentColor = huhLauncher.getAttribute( 'data-accent-color' ); |
||||
|
||||
// fetch the markdown file (set in huh.php)
|
||||
// then load the content into the container
|
||||
fetch( huhDocUrl ) |
||||
.then( blob => blob.text() ) |
||||
.then( data => loadContent( data ) ); |
||||
} |
||||
|
||||
function loadContent( data ) { |
||||
// first we format the content
|
||||
const dataFormat = marked( data ); |
||||
|
||||
// then we create our custom content structure
|
||||
const content = createContent( dataFormat ); |
||||
|
||||
// then we insert content into the content box
|
||||
huhContent.innerHTML = content; |
||||
|
||||
// apply accent color
|
||||
applyAccentColor( huhAccentColor ); |
||||
|
||||
// bind interaction events after all content is loaded
|
||||
huhBindEvents(); |
||||
} |
||||
|
||||
function createContent( data ) { |
||||
let sections = data.split( '<h1' ); // split at h1
|
||||
sections = sections.filter( ( n ) => { return n != '' } ); // remove empty elements
|
||||
|
||||
const content = sections.map( section => { |
||||
const splitIndex = section.indexOf( '</h1>' ); // split into two blocks after <h1>
|
||||
const headingSplit = section.slice( 0, splitIndex ); |
||||
const heading = headingSplit.slice( headingSplit.indexOf( '>' ) + 1 ); // content after `id="*">``
|
||||
const body = section.slice( splitIndex + 5 ); // content after closing `</h1>`
|
||||
|
||||
return { |
||||
heading: heading, |
||||
body: body |
||||
}; |
||||
} ); |
||||
|
||||
const contentHtml = formatContent( content ); |
||||
|
||||
return contentHtml; |
||||
} |
||||
|
||||
function formatContent( content ) { |
||||
const html = content.map( item => { |
||||
return ` |
||||
<a class="huh-toc--trigger">${ item.heading }<span>→</span></a> |
||||
<div class="huh-toc--content"> |
||||
${ item.body } |
||||
</div> |
||||
`;
|
||||
} ).join( '' ); |
||||
|
||||
return html; |
||||
} |
||||
|
||||
function showHideContainer( e ) { |
||||
huhLauncher.classList.toggle( 'active' ); |
||||
huhContainer.classList.toggle( 'open' ); |
||||
} |
||||
|
||||
function showContent( e ) { |
||||
// hide all triggers
|
||||
for ( i = 0; i < huhTocTriggers.length; i++ ) { |
||||
huhTocTriggers[i].classList.add( 'hidden' ); |
||||
huhTocTriggers[i].classList.remove( 'show' ); |
||||
} |
||||
|
||||
// add a class to indicate current selection
|
||||
e.target.classList.add( 'current' ); |
||||
|
||||
// add a class to content block of the current selection
|
||||
// so we can show just that one
|
||||
const content = e.target.nextElementSibling; |
||||
content.classList.add( 'open' ); |
||||
|
||||
// show back button
|
||||
huhHeader.classList.add( 'with-content' ); |
||||
} |
||||
|
||||
function backToToc() { |
||||
// show all triggers
|
||||
for ( i = 0; i < huhTocTriggers.length; i++ ) { |
||||
huhTocTriggers[i].classList.remove( 'hidden', 'current' ); |
||||
huhTocTriggers[i].classList.add( 'show' ); |
||||
} |
||||
|
||||
// hide all content blocks
|
||||
const contentBlocks = document.querySelectorAll( '.huh-toc--content' ); |
||||
for ( i = 0; i < contentBlocks.length; i++ ) { |
||||
contentBlocks[i].classList.remove( 'open' ); |
||||
} |
||||
|
||||
// show main header
|
||||
huhHeader.classList.remove( 'with-content' ); |
||||
} |
||||
|
||||
function applyAccentColor( color ) { |
||||
huhLauncher.setAttribute( 'style', 'background:' + color ); |
||||
huhHeader.setAttribute( 'style', 'background:' + color ); |
||||
} |
||||
|
||||
function huhBindEvents() { |
||||
huhLauncher.addEventListener( 'click', showHideContainer ); |
||||
huhMobileClose.addEventListener( 'click', showHideContainer ); |
||||
huhBackButton.addEventListener( 'click', backToToc ); |
||||
|
||||
huhTocTriggers = document.querySelectorAll( '.huh-toc--trigger' ); |
||||
for ( i = 0; i < huhTocTriggers.length; i++ ) { |
||||
huhTocTriggers[i].addEventListener( 'click', showContent ); |
||||
} |
||||
} |
||||
|
||||
// init after page has loaded to make sure
|
||||
// we can find the DOM nodes to modify
|
||||
window.addEventListener( 'load', huhInit ); |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,25 @@
|
||||
{ |
||||
"name": "huh", |
||||
"title": "huh", |
||||
"version": "1.0.0", |
||||
"repository": { |
||||
"type": "git", |
||||
"url": "https://github.com/secretpizzaparty/huh" |
||||
}, |
||||
"license": "GPL-2.0+", |
||||
"main": "Gruntfile.js", |
||||
"devDependencies": { |
||||
"grunt": "~1.0.1", |
||||
"grunt-checktextdomain": "~1.0.0", |
||||
"grunt-contrib-clean": "~1.0.0", |
||||
"grunt-contrib-cssmin": "~1.0.0", |
||||
"grunt-contrib-sass": "~1.0.0", |
||||
"grunt-contrib-watch": "~1.0.0", |
||||
"grunt-wp-i18n": "~0.5.4", |
||||
"node-bourbon": "~4.2.3" |
||||
}, |
||||
"engines": { |
||||
"node": ">=0.8.0", |
||||
"npm": ">=1.1.0" |
||||
} |
||||
} |
@ -0,0 +1,51 @@
|
||||
// huh animations |
||||
|
||||
@keyframes popIn { |
||||
0% { |
||||
opacity: 0; |
||||
transform: scale( 0 ); |
||||
} |
||||
55% { |
||||
opacity: 0; |
||||
transform: scale( 0 ); |
||||
} |
||||
75% { |
||||
opacity: 1; |
||||
transform: scale( 1.1 ); |
||||
} |
||||
90% { |
||||
opacity: 1; |
||||
transform: scale( 0.9 ); |
||||
} |
||||
100% { |
||||
opacity: 1; |
||||
transform: scale( 1 ); |
||||
} |
||||
} |
||||
|
||||
@keyframes sonarEffect { |
||||
0% { |
||||
opacity: 1; |
||||
} |
||||
40% { |
||||
opacity: 0.5; |
||||
box-shadow: 0 0 4px 2px rgba( 0, 0, 0 , 0.2 ); |
||||
} |
||||
100% { |
||||
box-shadow: 0 0 4px 2px rgba( 0, 0, 0 , 0.2 ); |
||||
transform: scale(1.5); |
||||
opacity: 0; |
||||
} |
||||
} |
||||
|
||||
@keyframes fadeIn { |
||||
0% { |
||||
opacity: 0; |
||||
transform: translateY( 20px ); |
||||
} |
||||
|
||||
100% { |
||||
opacity: 1; |
||||
transform: translateY( 0 ); |
||||
} |
||||
} |
@ -0,0 +1,214 @@
|
||||
// huh content container |
||||
.huh-container { |
||||
background: #fff; |
||||
border-radius: 4px; |
||||
bottom: 90px; |
||||
box-shadow: 0 5px 20px rgba( 0, 0, 0, 0.15 ); |
||||
display: none; |
||||
@include calc( 'height', '100% - 150px' ); |
||||
max-height: 550px; |
||||
max-width: 350px; |
||||
position: fixed; |
||||
right: 20px; |
||||
width: 100%; |
||||
z-index: 500001; |
||||
|
||||
&.open { |
||||
animation: fadeIn 0.3s ease-in-out; |
||||
display: flex; |
||||
flex-direction: column; |
||||
} |
||||
|
||||
@media screen and ( max-width: 600px ) { |
||||
bottom: 0; |
||||
border-radius: 0; |
||||
height: 100%; |
||||
max-width: none; |
||||
right: 0; |
||||
top: 46px; |
||||
} |
||||
} |
||||
|
||||
.huh-container--head { |
||||
background: $main-accent; |
||||
border-radius: 4px 4px 0 0; |
||||
height: 60px; |
||||
flex-shrink: 0; |
||||
overflow: hidden; |
||||
position: relative; |
||||
transition: background 0.3s; |
||||
|
||||
@media screen and ( max-width: 600px ) { |
||||
border-radius: 0; |
||||
} |
||||
|
||||
&.with-content { |
||||
background: #f5f5f5 !important; |
||||
border-bottom: 1px solid #ddd; |
||||
|
||||
.huh-container--heading { |
||||
transform: translateX( -100% ); |
||||
} |
||||
|
||||
.huh-container--back { |
||||
transform: translateX( 0 ); |
||||
} |
||||
} |
||||
} |
||||
|
||||
.huh-container--heading, |
||||
.huh-container--back { |
||||
box-sizing: border-box; |
||||
font-size: 16px; |
||||
left: 0; |
||||
line-height: 60px; |
||||
margin: 0; |
||||
padding: 0 20px; |
||||
position: absolute; |
||||
top: 0; |
||||
transition: transform 0.2s; |
||||
width: 100%; |
||||
} |
||||
|
||||
.huh-container--heading { |
||||
color: #fff; |
||||
font-weight: 400; |
||||
text-align: center; |
||||
transform: translateX( 0 ); |
||||
width: 100%; |
||||
|
||||
@media all and ( max-width: 600px ) { |
||||
text-align: left; |
||||
} |
||||
} |
||||
|
||||
.huh-container--back { |
||||
text-decoration: none; |
||||
transform: translateX( 100% ); |
||||
|
||||
> svg { |
||||
display: inline-block; |
||||
fill: #444; |
||||
height: 16px; |
||||
position: relative; |
||||
top: 2px; |
||||
width: 16px; |
||||
} |
||||
} |
||||
|
||||
.huh-container--content { |
||||
overflow: scroll; |
||||
padding: 0 20px 20px; |
||||
|
||||
&::after { |
||||
background: -moz-linear-gradient(top, rgba( #fff, 0 ) 0%, #fff 55%, #fff 100%); |
||||
background: -webkit-linear-gradient(top, rgba( #fff, 0 ) 0%, #fff 55%, #fff 100%); |
||||
background: linear-gradient(to bottom, rgba( #fff, 0 ) 0%, #fff 55%, #fff 100%); |
||||
bottom: 0; |
||||
content: ''; |
||||
display: block; |
||||
height: 20px; |
||||
left: 0; |
||||
position: absolute; |
||||
width: 100%; |
||||
} |
||||
|
||||
p, |
||||
ul, |
||||
ol { |
||||
font-size: 14px; |
||||
} |
||||
|
||||
img { |
||||
max-width: 100%; |
||||
} |
||||
|
||||
code, |
||||
pre { |
||||
max-width: 100%; |
||||
overflow: scroll; |
||||
white-space: pre-wrap; |
||||
word-wrap: break-word; |
||||
} |
||||
} |
||||
|
||||
.huh-container--close-mobile { |
||||
cursor: pointer; |
||||
display: none; |
||||
fill: #fff; |
||||
height: 24px; |
||||
padding: 17px 10px; |
||||
position: absolute; |
||||
right: 0; |
||||
top: 0; |
||||
width: 24px; |
||||
|
||||
@media all and ( max-width: 600px ) { |
||||
display: block; |
||||
} |
||||
} |
||||
|
||||
.huh-toc--trigger { |
||||
border-bottom: 1px solid #eee; |
||||
cursor: pointer; |
||||
display: block; |
||||
font-size: 16px; |
||||
font-weight: 600; |
||||
margin: 0 -20px; |
||||
padding: 20px; |
||||
position: relative; |
||||
transition: background 0.3s, box-shadow 0.1s; |
||||
|
||||
> span { |
||||
color: #666; |
||||
float: right; |
||||
opacity: 0; |
||||
transform: translateX( 10px ); |
||||
transition: opacity 0.3s, transform 0.3s; |
||||
} |
||||
|
||||
&:hover { |
||||
background: #f9f9f9; |
||||
|
||||
> span { |
||||
opacity: 1; |
||||
transform: translateX( 0 ); |
||||
} |
||||
} |
||||
|
||||
&.hidden { |
||||
display: none; |
||||
} |
||||
|
||||
&.current { |
||||
animation: fadeIn 0.3s ease-in-out; |
||||
border: 0; |
||||
color: #222; |
||||
cursor: auto; |
||||
display: block; |
||||
font-size: 18px; |
||||
padding-bottom: 0; |
||||
|
||||
> span { |
||||
display: none; |
||||
} |
||||
|
||||
&:hover { |
||||
background: 0; |
||||
box-shadow: none; |
||||
} |
||||
} |
||||
|
||||
&.show { |
||||
animation: fadeIn 0.3s ease-in-out; |
||||
} |
||||
} |
||||
|
||||
.huh-toc--content { |
||||
display: none; |
||||
|
||||
&.open { |
||||
animation: fadeIn 0.3s ease-in-out; |
||||
display: block; |
||||
} |
||||
} |
@ -0,0 +1,86 @@
|
||||
// huh launcher button |
||||
.huh-launcher { |
||||
animation: popIn 0.8s ease-in-out; |
||||
bottom: 30px; |
||||
position: fixed; |
||||
right: 20px; |
||||
z-index: 500001; |
||||
} |
||||
|
||||
.huh-launcher--button { |
||||
-webkit-appearance: none; |
||||
background: $main-accent; |
||||
border: none; |
||||
border-radius: 50px; |
||||
box-shadow: 0 2px 10px rgba( 0, 0, 0, 0.2 ); |
||||
box-sizing: border-box; |
||||
cursor: pointer; |
||||
height: 50px; |
||||
padding: 0; |
||||
position: relative; |
||||
transition: transform ease-out 0.1s; |
||||
width: 50px; |
||||
z-index: 1; |
||||
|
||||
svg { |
||||
fill: #fff; |
||||
float: right; |
||||
height: 50px; |
||||
left: 0; |
||||
position: absolute; |
||||
top: 0; |
||||
transition: transform 0.2s; |
||||
width: 50px; |
||||
} |
||||
|
||||
.huh-launcher--icon-close { |
||||
height: 30px; |
||||
opacity: 0; |
||||
padding: 10px; |
||||
transform: scale( 0.2 ); |
||||
width: 30px; |
||||
} |
||||
|
||||
&.active { |
||||
.huh-launcher--icon-enable { |
||||
opacity: 0; |
||||
transform: scale( 0.2 ); |
||||
} |
||||
|
||||
.huh-launcher--icon-close { |
||||
opacity: 1; |
||||
transform: scale( 1); |
||||
} |
||||
} |
||||
|
||||
&::after, |
||||
&::before { |
||||
border-radius: 50%; |
||||
box-sizing: content-box; |
||||
content: ''; |
||||
left: 0; |
||||
height: 100%; |
||||
pointer-events: none; |
||||
position: absolute; |
||||
top: 0; |
||||
transform: scale( 0.9 ); |
||||
width: 100%; |
||||
} |
||||
|
||||
&:hover, |
||||
&:focus { |
||||
outline: none; |
||||
transform: scale( 0.9 ); |
||||
|
||||
&::after { |
||||
animation: sonarEffect 1.3s ease-out; |
||||
} |
||||
} |
||||
} |
||||
|
||||
.huh-launcher--label { |
||||
display: block; |
||||
font-size: 0; |
||||
height: 0; |
||||
width: 0; |
||||
} |
@ -0,0 +1,4 @@
|
||||
// huh mixins |
||||
@mixin calc( $property, $expression ) { |
||||
#{$property}: calc( #{$expression} ); |
||||
} |
Loading…
Reference in new issue