パッケージを作成フォームを作成する反応
49828 ワード
したい予約フォームを作成するairbnb.com or booking.com 何週間も費やさずに、バグを修正してください.
react-booking-form Githubのパッケージを使用するだけで行うことができます!
プレビュー
ライブプレイグラウンド
Tooescript + TailWindCSSの例
ここでは、簡単で迅速な方法を開始します.
セットアップ
このチュートリアルでは、典型的には、TypeScriptで基本的な反応アプリケーションを起動する方法に精通している必要があります.ギャツビーをインストールしたと仮定しましょうTS starter package :
2 .ライブラリのインポート
この部分は簡単でまっすぐ進む.
新しいファイルを作る
ヘルパー関数
ここではいくつかのヘルパーが表示されます.
4 .定義フォームスキーマ
このパッケージでは、できるだけ多くのフィールドを構築することができます柔軟なフォームのスキーマを使用します.フィールドの3種類があります(あなたは、同様に真ん中に自分の完全に別のフィールドを作成することができます恐れてはいけない)があります🤓):
はい
ここでは、4つのフィールドが欲しいと言います. 受け入れられる場所検索フィールド チェックイン日の日付フィールド.これは、軽量で強力なライブラリをflatpickr . あなたはそれを調べることができますoptions このフィールドの選択については、 チェックアウトのための日付フィールド.これには、minminefromと呼ばれる余分なオプションがあります 客/乗客セレクタ.これは、どのように多くの人々のクラスは、サービス/場所を予約していることを示すことができるスマートセレクタです.
JSX予約フォーム
もう少しで終わりだ.JSXパターンはこちら
6 .スタイル!🎩
そして今、我々は追加/スタイル我々の補完的なコンポーネントを任意の方法で我々が欲しい.
この例では、TailWindCSSを使用していますが、スタイルのコンポーネントを使用できます.
結果
ここでは、
あなたが遊ぶならば、あなたはこのように何かをつくることができます:
はい、どうぞlink to the repository Githubであなたと遊ぶことができます.ピース🚀
react-booking-form Githubのパッケージを使用するだけで行うことができます!
プレビュー
ライブプレイグラウンド
Tooescript + TailWindCSSの例
ここでは、簡単で迅速な方法を開始します.
セットアップ
このチュートリアルでは、典型的には、TypeScriptで基本的な反応アプリケーションを起動する方法に精通している必要があります.ギャツビーをインストールしたと仮定しましょうTS starter package :
npx gatsby new hotel-website https://github.com/jpedroschmitz/gatsby-starter-ts
パッケージを追加しますyarn add react-booking-form react-icons
ではノードサーバを起動しますyarn start
そして、あなたの上に何かがあるかどうかチェックしてくださいlocalhost:8000
🚀2 .ライブラリのインポート
この部分は簡単でまっすぐ進む.
新しいファイルを作る
./src/pages/BookingForm.tsx
import {
DateInput,
FormSchema,
GuestsSelect,
LocationSelect,
useReactBookingForm,
BookingForm as BookingFormType,
} from "react-booking-form"
import "flatpickr/dist/themes/material_green.css"
注意:カレンダー(他のCSSテーマ)をインポートすることができます.flatpickrテーマを読むhere ヘルパー関数
ここではいくつかのヘルパーが表示されます.
// cities is an array of strings such as ["New York", "Alabama", ...]
import { cities } from "./dummy-data/cities"
// This is mocking a call to API that would return location search results
// whenever user types into the location input field.
const searchPlace = async (query) =>
new Promise((resolve, _reject) => {
setTimeout(() => resolve(filterAndMapCiies(query)), 600)
})
// This is what might happen on the backend in real-life application: it would search for the city and return the results in correct format `{value: string, label: string}`.
const filterAndMapCiies = (query) =>
cities
.filter((city) => city.toLowerCase().includes(query.toLowerCase()))
.map((city) => ({ value: city.toLowerCase(), label: city }))
// This is intended to be loaded into the location input field by default
const defaultLocationOptions = [
{ value: "new-york", label: "New York" },
{ value: "barcelona", label: "Barcelona" },
{ value: "los-angeles", label: "Los Angeles" },
]
4 .定義フォームスキーマ
このパッケージでは、できるだけ多くのフィールドを構築することができます柔軟なフォームのスキーマを使用します.フィールドの3種類があります(あなたは、同様に真ん中に自分の完全に別のフィールドを作成することができます恐れてはいけない)があります🤓):
location
, date
( datetimeを許可する)peopleCount
セレクタ.はい
const formSchema: FormSchema = {
location: {
type: "location",
focusOnNext: "checkIn",
options: { defaultLocationOptions, searchPlace },
},
checkIn: {
type: "date",
focusOnNext: "checkOut",
options: {
// These are entirely flatpickr options
altInput: true,
altFormat: "M j, Y",
dateFormat: "Y-m-d",
minDate: "today",
wrap: true,
},
},
checkOut: {
type: "date",
focusOnNext: "guests",
options: {
minDateFrom: "checkIn",
// These are entirely flatpickr options
altInput: true,
altFormat: "M j, Y",
dateFormat: "Y-m-d",
wrap: true,
},
},
guests: {
type: "peopleCount",
defaultValue: [
{
name: "adults",
label: "Adults",
description: "Ages 13+",
value: 1,
min: 0,
max: 10,
},
{
name: "children",
label: "Children",
description: "Ages 4-12",
value: 0,
min: 0,
max: 10,
},
{
name: "infants",
label: "Infants",
description: "Under 4 years old",
value: 0,
min: 0,
max: 10,
},
],
},
}
フォーマットは自己記述的です.キー名は我々が望むものであるかもしれません、しかし、オブジェクトの各々の値は特定のタイプに従わなければなりません.詳細についてはrepoのドキュメントを参照してください.ここでは、4つのフィールドが欲しいと言います.
searchPlace
(上記のヘルパーから)ユーザがフィールドで何かをタイプするたびに、「デッドド」方式で実行されます.選択の後、それはcheckIn
…という分野options
キー.そして、それはに集中するでしょう.checkIn
これにより、ユーザーは、checkIn
値.そして、それが変わるとき、それは焦点を当てます...JSX予約フォーム
もう少しで終わりだ.JSXパターンはこちら
BookingForm
コンポーネントexport const BookingForm = () => {
const form = useReactBookingForm({ formSchema })
return (
<Container>
<InputContainer>
<Label>{"Location"}</Label>
<LocationSelect
form={form}
menuContainer={MenuContainer}
optionContainer={OptionContainer}
inputComponent={InputComponent}
name="location"
inputProps={{ placeholder: "Where are you going?" }}
/>
</InputContainer>
<InputContainer>
<Label>{"Check in"}</Label>
<DatePicker placeholder="Add date" form={form} name={"checkIn"} />
</InputContainer>
<InputContainer>
<Label>{"Check out"}</Label>
<DatePicker placeholder="Add date" form={form} name={"checkOut"} />
</InputContainer>
<InputContainer>
<Label>{"Guests"}</Label>
<GuestsSelect
form={form}
menuContainer={MenuContainer}
optionComponent={OptionComponent}
controlComponent={ControlComponent}
controlProps={{ placeholder: "Add guests" }}
name={"guests"}
/>
</InputContainer>
<InputContainer>
<MainButton>
<FaSearch/>
<ButtonText>{"Search"}</ButtonText>
</MainButton>
</InputContainer>
</Container>
)
}
簡単、右?今、私たちはTarwindCSSで動作して、速度のために(そして、読みやすさのためにコードのいくつかの線を節約するために)我々は少しそれを変えるでしょうexport const BookingForm = () => {
const form = useReactBookingForm({ formSchema })
return (
<div
className="w-full mx-auto rounded-full bg-black bg-opacity-30 backdrop-filter backdrop-blur p-6 flex justify-between flex-col md:flex-row md:space-x-2 md:space-y-0 space-y-2 border border-purple-500"
style={{ boxShadow: "0px 0px 50px #a025da44 inset" }}
>
<div className="relative w-full md:w-1/3 border-l-0 flex flex-col justify-center items-center pl-2">
<Label>{"Location"}</Label>
<LocationSelect
form={form}
menuContainer={MenuContainer}
optionContainer={OptionContainer}
inputComponent={InputComponent}
name="location"
inputProps={{ placeholder: "Where are you going?" }}
/>
</div>
<div className="relative w-full md:w-1/3 border-l-0 flex flex-col justify-center items-center pl-2">
<Label>{"Check in"}</Label>
<DatePicker placeholder="Add date" form={form} name={"checkIn"} />
</div>
<div className="relative w-full md:w-1/3 border-l-0 flex flex-col justify-center items-center pl-2">
<Label>{"Guests"}</Label>
<GuestsSelect
form={form}
menuContainer={MenuContainer}
optionComponent={OptionComponent}
controlComponent={ControlComponent}
controlProps={{ placeholder: "Add guests" }}
name={"guests"}
/>
</div>
<div className="relative w-full md:w-1/3 border-l-0 flex flex-col justify-center items-center pl-2">
<button className="appearance-none mt-5 border w-full h-10 bg-purple-900 hover:bg-purple-500 transition border-purple-500 rounded-full flex justify-center items-center bg-transparent text-white font-bold px-3 font-title-2 uppercase">
{"Book"}
</button>
</div>
</div>
)
}
6 .スタイル!🎩
そして今、我々は追加/スタイル我々の補完的なコンポーネントを任意の方法で我々が欲しい.
この例では、TailWindCSSを使用していますが、スタイルのコンポーネントを使用できます.
twin.macro
, モジュールのscssまたは他の方法でパターンを理解します.const DatePickerInput = ({ placeholder, inputRef }) => (
<div className="relative flex group h-10 w-full" ref={inputRef}>
<InputCore type="input" data-input placeholder={placeholder} />
</div>
)
const DatePicker = (props) => (
<DateInput className="w-full" inputComponent={DatePickerInput} {...props} />
)
const MenuContainer = React.forwardRef(
({ isOpen, children, style, ...props }: any, ref) => (
<div
className={`w-full w-64 border border-purple-500 z-10 mt-12 transform transition ease-in-out bg-black bg-opacity-60 backdrop-filter backdrop-blur rounded-3xl overflow-y-auto overflow-x-hidden
${
isOpen
? "opacity-100"
: "opacity-0 -translate-y-4 pointer-events-none"
}
`}
style={{ ...style, maxWidth: "240px" }}
ref={ref}
{...props}
>
{children}
</div>
),
)
const inputClassName =
"appearance-none border rounded-full w-full outline-none transition pl-4 pr-6 bg-transparent border-purple-500 cursor-pointer flex items-center text-white"
const InputCore = React.forwardRef((props, ref) => (
<input className={inputClassName} ref={ref} {...props} />
))
const RoundButton = ({ children, ...props }) => (
<button
{...props}
className="appearance-none rounded-full p-2 flex items-center justify-center h-full overflow-hidden border border-gray-500 text-gray-500 hover:text-white hover:bg-purple-500 hover:border-transparent transition ease-in-out disabled:opacity-50"
>
{children}
</button>
)
const OptionComponent = ({
form,
name,
option,
}: {
form: BookingFormType
name: string
option: any
}) => {
const onPlusClick = () => {
form.setGuestOptionValue(name, option, option.value + 1)
}
const onMinusClick = () => {
form.setGuestOptionValue(name, option, option.value - 1)
}
return (
<div className="transition ease-in-out relative py-2 px-4 flex justify-between items-center">
<div>
<p className="font-title font-bold text-sm text-white">
{option.label}
</p>
<p className="text-white text-sm">{option.description}</p>
</div>
<div className="flex justify-center items-center gap-x-2">
<RoundButton
onClick={onPlusClick}
disabled={option.value >= (option.max || 100)}
>
<FaPlus />
</RoundButton>
<p className="font-title font-bold text-sm text-white">
{option.value}
</p>
<RoundButton onClick={onMinusClick} disabled={option.value === 0}>
<FaMinus />
</RoundButton>
</div>
</div>
)
}
const InputComponent = ({ form, name, isLoading, ...props }) => (
<div className="relative flex group h-10 w-full">
<InputCore ref={form.refs[name]} {...props} />
</div>
)
const OptionContainer = ({ children, ...props }) => (
<div
className="transition ease-in-out relative py-2 px-4 hover:bg-gray-800 cursor-pointer text-white"
{...props}
>
{children}
</div>
)
const ControlComponent = ({
form,
name,
placeholder,
...props
}: {
form: BookingFormType
name: string
placeholder?: string
}) => {
const count = form.state[name].totalCount
return (
<div className="relative flex group h-10 w-full">
<div
className={inputClassName}
ref={form.refs[name]}
tabIndex={-1}
{...props}
>
<p>{count ? `${count} guest${count > 1 ? "s" : ""}` : ""} </p>
<div>{count ? "" : placeholder}</div>
</div>
</div>
)
}
const Label = ({ children }) => (
<div className="text-sm w-full font-bold mb-1 text-white">{children}</div>
)
結果
ここでは、
./pages/index.tsx
レンダリングします.import { BookingForm } from "./BookingForm.tsx"
...
const Home = () => (
...
<BookingForm />
...
)
そして今、あなたはブラウザで何かを見ることができるはずです🎩あなたが遊ぶならば、あなたはこのように何かをつくることができます:
はい、どうぞlink to the repository Githubであなたと遊ぶことができます.ピース🚀
Reference
この問題について(パッケージを作成フォームを作成する反応), 我々は、より多くの情報をここで見つけました https://dev.to/maxsym/react-package-to-create-booking-forms-introduction-5dljテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol