diff options
| author | Rafi Zadanly <zadanlyr@gmail.com> | 2024-01-31 09:03:22 +0700 |
|---|---|---|
| committer | Rafi Zadanly <zadanlyr@gmail.com> | 2024-01-31 09:03:22 +0700 |
| commit | b8764138241116e0c741a7786364f5630080720c (patch) | |
| tree | caf4396671469bc6ac992c9b741fe3f8701c986e /src | |
| parent | 3f849355048e5c280a35a5747577e5296b90e9fd (diff) | |
| parent | 0550b0dbe9b8e369cfe211b78ab0de49a6e1f49d (diff) | |
Merge branch 'release' into feature/all-promotion
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/components/ScrollToTop.jsx | 24 | ||||
| -rw-r--r-- | src/core/components/elements/Navbar/NavbarDesktop.jsx | 33 | ||||
| -rw-r--r-- | src/core/components/elements/Navbar/NavbarMobile.jsx | 12 | ||||
| -rw-r--r-- | src/core/components/layouts/BasicLayout.jsx | 33 | ||||
| -rw-r--r-- | src/core/utils/slug.js | 34 | ||||
| -rw-r--r-- | src/lib/form/components/KunjunganSales.jsx | 11 | ||||
| -rw-r--r-- | src/lib/form/components/KunjunganService.jsx | 10 | ||||
| -rw-r--r-- | src/lib/form/components/Merchant.jsx | 9 | ||||
| -rw-r--r-- | src/lib/form/components/PembayaranTempo.jsx | 14 | ||||
| -rw-r--r-- | src/lib/form/components/RequestForQuotation.jsx | 10 | ||||
| -rw-r--r-- | src/lib/form/components/SuratDukungan.jsx | 9 | ||||
| -rw-r--r-- | src/lib/product/components/ProductCard.jsx | 10 | ||||
| -rw-r--r-- | src/lib/product/components/ProductSearch.jsx | 2 | ||||
| -rw-r--r-- | src/pages/_app.jsx | 6 | ||||
| -rw-r--r-- | src/pages/_document.jsx | 12 | ||||
| -rw-r--r-- | src/pages/api/shop/brands.js | 2 | ||||
| -rw-r--r-- | src/pages/api/shop/search.js | 2 | ||||
| -rw-r--r-- | src/styles/normalize.css | 351 |
18 files changed, 522 insertions, 62 deletions
diff --git a/src/core/components/ScrollToTop.jsx b/src/core/components/ScrollToTop.jsx new file mode 100644 index 00000000..f8e85167 --- /dev/null +++ b/src/core/components/ScrollToTop.jsx @@ -0,0 +1,24 @@ +import { useEffect } from 'react'; +import { useRouter } from 'next/router'; + +const ScrollToTop = () => { + const router = useRouter(); + + useEffect(() => { + const handleRouteChange = (url, { shallow }) => { + if (!shallow) { + window.scrollTo(0, 0); + } + }; + + router.events.on('routeChangeComplete', handleRouteChange); + + return () => { + router.events.off('routeChangeComplete', handleRouteChange); + }; + }, [router.events]); + + return null; +}; + +export default ScrollToTop; diff --git a/src/core/components/elements/Navbar/NavbarDesktop.jsx b/src/core/components/elements/Navbar/NavbarDesktop.jsx index 2605acbb..760e627d 100644 --- a/src/core/components/elements/Navbar/NavbarDesktop.jsx +++ b/src/core/components/elements/Navbar/NavbarDesktop.jsx @@ -1,29 +1,30 @@ +import { useProductContext } from '@/contexts/ProductContext'; +import useAuth from '@/core/hooks/useAuth'; +import { getCountCart } from '@/core/utils/cart'; +import { createSlug } from '@/core/utils/slug'; +import whatsappUrl from '@/core/utils/whatsappUrl'; +import IndoteknikLogo from '@/images/logo.png'; +import Cardheader from '@/lib/cart/components/Cartheader'; +import Category from '@/lib/category/components/Category'; import { ChevronDownIcon, - HeartIcon, - ShoppingCartIcon, DocumentCheckIcon, + HeartIcon, } from '@heroicons/react/24/outline'; -import Link from '../Link/Link'; +import dynamic from 'next/dynamic'; import Image from 'next/image'; +import { useRouter } from 'next/router'; +import { useEffect, useState } from 'react'; import DesktopView from '../../views/DesktopView'; -import dynamic from 'next/dynamic'; -import IndoteknikLogo from '@/images/logo.png'; -import Category from '@/lib/category/components/Category'; -import { useCallback, useContext, useEffect, useState } from 'react'; -import useAuth from '@/core/hooks/useAuth'; +import Link from '../Link/Link'; import NavbarUserDropdown from './NavbarUserDropdown'; -import { getCartApi, getCountCart } from '@/core/utils/cart'; -import whatsappUrl from '@/core/utils/whatsappUrl'; -import { useRouter } from 'next/router'; -import { getAuth, setAuth } from '@/core/utils/auth'; -import { createSlug, getIdFromSlug } from '@/core/utils/slug'; import { TopBannerSkeleton } from '../Skeleton/TopBannerSkeleton'; -import { useProductContext } from '@/contexts/ProductContext'; -import Cardheader from '@/lib/cart/components/Cartheader'; const Search = dynamic(() => import('./Search'), { ssr: false }); -const TopBanner = dynamic(() => import('./TopBanner'), { ssr: false }); +const TopBanner = dynamic(() => import('./TopBanner'), { + ssr: false, + loading: () => <TopBannerSkeleton />, +}); const NavbarDesktop = () => { const [isOpenCategory, setIsOpenCategory] = useState(false); diff --git a/src/core/components/elements/Navbar/NavbarMobile.jsx b/src/core/components/elements/Navbar/NavbarMobile.jsx index 92bd5627..bcf45e0a 100644 --- a/src/core/components/elements/Navbar/NavbarMobile.jsx +++ b/src/core/components/elements/Navbar/NavbarMobile.jsx @@ -1,16 +1,16 @@ -import Image from 'next/image'; -import MobileView from '../../views/MobileView'; -import Link from '../Link/Link'; +import useSidebar from '@/core/hooks/useSidebar'; +import { getCountCart } from '@/core/utils/cart'; +import IndoteknikLogo from '@/images/logo.png'; import { Bars3Icon, HeartIcon, ShoppingCartIcon, } from '@heroicons/react/24/outline'; -import useSidebar from '@/core/hooks/useSidebar'; import dynamic from 'next/dynamic'; -import IndoteknikLogo from '@/images/logo.png'; +import Image from 'next/image'; import { useEffect, useState } from 'react'; -import { getCart, getCountCart } from '@/core/utils/cart'; +import MobileView from '../../views/MobileView'; +import Link from '../Link/Link'; // import TopBanner from './TopBanner'; const Search = dynamic(() => import('./Search')); diff --git a/src/core/components/layouts/BasicLayout.jsx b/src/core/components/layouts/BasicLayout.jsx index 2962a08b..b6e2c59f 100644 --- a/src/core/components/layouts/BasicLayout.jsx +++ b/src/core/components/layouts/BasicLayout.jsx @@ -1,15 +1,14 @@ import dynamic from 'next/dynamic'; import Image from 'next/image'; import { useEffect, useState } from 'react'; -import axios from 'axios'; +import { useProductContext } from '@/contexts/ProductContext'; import whatsappUrl from '@/core/utils/whatsappUrl'; -import odooApi from '@/core/api/odooApi'; import { useRouter } from 'next/router'; -import { useProductContext } from '@/contexts/ProductContext'; const Navbar = dynamic(() => import('../elements/Navbar/Navbar'), { ssr: false, + loading: () => <div className='h-[156px]' />, }); const AnimationLayout = dynamic(() => import('./AnimationLayout'), { ssr: false, @@ -42,20 +41,20 @@ const BasicLayout = ({ children }) => { } }, [product, router]); - useEffect(() => { - const getIP = async () => { - const ip = await odooApi('GET', '/api/ip-address'); - const data = { - page_title: document.title, - url: window.location.href, - ip: ip, - }; - axios.get( - `/api/user-activity?page_title=${data.page_title}&url=${data.url}&ip=${data.ip}` - ); - }; - getIP(); - }, []); + // useEffect(() => { + // const getIP = async () => { + // const ip = await odooApi('GET', '/api/ip-address'); + // const data = { + // page_title: document.title, + // url: window.location.href, + // ip: ip, + // }; + // axios.get( + // `/api/user-activity?page_title=${data.page_title}&url=${data.url}&ip=${data.ip}` + // ); + // }; + // getIP(); + // }, []); return ( <> <Navbar /> diff --git a/src/core/utils/slug.js b/src/core/utils/slug.js index e91bcf83..19c7b115 100644 --- a/src/core/utils/slug.js +++ b/src/core/utils/slug.js @@ -1,4 +1,4 @@ -import toTitleCase from './toTitleCase' +import toTitleCase from './toTitleCase'; /** * Creates a slug from input parameters by converting the name and appending it with an ID. @@ -10,19 +10,20 @@ import toTitleCase from './toTitleCase' * @returns {string} - The generated slug with the prefix, name, and ID. */ const createSlug = (prefix, name, id, withHost = false) => { + name ||= ''; let slug = name ?.trim() .replace(new RegExp(/[^A-Za-z0-9]/, 'g'), '-') .toLowerCase() + '-' + - id - let splitSlug = slug.split('-') - let filterSlugFromEmptyChar = splitSlug.filter((x) => x != '') - slug = prefix + filterSlugFromEmptyChar.join('-') - if (withHost) slug = process.env.NEXT_PUBLIC_SELF_HOST + slug - return slug -} + id; + let splitSlug = slug.split('-'); + let filterSlugFromEmptyChar = splitSlug.filter((x) => x != ''); + slug = prefix + filterSlugFromEmptyChar.join('-'); + if (withHost) slug = process.env.NEXT_PUBLIC_SELF_HOST + slug; + return slug; +}; /** * Extracts the ID from a slug. @@ -32,9 +33,9 @@ const createSlug = (prefix, name, id, withHost = false) => { * @returns {string} - The extracted ID from the slug. */ const getIdFromSlug = (slug) => { - let id = slug.split('-') - return id[id.length - 1] -} + let id = slug.split('-'); + return id[id.length - 1]; +}; /** * Extracts the name from a slug. @@ -45,9 +46,10 @@ const getIdFromSlug = (slug) => { * @returns {string} - The extracted name from the slug in title case. */ const getNameFromSlug = (slug) => { - let name = slug.split('-') - name.pop() - return toTitleCase(name.join(' ')) -} + let name = slug.split('-'); + name.pop(); + return toTitleCase(name.join(' ')); +}; + +export { createSlug, getIdFromSlug, getNameFromSlug }; -export { createSlug, getIdFromSlug, getNameFromSlug } diff --git a/src/lib/form/components/KunjunganSales.jsx b/src/lib/form/components/KunjunganSales.jsx index 7470395a..29940edf 100644 --- a/src/lib/form/components/KunjunganSales.jsx +++ b/src/lib/form/components/KunjunganSales.jsx @@ -10,6 +10,9 @@ import * as Yup from 'yup' import createLeadApi from '../api/createLeadApi' import PageContent from '@/lib/content/components/PageContent' +import useAuth from '@/core/hooks/useAuth' +import { useRouter } from 'next/router' + const KunjunganSales = () => { const { register, @@ -23,10 +26,18 @@ const KunjunganSales = () => { }) const [cities, setCities] = useState([]) const [companyTypes, setCompanyTypes] = useState([]) + const router = useRouter() + + const auth = useAuth() + + const recaptchaRef = useRef(null) useEffect(() => { + if(!auth) { + router.push('/login') + } const loadCities = async () => { let dataCities = await cityApi() dataCities = dataCities.map((obj) => ({ value: obj.name, label: obj.name })) diff --git a/src/lib/form/components/KunjunganService.jsx b/src/lib/form/components/KunjunganService.jsx index 1cb0b446..0e1d1ab3 100644 --- a/src/lib/form/components/KunjunganService.jsx +++ b/src/lib/form/components/KunjunganService.jsx @@ -8,6 +8,9 @@ import { toast } from 'react-hot-toast' import * as Yup from 'yup' import createLeadApi from '../api/createLeadApi' import PageContent from '@/lib/content/components/PageContent' +import { useRouter } from 'next/router' + +import useAuth from '@/core/hooks/useAuth' const CreateKunjunganService = () => { const { @@ -22,10 +25,17 @@ const CreateKunjunganService = () => { }) const [cities, setCities] = useState([]) const [company_unit, setCompany_unit] = useState([]) + + const router = useRouter() + + const auth = useAuth() const recaptchaRef = useRef(null) useEffect(() => { + if(!auth) { + router.push('/login') + } const loadCities = async () => { let dataCities = await cityApi() dataCities = dataCities.map((city) => ({ value: city.id, label: city.name })) diff --git a/src/lib/form/components/Merchant.jsx b/src/lib/form/components/Merchant.jsx index 6c1af231..770bfb82 100644 --- a/src/lib/form/components/Merchant.jsx +++ b/src/lib/form/components/Merchant.jsx @@ -8,6 +8,9 @@ import { toast } from 'react-hot-toast'; import * as Yup from 'yup'; import createLeadApi from '../api/createLeadApi'; import PageContent from '@/lib/content/components/PageContent'; +import { useRouter } from 'next/router'; +import useAuth from '@/core/hooks/useAuth' + const CreateMerchant = () => { const { @@ -50,8 +53,14 @@ const CreateMerchant = () => { const [company_unit, setCompany_unit] = useState(list_unit); const recaptchaRef = useRef(null); + const router = useRouter() + + const auth = useAuth() useEffect(() => { + if(!auth) { + router.push('/login') + } const loadCities = async () => { let dataCities = await cityApi(); dataCities = dataCities.map((city) => ({ diff --git a/src/lib/form/components/PembayaranTempo.jsx b/src/lib/form/components/PembayaranTempo.jsx index 8c624fe2..73ceee49 100644 --- a/src/lib/form/components/PembayaranTempo.jsx +++ b/src/lib/form/components/PembayaranTempo.jsx @@ -1,12 +1,15 @@ import getFileBase64 from '@/core/utils/getFileBase64' import { yupResolver } from '@hookform/resolvers/yup' -import React, { useRef } from 'react' +import React, { useEffect, useRef } from 'react' import ReCAPTCHA from 'react-google-recaptcha' import { useForm } from 'react-hook-form' import { toast } from 'react-hot-toast' import * as Yup from 'yup' import createLeadApi from '../api/createLeadApi' import PageContent from '@/lib/content/components/PageContent' +import { useRouter } from 'next/router' + +import useAuth from '@/core/hooks/useAuth' const PembayaranTempo = () => { @@ -21,6 +24,15 @@ const PembayaranTempo = () => { }) const recaptchaRef = useRef(null) + const router = useRouter() + + const auth = useAuth() + + useEffect(() => { + if(!auth) { + router.push('/login') + } + },[]) const onSubmitHandler = async (values) => { const recaptchaValue = recaptchaRef.current.getValue() diff --git a/src/lib/form/components/RequestForQuotation.jsx b/src/lib/form/components/RequestForQuotation.jsx index fa526d5f..34434dd5 100644 --- a/src/lib/form/components/RequestForQuotation.jsx +++ b/src/lib/form/components/RequestForQuotation.jsx @@ -10,6 +10,9 @@ import * as Yup from 'yup' import createLeadApi from '../api/createLeadApi' import getFileBase64 from '@/core/utils/getFileBase64' import PageContent from '@/lib/content/components/PageContent' +import { useRouter } from 'next/router' + +import useAuth from '@/core/hooks/useAuth' const RequestForQuotation = () => { const { @@ -26,8 +29,15 @@ const RequestForQuotation = () => { const quotationFileRef = useRef(null) const recaptchaRef = useRef(null) + const router = useRouter() + + const auth = useAuth() + useEffect(() => { + if(!auth) { + router.push('/login') + } const loadCities = async () => { let dataCities = await cityApi() dataCities = dataCities.map((obj) => ({ value: obj.name, label: obj.name })) diff --git a/src/lib/form/components/SuratDukungan.jsx b/src/lib/form/components/SuratDukungan.jsx index d73c3fab..0b3b650e 100644 --- a/src/lib/form/components/SuratDukungan.jsx +++ b/src/lib/form/components/SuratDukungan.jsx @@ -10,6 +10,9 @@ import createLeadsApi from '../api/createLeadApi'; import PageContent from '@/lib/content/components/PageContent'; +import useAuth from '@/core/hooks/useAuth' +import { useRouter } from 'next/router'; + const CreateSuratDukungan = () => { const { register, @@ -25,8 +28,14 @@ const CreateSuratDukungan = () => { const [company_unit, setCompany_unit] = useState([]); const recaptchaRef = useRef(null); + const router = useRouter() + + const auth = useAuth() useEffect(() => { + if(!auth) { + router.push('/login') + } const loadCities = async () => { let dataCities = await cityApi(); dataCities = dataCities.map((city) => ({ diff --git a/src/lib/product/components/ProductCard.jsx b/src/lib/product/components/ProductCard.jsx index fa555bcf..1cec0804 100644 --- a/src/lib/product/components/ProductCard.jsx +++ b/src/lib/product/components/ProductCard.jsx @@ -6,6 +6,7 @@ import { createSlug } from '@/core/utils/slug' import whatsappUrl from '@/core/utils/whatsappUrl' import ImageNext from 'next/image' import { useRouter } from 'next/router' +import { useMemo } from 'react' const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { const router = useRouter() @@ -16,6 +17,11 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { url: createSlug('/shop/product/', product.name, product.id, true) }) + const image = useMemo(() => { + if (product.image) return product.image + '?ratio=square' + return '/images/noimage.jpeg' + }, [product.image]) + if (variant == 'vertical') { return ( <div className='rounded shadow-sm border border-gray_r-4 bg-white h-[300px] md:h-[350px]'> @@ -24,7 +30,7 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { className='border-b border-gray_r-4 relative' > <Image - src={product?.image} + src={image} alt={product?.name} className='w-full object-contain object-center h-36 sm:h-48' /> @@ -150,7 +156,7 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { className='relative' > <Image - src={product?.image} + src={image} alt={product?.name} className='w-full object-contain object-center h-36' /> diff --git a/src/lib/product/components/ProductSearch.jsx b/src/lib/product/components/ProductSearch.jsx index ed4365a8..90e93aa0 100644 --- a/src/lib/product/components/ProductSearch.jsx +++ b/src/lib/product/components/ProductSearch.jsx @@ -105,7 +105,7 @@ const ProductSearch = ({ setIsBrand(null); } }; - if (router.pathname.includes('search')) { + if (router.pathname.includes('search') && q !== '*') { checkIfBrand(); } }, [q]); diff --git a/src/pages/_app.jsx b/src/pages/_app.jsx index 9067fd03..01dec611 100644 --- a/src/pages/_app.jsx +++ b/src/pages/_app.jsx @@ -1,5 +1,6 @@ import '@/fonts/Inter/inter.css'; import '@/styles/globals.css'; +import '@/styles/normalize.css'; // import 'react-loading-skeleton/dist/skeleton.css'; import { useEffect, useState } from 'react'; @@ -35,6 +36,9 @@ const LogoSpinner = dynamic( () => import('@/core/components/elements/Spinner/LogoSpinner'), { ssr: false } ); +const ScrollToTop = dynamic(() => import('@/core/components/ScrollToTop'), { + ssr: false, +}); const Toaster = dynamic( () => import('react-hot-toast').then((mod) => mod.Toaster), { ssr: false } @@ -80,6 +84,8 @@ function MyApp({ Component, pageProps: { session, ...pageProps } }) { return ( <SessionProvider session={session}> + <ScrollToTop /> + <AnimatePresence> {animateLoader && ( <motion.div diff --git a/src/pages/_document.jsx b/src/pages/_document.jsx index fc9f2ee0..cd60bd89 100644 --- a/src/pages/_document.jsx +++ b/src/pages/_document.jsx @@ -8,9 +8,19 @@ export default function MyDocument() { <Html> <Head> <link rel='preconnect' href='https://connect.facebook.net' /> + <link rel='dns-prefetch' href='https://connect.facebook.net' /> + <link rel='preconnect' href='https://googleads.g.doubleclick.net' /> + <link rel='dns-prefetch' href='https://googleads.g.doubleclick.net' /> + + <link rel='preconnect' href='https://www.googletagmanager.com' /> + <link rel='dns-prefetch' href='https://www.googletagmanager.com' /> + <link rel='preconnect' href={process.env.NEXT_PUBLIC_ODOO_API_HOST} /> - <link rel='prefetch' href='/images/logo-indoteknik-gear.png' /> + <link rel='dns-prefetch' href={process.env.NEXT_PUBLIC_ODOO_API_HOST} /> + + <link rel='preconnect' href='/images/logo-indoteknik-gear.png' /> + <link rel='dns-prefetch' href='/images/logo-indoteknik-gear.png' /> <link rel='icon' href='/favicon.ico' /> <link rel='manifest' href='/manifest.json' /> diff --git a/src/pages/api/shop/brands.js b/src/pages/api/shop/brands.js index 8c608b5e..cc64a7e7 100644 --- a/src/pages/api/shop/brands.js +++ b/src/pages/api/shop/brands.js @@ -16,7 +16,7 @@ export default async function handler(req, res) { params = 'level_s:prioritas'; break; case 'search': - params = `name_s:${req?.query?.q.toLowerCase()}`; + params = `name_s:"${req?.query?.q.toLowerCase()}"`; sort = ''; rows = 1; break; diff --git a/src/pages/api/shop/search.js b/src/pages/api/shop/search.js index 576d028a..adb23511 100644 --- a/src/pages/api/shop/search.js +++ b/src/pages/api/shop/search.js @@ -32,7 +32,7 @@ export default async function handler(req, res) { paramOrderBy += 'search_rank_weekly_i DESC' break case 'stock': - paramOrderBy += 'stock_total_f DESC' + paramOrderBy += 'product_rating_f DESC, stock_total_f DESC' break case 'flashsale-price-asc': paramOrderBy += 'flashsale_price_f ASC' diff --git a/src/styles/normalize.css b/src/styles/normalize.css new file mode 100644 index 00000000..92aed47e --- /dev/null +++ b/src/styles/normalize.css @@ -0,0 +1,351 @@ +/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ + +/* Document + ========================================================================== */ + +/** + * 1. Correct the line height in all browsers. + * 2. Prevent adjustments of font size after orientation changes in iOS. + */ + +html { + line-height: 1.15; /* 1 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/* Sections + ========================================================================== */ + +/** + * Remove the margin in all browsers. + */ + +body { + margin: 0; +} + +/** + * Render the `main` element consistently in IE. + */ + +main { + display: block; +} + +/** + * Correct the font size and margin on `h1` elements within `section` and + * `article` contexts in Chrome, Firefox, and Safari. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +/* Grouping content + ========================================================================== */ + +/** + * 1. Add the correct box sizing in Firefox. + * 2. Show the overflow in Edge and IE. + */ + +hr { + box-sizing: content-box; /* 1 */ + height: 0; /* 1 */ + overflow: visible; /* 2 */ +} + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + +pre { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ +} + +/* Text-level semantics + ========================================================================== */ + +/** + * Remove the gray background on active links in IE 10. + */ + +a { + background-color: transparent; +} + +/** + * 1. Remove the bottom border in Chrome 57- + * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. + */ + +abbr[title] { + border-bottom: none; /* 1 */ + text-decoration: underline; /* 2 */ + text-decoration: underline dotted; /* 2 */ +} + +/** + * Add the correct font weight in Chrome, Edge, and Safari. + */ + +b, +strong { + font-weight: bolder; +} + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + +code, +kbd, +samp { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ +} + +/** + * Add the correct font size in all browsers. + */ + +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` elements from affecting the line height in + * all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +/* Embedded content + ========================================================================== */ + +/** + * Remove the border on images inside links in IE 10. + */ + +img { + border-style: none; +} + +/* Forms + ========================================================================== */ + +/** + * 1. Change the font styles in all browsers. + * 2. Remove the margin in Firefox and Safari. + */ + +button, +input, +optgroup, +select, +textarea { + font-family: inherit; /* 1 */ + font-size: 100%; /* 1 */ + line-height: 1.15; /* 1 */ + margin: 0; /* 2 */ +} + +/** + * Show the overflow in IE. + * 1. Show the overflow in Edge. + */ + +button, +input { + /* 1 */ + overflow: visible; +} + +/** + * Remove the inheritance of text transform in Edge, Firefox, and IE. + * 1. Remove the inheritance of text transform in Firefox. + */ + +button, +select { + /* 1 */ + text-transform: none; +} + +/** + * Correct the inability to style clickable types in iOS and Safari. + */ + +button, +[type='button'], +[type='reset'], +[type='submit'] { + -webkit-appearance: button; +} + +/** + * Remove the inner border and padding in Firefox. + */ + +button::-moz-focus-inner, +[type='button']::-moz-focus-inner, +[type='reset']::-moz-focus-inner, +[type='submit']::-moz-focus-inner { + border-style: none; + padding: 0; +} + +/** + * Restore the focus styles unset by the previous rule. + */ + +button:-moz-focusring, +[type='button']:-moz-focusring, +[type='reset']:-moz-focusring, +[type='submit']:-moz-focusring { + outline: 1px dotted ButtonText; +} + +/** + * Correct the padding in Firefox. + */ + +fieldset { + padding: 0.35em 0.75em 0.625em; +} + +/** + * 1. Correct the text wrapping in Edge and IE. + * 2. Correct the color inheritance from `fieldset` elements in IE. + * 3. Remove the padding so developers are not caught out when they zero out + * `fieldset` elements in all browsers. + */ + +legend { + box-sizing: border-box; /* 1 */ + color: inherit; /* 2 */ + display: table; /* 1 */ + max-width: 100%; /* 1 */ + padding: 0; /* 3 */ + white-space: normal; /* 1 */ +} + +/** + * Add the correct vertical alignment in Chrome, Firefox, and Opera. + */ + +progress { + vertical-align: baseline; +} + +/** + * Remove the default vertical scrollbar in IE 10+. + */ + +textarea { + overflow: auto; +} + +/** + * 1. Add the correct box sizing in IE 10. + * 2. Remove the padding in IE 10. + */ + +[type='checkbox'], +[type='radio'] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Correct the cursor style of increment and decrement buttons in Chrome. + */ + +[type='number']::-webkit-inner-spin-button, +[type='number']::-webkit-outer-spin-button { + height: auto; +} + +/** + * 1. Correct the odd appearance in Chrome and Safari. + * 2. Correct the outline style in Safari. + */ + +[type='search'] { + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ +} + +/** + * Remove the inner padding in Chrome and Safari on macOS. + */ + +[type='search']::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * 1. Correct the inability to style clickable types in iOS and Safari. + * 2. Change font properties to `inherit` in Safari. + */ + +::-webkit-file-upload-button { + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ +} + +/* Interactive + ========================================================================== */ + +/* + * Add the correct display in Edge, IE 10+, and Firefox. + */ + +details { + display: block; +} + +/* + * Add the correct display in all browsers. + */ + +summary { + display: list-item; +} + +/* Misc + ========================================================================== */ + +/** + * Add the correct display in IE 10+. + */ + +template { + display: none; +} + +/** + * Add the correct display in IE 10. + */ + +[hidden] { + display: none; +} |
