1
0
mirror of https://github.com/squidfunk/mkdocs-material.git synced 2024-09-24 19:38:27 +02:00

Refactored sponsorship overview into component

This commit is contained in:
squidfunk 2021-03-13 15:53:37 +01:00
parent e9c5b53e0f
commit 5fbcef3564
22 changed files with 358 additions and 109 deletions

View File

@ -89,21 +89,19 @@ You can cancel your sponsorship anytime.[^3]
through Stripe. As we don't receive any information regarding your payment,
and GitHub doesn't offer refunds, sponsorships are non-refundable.
[:octicons-heart-fill-24:{ .mdx-heart } &nbsp; Join our <span class="mdx-insiders-count"></span> awesome sponsors][5]{ .md-button .md-button--primary .mdx-insiders-button }
[:octicons-heart-fill-24:{ .mdx-heart } &nbsp; Join our <span class="mdx-sponsorship-count" data-mdx-component="sponsorship-count"></span> awesome sponsors][5]{ .md-button .md-button--primary .mdx-sponsorship-button }
<div class="mdx-insiders-container" markdown="1" hidden>
<div class="mdx-insiders-list"></div>
_If you sponsor publicly, you're automatically added here with a link to
your profile and avatar to show your support for Material for MkDocs.
Alternatively, if you wish to keep your sponsorship private, you'll be a
silent +1. You can select visibility during checkout and change it
afterwards._
<div class="mdx-sponsorship" data-mdx-component="sponsorship" hidden>
<div class="mdx-sponsorship__list"></div>
<small>
If you sponsor publicly, you're automatically added here with a link to
your profile and avatar to show your support for Material for MkDocs.
Alternatively, if you wish to keep your sponsorship private, you'll be a
silent +1. You can select visibility during checkout and change it
afterwards.
</small>
</div>
<script>
fetch("https://gpiqp43wvb.execute-api.us-east-1.amazonaws.com/_/").then(function(e){return e.json()}).then(function(e){var t=document.querySelector(".mdx-insiders-list"),n=0;for(var o of e.sponsors)if("PUBLIC"===o.type){var s;(s=document.createElement("a")).href=o.url,s.title="@"+o.name,s.className="mdx-insiders-list__item",t.appendChild(s);var r=document.createElement("img");r.src=o.image,s.appendChild(r)}else n++;(s=document.createElement("a")).href="https://github.com/sponsors/squidfunk",s.title="[private]",s.innerText="+"+n,s.className="mdx-insiders-list__item mdx-insiders-list__item--private",t.appendChild(s),document.querySelector(".mdx-insiders-count").innerText=e.sponsors.length,document.querySelector(".mdx-insiders-container").removeAttribute("hidden"),document.querySelector('.mdx-insiders-total').innerText=" $ "+e.total.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,")}).catch(console.log);
</script>
[5]: https://github.com/sponsors/squidfunk
## Exclusive features
@ -133,7 +131,7 @@ from time to time to learn about what's new, or follow [@squidfunk on
[6]: https://twitter.com/squidfunk
## Funding<span class="mdx-insiders-total mdx-insiders-count"></span>
## Funding <span class="mdx-sponsorship-total" data-mdx-component="sponsorship-total"></span>
### Goals

View File

@ -28,5 +28,5 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
//# sourceMappingURL=bundle.9b55be7b.min.js.map
//# sourceMappingURL=bundle.1a39fc1d.min.js.map

View File

@ -217,7 +217,7 @@
</script>
{% endblock %}
{% block scripts %}
<script src="{{ 'assets/javascripts/bundle.9b55be7b.min.js' | url }}"></script>
<script src="{{ 'assets/javascripts/bundle.1a39fc1d.min.js' | url }}"></script>
{% for path in config["extra_javascript"] %}
<script src="{{ path | url }}"></script>
{% endfor %}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -22,7 +22,7 @@
<meta name="twitter:title" content="{{ title }}">
<meta name="twitter:description" content="{{ config.site_description }}">
<meta name="twitter:image" content="{{ image }}">
<link rel="stylesheet" href="{{ 'overrides/assets/stylesheets/main.6c7993e4.min.css' | url }}">
<link rel="stylesheet" href="{{ 'overrides/assets/stylesheets/main.0220c4ec.min.css' | url }}">
{% endblock %}
{% block announce %}
<a href="https://twitter.com/squidfunk">
@ -53,5 +53,5 @@
{% endblock %}
{% block scripts %}
{{ super() }}
<script src="{{ 'overrides/assets/javascripts/bundle.cf78cd63.min.js' | url }}"></script>
<script src="{{ 'overrides/assets/javascripts/bundle.55e80bbe.min.js' | url }}"></script>
{% endblock %}

View File

@ -259,7 +259,8 @@
{% endif %}
<div
class="md-sidebar md-sidebar--primary"
data-md-component="sidebar" data-md-type="navigation"
data-md-component="sidebar"
data-md-type="navigation"
{{ hidden }}
>
<div class="md-sidebar__scrollwrap">
@ -277,7 +278,8 @@
{% endif %}
<div
class="md-sidebar md-sidebar--secondary"
data-md-component="sidebar" data-md-type="toc"
data-md-component="sidebar"
data-md-type="toc"
{{ hidden }}
>
<div class="md-sidebar__scrollwrap">

View File

@ -25,7 +25,8 @@ import { switchMap } from "rxjs/operators"
import {
getComponentElements,
mountIconSearch
mountIconSearch,
mountSponsorship
} from "./components"
import { setupAnalytics } from "./integrations"
@ -43,7 +44,11 @@ document$
/* Icon search */
...getComponentElements("iconsearch")
.map(el => mountIconSearch(el))
.map(el => mountIconSearch(el)),
/* Sponsorship */
...getComponentElements("sponsorship")
.map(el => mountSponsorship(el))
))
)
.subscribe()

View File

@ -33,6 +33,9 @@ export type ComponentType =
| "iconsearch" /* Icon search */
| "iconsearch-query" /* Icon search input */
| "iconsearch-result" /* Icon search results */
| "sponsorship" /* Sponsorship */
| "sponsorship-count" /* Sponsorship count */
| "sponsorship-total" /* Sponsorship total */
/**
* A component
@ -59,6 +62,9 @@ interface ComponentTypeMap {
"iconsearch": HTMLElement /* Icon search */
"iconsearch-query": HTMLInputElement /* Icon search input */
"iconsearch-result": HTMLElement /* Icon search results */
"sponsorship": HTMLElement /* Sponsorship */
"sponsorship-count": HTMLElement /* Sponsorship count */
"sponsorship-total": HTMLElement /* Sponsorship total */
}
/* ----------------------------------------------------------------------------

View File

@ -22,3 +22,4 @@
export * from "./_"
export * from "./iconsearch"
export * from "./sponsorship"

View File

@ -0,0 +1,134 @@
/*
* Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com>
*
* 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 NON-INFRINGEMENT. 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.
*/
import { Observable } from "rxjs"
import { map } from "rxjs/operators"
import { getElementOrThrow, requestJSON } from "~/browser"
import { renderPrivateSponsor, renderPublicSponsor } from "_/templates"
import { Component, getComponentElement } from "../_"
/* ----------------------------------------------------------------------------
* Types
* ------------------------------------------------------------------------- */
/**
* Sponsor visibility
*/
export enum SponsorType {
PUBLIC = "PUBLIC", /* Public sponsorship */
PRIVATE = "PRIVATE" /* Private sponsorship */
}
/* ------------------------------------------------------------------------- */
/**
* Public sponsor
*/
export interface PublicSponsor {
type: SponsorType.PUBLIC /* Sponsor visibility */
name: string /* Sponsor login name */
image: string /* Sponsor image URL */
url: string /* Sponsor URL */
}
/**
* Private sponsor
*/
export interface PrivateSponsor {
type: SponsorType.PRIVATE /* Sponsor visibility */
}
/* ------------------------------------------------------------------------- */
/**
* Sponsor
*/
export type Sponsor =
| PublicSponsor
| PrivateSponsor
/* ------------------------------------------------------------------------- */
/**
* Sponsorship
*/
export interface Sponsorship {
sponsors: Sponsor[] /* Sponsors */
total: number /* Total amount */
}
/* ----------------------------------------------------------------------------
* Functions
* ------------------------------------------------------------------------- */
/**
* Mount sponsorship
*
* @param el - Sponsorship element
*
* @returns Sponsorship component observable
*/
export function mountSponsorship(
el: HTMLElement
): Observable<Component<Sponsorship>> {
const sponsorship$ = requestJSON<Sponsorship>(
"https://gpiqp43wvb.execute-api.us-east-1.amazonaws.com/_/"
)
/* Retrieve adjacent components */
const count = getComponentElement("sponsorship-count")
const total = getComponentElement("sponsorship-total")
/* Render sponsorship */
sponsorship$.subscribe(sponsorship => {
el.removeAttribute("hidden")
/* Render public sponsors with avatar and links */
const list = getElementOrThrow(":scope > :first-child", el)
for (const sponsor of sponsorship.sponsors)
if (sponsor.type === SponsorType.PUBLIC)
list.appendChild(renderPublicSponsor(sponsor))
/* Render combined private sponsors */
list.appendChild(renderPrivateSponsor(
sponsorship.sponsors.filter(({ type }) => (
type === SponsorType.PRIVATE
)).length
))
/* Render sponsorship count and total */
count.innerText = `${sponsorship.sponsors.length}`
total.innerText = `$ ${sponsorship.total
.toString()
.replace(/\B(?=(\d{3})+(?!\d))/g, ",")
}`
})
// /* Create and return component */
return sponsorship$
.pipe(
map(state => ({ ref: el, ...state }))
)
}

View File

@ -21,3 +21,4 @@
*/
export * from "./iconsearch"
export * from "./sponsorship"

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com>
*
* 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 NON-INFRINGEMENT. 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.
*/
import { h } from "~/utilities"
import { PublicSponsor } from "_/components"
/* ----------------------------------------------------------------------------
* Functions
* ------------------------------------------------------------------------- */
/**
* Render public sponsor
*
* @param sponsor - Public sponsor
*
* @returns Element
*/
export function renderPublicSponsor(
sponsor: PublicSponsor
): HTMLElement {
const title = `@${sponsor.name}`
return (
<a href={sponsor.url} title={title} class="mdx-sponsorship__item">
<img src={sponsor.image} />
</a>
)
}
/**
* Render private sponsor
*
* @param count - Number of private sponsors
*
* @returns Element
*/
export function renderPrivateSponsor(
count: number
): HTMLElement {
return (
<a
href="https://github.com/sponsors/squidfunk"
class="mdx-sponsorship__item mdx-sponsorship__item--private"
>
+{count}
</a>
)
}

View File

@ -42,5 +42,6 @@
@import "main/layout/content";
@import "main/layout/hero";
@import "main/layout/iconsearch";
@import "main/layout/sponsorship";
@import "main/shame";

View File

@ -90,67 +90,6 @@
color: $clr-pink-500;
}
// Insiders button
.mdx-insiders-button {
font-weight: 400;
}
// Insiders count
.mdx-insiders-count {
font-weight: 700;
}
// Insiders list
.mdx-insiders-list {
margin: 2em 0;
overflow: auto;
// Insiders list item
&__item {
display: block;
float: left;
width: px2rem(60px);
height: px2rem(60px);
margin: px2rem(4px);
overflow: hidden;
border-radius: 100%;
transform: scale(1);
transition:
color 125ms,
transform 125ms;
// Sponsor avatar
img {
display: block;
width: 100%;
height: auto;
filter: grayscale(100%);
transition: filter 125ms;
}
// Sponsor item on focus/hover
&:focus,
&:hover {
transform: scale(1.1);
// Sponsor avatar
img {
filter: grayscale(0%);
}
}
// Private sponsor
&--private {
color: var(--md-default-fg-color--lighter);
font-weight: 700;
font-size: px2rem(24px);
line-height: px2rem(60px);
text-align: center;
background: var(--md-default-fg-color--lightest);
}
}
}
// Switch buttons
.mdx-switch button {
cursor: pointer;

View File

@ -0,0 +1,95 @@
////
/// Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com>
///
/// 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 NON-INFRINGEMENT. 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
////
// ----------------------------------------------------------------------------
// Rules
// ----------------------------------------------------------------------------
// Scoped in typesetted content to match specificity of regular content
.md-typeset {
// Sponsorship
.mdx-sponsorship {
// Sponsorship list
&__list {
margin: 2em 0;
overflow: auto;
}
// Sponsorship item
&__item {
display: block;
float: left;
width: px2rem(60px);
height: px2rem(60px);
margin: px2rem(4px);
overflow: hidden;
border-radius: 100%;
transform: scale(1);
transition:
color 125ms,
transform 125ms;
// Sponsor item on focus/hover
&:focus,
&:hover {
transform: scale(1.1);
// Sponsor avatar
img {
filter: grayscale(0%);
}
}
// Private sponsor
&--private {
color: var(--md-default-fg-color--lighter);
font-weight: 700;
font-size: px2rem(24px);
line-height: px2rem(60px);
text-align: center;
background: var(--md-default-fg-color--lightest);
}
// Sponsor avatar
img {
display: block;
width: 100%;
height: auto;
filter: grayscale(100%);
transition: filter 125ms;
}
}
}
// Sponsorship button
.mdx-sponsorship-button {
font-weight: 400;
}
// Sponsorship count and total
.mdx-sponsorship-count,
.mdx-sponsorship-total {
font-weight: 700;
}
}