Login page completed
parent
cc421f40c6
commit
2f2ee1100f
@ -0,0 +1 @@
|
||||
../mini-svg-data-uri/cli.js
|
@ -0,0 +1,38 @@
|
||||
name: Bug Report
|
||||
description: Create a bug report for @tailwindcss/forms.
|
||||
labels: []
|
||||
body:
|
||||
- type: input
|
||||
attributes:
|
||||
label: What version of @tailwindcss/forms are you using?
|
||||
description: 'For example: v0.1.4'
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: What version of Node.js are you using?
|
||||
description: 'For example: v12.0.0'
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: What browser are you using?
|
||||
description: 'For example: Chrome, Safari, or N/A'
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: What operating system are you using?
|
||||
description: 'For example: macOS, Windows'
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: Reproduction repository
|
||||
description: A public GitHub repo that includes a minimal reproduction of the bug. Unfortunately we can't provide support without a reproduction, and your issue will be closed and locked with no comment if this is not provided.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe your issue
|
||||
description: Describe the problem you're seeing, any important steps to reproduce and what behavior you expect instead
|
@ -0,0 +1,11 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Feature Request
|
||||
url: https://github.com/tailwindlabs/tailwindcss/discussions/new?category=ideas
|
||||
about: 'Suggest any ideas you have using our discussion forums.'
|
||||
- name: Help
|
||||
url: https://github.com/tailwindlabs/tailwindcss/discussions/new?category=help
|
||||
about: 'If you have a question or need help, ask a question on the discussion forums.'
|
||||
- name: Kind Words
|
||||
url: https://github.com/tailwindlabs/tailwindcss/discussions/new?category=kind-words
|
||||
about: "Have something nice to say about @tailwindcss/forms or Tailwind CSS in general? We'd love to hear it!"
|
@ -0,0 +1,50 @@
|
||||
name: Release Insiders
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [12]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
|
||||
- name: Use cached node_modules
|
||||
id: cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: node_modules
|
||||
key: nodeModules-${{ hashFiles('**/package-lock.json') }}-${{ matrix.node-version }}
|
||||
restore-keys: |
|
||||
nodeModules-
|
||||
|
||||
- name: Install dependencies
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
run: npm install
|
||||
env:
|
||||
CI: true
|
||||
|
||||
- name: Resolve version
|
||||
id: vars
|
||||
run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
|
||||
|
||||
- name: "Version based on commit: 0.0.0-insiders.${{ steps.vars.outputs.sha_short }}"
|
||||
run: npm version 0.0.0-insiders.${{ steps.vars.outputs.sha_short }} --force --no-git-tag-version
|
||||
|
||||
- name: Publish
|
||||
run: npm publish --tag insiders
|
||||
env:
|
||||
CI: true
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
@ -0,0 +1,144 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
- Nothing yet!
|
||||
|
||||
## [0.5.3] - 2022-09-02
|
||||
|
||||
### Fixed
|
||||
|
||||
- Update TypeScript types ([#126](https://github.com/tailwindlabs/tailwindcss-forms/pull/126))
|
||||
|
||||
## [0.5.2] - 2022-05-18
|
||||
|
||||
### Added
|
||||
|
||||
- Add TypeScript type declarations ([#118](https://github.com/tailwindlabs/tailwindcss-forms/pull/118))
|
||||
|
||||
## [0.5.1] - 2022-05-03
|
||||
|
||||
### Fixed
|
||||
|
||||
- Remove duplicate `outline` property ([#116](https://github.com/tailwindlabs/tailwindcss-forms/pull/116))
|
||||
- Fix autoprefixer warning about `color-adjust` ([#115](https://github.com/tailwindlabs/tailwindcss-forms/pull/115))
|
||||
|
||||
## [0.5.0] - 2022-03-02
|
||||
|
||||
### Changed
|
||||
|
||||
- Generate both global styles and classes by default ([#71](https://github.com/tailwindlabs/tailwindcss-forms/pull/71))
|
||||
|
||||
## [0.4.1] - 2022-03-02
|
||||
|
||||
### Added
|
||||
|
||||
- Remove `dist` folder and related dependencies ([#96](https://github.com/tailwindlabs/tailwindcss-forms/pull/96))
|
||||
|
||||
### Fixed
|
||||
|
||||
- Use `addComponents` for class strategy ([#91](https://github.com/tailwindlabs/tailwindcss-forms/pull/91))
|
||||
- Fix extra height on Safari date/time inputs ([#109](https://github.com/tailwindlabs/tailwindcss-forms/pull/109))
|
||||
|
||||
## [0.4.0] - 2021-12-09
|
||||
|
||||
### Changed
|
||||
|
||||
- Update color palette references for v3 ([#83](https://github.com/tailwindlabs/tailwindcss-forms/pull/83))
|
||||
- Don't read outline.none value from config ([#89](https://github.com/tailwindlabs/tailwindcss-forms/pull/89))
|
||||
|
||||
## [0.3.4] - 2021-09-28
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix compatibility with `optimizeUniversalDefaults` experimental feature in Tailwind CSS v2.2 ([#81](https://github.com/tailwindlabs/tailwindcss-forms/pull/81))
|
||||
|
||||
## [0.3.3] - 2021-06-03
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix typo in selector when using `class` strategy that breaks background colors on checkboxes and radio buttons ([#72](https://github.com/tailwindlabs/tailwindcss-forms/pull/72))
|
||||
|
||||
## [0.3.2] - 2021-03-26
|
||||
|
||||
### Fixed
|
||||
|
||||
- Filter `null` rules for JIT compatibility ([b4c4e03](https://github.com/tailwindlabs/tailwindcss-forms/commit/b4c4e039337c3a5599f5b6d9eabbcc8ab9e8c8d9))
|
||||
|
||||
## [0.3.1] - 2021-03-26
|
||||
|
||||
### Fixed
|
||||
|
||||
- Use `base` as default strategy, not `class` ([#61](https://github.com/tailwindlabs/tailwindcss-forms/pull/61))
|
||||
|
||||
## [0.3.0] - 2021-03-25
|
||||
|
||||
### Added
|
||||
|
||||
- Add `class` strategy for you babies and your custom select and date picker libraries ;) ([#39](https://github.com/tailwindlabs/tailwindcss-forms/pull/39))
|
||||
|
||||
## [0.2.1] - 2020-11-17
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix issue where default checkbox/radio border color took precedence over user border color on focus ([d0b9fd9](https://github.com/tailwindlabs/tailwindcss-forms/commit/d0b9fd9))
|
||||
|
||||
## [0.2.0] - 2020-11-16
|
||||
|
||||
### Changed
|
||||
|
||||
- Update form styles to be less opinionated and encourage custom styling ([3288709](https://github.com/tailwindlabs/tailwindcss-forms/commit/3288709b59f4101511ec19f30cb2dafe7738251e))
|
||||
- Update custom property names to match namespaced variables in Tailwind CSS v2.0 ([adb9807](https://github.com/tailwindlabs/tailwindcss-forms/commit/adb98078fc830d0416cb5ea2c895e997d5f0a5ec), [bbd8510](https://github.com/tailwindlabs/tailwindcss-forms/commit/bbd85102ef4a402b3c39d997c025208a33694cc4))
|
||||
|
||||
## [0.1.4] - 2020-11-12
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix SVG background images not rendering properly in all browsers ([#5](https://github.com/tailwindlabs/tailwindcss-forms/pull/5))
|
||||
|
||||
## [0.1.3] - 2020-11-12
|
||||
|
||||
### Changed
|
||||
|
||||
- Update focus styles to account for changes to `ring` API in latest Tailwind CSS 2.0 alpha ([5c16689](https://github.com/tailwindlabs/tailwindcss-forms/commit/5c166896b06475832bd8364f9f3ef5c4baec585f))
|
||||
|
||||
## [0.1.2] - 2020-11-11
|
||||
|
||||
### Fixed
|
||||
|
||||
- Work around iOS Safari bug that causes date inputs to render with no height when empty ([b98365b](https://github.com/tailwindlabs/tailwindcss-forms/commit/b98365b903b586bfbe7a6ae745ba64b5d87e23e3))
|
||||
|
||||
## [0.1.1] - 2020-11-11
|
||||
|
||||
### Changed
|
||||
|
||||
- Move `tailwindcss` to dependencies, hoping to get it working with Tailwind Play ([d625ea1](https://github.com/tailwindlabs/tailwindcss-forms/commit/d625ea11bd111a4d8cde937e36f3d229ecdf7c6a))
|
||||
|
||||
## [0.1.0] - 2020-11-11
|
||||
|
||||
Initial release!
|
||||
|
||||
[unreleased]: https://github.com/tailwindlabs/tailwindcss-forms/compare/v0.5.3...HEAD
|
||||
[0.5.3]: https://github.com/tailwindlabs/tailwindcss-forms/compare/v0.5.2...v0.5.3
|
||||
[0.5.2]: https://github.com/tailwindlabs/tailwindcss-forms/compare/v0.5.1...v0.5.2
|
||||
[0.5.1]: https://github.com/tailwindlabs/tailwindcss-forms/compare/v0.5.0...v0.5.1
|
||||
[0.5.0]: https://github.com/tailwindlabs/tailwindcss-forms/compare/v0.4.1...v0.5.0
|
||||
[0.4.1]: https://github.com/tailwindlabs/tailwindcss-forms/compare/v0.4.0...v0.4.1
|
||||
[0.4.0]: https://github.com/tailwindlabs/tailwindcss-forms/compare/v0.3.3...v0.4.0
|
||||
[0.3.4]: https://github.com/tailwindlabs/tailwindcss-forms/compare/v0.3.3...v0.3.4
|
||||
[0.3.3]: https://github.com/tailwindlabs/tailwindcss-forms/compare/v0.3.2...v0.3.3
|
||||
[0.3.2]: https://github.com/tailwindlabs/tailwindcss-forms/compare/v0.3.1...v0.3.2
|
||||
[0.3.1]: https://github.com/tailwindlabs/tailwindcss-forms/compare/v0.3.0...v0.3.1
|
||||
[0.3.0]: https://github.com/tailwindlabs/tailwindcss-forms/compare/v0.2.1...v0.3.0
|
||||
[0.2.1]: https://github.com/tailwindlabs/tailwindcss-forms/compare/v0.2.0...v0.2.1
|
||||
[0.2.0]: https://github.com/tailwindlabs/tailwindcss-forms/compare/v0.1.4...v0.2.0
|
||||
[0.1.4]: https://github.com/tailwindlabs/tailwindcss-forms/compare/v0.1.3...v0.1.4
|
||||
[0.1.3]: https://github.com/tailwindlabs/tailwindcss-forms/compare/v0.1.2...v0.1.3
|
||||
[0.1.2]: https://github.com/tailwindlabs/tailwindcss-forms/compare/v0.1.1...v0.1.2
|
||||
[0.1.1]: https://github.com/tailwindlabs/tailwindcss-forms/compare/v0.1.0...v0.1.1
|
||||
[0.1.0]: https://github.com/tailwindlabs/tailwindcss-forms/releases/tag/v0.1.0
|
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) Tailwind Labs, Inc.
|
||||
|
||||
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 NONINFRINGEMENT. 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.
|
@ -0,0 +1,124 @@
|
||||
# @tailwindcss/forms
|
||||
|
||||
A plugin that provides a basic reset for form styles that makes form elements easy to override with utilities.
|
||||
|
||||
## Installation
|
||||
|
||||
Install the plugin from npm:
|
||||
|
||||
```sh
|
||||
npm install -D @tailwindcss/forms
|
||||
```
|
||||
|
||||
Then add the plugin to your `tailwind.config.js` file:
|
||||
|
||||
```js
|
||||
// tailwind.config.js
|
||||
module.exports = {
|
||||
theme: {
|
||||
// ...
|
||||
},
|
||||
plugins: [
|
||||
require('@tailwindcss/forms'),
|
||||
// ...
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
[**View the live demo**](https://tailwindcss-forms.vercel.app/)
|
||||
|
||||
All of the basic form elements you use will now have some simple default styles that are easy to override with utilities.
|
||||
|
||||
Currently we add basic utility-friendly form styles for the following form element types:
|
||||
|
||||
- `input[type='text']`
|
||||
- `input[type='password']`
|
||||
- `input[type='email']`
|
||||
- `input[type='number']`
|
||||
- `input[type='url']`
|
||||
- `input[type='date']`
|
||||
- `input[type='datetime-local']`
|
||||
- `input[type='month']`
|
||||
- `input[type='week']`
|
||||
- `input[type='time']`
|
||||
- `input[type='search']`
|
||||
- `input[type='tel']`
|
||||
- `input[type='checkbox']`
|
||||
- `input[type='radio']`
|
||||
- `select`
|
||||
- `select[multiple]`
|
||||
- `textarea`
|
||||
|
||||
**Note that for text inputs, you must add the `type="text"` attribute for these styles to take effect.** This is a necessary trade-off to avoid relying on the overly greedy `input` selector and unintentionally styling elements we don't have solutions for yet, like `input[type="range"]` for example.
|
||||
|
||||
Every element has been normalized/reset to a simple visually consistent style that is easy to customize with utilities, even elements like `<select>` or `<input type="checkbox">` that normally need to be reset with `appearance: none` and customized using custom CSS:
|
||||
|
||||
```html
|
||||
<!-- You can actually customize padding on a select element now: -->
|
||||
<select class="px-4 py-3 rounded-full">
|
||||
<!-- ... -->
|
||||
</select>
|
||||
|
||||
<!-- Or change a checkbox color using text color utilities: -->
|
||||
<input type="checkbox" class="rounded text-pink-500" />
|
||||
```
|
||||
|
||||
More customization examples and best practices coming soon.
|
||||
|
||||
### Using classes to style
|
||||
|
||||
In addition to the global styles, we also generate a set of corresponding classes which can be used to explicitly apply the form styles to an element. This can be useful in situations where you need to make a non-form element, such as a `<div>`, look like a form element.
|
||||
|
||||
```html
|
||||
<input type="email" class="form-input px-4 py-3 rounded-full">
|
||||
|
||||
<select class="form-select px-4 py-3 rounded-full">
|
||||
<!-- ... -->
|
||||
</select>
|
||||
|
||||
<input type="checkbox" class="form-checkbox rounded text-pink-500" />
|
||||
```
|
||||
|
||||
Here is a complete table of the provided `form-*` classes for reference:
|
||||
|
||||
| Base | Class |
|
||||
| ------------------------- | ------------------ |
|
||||
| `[type='text']` | `form-input` |
|
||||
| `[type='email']` | `form-input` |
|
||||
| `[type='url']` | `form-input` |
|
||||
| `[type='password']` | `form-input` |
|
||||
| `[type='number']` | `form-input` |
|
||||
| `[type='date']` | `form-input` |
|
||||
| `[type='datetime-local']` | `form-input` |
|
||||
| `[type='month']` | `form-input` |
|
||||
| `[type='search']` | `form-input` |
|
||||
| `[type='tel']` | `form-input` |
|
||||
| `[type='time']` | `form-input` |
|
||||
| `[type='week']` | `form-input` |
|
||||
| `textarea` | `form-textarea` |
|
||||
| `select` | `form-select` |
|
||||
| `select[multiple]` | `form-multiselect` |
|
||||
| `[type='checkbox']` | `form-checkbox` |
|
||||
| `[type='radio']` | `form-radio` |
|
||||
|
||||
### Using only global styles or only classes
|
||||
|
||||
Although we recommend thinking of this plugin as a "form reset" rather than a collection of form component styles, in some cases our default approach may be too heavy-handed, especially when integrating this plugin into existing projects.
|
||||
|
||||
If generating both the global (base) styles and classes doesn't work well with your project, you can use the `strategy` option to limit the plugin to just one of these approaches.
|
||||
|
||||
```js
|
||||
// tailwind.config.js
|
||||
plugins: [
|
||||
require("@tailwindcss/forms")({
|
||||
strategy: 'base', // only generate global styles
|
||||
strategy: 'class', // only generate classes
|
||||
}),
|
||||
],
|
||||
```
|
||||
|
||||
When using the `base` strategy, form elements are styled globally, and no `form-{name}` classes are generated.
|
||||
|
||||
When using the `class` strategy, form elements are not styled globally, and instead must be styled using the generated `form-{name}` classes.
|
@ -0,0 +1,390 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>@tailwindcss/forms examples</title>
|
||||
<link rel="stylesheet" href="/dist/tailwind.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="antialiased text-gray-900 px-6">
|
||||
<div class="max-w-xl mx-auto py-12 divide-y md:max-w-4xl">
|
||||
<div class="py-8">
|
||||
<h1 class="text-4xl font-bold">@tailwindcss/forms examples</h1>
|
||||
<p class="mt-2 text-lg text-gray-600">
|
||||
An opinionated form reset designed to make form elements easy to style with utility
|
||||
classes.
|
||||
</p>
|
||||
<div class="mt-4 flex space-x-4">
|
||||
<a class="text-lg underline" href="https://github.com/tailwindlabs/tailwindcss-forms"
|
||||
>Documentation</a
|
||||
>
|
||||
<a class="text-lg underline" href="/kitchen-sink.html">Kitchen Sink</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="py-12">
|
||||
<h2 class="text-2xl font-bold">Unstyled</h2>
|
||||
<p class="mt-2 text-lg text-gray-600">This is how form elements look out of the box.</p>
|
||||
<div class="mt-8 max-w-md">
|
||||
<div class="grid grid-cols-1 gap-6">
|
||||
<label class="block">
|
||||
<span class="text-gray-700">Full name</span>
|
||||
<input type="text" class="mt-1 block w-full" placeholder="" />
|
||||
</label>
|
||||
<label class="block">
|
||||
<span class="text-gray-700">Email address</span>
|
||||
<input type="email" class="mt-1 block w-full" placeholder="john@example.com" />
|
||||
</label>
|
||||
<label class="block">
|
||||
<span class="text-gray-700">When is your event?</span>
|
||||
<input type="date" class="mt-1 block w-full" />
|
||||
</label>
|
||||
<label class="block">
|
||||
<span class="text-gray-700">What type of event is it?</span>
|
||||
<select class="block w-full mt-1">
|
||||
<option>Corporate event</option>
|
||||
<option>Wedding</option>
|
||||
<option>Birthday</option>
|
||||
<option>Other</option>
|
||||
</select>
|
||||
</label>
|
||||
<label class="block">
|
||||
<span class="text-gray-700">Additional details</span>
|
||||
<textarea class="mt-1 block w-full" rows="3"></textarea>
|
||||
</label>
|
||||
<div class="block">
|
||||
<div class="mt-2">
|
||||
<div>
|
||||
<label class="inline-flex items-center">
|
||||
<input type="checkbox" checked />
|
||||
<span class="ml-2">Email me news and special offers</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="py-12">
|
||||
<h2 class="text-2xl font-bold">Simple</h2>
|
||||
<div class="mt-8 max-w-md">
|
||||
<div class="grid grid-cols-1 gap-6">
|
||||
<label class="block">
|
||||
<span class="text-gray-700">Full name</span>
|
||||
<input
|
||||
type="text"
|
||||
class="
|
||||
mt-1
|
||||
block
|
||||
w-full
|
||||
rounded-md
|
||||
border-gray-300
|
||||
shadow-sm
|
||||
focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50
|
||||
"
|
||||
placeholder=""
|
||||
/>
|
||||
</label>
|
||||
<label class="block">
|
||||
<span class="text-gray-700">Email address</span>
|
||||
<input
|
||||
type="email"
|
||||
class="
|
||||
mt-1
|
||||
block
|
||||
w-full
|
||||
rounded-md
|
||||
border-gray-300
|
||||
shadow-sm
|
||||
focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50
|
||||
"
|
||||
placeholder="john@example.com"
|
||||
/>
|
||||
</label>
|
||||
<label class="block">
|
||||
<span class="text-gray-700">When is your event?</span>
|
||||
<input
|
||||
type="date"
|
||||
class="
|
||||
mt-1
|
||||
block
|
||||
w-full
|
||||
rounded-md
|
||||
border-gray-300
|
||||
shadow-sm
|
||||
focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50
|
||||
"
|
||||
/>
|
||||
</label>
|
||||
<label class="block">
|
||||
<span class="text-gray-700">What type of event is it?</span>
|
||||
<select
|
||||
class="
|
||||
block
|
||||
w-full
|
||||
mt-1
|
||||
rounded-md
|
||||
border-gray-300
|
||||
shadow-sm
|
||||
focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50
|
||||
"
|
||||
>
|
||||
<option>Corporate event</option>
|
||||
<option>Wedding</option>
|
||||
<option>Birthday</option>
|
||||
<option>Other</option>
|
||||
</select>
|
||||
</label>
|
||||
<label class="block">
|
||||
<span class="text-gray-700">Additional details</span>
|
||||
<textarea
|
||||
class="
|
||||
mt-1
|
||||
block
|
||||
w-full
|
||||
rounded-md
|
||||
border-gray-300
|
||||
shadow-sm
|
||||
focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50
|
||||
"
|
||||
rows="3"
|
||||
></textarea>
|
||||
</label>
|
||||
<div class="block">
|
||||
<div class="mt-2">
|
||||
<div>
|
||||
<label class="inline-flex items-center">
|
||||
<input
|
||||
type="checkbox"
|
||||
class="
|
||||
rounded
|
||||
border-gray-300
|
||||
text-indigo-600
|
||||
shadow-sm
|
||||
focus:border-indigo-300
|
||||
focus:ring
|
||||
focus:ring-offset-0
|
||||
focus:ring-indigo-200
|
||||
focus:ring-opacity-50
|
||||
"
|
||||
checked
|
||||
/>
|
||||
<span class="ml-2">Email me news and special offers</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="py-12">
|
||||
<h2 class="text-2xl font-bold">Underline</h2>
|
||||
<div class="mt-8 max-w-md">
|
||||
<div class="grid grid-cols-1 gap-6">
|
||||
<label class="block">
|
||||
<span class="text-gray-700">Full name</span>
|
||||
<input
|
||||
type="text"
|
||||
class="
|
||||
mt-0
|
||||
block
|
||||
w-full
|
||||
px-0.5
|
||||
border-0 border-b-2 border-gray-200
|
||||
focus:ring-0 focus:border-black
|
||||
"
|
||||
placeholder=""
|
||||
/>
|
||||
</label>
|
||||
<label class="block">
|
||||
<span class="text-gray-700">Email address</span>
|
||||
<input
|
||||
type="email"
|
||||
class="
|
||||
mt-0
|
||||
block
|
||||
w-full
|
||||
px-0.5
|
||||
border-0 border-b-2 border-gray-200
|
||||
focus:ring-0 focus:border-black
|
||||
"
|
||||
placeholder="john@example.com"
|
||||
/>
|
||||
</label>
|
||||
<label class="block">
|
||||
<span class="text-gray-700">When is your event?</span>
|
||||
<input
|
||||
type="date"
|
||||
class="
|
||||
mt-0
|
||||
block
|
||||
w-full
|
||||
px-0.5
|
||||
border-0 border-b-2 border-gray-200
|
||||
focus:ring-0 focus:border-black
|
||||
"
|
||||
/>
|
||||
</label>
|
||||
<label class="block">
|
||||
<span class="text-gray-700">What type of event is it?</span>
|
||||
<select
|
||||
class="
|
||||
block
|
||||
w-full
|
||||
mt-0
|
||||
px-0.5
|
||||
border-0 border-b-2 border-gray-200
|
||||
focus:ring-0 focus:border-black
|
||||
"
|
||||
>
|
||||
<option>Corporate event</option>
|
||||
<option>Wedding</option>
|
||||
<option>Birthday</option>
|
||||
<option>Other</option>
|
||||
</select>
|
||||
</label>
|
||||
<label class="block">
|
||||
<span class="text-gray-700">Additional details</span>
|
||||
<textarea
|
||||
class="
|
||||
mt-0
|
||||
block
|
||||
w-full
|
||||
px-0.5
|
||||
border-0 border-b-2 border-gray-200
|
||||
focus:ring-0 focus:border-black
|
||||
"
|
||||
rows="2"
|
||||
></textarea>
|
||||
</label>
|
||||
<div class="block">
|
||||
<div class="mt-2">
|
||||
<div>
|
||||
<label class="inline-flex items-center">
|
||||
<input
|
||||
type="checkbox"
|
||||
class="
|
||||
border-gray-300 border-2
|
||||
text-black
|
||||
focus:border-gray-300 focus:ring-black
|
||||
"
|
||||
/>
|
||||
<span class="ml-2">Email me news and special offers</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="py-12">
|
||||
<h2 class="text-2xl font-bold">Solid</h2>
|
||||
<div class="mt-8 max-w-md">
|
||||
<div class="grid grid-cols-1 gap-6">
|
||||
<label class="block">
|
||||
<span class="text-gray-700">Full name</span>
|
||||
<input
|
||||
type="text"
|
||||
class="
|
||||
mt-1
|
||||
block
|
||||
w-full
|
||||
rounded-md
|
||||
bg-gray-100
|
||||
border-transparent
|
||||
focus:border-gray-500 focus:bg-white focus:ring-0
|
||||
"
|
||||
placeholder=""
|
||||
/>
|
||||
</label>
|
||||
<label class="block">
|
||||
<span class="text-gray-700">Email address</span>
|
||||
<input
|
||||
type="email"
|
||||
class="
|
||||
mt-1
|
||||
block
|
||||
w-full
|
||||
rounded-md
|
||||
bg-gray-100
|
||||
border-transparent
|
||||
focus:border-gray-500 focus:bg-white focus:ring-0
|
||||
"
|
||||
placeholder="john@example.com"
|
||||
/>
|
||||
</label>
|
||||
<label class="block">
|
||||
<span class="text-gray-700">When is your event?</span>
|
||||
<input
|
||||
type="date"
|
||||
class="
|
||||
mt-1
|
||||
block
|
||||
w-full
|
||||
rounded-md
|
||||
bg-gray-100
|
||||
border-transparent
|
||||
focus:border-gray-500 focus:bg-white focus:ring-0
|
||||
"
|
||||
/>
|
||||
</label>
|
||||
<label class="block">
|
||||
<span class="text-gray-700">What type of event is it?</span>
|
||||
<select
|
||||
class="
|
||||
block
|
||||
w-full
|
||||
mt-1
|
||||
rounded-md
|
||||
bg-gray-100
|
||||
border-transparent
|
||||
focus:border-gray-500 focus:bg-white focus:ring-0
|
||||
"
|
||||
>
|
||||
<option>Corporate event</option>
|
||||
<option>Wedding</option>
|
||||
<option>Birthday</option>
|
||||
<option>Other</option>
|
||||
</select>
|
||||
</label>
|
||||
<label class="block">
|
||||
<span class="text-gray-700">Additional details</span>
|
||||
<textarea
|
||||
class="
|
||||
mt-1
|
||||
block
|
||||
w-full
|
||||
rounded-md
|
||||
bg-gray-100
|
||||
border-transparent
|
||||
focus:border-gray-500 focus:bg-white focus:ring-0
|
||||
"
|
||||
rows="3"
|
||||
></textarea>
|
||||
</label>
|
||||
<div class="block">
|
||||
<div class="mt-2">
|
||||
<div>
|
||||
<label class="inline-flex items-center">
|
||||
<input
|
||||
type="checkbox"
|
||||
class="
|
||||
rounded
|
||||
bg-gray-200
|
||||
border-transparent
|
||||
focus:border-transparent focus:bg-gray-200
|
||||
text-gray-700
|
||||
focus:ring-1 focus:ring-offset-2 focus:ring-gray-500
|
||||
"
|
||||
/>
|
||||
<span class="ml-2">Email me news and special offers</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,201 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>@tailwindcss/forms Kitchen Sink</title>
|
||||
<link rel="stylesheet" href="/dist/tailwind.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="antialiased text-gray-900 px-6">
|
||||
<div class="max-w-xl mx-auto py-12 md:max-w-4xl">
|
||||
<h2 class="text-2xl font-bold">Reset styles</h2>
|
||||
<p class="mt-2 text-lg text-gray-500">
|
||||
These are form elements this plugin styles by default.
|
||||
</p>
|
||||
<div class="mt-8 grid grid-cols-1 md:grid-cols-2 gap-6 items-start">
|
||||
<div class="grid grid-cols-1 gap-6">
|
||||
<label class="block">
|
||||
<span class="text-gray-700">Input (text)</span>
|
||||
<input
|
||||
type="text"
|
||||
class="form-input mt-1 block w-full"
|
||||
placeholder="john@example.com"
|
||||
/>
|
||||
</label>
|
||||
<label class="block">
|
||||
<span class="text-gray-700">Input (email)</span>
|
||||
<input
|
||||
type="email"
|
||||
class="form-input mt-1 block w-full"
|
||||
placeholder="john@example.com"
|
||||
/>
|
||||
</label>
|
||||
<label class="block">
|
||||
<span class="text-gray-700">Input (email, multiple)</span>
|
||||
<input
|
||||
type="email"
|
||||
multiple
|
||||
class="form-input mt-1 block w-full"
|
||||
placeholder="john@example.com"
|
||||
/>
|
||||
</label>
|
||||
<label class="block">
|
||||
<span class="text-gray-700">Input (password)</span>
|
||||
<input
|
||||
type="password"
|
||||
class="form-input mt-1 block w-full"
|
||||
placeholder="john@example.com"
|
||||
/>
|
||||
</label>
|
||||
<label class="block">
|
||||
<span class="text-gray-700">Input (date)</span>
|
||||
<input type="date" class="form-input mt-1 block w-full" />
|
||||
</label>
|
||||
<label class="block">
|
||||
<span class="text-gray-700">Input (datetime-local)</span>
|
||||
<input type="datetime-local" class="form-input mt-1 block w-full" />
|
||||
</label>
|
||||
<label class="block">
|
||||
<span class="text-gray-700">Input (month)</span>
|
||||
<input type="month" class="form-input mt-1 block w-full" />
|
||||
</label>
|
||||
<label class="block">
|
||||
<span class="text-gray-700">Input (number)</span>
|
||||
<input type="number" class="form-input mt-1 block w-full" />
|
||||
</label>
|
||||
<label class="block">
|
||||
<span class="text-gray-700">Input (search)</span>
|
||||
<input type="search" class="form-input mt-1 block w-full" />
|
||||
</label>
|
||||
<label class="block">
|
||||
<span class="text-gray-700">Input (time)</span>
|
||||
<input type="time" class="form-input mt-1 block w-full" />
|
||||
</label>
|
||||
<label class="block">
|
||||
<span class="text-gray-700">Input (week)</span>
|
||||
<input type="week" class="form-input mt-1 block w-full" />
|
||||
</label>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 gap-6">
|
||||
<label class="block">
|
||||
<span class="text-gray-700">Input (tel)</span>
|
||||
<input
|
||||
type="tel"
|
||||
multiple
|
||||
class="form-input mt-1 block w-full"
|
||||
placeholder="john@example.com"
|
||||
/>
|
||||
</label>
|
||||
<label class="block">
|
||||
<span class="text-gray-700">Input (url)</span>
|
||||
<input
|
||||
type="url"
|
||||
multiple
|
||||
class="form-input mt-1 block w-full"
|
||||
placeholder="john@example.com"
|
||||
/>
|
||||
</label>
|
||||
<label class="block">
|
||||
<span class="text-gray-700">Select</span>
|
||||
<select class="form-select block w-full mt-1">
|
||||
<option>Option 1</option>
|
||||
<option>Option 2</option>
|
||||
</select>
|
||||
</label>
|
||||
<label class="block">
|
||||
<span class="text-gray-700">Select (multiple)</span>
|
||||
<select class="form-multiselect block w-full mt-1" multiple>
|
||||
<option>Option 1</option>
|
||||
<option>Option 2</option>
|
||||
<option>Option 3</option>
|
||||
<option>Option 4</option>
|
||||
<option>Option 5</option>
|
||||
</select>
|
||||
</label>
|
||||
<label class="block">
|
||||
<span class="text-gray-700">Textarea</span>
|
||||
<textarea
|
||||
class="form-textarea mt-1 block w-full h-24"
|
||||
rows="3"
|
||||
placeholder="Enter some long form content."
|
||||
></textarea>
|
||||
</label>
|
||||
<fieldset class="block">
|
||||
<legend class="text-gray-700">Checkboxes</legend>
|
||||
<div class="mt-2">
|
||||
<div>
|
||||
<label class="inline-flex items-center">
|
||||
<input class="form-checkbox" type="checkbox" checked />
|
||||
<span class="ml-2">Option 1</span>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label class="inline-flex items-center">
|
||||
<input class="form-checkbox" type="checkbox" />
|
||||
<span class="ml-2">Option 2</span>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label class="inline-flex items-center">
|
||||
<input class="form-checkbox" type="checkbox" />
|
||||
<span class="ml-2">Option 3</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="block">
|
||||
<legend class="text-gray-700">Radio Buttons</legend>
|
||||
<div class="mt-2">
|
||||
<div>
|
||||
<label class="inline-flex items-center">
|
||||
<input class="form-radio" type="radio" checked name="radio-direct" value="1" />
|
||||
<span class="ml-2">Option 1</span>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label class="inline-flex items-center">
|
||||
<input class="form-radio" type="radio" name="radio-direct" value="2" />
|
||||
<span class="ml-2">Option 2</span>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label class="inline-flex items-center">
|
||||
<input class="form-radio" type="radio" name="radio-direct" value="3" />
|
||||
<span class="ml-2">Option 3</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="max-w-4xl mx-auto py-12">
|
||||
<h2 class="text-2xl font-bold">Untouched</h2>
|
||||
<p class="mt-2 text-lg text-gray-500">
|
||||
These are form elements we don't handle (yet?), but we use this to make sure we haven't
|
||||
accidentally styled them by mistake.
|
||||
</p>
|
||||
<div class="mt-8 grid grid-cols-2 gap-6 items-start">
|
||||
<div class="grid grid-cols-1 gap-6">
|
||||
<label class="block">
|
||||
<span class="text-gray-700">Input (range)</span>
|
||||
<input type="range" class="mt-1 block w-full" />
|
||||
</label>
|
||||
<label class="block">
|
||||
<span class="text-gray-700">Input (color)</span>
|
||||
<input type="color" class="mt-1 block w-full" />
|
||||
</label>
|
||||
<label class="block">
|
||||
<span class="text-gray-700">Input (file)</span>
|
||||
<input type="file" class="mt-1 block w-full" />
|
||||
</label>
|
||||
<label class="block">
|
||||
<span class="text-gray-700">Input (file, multiple)</span>
|
||||
<input type="file" multiple class="mt-1 block w-full" />
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "@tailwindcss/forms",
|
||||
"version": "0.5.3",
|
||||
"main": "src/index.js",
|
||||
"types": "src/index.d.ts",
|
||||
"license": "MIT",
|
||||
"repository": "https://github.com/tailwindlabs/tailwindcss-forms",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"prettier": {
|
||||
"printWidth": 100,
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "es5"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "concurrently \"npm run serve\" \"npm run watch\"",
|
||||
"serve": "live-server .",
|
||||
"watch": "npm run build -- -w",
|
||||
"build": "tailwindcss -o dist/tailwind.css"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "^10.4.6",
|
||||
"concurrently": "^5.3.0",
|
||||
"live-server": "^1.2.2",
|
||||
"postcss": "^8.4.13",
|
||||
"tailwindcss": "^3.0.24"
|
||||
},
|
||||
"dependencies": {
|
||||
"mini-svg-data-uri": "^1.2.3"
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
declare function plugin(options?: Partial<{ strategy: 'base' | 'class' }>): { handler: () => void }
|
||||
|
||||
declare namespace plugin {
|
||||
const __isOptionsFunction: true
|
||||
}
|
||||
|
||||
export = plugin
|
@ -0,0 +1,306 @@
|
||||
const svgToDataUri = require('mini-svg-data-uri')
|
||||
const plugin = require('tailwindcss/plugin')
|
||||
const defaultTheme = require('tailwindcss/defaultTheme')
|
||||
const colors = require('tailwindcss/colors')
|
||||
const [baseFontSize, { lineHeight: baseLineHeight }] = defaultTheme.fontSize.base
|
||||
const { spacing, borderWidth, borderRadius } = defaultTheme
|
||||
|
||||
const forms = plugin.withOptions(function (options = { strategy: undefined }) {
|
||||
return function ({ addBase, addComponents, theme }) {
|
||||
const strategy = options.strategy === undefined ? ['base', 'class'] : [options.strategy]
|
||||
|
||||
const rules = [
|
||||
{
|
||||
base: [
|
||||
"[type='text']",
|
||||
"[type='email']",
|
||||
"[type='url']",
|
||||
"[type='password']",
|
||||
"[type='number']",
|
||||
"[type='date']",
|
||||
"[type='datetime-local']",
|
||||
"[type='month']",
|
||||
"[type='search']",
|
||||
"[type='tel']",
|
||||
"[type='time']",
|
||||
"[type='week']",
|
||||
'[multiple]',
|
||||
'textarea',
|
||||
'select',
|
||||
],
|
||||
class: ['.form-input', '.form-textarea', '.form-select', '.form-multiselect'],
|
||||
styles: {
|
||||
appearance: 'none',
|
||||
'background-color': '#fff',
|
||||
'border-color': theme('colors.gray.500', colors.gray[500]),
|
||||
'border-width': borderWidth['DEFAULT'],
|
||||
'border-radius': borderRadius.none,
|
||||
'padding-top': spacing[2],
|
||||
'padding-right': spacing[3],
|
||||
'padding-bottom': spacing[2],
|
||||
'padding-left': spacing[3],
|
||||
'font-size': baseFontSize,
|
||||
'line-height': baseLineHeight,
|
||||
'--tw-shadow': '0 0 #0000',
|
||||
'&:focus': {
|
||||
outline: '2px solid transparent',
|
||||
'outline-offset': '2px',
|
||||
'--tw-ring-inset': 'var(--tw-empty,/*!*/ /*!*/)',
|
||||
'--tw-ring-offset-width': '0px',
|
||||
'--tw-ring-offset-color': '#fff',
|
||||
'--tw-ring-color': theme('colors.blue.600', colors.blue[600]),
|
||||
'--tw-ring-offset-shadow': `var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)`,
|
||||
'--tw-ring-shadow': `var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color)`,
|
||||
'box-shadow': `var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)`,
|
||||
'border-color': theme('colors.blue.600', colors.blue[600]),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
base: ['input::placeholder', 'textarea::placeholder'],
|
||||
class: ['.form-input::placeholder', '.form-textarea::placeholder'],
|
||||
styles: {
|
||||
color: theme('colors.gray.500', colors.gray[500]),
|
||||
opacity: '1',
|
||||
},
|
||||
},
|
||||
{
|
||||
base: ['::-webkit-datetime-edit-fields-wrapper'],
|
||||
class: ['.form-input::-webkit-datetime-edit-fields-wrapper'],
|
||||
styles: {
|
||||
padding: '0',
|
||||
},
|
||||
},
|
||||
{
|
||||
// Unfortunate hack until https://bugs.webkit.org/show_bug.cgi?id=198959 is fixed.
|
||||
// This sucks because users can't change line-height with a utility on date inputs now.
|
||||
// Reference: https://github.com/twbs/bootstrap/pull/31993
|
||||
base: ['::-webkit-date-and-time-value'],
|
||||
class: ['.form-input::-webkit-date-and-time-value'],
|
||||
styles: {
|
||||
'min-height': '1.5em',
|
||||
},
|
||||
},
|
||||
{
|
||||
// In Safari on macOS date time inputs are 4px taller than normal inputs
|
||||
// This is because there is extra padding on the datetime-edit and datetime-edit-{part}-field pseudo elements
|
||||
// See https://github.com/tailwindlabs/tailwindcss-forms/issues/95
|
||||
base: [
|
||||
'::-webkit-datetime-edit',
|
||||
'::-webkit-datetime-edit-year-field',
|
||||
'::-webkit-datetime-edit-month-field',
|
||||
'::-webkit-datetime-edit-day-field',
|
||||
'::-webkit-datetime-edit-hour-field',
|
||||
'::-webkit-datetime-edit-minute-field',
|
||||
'::-webkit-datetime-edit-second-field',
|
||||
'::-webkit-datetime-edit-millisecond-field',
|
||||
'::-webkit-datetime-edit-meridiem-field',
|
||||
],
|
||||
class: [
|
||||
'.form-input::-webkit-datetime-edit',
|
||||
'.form-input::-webkit-datetime-edit-year-field',
|
||||
'.form-input::-webkit-datetime-edit-month-field',
|
||||
'.form-input::-webkit-datetime-edit-day-field',
|
||||
'.form-input::-webkit-datetime-edit-hour-field',
|
||||
'.form-input::-webkit-datetime-edit-minute-field',
|
||||
'.form-input::-webkit-datetime-edit-second-field',
|
||||
'.form-input::-webkit-datetime-edit-millisecond-field',
|
||||
'.form-input::-webkit-datetime-edit-meridiem-field',
|
||||
],
|
||||
styles: {
|
||||
'padding-top': 0,
|
||||
'padding-bottom': 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
base: ['select'],
|
||||
class: ['.form-select'],
|
||||
styles: {
|
||||
'background-image': `url("${svgToDataUri(
|
||||
`<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20"><path stroke="${theme(
|
||||
'colors.gray.500',
|
||||
colors.gray[500]
|
||||
)}" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M6 8l4 4 4-4"/></svg>`
|
||||
)}")`,
|
||||
'background-position': `right ${spacing[2]} center`,
|
||||
'background-repeat': `no-repeat`,
|
||||
'background-size': `1.5em 1.5em`,
|
||||
'padding-right': spacing[10],
|
||||
'print-color-adjust': `exact`,
|
||||
},
|
||||
},
|
||||
{
|
||||
base: ['[multiple]'],
|
||||
class: null,
|
||||
styles: {
|
||||
'background-image': 'initial',
|
||||
'background-position': 'initial',
|
||||
'background-repeat': 'unset',
|
||||
'background-size': 'initial',
|
||||
'padding-right': spacing[3],
|
||||
'print-color-adjust': 'unset',
|
||||
},
|
||||
},
|
||||
{
|
||||
base: [`[type='checkbox']`, `[type='radio']`],
|
||||
class: ['.form-checkbox', '.form-radio'],
|
||||
styles: {
|
||||
appearance: 'none',
|
||||
padding: '0',
|
||||
'print-color-adjust': 'exact',
|
||||
display: 'inline-block',
|
||||
'vertical-align': 'middle',
|
||||
'background-origin': 'border-box',
|
||||
'user-select': 'none',
|
||||
'flex-shrink': '0',
|
||||
height: spacing[4],
|
||||
width: spacing[4],
|
||||
color: theme('colors.blue.600', colors.blue[600]),
|
||||
'background-color': '#fff',
|
||||
'border-color': theme('colors.gray.500', colors.gray[500]),
|
||||
'border-width': borderWidth['DEFAULT'],
|
||||
'--tw-shadow': '0 0 #0000',
|
||||
},
|
||||
},
|
||||
{
|
||||
base: [`[type='checkbox']`],
|
||||
class: ['.form-checkbox'],
|
||||
styles: {
|
||||
'border-radius': borderRadius['none'],
|
||||
},
|
||||
},
|
||||
{
|
||||
base: [`[type='radio']`],
|
||||
class: ['.form-radio'],
|
||||
styles: {
|
||||
'border-radius': '100%',
|
||||
},
|
||||
},
|
||||
{
|
||||
base: [`[type='checkbox']:focus`, `[type='radio']:focus`],
|
||||
class: ['.form-checkbox:focus', '.form-radio:focus'],
|
||||
styles: {
|
||||
outline: '2px solid transparent',
|
||||
'outline-offset': '2px',
|
||||
'--tw-ring-inset': 'var(--tw-empty,/*!*/ /*!*/)',
|
||||
'--tw-ring-offset-width': '2px',
|
||||
'--tw-ring-offset-color': '#fff',
|
||||
'--tw-ring-color': theme('colors.blue.600', colors.blue[600]),
|
||||
'--tw-ring-offset-shadow': `var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)`,
|
||||
'--tw-ring-shadow': `var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color)`,
|
||||
'box-shadow': `var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)`,
|
||||
},
|
||||
},
|
||||
{
|
||||
base: [`[type='checkbox']:checked`, `[type='radio']:checked`],
|
||||
class: ['.form-checkbox:checked', '.form-radio:checked'],
|
||||
styles: {
|
||||
'border-color': `transparent`,
|
||||
'background-color': `currentColor`,
|
||||
'background-size': `100% 100%`,
|
||||
'background-position': `center`,
|
||||
'background-repeat': `no-repeat`,
|
||||
},
|
||||
},
|
||||
{
|
||||
base: [`[type='checkbox']:checked`],
|
||||
class: ['.form-checkbox:checked'],
|
||||
styles: {
|
||||
'background-image': `url("${svgToDataUri(
|
||||
`<svg viewBox="0 0 16 16" fill="white" xmlns="http://www.w3.org/2000/svg"><path d="M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z"/></svg>`
|
||||
)}")`,
|
||||
},
|
||||
},
|
||||
{
|
||||
base: [`[type='radio']:checked`],
|
||||
class: ['.form-radio:checked'],
|
||||
styles: {
|
||||
'background-image': `url("${svgToDataUri(
|
||||
`<svg viewBox="0 0 16 16" fill="white" xmlns="http://www.w3.org/2000/svg"><circle cx="8" cy="8" r="3"/></svg>`
|
||||
)}")`,
|
||||
},
|
||||
},
|
||||
{
|
||||
base: [
|
||||
`[type='checkbox']:checked:hover`,
|
||||
`[type='checkbox']:checked:focus`,
|
||||
`[type='radio']:checked:hover`,
|
||||
`[type='radio']:checked:focus`,
|
||||
],
|
||||
class: [
|
||||
'.form-checkbox:checked:hover',
|
||||
'.form-checkbox:checked:focus',
|
||||
'.form-radio:checked:hover',
|
||||
'.form-radio:checked:focus',
|
||||
],
|
||||
styles: {
|
||||
'border-color': 'transparent',
|
||||
'background-color': 'currentColor',
|
||||
},
|
||||
},
|
||||
{
|
||||
base: [`[type='checkbox']:indeterminate`],
|
||||
class: ['.form-checkbox:indeterminate'],
|
||||
styles: {
|
||||
'background-image': `url("${svgToDataUri(
|
||||
`<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 16 16"><path stroke="white" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 8h8"/></svg>`
|
||||
)}")`,
|
||||
'border-color': `transparent`,
|
||||
'background-color': `currentColor`,
|
||||
'background-size': `100% 100%`,
|
||||
'background-position': `center`,
|
||||
'background-repeat': `no-repeat`,
|
||||
},
|
||||
},
|
||||
{
|
||||
base: [`[type='checkbox']:indeterminate:hover`, `[type='checkbox']:indeterminate:focus`],
|
||||
class: ['.form-checkbox:indeterminate:hover', '.form-checkbox:indeterminate:focus'],
|
||||
styles: {
|
||||
'border-color': 'transparent',
|
||||
'background-color': 'currentColor',
|
||||
},
|
||||
},
|
||||
{
|
||||
base: [`[type='file']`],
|
||||
class: null,
|
||||
styles: {
|
||||
background: 'unset',
|
||||
'border-color': 'inherit',
|
||||
'border-width': '0',
|
||||
'border-radius': '0',
|
||||
padding: '0',
|
||||
'font-size': 'unset',
|
||||
'line-height': 'inherit',
|
||||
},
|
||||
},
|
||||
{
|
||||
base: [`[type='file']:focus`],
|
||||
class: null,
|
||||
styles: {
|
||||
outline: [
|
||||
`1px solid ButtonText`,
|
||||
`1px auto -webkit-focus-ring-color`
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
const getStrategyRules = (strategy) => rules
|
||||
.map((rule) => {
|
||||
if (rule[strategy] === null) return null
|
||||
|
||||
return { [rule[strategy]]: rule.styles }
|
||||
})
|
||||
.filter(Boolean)
|
||||
|
||||
if (strategy.includes('base')) {
|
||||
addBase(getStrategyRules('base'))
|
||||
}
|
||||
|
||||
if (strategy.includes('class')) {
|
||||
addComponents(getStrategyRules('class'))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
module.exports = forms
|
@ -0,0 +1,9 @@
|
||||
module.exports = {
|
||||
content: ['./index.html', './kitchen-sink.html'],
|
||||
theme: {
|
||||
extend: {
|
||||
//
|
||||
},
|
||||
},
|
||||
plugins: [require('./src')],
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 Taylor Hunt
|
||||
|
||||
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 NONINFRINGEMENT. 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.
|
@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
let help = `
|
||||
Usage: mini-svg-data-uri <source> [dest]
|
||||
|
||||
Options:
|
||||
-v, --version Output the version number
|
||||
-h, --help Display help for command
|
||||
|
||||
Examples:
|
||||
mini-svg-data-uri file.svg Write to stdout
|
||||
mini-svg-data-uri icon.svg icon.uri Write to file
|
||||
`;
|
||||
|
||||
let [source, dest] = process.argv.slice(2);
|
||||
|
||||
switch (source) {
|
||||
case '-h':
|
||||
case '--help':
|
||||
case undefined:
|
||||
console.log(help);
|
||||
process.exit();
|
||||
|
||||
case '-v':
|
||||
case '--version':
|
||||
console.log(require('./package').version);
|
||||
process.exit();
|
||||
}
|
||||
|
||||
const fs = require('fs');
|
||||
const svgToMiniDataURI = require('.');
|
||||
|
||||
fs.readFile(source, 'utf8', (err, data) => {
|
||||
if (err) {
|
||||
console.error(err.message);
|
||||
console.log(help);
|
||||
process.exit(1);
|
||||
}
|
||||
const out = svgToMiniDataURI(data);
|
||||
dest ? fs.writeFileSync(dest, out) : console.log(out);
|
||||
});
|
@ -0,0 +1,7 @@
|
||||
declare function svgToTinyDataUri(svgString: string): string;
|
||||
|
||||
declare namespace svgToTinyDataUri {
|
||||
function toSrcset(svgString: string): string;
|
||||
}
|
||||
|
||||
export = svgToTinyDataUri;
|
@ -0,0 +1,55 @@
|
||||
var shorterNames = require('./shorter-css-color-names');
|
||||
var REGEX = {
|
||||
whitespace: /\s+/g,
|
||||
urlHexPairs: /%[\dA-F]{2}/g,
|
||||
quotes: /"/g,
|
||||
}
|
||||
|
||||
function collapseWhitespace(str) {
|
||||
return str.trim().replace(REGEX.whitespace, ' ');
|
||||
}
|
||||
|
||||
function dataURIPayload(string) {
|
||||
return encodeURIComponent(string)
|
||||
.replace(REGEX.urlHexPairs, specialHexEncode);
|
||||
}
|
||||
|
||||
// `#` gets converted to `%23`, so quite a few CSS named colors are shorter than
|
||||
// their equivalent URL-encoded hex codes.
|
||||
function colorCodeToShorterNames(string) {
|
||||
Object.keys(shorterNames).forEach(function(key) {
|
||||
if (shorterNames[key].test(string)) {
|
||||
string = string.replace(shorterNames[key], key);
|
||||
}
|
||||
});
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
function specialHexEncode(match) {
|
||||
switch (match) { // Browsers tolerate these characters, and they're frequent
|
||||
case '%20': return ' ';
|
||||
case '%3D': return '=';
|
||||
case '%3A': return ':';
|
||||
case '%2F': return '/';
|
||||
default: return match.toLowerCase(); // compresses better
|
||||
}
|
||||
}
|
||||
|
||||
function svgToTinyDataUri(svgString) {
|
||||
if (typeof svgString !== 'string') {
|
||||
throw new TypeError('Expected a string, but received ' + typeof svgString);
|
||||
}
|
||||
// Strip the Byte-Order Mark if the SVG has one
|
||||
if (svgString.charCodeAt(0) === 0xfeff) { svgString = svgString.slice(1) }
|
||||
|
||||
var body = colorCodeToShorterNames(collapseWhitespace(svgString))
|
||||
.replace(REGEX.quotes, "'");
|
||||
return 'data:image/svg+xml,' + dataURIPayload(body);
|
||||
}
|
||||
|
||||
svgToTinyDataUri.toSrcset = function toSrcset(svgString) {
|
||||
return svgToTinyDataUri(svgString).replace(/ /g, '%20');
|
||||
}
|
||||
|
||||
module.exports = svgToTinyDataUri;
|
@ -0,0 +1,5 @@
|
||||
import svgToTinyDataUri from ".";
|
||||
|
||||
svgToTinyDataUri('xx');
|
||||
|
||||
svgToTinyDataUri.toSrcset('xxx');
|
@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "mini-svg-data-uri",
|
||||
"version": "1.4.4",
|
||||
"description": "Small, efficient encoding of SVG data URIs for CSS, HTML, etc.",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"bin": "cli.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/tigt/mini-svg-data-uri.git"
|
||||
},
|
||||
"keywords": [
|
||||
"svg",
|
||||
"url",
|
||||
"data",
|
||||
"uri",
|
||||
"minification",
|
||||
"url encoding"
|
||||
],
|
||||
"author": "Taylor “Tigt” Hunt <holla@ti.gt> (https://ti.gt/)",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/tigt/mini-svg-data-uri/issues"
|
||||
},
|
||||
"homepage": "https://github.com/tigt/mini-svg-data-uri#readme"
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
module.exports = {
|
||||
aqua: /#00ffff(ff)?(?!\w)|#0ff(f)?(?!\w)/gi,
|
||||
azure: /#f0ffff(ff)?(?!\w)/gi,
|
||||
beige: /#f5f5dc(ff)?(?!\w)/gi,
|
||||
bisque: /#ffe4c4(ff)?(?!\w)/gi,
|
||||
black: /#000000(ff)?(?!\w)|#000(f)?(?!\w)/gi,
|
||||
blue: /#0000ff(ff)?(?!\w)|#00f(f)?(?!\w)/gi,
|
||||
brown: /#a52a2a(ff)?(?!\w)/gi,
|
||||
coral: /#ff7f50(ff)?(?!\w)/gi,
|
||||
cornsilk: /#fff8dc(ff)?(?!\w)/gi,
|
||||
crimson: /#dc143c(ff)?(?!\w)/gi,
|
||||
cyan: /#00ffff(ff)?(?!\w)|#0ff(f)?(?!\w)/gi,
|
||||
darkblue: /#00008b(ff)?(?!\w)/gi,
|
||||
darkcyan: /#008b8b(ff)?(?!\w)/gi,
|
||||
darkgrey: /#a9a9a9(ff)?(?!\w)/gi,
|
||||
darkred: /#8b0000(ff)?(?!\w)/gi,
|
||||
deeppink: /#ff1493(ff)?(?!\w)/gi,
|
||||
dimgrey: /#696969(ff)?(?!\w)/gi,
|
||||
gold: /#ffd700(ff)?(?!\w)/gi,
|
||||
green: /#008000(ff)?(?!\w)/gi,
|
||||
grey: /#808080(ff)?(?!\w)/gi,
|
||||
honeydew: /#f0fff0(ff)?(?!\w)/gi,
|
||||
hotpink: /#ff69b4(ff)?(?!\w)/gi,
|
||||
indigo: /#4b0082(ff)?(?!\w)/gi,
|
||||
ivory: /#fffff0(ff)?(?!\w)/gi,
|
||||
khaki: /#f0e68c(ff)?(?!\w)/gi,
|
||||
lavender: /#e6e6fa(ff)?(?!\w)/gi,
|
||||
lime: /#00ff00(ff)?(?!\w)|#0f0(f)?(?!\w)/gi,
|
||||
linen: /#faf0e6(ff)?(?!\w)/gi,
|
||||
maroon: /#800000(ff)?(?!\w)/gi,
|
||||
moccasin: /#ffe4b5(ff)?(?!\w)/gi,
|
||||
navy: /#000080(ff)?(?!\w)/gi,
|
||||
oldlace: /#fdf5e6(ff)?(?!\w)/gi,
|
||||
olive: /#808000(ff)?(?!\w)/gi,
|
||||
orange: /#ffa500(ff)?(?!\w)/gi,
|
||||
orchid: /#da70d6(ff)?(?!\w)/gi,
|
||||
peru: /#cd853f(ff)?(?!\w)/gi,
|
||||
pink: /#ffc0cb(ff)?(?!\w)/gi,
|
||||
plum: /#dda0dd(ff)?(?!\w)/gi,
|
||||
purple: /#800080(ff)?(?!\w)/gi,
|
||||
red: /#ff0000(ff)?(?!\w)|#f00(f)?(?!\w)/gi,
|
||||
salmon: /#fa8072(ff)?(?!\w)/gi,
|
||||
seagreen: /#2e8b57(ff)?(?!\w)/gi,
|
||||
seashell: /#fff5ee(ff)?(?!\w)/gi,
|
||||
sienna: /#a0522d(ff)?(?!\w)/gi,
|
||||
silver: /#c0c0c0(ff)?(?!\w)/gi,
|
||||
skyblue: /#87ceeb(ff)?(?!\w)/gi,
|
||||
snow: /#fffafa(ff)?(?!\w)/gi,
|
||||
tan: /#d2b48c(ff)?(?!\w)/gi,
|
||||
teal: /#008080(ff)?(?!\w)/gi,
|
||||
thistle: /#d8bfd8(ff)?(?!\w)/gi,
|
||||
tomato: /#ff6347(ff)?(?!\w)/gi,
|
||||
violet: /#ee82ee(ff)?(?!\w)/gi,
|
||||
wheat: /#f5deb3(ff)?(?!\w)/gi,
|
||||
white: /#ffffff(ff)?(?!\w)|#fff(f)?(?!\w)/gi,
|
||||
};
|
@ -1,610 +0,0 @@
|
||||
/*
|
||||
! tailwindcss v3.3.2 | MIT License | https://tailwindcss.com
|
||||
*/
|
||||
|
||||
/*
|
||||
1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
|
||||
2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
|
||||
*/
|
||||
|
||||
*,
|
||||
::before,
|
||||
::after {
|
||||
box-sizing: border-box;
|
||||
/* 1 */
|
||||
border-width: 0;
|
||||
/* 2 */
|
||||
border-style: solid;
|
||||
/* 2 */
|
||||
border-color: #e5e7eb;
|
||||
/* 2 */
|
||||
}
|
||||
|
||||
::before,
|
||||
::after {
|
||||
--tw-content: '';
|
||||
}
|
||||
|
||||
/*
|
||||
1. Use a consistent sensible line-height in all browsers.
|
||||
2. Prevent adjustments of font size after orientation changes in iOS.
|
||||
3. Use a more readable tab size.
|
||||
4. Use the user's configured `sans` font-family by default.
|
||||
5. Use the user's configured `sans` font-feature-settings by default.
|
||||
6. Use the user's configured `sans` font-variation-settings by default.
|
||||
*/
|
||||
|
||||
html {
|
||||
line-height: 1.5;
|
||||
/* 1 */
|
||||
-webkit-text-size-adjust: 100%;
|
||||
/* 2 */
|
||||
-moz-tab-size: 4;
|
||||
/* 3 */
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
/* 3 */
|
||||
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
/* 4 */
|
||||
font-feature-settings: normal;
|
||||
/* 5 */
|
||||
font-variation-settings: normal;
|
||||
/* 6 */
|
||||
}
|
||||
|
||||
/*
|
||||
1. Remove the margin in all browsers.
|
||||
2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.
|
||||
*/
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
/* 1 */
|
||||
line-height: inherit;
|
||||
/* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
1. Add the correct height in Firefox.
|
||||
2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
|
||||
3. Ensure horizontal rules are visible by default.
|
||||
*/
|
||||
|
||||
hr {
|
||||
height: 0;
|
||||
/* 1 */
|
||||
color: inherit;
|
||||
/* 2 */
|
||||
border-top-width: 1px;
|
||||
/* 3 */
|
||||
}
|
||||
|
||||
/*
|
||||
Add the correct text decoration in Chrome, Edge, and Safari.
|
||||
*/
|
||||
|
||||
abbr:where([title]) {
|
||||
-webkit-text-decoration: underline dotted;
|
||||
text-decoration: underline dotted;
|
||||
}
|
||||
|
||||
/*
|
||||
Remove the default font size and weight for headings.
|
||||
*/
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-size: inherit;
|
||||
font-weight: inherit;
|
||||
}
|
||||
|
||||
/*
|
||||
Reset links to optimize for opt-in styling instead of opt-out.
|
||||
*/
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
|
||||
/*
|
||||
Add the correct font weight in Edge and Safari.
|
||||
*/
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
/*
|
||||
1. Use the user's configured `mono` font family by default.
|
||||
2. Correct the odd `em` font sizing in all browsers.
|
||||
*/
|
||||
|
||||
code,
|
||||
kbd,
|
||||
samp,
|
||||
pre {
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", 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;
|
||||
}
|
||||
|
||||
/*
|
||||
1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
|
||||
2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
|
||||
3. Remove gaps between table borders by default.
|
||||
*/
|
||||
|
||||
table {
|
||||
text-indent: 0;
|
||||
/* 1 */
|
||||
border-color: inherit;
|
||||
/* 2 */
|
||||
border-collapse: collapse;
|
||||
/* 3 */
|
||||
}
|
||||
|
||||
/*
|
||||
1. Change the font styles in all browsers.
|
||||
2. Remove the margin in Firefox and Safari.
|
||||
3. Remove default padding in all browsers.
|
||||
*/
|
||||
|
||||
button,
|
||||
input,
|
||||
optgroup,
|
||||
select,
|
||||
textarea {
|
||||
font-family: inherit;
|
||||
/* 1 */
|
||||
font-size: 100%;
|
||||
/* 1 */
|
||||
font-weight: inherit;
|
||||
/* 1 */
|
||||
line-height: inherit;
|
||||
/* 1 */
|
||||
color: inherit;
|
||||
/* 1 */
|
||||
margin: 0;
|
||||
/* 2 */
|
||||
padding: 0;
|
||||
/* 3 */
|
||||
}
|
||||
|
||||
/*
|
||||
Remove the inheritance of text transform in Edge and Firefox.
|
||||
*/
|
||||
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
/*
|
||||
1. Correct the inability to style clickable types in iOS and Safari.
|
||||
2. Remove default button styles.
|
||||
*/
|
||||
|
||||
button,
|
||||
[type='button'],
|
||||
[type='reset'],
|
||||
[type='submit'] {
|
||||
-webkit-appearance: button;
|
||||
/* 1 */
|
||||
background-color: transparent;
|
||||
/* 2 */
|
||||
background-image: none;
|
||||
/* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
Use the modern Firefox focus style for all focusable elements.
|
||||
*/
|
||||
|
||||
:-moz-focusring {
|
||||
outline: auto;
|
||||
}
|
||||
|
||||
/*
|
||||
Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
|
||||
*/
|
||||
|
||||
:-moz-ui-invalid {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
/*
|
||||
Add the correct vertical alignment in Chrome and Firefox.
|
||||
*/
|
||||
|
||||
progress {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
/*
|
||||
Correct the cursor style of increment and decrement buttons in Safari.
|
||||
*/
|
||||
|
||||
::-webkit-inner-spin-button,
|
||||
::-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.
|
||||
*/
|
||||
|
||||
::-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 */
|
||||
}
|
||||
|
||||
/*
|
||||
Add the correct display in Chrome and Safari.
|
||||
*/
|
||||
|
||||
summary {
|
||||
display: list-item;
|
||||
}
|
||||
|
||||
/*
|
||||
Removes the default spacing and border for appropriate elements.
|
||||
*/
|
||||
|
||||
blockquote,
|
||||
dl,
|
||||
dd,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
hr,
|
||||
figure,
|
||||
p,
|
||||
pre {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
legend {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul,
|
||||
menu {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Prevent resizing textareas horizontally by default.
|
||||
*/
|
||||
|
||||
textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
/*
|
||||
1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
|
||||
2. Set the default placeholder color to the user's configured gray 400 color.
|
||||
*/
|
||||
|
||||
input::-moz-placeholder, textarea::-moz-placeholder {
|
||||
opacity: 1;
|
||||
/* 1 */
|
||||
color: #9ca3af;
|
||||
/* 2 */
|
||||
}
|
||||
|
||||
input::placeholder,
|
||||
textarea::placeholder {
|
||||
opacity: 1;
|
||||
/* 1 */
|
||||
color: #9ca3af;
|
||||
/* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
Set the default cursor for buttons.
|
||||
*/
|
||||
|
||||
button,
|
||||
[role="button"] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/*
|
||||
Make sure disabled buttons don't get the pointer cursor.
|
||||
*/
|
||||
|
||||
:disabled {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/*
|
||||
1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
|
||||
2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
|
||||
This can trigger a poorly considered lint error in some tools but is included by design.
|
||||
*/
|
||||
|
||||
img,
|
||||
svg,
|
||||
video,
|
||||
canvas,
|
||||
audio,
|
||||
iframe,
|
||||
embed,
|
||||
object {
|
||||
display: block;
|
||||
/* 1 */
|
||||
vertical-align: middle;
|
||||
/* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
|
||||
*/
|
||||
|
||||
img,
|
||||
video {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
/* Make elements with the HTML hidden attribute stay hidden by default */
|
||||
|
||||
[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
*, ::before, ::after {
|
||||
--tw-border-spacing-x: 0;
|
||||
--tw-border-spacing-y: 0;
|
||||
--tw-translate-x: 0;
|
||||
--tw-translate-y: 0;
|
||||
--tw-rotate: 0;
|
||||
--tw-skew-x: 0;
|
||||
--tw-skew-y: 0;
|
||||
--tw-scale-x: 1;
|
||||
--tw-scale-y: 1;
|
||||
--tw-pan-x: ;
|
||||
--tw-pan-y: ;
|
||||
--tw-pinch-zoom: ;
|
||||
--tw-scroll-snap-strictness: proximity;
|
||||
--tw-gradient-from-position: ;
|
||||
--tw-gradient-via-position: ;
|
||||
--tw-gradient-to-position: ;
|
||||
--tw-ordinal: ;
|
||||
--tw-slashed-zero: ;
|
||||
--tw-numeric-figure: ;
|
||||
--tw-numeric-spacing: ;
|
||||
--tw-numeric-fraction: ;
|
||||
--tw-ring-inset: ;
|
||||
--tw-ring-offset-width: 0px;
|
||||
--tw-ring-offset-color: #fff;
|
||||
--tw-ring-color: rgb(59 130 246 / 0.5);
|
||||
--tw-ring-offset-shadow: 0 0 #0000;
|
||||
--tw-ring-shadow: 0 0 #0000;
|
||||
--tw-shadow: 0 0 #0000;
|
||||
--tw-shadow-colored: 0 0 #0000;
|
||||
--tw-blur: ;
|
||||
--tw-brightness: ;
|
||||
--tw-contrast: ;
|
||||
--tw-grayscale: ;
|
||||
--tw-hue-rotate: ;
|
||||
--tw-invert: ;
|
||||
--tw-saturate: ;
|
||||
--tw-sepia: ;
|
||||
--tw-drop-shadow: ;
|
||||
--tw-backdrop-blur: ;
|
||||
--tw-backdrop-brightness: ;
|
||||
--tw-backdrop-contrast: ;
|
||||
--tw-backdrop-grayscale: ;
|
||||
--tw-backdrop-hue-rotate: ;
|
||||
--tw-backdrop-invert: ;
|
||||
--tw-backdrop-opacity: ;
|
||||
--tw-backdrop-saturate: ;
|
||||
--tw-backdrop-sepia: ;
|
||||
}
|
||||
|
||||
::backdrop {
|
||||
--tw-border-spacing-x: 0;
|
||||
--tw-border-spacing-y: 0;
|
||||
--tw-translate-x: 0;
|
||||
--tw-translate-y: 0;
|
||||
--tw-rotate: 0;
|
||||
--tw-skew-x: 0;
|
||||
--tw-skew-y: 0;
|
||||
--tw-scale-x: 1;
|
||||
--tw-scale-y: 1;
|
||||
--tw-pan-x: ;
|
||||
--tw-pan-y: ;
|
||||
--tw-pinch-zoom: ;
|
||||
--tw-scroll-snap-strictness: proximity;
|
||||
--tw-gradient-from-position: ;
|
||||
--tw-gradient-via-position: ;
|
||||
--tw-gradient-to-position: ;
|
||||
--tw-ordinal: ;
|
||||
--tw-slashed-zero: ;
|
||||
--tw-numeric-figure: ;
|
||||
--tw-numeric-spacing: ;
|
||||
--tw-numeric-fraction: ;
|
||||
--tw-ring-inset: ;
|
||||
--tw-ring-offset-width: 0px;
|
||||
--tw-ring-offset-color: #fff;
|
||||
--tw-ring-color: rgb(59 130 246 / 0.5);
|
||||
--tw-ring-offset-shadow: 0 0 #0000;
|
||||
--tw-ring-shadow: 0 0 #0000;
|
||||
--tw-shadow: 0 0 #0000;
|
||||
--tw-shadow-colored: 0 0 #0000;
|
||||
--tw-blur: ;
|
||||
--tw-brightness: ;
|
||||
--tw-contrast: ;
|
||||
--tw-grayscale: ;
|
||||
--tw-hue-rotate: ;
|
||||
--tw-invert: ;
|
||||
--tw-saturate: ;
|
||||
--tw-sepia: ;
|
||||
--tw-drop-shadow: ;
|
||||
--tw-backdrop-blur: ;
|
||||
--tw-backdrop-brightness: ;
|
||||
--tw-backdrop-contrast: ;
|
||||
--tw-backdrop-grayscale: ;
|
||||
--tw-backdrop-hue-rotate: ;
|
||||
--tw-backdrop-invert: ;
|
||||
--tw-backdrop-opacity: ;
|
||||
--tw-backdrop-saturate: ;
|
||||
--tw-backdrop-sepia: ;
|
||||
}
|
||||
|
||||
.relative {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.font-rubik {
|
||||
font-family: Rubik-Medium, sans-serif;
|
||||
}
|
||||
|
||||
.text-2xl {
|
||||
font-size: 1.5rem;
|
||||
line-height: 2rem;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Rubik-Medium";
|
||||
|
||||
src: url('./fonts/Rubik-Medium.ttf');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "grenzeGotisch";
|
||||
|
||||
src: url('./fonts/GrenzeGotisch-Regular.ttf');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "fingerPaint";
|
||||
|
||||
src: url(./fonts/FingerPaint-Regular.ttf) format("ttf");
|
||||
}
|
||||
|
||||
ul {
|
||||
display: flex;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
li {
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: black;
|
||||
}
|
||||
|
||||
#root {
|
||||
color: black;
|
||||
}
|
||||
|
||||
#button {
|
||||
width: 100px;
|
||||
height: 30px;
|
||||
background: lightgreen;
|
||||
font-size: large;
|
||||
}
|
||||
|
||||
.glink {
|
||||
}
|
||||
|
||||
#error {
|
||||
display: none;
|
||||
color: red;
|
||||
}
|
||||
|
||||
#error.visible {
|
||||
display: block;
|
||||
}
|
||||
|
||||
input.invalid {
|
||||
border-color: red;
|
||||
border-style: solid;
|
||||
border-width: medium;
|
||||
}
|
||||
|
||||
input.valid {
|
||||
border-color: green;
|
||||
border-style: solid;
|
||||
border-width: medium
|
||||
}
|
||||
|
||||
.mandatory {
|
||||
color: red;
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="h-full bg-white">
|
||||
<head>
|
||||
<link rel="stylesheet" href="css/output.css">
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body class="h-full">
|
||||
<div class="flex min-h-full flex-col justify-center px-6 py-12 lg:px-8">
|
||||
<div class="sm:mx-auto sm:w-full sm:max-w-sm">
|
||||
<img class="mx-auto h-10 w-auto" src="https://tailwindui.com/img/logos/mark.svg?color=indigo&shade=600" alt="Your Company">
|
||||
<h2 class="mt-10 text-center text-2xl font-bold leading-9 tracking-tight text-gray-900">Sign in to your account</h2>
|
||||
</div>
|
||||
|
||||
<div class="mt-10 sm:mx-auto sm:w-full sm:max-w-sm">
|
||||
<form class="space-y-6" action="#" method="POST">
|
||||
<div>
|
||||
<label for="email" class="block text-sm font-medium leading-6 text-gray-900">Email address</label>
|
||||
<div class="mt-2">
|
||||
<input id="email" name="email" type="email" autocomplete="email" required class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
|
||||
<div id="email-error" class="hidden mt-2 text-red-800 text-xs">
|
||||
invalid Email
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex items-center justify-between">
|
||||
<label for="password" class="block text-sm font-medium leading-6 text-gray-900">Password</label>
|
||||
<div class="text-sm">
|
||||
<a href="#" class="font-semibold text-indigo-600 hover:text-indigo-500">Forgot password?</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-2">
|
||||
<input id="password" name="password" type="password" autocomplete="current-password" required class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
|
||||
</div>
|
||||
<p id="letter" class="hidden text-red-800 text-xs">
|
||||
A <b>lowercase</b> letter
|
||||
</p>
|
||||
<p id="capital" class="hidden text-red-800 text-xs">
|
||||
A <b>capital (uppercase)</b> letter
|
||||
</p>
|
||||
<p id="number" class="hidden text-red-800 text-xs">
|
||||
A <b>number</b>
|
||||
</p>
|
||||
<p id="symbol" class="hidden text-red-800 text-xs">
|
||||
A <b>symbol</b>
|
||||
</p>
|
||||
<p id="length" class="hidden text-red-800 text-xs">
|
||||
Minimum <b>10 characters</b>
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<button type="submit" class="flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">Sign in</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script src="./src/login.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,84 @@
|
||||
let email = document.getElementById("email");
|
||||
let password = document.getElementById("password");
|
||||
let emailRX = new RegExp("^[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(\\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z]+)+$");
|
||||
let emailError = document.getElementById("email-error");
|
||||
let capsRX = new RegExp(".*[A-Z]+");
|
||||
let capsError = document.getElementById("capital");
|
||||
let lowRX = new RegExp(".*[a-z]+");
|
||||
let lowError = document.getElementById("letter");
|
||||
let numRX = new RegExp(".*[0-9]+");
|
||||
let numError = document.getElementById("number");
|
||||
let symbolRX = new RegExp(".*[!@#$%^&*]+");
|
||||
let symbolError = document.getElementById("symbol");
|
||||
let MIN_LENGTH = 10;
|
||||
let lenError = document.getElementById("length");
|
||||
email.addEventListener('keyup', function(event) {
|
||||
if (emailRX.test(email.value)) {
|
||||
console.log("email valid");
|
||||
email.classList.add("ring-green-400");
|
||||
email.classList.add("focus:ring-green-400");
|
||||
email.classList.remove("ring-red-400");
|
||||
email.classList.remove("focus:ring-red-400");
|
||||
emailError.classList.add("hidden");
|
||||
emailError.classList.remove("block");
|
||||
return true;
|
||||
} else {
|
||||
console.log("email invalid");
|
||||
email.classList.add("ring-red-400");
|
||||
email.classList.add("focus:ring-red-400");
|
||||
email.classList.remove("ring-green-400");
|
||||
email.classList.remove("focus:ring-green-400");
|
||||
emailError.classList.remove("hidden");
|
||||
emailError.classList.add("block");
|
||||
return false;
|
||||
}
|
||||
});
|
||||
password.addEventListener('keyup', function() {
|
||||
let pswd = password.value;
|
||||
if (!capsRX.test(pswd)) {
|
||||
capsError.classList.remove("hidden");
|
||||
capsError.classList.add("block");
|
||||
} else {
|
||||
capsError.classList.add("hidden");
|
||||
capsError.classList.remove("block");
|
||||
}
|
||||
if (!lowRX.test(pswd)) {
|
||||
lowError.classList.remove("hidden");
|
||||
lowError.classList.add("block");
|
||||
} else {
|
||||
lowError.classList.add("hidden");
|
||||
lowError.classList.remove("block");
|
||||
}
|
||||
if (!numRX.test(pswd)) {
|
||||
numError.classList.remove("hidden");
|
||||
numError.classList.add("block");
|
||||
} else {
|
||||
numError.classList.add("hidden");
|
||||
numError.classList.remove("block");
|
||||
}
|
||||
if (!symbolRX.test(pswd)) {
|
||||
symbolError.classList.remove("hidden");
|
||||
symbolError.classList.add("block");
|
||||
} else {
|
||||
symbolError.classList.add("hidden");
|
||||
symbolError.classList.remove("block");
|
||||
}
|
||||
if (pswd.length < MIN_LENGTH) {
|
||||
lenError.classList.remove("hidden");
|
||||
lenError.classList.add("block");
|
||||
} else {
|
||||
lenError.classList.add("hidden");
|
||||
lenError.classList.remove("block");
|
||||
}
|
||||
if (capsError.classList.contains("block") || lowError.classList.contains("block") || numError.classList.contains("block") || symbolError.classList.contains("block") || lenError.classList.contains("block")) {
|
||||
password.classList.remove("ring-green-400");
|
||||
password.classList.remove("focus:ring-green-400");
|
||||
password.classList.add("ring-red-400");
|
||||
password.classList.add("focus:ring-red-400");
|
||||
} else {
|
||||
password.classList.add("ring-green-400");
|
||||
password.classList.add("focus:ring-green-400");
|
||||
password.classList.remove("ring-red-400");
|
||||
password.classList.remove("focus:ring-red-400");
|
||||
}
|
||||
})
|
Loading…
Reference in New Issue