1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-09-17 18:26:57 +00:00
This was a small update until Twitch ripped out half their CSS.

* Added: Cross-Origin Storage Bridge for settings, better synchronizing settings on sub-domains with support for binary blobs at the cost of slightly increased start-up time.
* Fixed: Rendering issues caused by missing CSS.
* Fixed: FFZ Control Center button not appearing on dashboard pages, and appearing in the incorrect place.
* Changed: Work towards splitting modules into their own JS files for a faster, more asynchronous startup.
* API Added: Methods for serializing and deserializing Blobs for transmission across postMessage.
This commit is contained in:
SirStendec 2021-02-11 19:40:12 -05:00
parent 2c5937c8af
commit 264c375f13
88 changed files with 1685 additions and 500 deletions

268
styles/input/checkbox.scss Normal file
View file

@ -0,0 +1,268 @@
.ffz-checkbox .ffz-checkbox__label:before,
.ffz-radio__label:before {
background-clip: padding-box;
box-sizing: border-box;
content: "";
height: 1.6rem;
margin-top: -.8rem;
transition: box-shadow .1s ease-in, background .1s ease-in;
width: 1.6rem;
}
.ffz-checkbox__input,
.ffz-radio__input {
clip: rect(0 0 0 0);
height: .1rem;
margin: -.1rem;
overflow: hidden;
width: .1rem;
}
.ffz-checkbox__input {
border: none;
color: var(--color-text-label);
padding: 0;
position: absolute;
&:hover:checked,
&:hover:indeterminate {
& + .ffz-checkbox__label:before {
border: var(--border-width-input) solid var(--color-border-input-checkbox-checked);
}
}
&:checked,
&:indeterminate {
& + .ffz-checkbox__label {
&:before {
background-color: var(--color-background-input-checkbox-checked-background);
border: var(--border-width-input) solid var(--color-border-input-checkbox-checked);
}
&:after {
background-color: var(--color-background-input-checkbox-checked);
content: "";
left: .4rem;
position: absolute;
top: 50%;
width: .8rem;
}
}
}
&:checked + .ffz-checkbox__label:after {
height: .8rem;
transform: translate3d(0, -50%, 0);
}
&:indeterminate + .ffz-checkbox__label:after {
display: block;
height: .2rem;
transform: translateY(-50%);
}
&:disabled + .ffz-checkbox__label {
opacity: 0.5;
pointer-events: none;
}
.js-focus-visible &:focus:not([data-focus-visible-added]) + .ffz-checkbox__label {
outline: none;
}
&[data-focus-visible-added] + .ffz-checkbox__label:before {
border: var(--border-width-input) solid var(--color-border-input-checkbox-focus);
box-shadow: var(--shadow-input-focus);
}
}
.ffz-checkbox {
.ffz-checkbox__label {
border-radius: var(--border-radius-medium);
color: var(--color-text-label);
cursor: pointer;
display: inline-block;
padding: 0 0 0 1.6rem;
position: relative;
&:before {
border: var(--border-width-input) solid var(--color-border-input-checkbox);
border-radius: .2rem;
border-radius: var(--border-radius-small);
left: 0;
position: absolute;
top: 50%;
}
&:after {
content: '';
display: block;
}
&:hover:before {
border-color: var(--color-border-input-checkbox-hover);
}
}
}
.ffz-checkbox--error .ffz-checkbox__label:before {
border: var(--border-width-input) solid var(--color-border-input-checkbox-error);
}
.ffz-checkbox--overlay {
.ffz-checkbox__input {
&:checked + .ffz-checkbox__label {
&:before {
background-color: var(--color-background-input-checkbox-checked-background-overlay);
border: var(--border-width-input) solid var(--color-border-input-checkbox-checked-overlay);
}
&:after {
background-color: var(--color-background-input-checkbox-checked-overlay);
}
}
&:hover:checked,
&:indeterminate {
& + .ffz-checkbox__label:before {
border: var(--border-width-input) solid var(--color-border-input-checkbox-checked-overlay);
}
}
&:indeterminate + .ffz-checkbox__label {
&:before {
background-color: var(--color-background-input-checkbox-checked-background-overlay);
border: var(--border-width-input) solid var(--color-border-input-checkbox-checked-overlay);
}
&:after {
background: var(--color-background-input-checkbox-checked-overlay);
content: "";
display: block;
height: .2rem;
left: .4rem;
position: absolute;
top: 50%;
transform: translateY(-50%);
width: .8rem;
}
}
.js-focus-visible &:focus:not([data-focus-visible-added]) + .ffz-checkbox__label {
outline: none;
}
&[data-focus-visible-added] + .ffz-checkbox__label:before {
border: var(--border-width-input) solid var(--color-border-input-overlay-focus);
box-shadow: 0 0 6px 0 var(--color-border-input-overlay-focus);
}
}
.ffz-checkbox__label {
color: var(--color-text-overlay);
&:before {
background-color: var(--color-background-input-overlay);
border: var(--border-width-input) solid var(--color-border-input-checkbox-overlay);
}
&:hover:before {
border-color: var(--color-border-input-checkbox-hover-overlay);
}
}
}
// Radio
.ffz-radio__input {
border: none;
color: var(--color-text-label);
padding: 0;
position: absolute;
&:checked + .ffz-radio__label:after {
background-color: var(--color-background-input-checkbox-checked);
border-radius: 50%;
height: .8rem;
left: .4rem;
position: absolute;
top: 50%;
transform: translate3d(0, -50%, 0);
width: .8rem;
}
&:disabled + .ffz-radio__label {
opacity: .5;
pointer-events: none;
}
.js-focus-visible &:focus:not([data-focus-visible-added]) + .ffz-radio__label {
outline: 0;
}
&[data-focus-visible-added] + .ffz-radio__label:before {
border: var(--border-width-input) solid var(--color-border-input-checkbox-focus);
box-shadow: var(--shadow-input-focus);
}
}
.ffz-radio__label {
border-radius: var(--border-radius-medium);
color: var(--color-text-label);
cursor: pointer;
display: inline-block;
padding: 0 0 0 1.6rem;
position: relative;
&:before {
border: var(--border-width-input) solid var(--color-border-input-checkbox);
border-radius: 50%;
left: 0;
position: absolute;
top: 50%;
}
&:after {
background-color: var(--color-background-input);
content: "";
display: block;
transition: background .1s ease-in;
}
&:hover:before {
border-color: var(--color-border-input-checkbox-hover);
}
}
.ffz-radio--error .ffz-radio__label:before {
border: var(--border-width-input) solid var(--color-border-input-checkbox-error);
}
// TODO: radio overlay
// Selection Stuff
@media (-webkit-min-device-pixel-ratio: 0) {
.ffz-checkbox--overlay .ffz-checkbox__input:focus+.ffz-checkbox__label:before,
.ffz-checkbox__input:focus+.ffz-checkbox__label,
.ffz-radio--overlay .ffz-radio__input:focus+.ffz-radio__label:before,
.ffz-radio__input:focus+.ffz-radio__label,
.ffz-segmented-button-option__input--checkbox:focus+.ffz-segmented-button-option__label,
.ffz-segmented-button-option__input--radio:focus+.ffz-segmented-button-option__label,
.ffz-toggle__input:focus+.ffz-toggle__button {
outline-color: -webkit-focus-ring-color;
outline-style: auto
}
}
.ffz-checkbox--overlay .ffz-checkbox__input:focus+.ffz-checkbox__label:before,
.ffz-checkbox__input:focus+.ffz-checkbox__label,
.ffz-radio--overlay .ffz-radio__input:focus+.ffz-radio__label:before,
.ffz-radio__input:focus+.ffz-radio__label,
.ffz-segmented-button-option__input--checkbox:focus+.ffz-segmented-button-option__label,
.ffz-segmented-button-option__input--radio:focus+.ffz-segmented-button-option__label,
.ffz-toggle__input:focus+.ffz-toggle__button {
outline: 5px solid Highlight;
}

3
styles/input/index.scss Normal file
View file

@ -0,0 +1,3 @@
@import "checkbox";
@import "text";
@import "interactable";

View file

@ -0,0 +1,115 @@
.ffz-interactable {
color: inherit;
&:hover {
color: inherit;
text-decoration: none;
}
&.ffz-interactable--hover-enabled:hover:active,
&:active {
background-color: var(--color-background-interactable-active);
}
&--selected, &:focus {
position: relative;
}
&--disabled, &:disabled {
opacity: 0.5;
pointer-events: none;
}
}
.ffz-interactable--default {
&.ffz-interactable--hover-forced,
&[data-focus-visible-added],
.tw-root--hover &.ffz-interactable--hover-enabled:hover {
background-color: var(--color-background-interactable-hover);
}
&.ffz-interactable--active,
&.ffz-interactable--hover-enabled:hover:active,
&:active {
background-color: var(--color-background-interactable-active);
}
&.ffz-interactable--selected {
color: var(--color-text-interactable-selected);
&,
&.ffz-interactable--hover-enabled:hover:active,
&.ffz-interactable--hover-forced,
&:active,
&[data-focus-visible-added],
.tw-root &.ffz-interactable--hover-enabled:hover {
background-color: var(--color-background-interactable-selected);
}
}
}
.ffz-interactable--alert {
&, &:hover {
color: var(--color-text-alert);
}
&.ffz-interactable--hover-forced,
&[data-focus-visible-added],
.tw-root--hover &.ffz-interactable--hover-enabled:hover {
background-color: var(--color-background-interactable-destructive-hover);
color: var(--color-text-interactable-inverted);
}
&.ffz-interactable--active,
&.ffz-interactable--hover-enabled:hover:active,
&:active {
background-color: var(--color-background-interactable-destructive-active);
}
}
.ffz-interactable--overlay {
background-color: transparent;
&.ffz-interactable--hover-forced,
&[data-focus-visible-added],
.tw-root--hover &.ffz-interactable--hover-enabled:hover {
background-color: var(--color-background-interactable-overlay-hover);
}
&.ffz-interactable--active,
&.ffz-interactable--hover-enabled:hover:active,
&:active {
background-color: var(--color-background-interactable-overlay-active);
}
&.ffz-interactable--selected {
color: var(--color-text-interactable-overlay-selected);
&,
&.ffz-interactable--hover-enabled:hover:active,
&.ffz-interactable--hover-forced,
&:active,
&[data-focus-visible-added],
.tw-root &.ffz-interactable--hover-enabled:hover {
background: var(--color-background-interactable-overlay-selected);
}
}
&.ffz-interactable--border {
border-color: var(--color-border-overlay);
}
}
.ffz-interactable--border {
border: var(--border-width-default) solid var(--color-border-base);
&.ffz-interactable--selected {
border: var(--border-width-default) solid var(--color-border-interactable-selected);
}
}
.ffz-interactable--selectable-text {
-ms-user-select: text;
-webkit-user-select: text;
user-select: text
}

232
styles/input/text.scss Normal file
View file

@ -0,0 +1,232 @@
/*
* Extracted styles for Twitch-like input elements
* because Twitch is stupid and removed their nice,
* standardized classes with nice standardized names
* in favor of procedural classes.
*/
// Input / Shared
.ffz-input {
-moz-appearance: none;
-webkit-appearance: none;
appearance: none;
border: var(--border-width-input) solid var(--color-border-input);
color: var(--color-text-input);
line-height: 1.5;
&[type=number] {
-moz-appearance: textfield;
&::-webkit-inner-spin-button {
-webkit-appearance: none;
}
&::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
}
}
.ffz-form-tag, .ffz-input, .ffz-select, .ffz-select-button, .ffz-textarea {
background-clip: padding-box;
}
.ffz-input, .ffz-select, .ffz-textarea {
font-family: inherit;
transition: box-shadow .1s ease-in, border .1s ease-in, background-color .1s ease-in;
//&::-webkit-input-placeholder,
//&:-ms-input-placeholder,
//&::-ms-input-placeholder,
&::placeholder {
color: var(--color-text-input-placeholder);
}
&::-ms-clear {
display: none;
}
&:-moz-focus-inner {
border: none;
padding: 0;
}
&:disabled {
opacity: 0.5;
pointer-events: none;
}
&, &:hover {
background-color: var(--color-background-input);
}
&:hover {
border-color: var(--color-border-input-hover);
outline: 0;
}
&:focus, &:focus:hover {
background-color: var(--color-background-input-focus);
border: var(--border-width-input) solid var(--color-border-input-focus);
outline: 0;
}
}
.ffz-input--error, .ffz-select--error {
box-shadow: var(--shadow-input-error);
&, &:focus {
border: var(--border-width-input) solid var(--color-border-input-error);
}
}
.ffz-input--error:focus,
.ffz-select--error:focus {
box-shadow: var(--shadow-input-error-focus);
}
.ffz-input--overlay,
.ffz-select--overlay,
.ffz-textarea--overlay {
background-color: var(--color-background-input-overlay);
border: none;
box-shadow: inset 0 0 0 var(--border-width-input) var(--color-border-input-overlay);
color: var(--color-text-overlay);
&:hover {
background-color: var(--color-background-input-overlay);
box-shadow: inset 0 0 0 var(--border-width-input) var(--color-border-input-overlay-hover);
}
&:focus, &:focus:hover {
background-color: var(--color-background-input-overlay-focus);
border: none;
box-shadow: inset 0 0 0 var(--border-width-input) var(--color-border-input-overlay-focus);
}
//&::-webkit-input-placeholder,
//&:-ms-input-placeholder,
//&::-ms-input-placeholder,
&::placeholder {
color: var(--color-text-input-placeholder-overlay);
}
&.ffz-input--error,
&.ffz-select--error {
border: var(--border-width-input) solid var(--color-border-input-error);
box-shadow: var(--shadow-input-error);
&:focus {
border: var(--border-width-input) solid var(--color-border-input-error);
box-shadow: var(--shadow-input-error-focus);
}
}
}
.ffz-input--password {
font-family: sans-serif;
}
.ffz-input__icon {
min-width: 3rem;
}
.ffz-input__icon--overlay {
color: var(--color-text-input-placeholder-overlay);
}
.ffz-input--small,
.ffz-select--small {
height: 2.4rem;
padding: .2rem 0
}
.ffz-input, .ffz-select {
height: 3rem;
}
.ffz-input--large,
.ffz-select--large {
height: 3.6rem
}
// Select
.ffz-select {
-moz-appearance: none;
-webkit-appearance: none;
appearance: none;
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%230e0e10' d='M10.5 13.683l2.85-2.442 1.3 1.518-3.337 2.86a1.25 1.25 0 01-1.626 0l-3.338-2.86 1.302-1.518 2.849 2.442zm0-7.366L7.65 8.76l-1.3-1.518 3.337-2.86a1.25 1.25 0 011.627 0l3.337 2.86-1.302 1.518L10.5 6.317z'/%3E%3C/svg%3E");
background-position: right .8rem center;
background-repeat: no-repeat;
background-size: 2rem;
border: var(--border-width-input) solid var(--color-border-input);
color: var(--color-text-input);
cursor: pointer;
line-height: 1.5;
line-height: normal;
.tw-root--theme-dark & {
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23efeff1' d='M10.5 13.683l2.85-2.442 1.3 1.518-3.337 2.86a1.25 1.25 0 01-1.626 0l-3.338-2.86 1.302-1.518 2.849 2.442zm0-7.366L7.65 8.76l-1.3-1.518 3.337-2.86a1.25 1.25 0 011.627 0l3.337 2.86-1.302 1.518L10.5 6.317z'/%3E%3C/svg%3E");
}
// option isn't scoped, unlike default Twitch, to avoid flicker
&[data-focus-visible-added], option {
background-color: var(--color-background-input-focus);
border-color: var(--color-border-input-focus)
}
}
.ffz-select--overlay {
&,
.tw-root--theme-dark &,
.tw-root--theme-light & {
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23fff' d='M10.5 13.683l2.85-2.442 1.3 1.518-3.337 2.86a1.25 1.25 0 01-1.626 0l-3.338-2.86 1.302-1.518 2.849 2.442zm0-7.366L7.65 8.76l-1.3-1.518 3.337-2.86a1.25 1.25 0 011.627 0l3.337 2.86-1.302 1.518L10.5 6.317z'/%3E%3C/svg%3E");
}
&[data-focus-visible-added] {
&, & option {
background-color: var(--color-background-input-overlay-focus);
box-shadow: inset 0 0 0 var(--border-width-input) var(--color-border-input-overlay-focus);
}
}
}
.ffz-select--small {
background-size: 1.6rem;
}
.ffz-select--large {
background-size: 2.4rem;
}
// Textarea
.ffz-textarea {
-moz-appearance: none;
-ms-overflow-style: none;
-webkit-appearance: none;
appearance: none;
border: var(--border-width-input) solid var(--color-border-input);
color: var(--color-text-input);
padding: .5rem 1rem;
resize: vertical;
&[cols] {
max-width: 100%;
width: auto;
}
}
.ffz-textarea--error:focus {
box-shadow: var(--shadow-input-error-focus);
}
.ffz-textarea--no-resize {
resize: none;
}