Revert "Revert "[SCSS/Bootstrap to Tailwind] .form-control and related stylings""

This commit is contained in:
Daniel Miranda 2023-03-09 14:05:30 -08:00 коммит произвёл GitHub
Родитель 14a8022227
Коммит 5c57f99533
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
16 изменённых файлов: 185 добавлений и 180 удалений

Просмотреть файл

@ -8,6 +8,10 @@ import { getCurrentLanguage } from "../petition/locales";
import LanguageSelect from "./language-select.jsx";
import utility from "../../utility";
const FORM_CONTROL_CLASS =
"tw-form-control has-error:tw-border has-error:tw-border-solid has-error:tw-border-[#c01] dark:has-error:tw-border-2 dark:has-error:tw-border-red-40";
const ERROR_CLASS = "tw-text-[#c01] dark:tw-text-red-40";
/**
* Newsletter sign-up form
* TODO: Need to split into separate components and reorganize. Component is way too big.
@ -350,7 +354,7 @@ class JoinUs extends Component {
: false;
let wrapperClasses = classNames({
"has-danger":
"tw-has-error":
(!this.state.apiSuccess &&
this.state.userTriedSubmitting &&
!emailValidation.valid) ||
@ -361,7 +365,7 @@ class JoinUs extends Component {
"position-relative": wrapperClasses !== ``,
});
let inputClasses = classNames(`form-control`, {
let inputClasses = classNames(`${FORM_CONTROL_CLASS} tw-pr-18`, {
"tw-border-1 tw-border-black placeholder:tw-text-gray-40 focus:tw-border-blue-40 focus:tw-shadow-none focus-visible:tw-drop-shadow-none tw-mt-8":
this.props.formStyle == `pop`,
"tw-h-24": this.props.formStyle == `pni`,
@ -396,12 +400,12 @@ class JoinUs extends Component {
)}
</div>
{this.state.userTriedSubmitting && !emailValidation.valid && (
<p className="tw-body-small form-control-feedback">
<p className={`tw-body-small ${ERROR_CLASS}`}>
{emailValidation.errorMessage}
</p>
)}
{this.state.signupFailed && (
<small className="form-control-feedback">
<small className={ERROR_CLASS}>
Something went wrong. Please check your email address and try again
</small>
)}
@ -418,7 +422,7 @@ class JoinUs extends Component {
}
renderLocaleFields() {
let selectInputClasses = classNames(`w-100`, {
let selectInputClasses = classNames(`tw-w-full`, {
"tw-border-1 tw-border-black focus:tw-border-blue-40 focus:tw-shadow-none":
this.props.formStyle == `pop`,
});
@ -456,7 +460,7 @@ class JoinUs extends Component {
<div className="mb-2">
<input
type="text"
className="form-control"
className={FORM_CONTROL_CLASS}
placeholder="First name"
ref={(el) => (this.givenNames = el)}
onFocus={(evt) => this.onInputFocus(evt)}
@ -465,7 +469,7 @@ class JoinUs extends Component {
<div className="mb-2">
<input
type="text"
className="form-control"
className={FORM_CONTROL_CLASS}
placeholder="Last name"
ref={(el) => (this.surname = el)}
onFocus={(evt) => this.onInputFocus(evt)}
@ -479,7 +483,7 @@ class JoinUs extends Component {
*/
renderPrivacyField() {
let classes = classNames(`my-3 form-check form-group`, {
"has-danger":
"tw-has-error":
!this.state.apiSuccess &&
this.state.userTriedSubmitting &&
!this.privacy.checked,
@ -516,7 +520,7 @@ class JoinUs extends Component {
)}
</div>
{this.state.userTriedSubmitting && !this.privacy.checked && (
<p className="tw-body-small form-control-feedback mt-0 mb-3">
<p className={`tw-body-small mt-0 mb-3 ${ERROR_CLASS}`}>
{getText(`Please check this box if you want to proceed.`)}
</p>
)}

Просмотреть файл

@ -1,34 +1,13 @@
.join-us {
background: inherit;
.has-danger {
.tw-has-error {
$glyph-container: (
"margin-x": 10px,
"height": 20px,
"width": 13px,
);
color: $danger;
.form-control {
padding-right: map-get($glyph-container, "margin-x") * 2 +
map-get($glyph-container, "width");
border: 1px solid $danger;
@at-root .tw-dark & {
border-width: 2px;
border-color: $dark-theme-danger;
}
}
.form-control-feedback {
color: $danger;
@at-root .tw-dark & {
color: $dark-theme-danger;
}
}
.glyph-container {
position: absolute;
top: 0;
@ -50,12 +29,6 @@
}
}
.form-control {
font-weight: 400;
color: $black;
border-radius: 0;
}
.fields-wrapper {
flex: 1 1 auto;
}

Просмотреть файл

@ -36,7 +36,7 @@ class JoinUsLanguageSelect extends Component {
}
render() {
let classes = classNames(`form-control`, this.props.className);
let classes = classNames(`tw-form-control`, this.props.className);
return (
<select

Просмотреть файл

@ -12,7 +12,7 @@ class CountrySelect extends Component {
render() {
let classes = classNames(
`country-picker form-control`,
`country-picker tw-form-control`,
this.props.className
);
let codes = Object.keys(SALESFORCE_COUNTRY_LIST);

Просмотреть файл

@ -11,7 +11,7 @@ class FloatingLabelInput extends Component {
return (
<div className={className}>
<input
className="form-control"
className="tw-form-control has-error:tw-border has-error:tw-border-solid has-error:tw-border-[#c01] dark:has-error:tw-border-2 dark:has-error:tw-border-red-40"
disabled={this.props.disabled}
ref={(element) => {
this.element = element;

Просмотреть файл

@ -11,7 +11,7 @@ class FloatingLabelTextarea extends Component {
return (
<div className={className}>
<textarea
className="form-control"
className="tw-form-control has-error:tw-border has-error:tw-border-solid has-error:tw-border-[#c01] dark:has-error:tw-border-2 dark:has-error:tw-border-red-40"
disabled={this.props.disabled}
ref={(element) => {
this.element = element;

Просмотреть файл

@ -506,38 +506,38 @@ class Petition extends Component {
: null;
let givenGroupClass = classNames({
"has-danger":
"tw-has-error":
this.state.userTriedSubmitting && !this.givenNames.element.value,
});
let surGroupClass = classNames({
"has-danger":
"tw-has-error":
this.state.userTriedSubmitting && !this.surname.element.value,
});
let emailGroupClass = classNames({
"has-danger":
"tw-has-error":
this.state.userTriedSubmitting &&
(!this.email.element.value ||
!this.validatesAsEmail(this.email.element.value)),
});
let countryGroupClass = classNames({
"has-danger":
"tw-has-error":
this.props.requiresCountryCode === `True` &&
this.state.userTriedSubmitting &&
!this.country.element.value,
});
let postalCodeGroupClass = classNames({
"has-danger":
"tw-has-error":
this.props.requiresPostalCode === `True` &&
this.state.userTriedSubmitting &&
!this.postalCode.element.value,
});
let commentGroupClass = classNames({
"has-danger":
"tw-has-error":
(this.props.commentRequirements === `required` &&
this.state.userTriedSubmitting &&
!this.comment.element.value) ||
@ -549,11 +549,11 @@ class Petition extends Component {
let privacyClass = classNames(`my-3`, {
"form-check": true,
"has-danger":
"tw-has-error":
this.state.userTriedSubmitting && !this.refs.privacy.checked,
});
let errorMessageClass = `tw-body-small form-control-feedback`;
let errorMessageClass = `tw-body-small tw-text-[#c01] dark:tw-text-red-40`;
let checkboxes = this.generateCheckboxes(disableFields);
@ -621,7 +621,7 @@ class Petition extends Component {
</div>
<div className={countryGroupClass}>
<CountrySelect
className="form-control-lg mb-1 w-100"
className="tw-form-control-lg mb-1 w-100"
ref={(element) => {
this.country = element;
}}
@ -709,7 +709,7 @@ class Petition extends Component {
</div>
{this.state.userTriedSubmitting &&
!this.refs.privacy.checked && (
<p className={errorMessageClass}>
<p className={`${errorMessageClass} tw-ml-[-1.2rem]`}>
{getText(`Please check this box if you want to proceed`)}
</p>
)}

Просмотреть файл

@ -11,7 +11,7 @@
margin: 0;
}
.form-control {
.tw-form-control {
color: $black;
height: auto;
}
@ -64,7 +64,7 @@
font-weight: 400;
}
select.form-control:not([size]):not([multiple]) {
select.tw-form-control:not([size]):not([multiple]) {
height: calc(2.25rem + 26px);
font-size: 1.25rem;
padding: 1rem 0.75rem;
@ -77,29 +77,3 @@
}
}
}
.petition-form {
.form-check {
.form-control-feedback {
margin-left: -$form-check-input-gutter;
}
}
.has-danger {
.form-control-feedback {
color: $danger;
@at-root .tw-dark & {
color: $dark-theme-danger;
}
}
.form-control {
border: 1px solid $danger;
@at-root .tw-dark & {
border-color: $dark-theme-danger;
}
}
}
}

Просмотреть файл

@ -46,7 +46,6 @@ html {
@import "../components/nav";
@import "../components/multipage-nav";
@import "../components/select-dropdown";
@import "../components/share-button-group";
@import "../components/sticky-cta";

Просмотреть файл

@ -1,38 +0,0 @@
// <select> styling
select {
&.form-control {
$background-size: 24px;
$padding-x: 12px;
$padding-right: $padding-x * 2 + $background-size;
-moz-appearance: none;
-webkit-appearance: none;
background-image: url("../_images/glyphs/down-chevron.svg");
background-repeat: no-repeat;
background-position: right $padding-x top 50%;
background-size: $background-size $background-size;
border-radius: 0;
border: 1px solid $gray-20;
padding: 5px $padding-right 5px $padding-x;
color: $black;
&-lg {
padding: $padding-x $padding-right $padding-x $padding-x;
}
@at-root .tw-dark & {
background-image: url("../_images/glyphs/down-chevron-dark-theme.svg");
background-color: transparent;
border: 1px solid $white;
color: $white;
// Explicitly setting <option>'s color to black.
// Otherwise, certain browsers would inherit the text color we set for <select>, and
// we would end up having white text on white background in the dropdown.
option {
color: $black;
}
}
}
}

Просмотреть файл

@ -28,7 +28,6 @@
@import "./components/primary-nav";
@import "./components/multipage-nav";
@import "./components/card";
@import "./components/select-dropdown"; // TODO:FIXME: consider relocate code to a new file scss/form.scss
@import "./components/blog-hero-video";
@import "./components/share-button-group";
@import "./components/foundation-slider";
@ -64,7 +63,6 @@
@import "./views/participate";
@import "./views/indexpage";
@import "./views/blog";
@import "./views/style-guide";
@import "./views/youtube-regrets-intro";
@import "./views/youtube-regrets";
@import "./views/youtube-regrets-reporter";

Просмотреть файл

@ -1,3 +0,0 @@
.form-control-lg {
height: auto;
}

Просмотреть файл

@ -3,50 +3,8 @@ const plugin = require("tailwindcss/plugin");
// TODO refactor with theme references after removing SASS/Bootstrap
// https://tailwindcss.com/docs/theme#referencing-other-values
const formControlStylings = {
appearance: "none",
backgroundImage: 'url("../_images/glyphs/down-chevron.svg")',
backgroundRepeat: "no-repeat",
backgroundPosition: "right 12px top 50%",
backgroundSize: "24px 24px",
borderRadius: "0",
border: "1px solid #cccccc",
padding: "5px 48px 5px 12px",
color: "#000000",
display: "block",
width: "100%",
height: "calc(1.5em + .75rem + 2px)",
fontSize: "1rem",
fontWeight: "400",
lineHeight: "1.25",
backgroundColor: "#ffffff",
backgroundClip: "padding-box",
transition:
"border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out",
"&:focus": {
color: "#495057",
backgroundColor: "#fff",
borderColor: "#80bdff",
outline: "0",
boxShadow: "0 0 0 0.2rem rgba(0, 123, 255, 0.25)",
},
".dark &": {
backgroundImage: "url(../_images/glyphs/down-chevron-dark-theme.svg)",
backgroundColor: "transparent",
border: "1px solid #ffffff",
color: "#ffffff",
option: {
color: "#000",
},
"&:focus": {
color: "#fff",
backgroundColor: "transparent",
borderColor: "#fff",
},
},
};
module.exports = [
plugin(function ({ addComponents }) {
plugin(function ({ addComponents, theme }) {
// Using Same breakpoints for containers as bootstrap
addComponents([
{
@ -95,19 +53,6 @@ module.exports = [
marginLeft: "-1rem",
},
},
// Add bootstrap form control to tailwind
{
"select.form-control": {
...formControlStylings,
"&-lg": {
...formControlStylings,
height: "auto",
padding: "12px 48px 12px 12px",
fontSize: "1.25rem",
lineHeight: "1.25",
},
},
},
]);
}),
];

Просмотреть файл

@ -0,0 +1,150 @@
const plugin = require("tailwindcss/plugin");
// Add Bootstrap .form-control stylings to Tailwind
// Stylings converted based on https://github.com/twbs/bootstrap/blob/v4.6.0/scss/_forms.scss
const SELECT = {
backgroundSize: "24px",
paddingX: "12px",
paddingRight: "48px", // paddingX * 2 + backgroundSize
};
/**
* Stylings for .form-control (converted from Bootstrap 4.6 with our custom SCSS)
* @param {*} theme Tailwind theme config
* @returns {object} Stylings
*/
function formControl(theme) {
return {
display: "block",
width: "100%",
height: "calc(1.5em + .75rem + 2px)",
padding: ".375rem .75rem",
fontFamily: theme("fontFamily.sans"),
fontSize: "1rem",
fontWeight: theme("fontWeight.normal"),
lineHeight: "1.25",
color: theme("colors.black"),
backgroundColor: theme("colors.white"),
backgroundClip: "padding-box",
border: `1px solid ${theme("colors.gray.20")}`,
borderRadius: 0,
transition:
"border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out",
// Unstyle the caret on `<select>`s in IE10+.
"&::-ms-expand": {
backgroundColor: "transparent",
border: 0,
},
// Remove select outline from select box in FF
"&:-moz-focusring": {
color: "transparent",
textShadow: "0 0 0 $input-color",
},
// Customize the `:focus` state to imitate native WebKit styles.
"&:focus": {
color: "#495057",
backgroundColor: theme("colors.white"),
borderColor: "#80bdff",
outline: "0",
boxShadow: "0 0 0 0.2rem rgba(0, 123, 255, 0.25)",
},
"&::placeholder": {
color: theme("colors.gray.60"),
// Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526.
opacity: 1,
},
// Disabled and read-only inputs
//
// HTML5 says that controls under a fieldset > legend:first-child won't be
// disabled if the fieldset is disabled. Due to implementation difficulty, we
// don't honor that edge case; we style them as disabled anyway.
"&:disabled, &[readonly]": {
backgroundColor: "#e9ecef",
// iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655.
opacity: 1,
},
"textarea&": {
height: "auto",
},
};
}
/**
* Stylings for select.form-control (converted from Bootstrap 4.6 with our custom SCSS)
* @param {*} theme Tailwind theme config
* @returns {object} Stylings
*/
function selectFormControl(theme) {
return {
appearance: "none",
backgroundRepeat: "no-repeat",
backgroundPosition: `right ${SELECT.paddingX} top 50%`,
backgroundImage: 'url("../_images/glyphs/down-chevron.svg")',
backgroundSize: `${SELECT.backgroundSize} ${SELECT.backgroundSize}`,
border: `1px solid ${theme("colors.gray.20")}`,
borderRadius: "0",
color: theme("colors.black"),
padding: `5px ${SELECT.paddingRight} 5px ${SELECT.paddingX}`,
".dark &": {
backgroundImage: "url(../_images/glyphs/down-chevron-dark-theme.svg)",
backgroundColor: "transparent",
border: `1px solid ${theme("colors.white")}`,
color: theme("colors.white"),
option: {
color: theme("colors.black"),
},
"&:focus": {
color: theme("colors.white"),
backgroundColor: "transparent",
borderColor: theme("colors.white"),
},
},
"&:focus::-ms-value": {
// Suppress the nested default white text on blue background highlight given to
// the selected option text when the (still closed) <select> receives focus
// in IE and (under certain conditions) Edge, as it looks bad and cannot be made to
// match the appearance of the native widget.
// See https://github.com/twbs/bootstrap/issues/19398.
color: "#495057",
backgroundColor: theme("colors.white"),
},
};
}
/**
* Stylings for select.form-control-lg (converted from Bootstrap 4.6 with our custom SCSS)
* @param {*} theme Tailwind theme config
* @returns {object} Stylings
*/
function selectFormLgControl(theme) {
return {
...selectFormControl(theme),
height: "auto",
padding: `${SELECT.paddingX} ${SELECT.paddingRight} ${SELECT.paddingX} ${SELECT.paddingX}`,
fontSize: "1.25rem",
lineHeight: "1.25",
};
}
module.exports = [
plugin(function ({ addComponents, theme }) {
addComponents([
{
".form-control": {
...formControl(theme),
},
"select.form-control": {
...selectFormControl(theme),
},
"select.form-control-lg": {
...selectFormLgControl(theme),
},
"input[type='date'].form-control, input[type='time'].form-control, input[type='datetime-local'].form-control, input[type='month'].form-control":
{
appearance: "none",
},
},
]);
}),
];

Просмотреть файл

@ -5,6 +5,7 @@ const componentPlugins = require("./tailwind-plugins/components");
const buttonPlugins = require("./tailwind-plugins/button");
const typePlugins = require("./tailwind-plugins/type");
const glyphPlugins = require("./tailwind-plugins/glyph");
const formControlPlugins = require("./tailwind-plugins/form-control");
module.exports = {
content: ["./source/js/**/*.{js,jsx}", "./network-api/networkapi/**/*.html"],
@ -48,6 +49,7 @@ module.exports = {
verticalAlign: "middle",
},
};
addVariant("has-error", ".has-error &");
addVariant("summary-open", ["details[open] > summary > &"]);
addVariant("details-open", ["details[open] > &"]);
addBase(newBase);
@ -56,6 +58,7 @@ module.exports = {
...buttonPlugins,
...typePlugins,
...glyphPlugins,
...formControlPlugins,
require("@tailwindcss/forms")({ strategy: "class" }),
require("@tailwindcss/line-clamp"),
],

Просмотреть файл

@ -20,7 +20,7 @@ test(`Foundation homepage`, async ({ page }, testInfo) => {
// Does the country list show only after we focus on the signup email field?
const countryPicker = await page.locator(
`#nav-newsletter-form-wrapper .country-picker.form-control`
`#nav-newsletter-form-wrapper .country-picker.tw-form-control`
);
const languagePicker = await page.locator(`#userLanguage-header`);
expect(await countryPicker.isVisible()).toBe(false);