Components

Located in @kiwicom/nitro/lib/components/<component>.

Features:

Utilities:

Features

Actual components that do stuff. See storybook for a live example.

CookiesConsent

Import:

import CookiesConsent from "@kiwicom/nitro/lib/components/CookiesConsent";

Types:

type Props = {|
  onAccept: () => void,
|};

declare export default React.ComponentType<Props>;

Storybook.

Context needs:

Selectors data-test:

Closeable cookies thingie.

Currency

Import:

import Currency from "@kiwicom/nitro/lib/components/Currency";

Types:

type Props = {|
  positionMenuTablet?: number,
  positionMenuDesktop?: number,
  inverted?: boolean,
  onSetModal?: (modal: ModalType) => void,
  // defaulted
  native?: boolean,
  loading?: React.Node,
|};

declare export default React.ComponentType<Props>;

See types:

Storybook.

Context needs:

Selectors data-test:

A currency picker.

DatePicker

Import:

import DatePicker from "@kiwicom/nitro/lib/components/DatePicker";

Types:

type Props = {|
  value: Date,
  onChange: (date: Date) => void,
  label: string,
  icon?: React.Node,
  min: Date,
  max: Date,
|};

declare export default React.ComponentType<Props>;

Storybook.

Context needs:

TODOs

Import:

import Footer from "@kiwicom/nitro/lib/components/Footer";

Types:

type Props = {||};

declare export default React.ComponentType<Props>;

Storybook.

Context needs:

Import:

import HeaderLinks from "@kiwicom/nitro/lib/components/HeaderLinks";

Types:

type Splitster = {
  // FIXME add a firm structure
  [key: string]: string,
};

type Response = {|
  splitster: Splitster,
  items: HeaderLink[],
|};

type Props = {|
  languageId: string,
  currencyId: string,
  searchForm: SearchForm | null,
  splitster: Splitster,
  active?: string, // TODO maybe add specific if ids are also specified
  inverted?: boolean,
  newDesign?: boolean,
  onFetch?: (services: Response) => void,
  testResponse?: Response, // TODO DI actual API call
  context?: HeaderLinksContext,
|};

declare export default React.ComponentType<Props>;

See types:

Storybook.

Context needs:

LocationPicker

Import:

import LocationPicker from "@kiwicom/nitro/lib/components/LocationPicker";

Types:

type Props = {|
  value: Location | null,
  onChange: (loc: Location) => void,
  label: React.Node,
  icon?: React.Node,
  error?: React.Node,
  // defaulted
  environment?: Environment,
  queryName?: "allLocations" | "holidaysLocations",
  locationType?:
    | "airport"
    | "autonomous_territory"
    | "city"
    | "country"
    | "station"
    | "subdivision",
|};

declare export default React.ComponentType<Props>;

See types:

Storybook.

Context needs:

Example:

import LocationPicker from "@kiwicom/nitro/lib/components/LocationPicker";
import Translate from "@kiwicom/nitro/lib/components/Translate";

<LocationPicker
  value={from}
  onChange={setSomething()}
  label={<Translate t="search.from" />}
/>;

with options

<LocationPicker
  value={from}
  onChange={setSomething()}
  // option
  locationType="airport"
  label={<Translate t="search.from" />}
/>

holidays

<LocationPicker
  value={from}
  onChange={setSomething()}
  // option
  queryName="holidaysLocations"
  label={<Translate t="search.from" />}
/>

MagicLogin

Import:

import MagicLogin from "@kiwicom/nitro/lib/components/MagicLogin";

Types:

type Props = {|
  initialScreen: "intro" | "signUp",
  type: "mmb" | "help" | "refer",
  disableSocialLogin?: boolean,
  onClose: () => void,
  onSignIn: (user: AuthUser) => void,
  onSocialLogin: (provider: SocialProvider) => Promise<void>,
  onGetSimpleToken: AuthToken => void,
|};

declare export default React.ComponentType<Props>;

See types:

Storybook.

Context needs:

Selectors data-test:

Modal component handling the whole login flow with magic link.

Docs

WIKI - New login flow with magic link

Props

data-test attributes for acceptance tests

Example

import * as React from "react"
import MagicLogin from "@kiwicom/nitro/lib/components/MagicLogin"
import type { AuthUser } from "@kiwicom/nitro/lib/records/Auth"

type Provider = "facebook" | "google"

type ConnectorHandlers = {|
  onSocialLogin: (provider: Provider) => Promise<*>,
  onSignIn: (userInfo: AuthUser) => void,
|}

type OwnProps = {|
  disableSocialLogin: boolean,
  initialScreen: "intro" | "signUp",
  type: "mmb" | "help" | "refer",
  onClose: () => void,
|}

type Props = {|
  ...ConnectorHandlers,
  ...OwnProps,
|}

// onSignIn fn should handle usual action which takes place after successful login via email & password
const onSignIn = (user) => ({ type: LOGIN_SUCCESS, res: user })
// onSocialLogin fn should trigger full OAuth login process thought specified provider
const onSocialLogin = (provider: Provider) => {}

// Redux connector HOC
const connector: Connector<OwnProps, Props> = connect(
  null,
  dispatch => ({
    onSignIn: (user: AuthUser) => dispatch(onSignIn(user)),
    onSocialLogin: (provider: Provider) => dispatch(onSocialLogin(provider)),
  }),
)
export default connector(MagicLogin)

Import:

import NavBar from "@kiwicom/nitro/lib/components/NavBar";

Types:

type NavElement = "currencies" | "help" | "starred" | "mmb" | "languages" | "logo" | "sideNav";

type Props = {|
  starred: React.Node,
  subscription: React.Node,
  portal: string,
  hide?: NavElement | NavElement[],
  onOpenFaq: ?() => void,
  onSetModal: (modal: Modal) => void,
  onSaveLanguage: (lang: string) => void,
  onSelectTrip: (bid: string) => void,
  onLogoClick: (ev: SyntheticMouseEvent<HTMLAnchorElement>) => void,
  // defaulted
  headerLinks?: React.Node, // null
  newDesign?: boolean,
  debug?: React.Node, // null
  inverted?: boolean, // false
  animateLogo?: boolean,
  logoAnimateShow?: boolean,
|};

declare export default React.ComponentType<Props>;

See types:

Storybook.

Context needs:

Selectors data-test:

Import:

import SideBar from "@kiwicom/nitro/lib/components/SideBar";

Types:

type Props = {|
  shown: boolean,
  inverted?: boolean, // opens from the other side
  unmasked?: boolean, // removes outer mask and disables onClick
  onClick: () => void,
  children: React.Node,
  className?: string,
|};

declare export default React.ComponentType<Props>;

Storybook.

A container for a sidebar sliding from the right (left in RTL). It is appended to document.body.

Utilities

Things that help in development.

BaggageOverview

Import:

import BaggageOverview from "@kiwicom/nitro/lib/components/BaggageOverview";

Types:

FAQLinksHandlerType,
  DefinitionWithPassenger,
  Definition,
  OverviewContextType,
} from "../../records/Baggage";

type Props = {|
  definitions?: Definition[],
  definitionsWithPassengers?: DefinitionWithPassenger[],
  FAQLinksHandler?: FAQLinksHandlerType,
  context: OverviewContextType,
|};

declare export default React.ComponentType<Props>;

Storybook.

Context needs:

Selectors data-test:

Example:

standalone

<BaggageOverview
  definitions={definitions}
  FAQLinksHandler={category => {}}
  context="MMB-PassengerCard"
/>

wrapped in Container

<Container
  passengers={[
    {
      paxId: 3,
      firstName: "George",
      lastName: "Bush",
      baggage: {
        holdBag: 0,
        handBag: 1
      }
    }
  ]}
  baggage={baggageData}
  context="booking"
>
  {({ props }) => <BaggageOverview {...props} />}
</Container>

BaggagePaymentSummary

Import:

import BaggagePaymentSummary from "@kiwicom/nitro/lib/components/BaggagePaymentSummary";

Types:

type Passenger = {|
  paxId: number,
  firstName: string,
  lastName: string,
  baggage: {
    holdBag: number,
    handBag: number,
  },
|};

type Props = {|
  passengers: Passenger[],
  baggage: BaggageType,
|};

declare export default React.ComponentType<Props>;

See types:

Storybook.

Context needs:

Selectors data-test:

Example:

<BaggagePaymentSummary
  passengers={[
    {
      paxId: 1,
      firstName: "Vaclav",
      lastName: "Havel",
      baggage: {
        holdBag: 1,
        handBag: 1
      }
    }
  ]}
  baggage={baggageData}
/>

BaggagePicker

Import:

import BaggagePicker from "@kiwicom/nitro/lib/components/BaggagePicker";

Types:

type Props = {|
  changeBagCombination: (picker: BaggageCategory, item: number) => void,
  passengerCategory: PassengerGroup,
  passengerBaggage: { handBag: number, holdBag: number },
  baggage: BaggageType,
  shouldShowRecheckNote?: boolean,
  airlines: { [string]: Airline },
  pickerType: BaggageCategory,
  context: "booking" | "mmb",
  currentCombination?: number,
  prioBoardingLinkHandler?: (arg: Airline[]) => void,
  description?: React.Node,
|};

declare export default React.ComponentType<Props>;

See types:

Storybook.

Context needs:

Selectors data-test:

Example:

<BaggagePicker
  airlines={airlines}
  baggage={baggageData}
  context="context"
  changeBagCombination={(type, index) => {}}
  passengerBaggage=
  passengerCategory="adult"
  prioBoardingLinkHandler={airlines => console.log("prioAirlines", airlines)}
  pickerType="handBag"
  shouldShowRecheckNote={false}
/>

BaggagePickerBRBRedesign

Import:

import BaggagePickerBRBRedesign from "@kiwicom/nitro/lib/components/BaggagePickerBRBRedesign";

Types:

type Props = {|
  changeBagCombination: (picker: BaggageCategory, item: number) => void,
  passengerCategory: PassengerGroup,
  passengerBaggage: { handBag: number, holdBag: number },
  baggage: BaggageType,
  shouldShowRecheckNote?: boolean,
  airlines: { [string]: Airline },
  pickerType: BaggageCategory,
  context: "booking" | "mmb",
  currentCombination?: number,
  prioBoardingLinkHandler?: (arg: Airline[]) => void,
  description?: React.Node,
  shouldShowAddBlueRibbonBag: boolean,
  blueRibbonBagPrice: PriceType,
  isBlueRibbonBagAdded: boolean,
  addBlueRibbonBag: () => void,
  removeBlueRibbonBag: () => void,
  openBlueribbonBagsSmartFAQ: () => void,
|};

declare export default React.ComponentType<Props>;

See types:

Storybook.

Context needs:

Selectors data-test:

Example:

<BaggagePickerBRBRedesign
  airlines={airlines}
  baggage={baggageData}
  context="context"
  changeBagCombination={(type, index) => {}}
  passengerBaggage=
  passengerCategory="adult"
  prioBoardingLinkHandler={airlines => console.log("prioAirlines", airlines)}
  pickerType="handBag"
  shouldShowRecheckNote={false}
  shouldShowAddBlueRibbonBag={true}
  blueRibbonBagPrice=
  isBlueRibbonBagAdded={isAdded}
  addBlueRibbonBag={add}
  removeBlueRibbonBag={remove}
  openBlueribbonBagsSmartFAQ={() => {console.log("opening SmartFAQ article")}}
/>

BookingSavingsBanner

Import:

import BookingSavingsBanner from "@kiwicom/nitro/lib/components/BookingSavingsBanner";

Types:

type Props = {|
  amount: number,
  currency: string,
  onLearnMoreClick: (e: SyntheticEvent<HTMLButtonElement>) => void, // Triggers redirection to learn more article
  onMoreTripsClick: (e: SyntheticEvent<HTMLButtonElement>) => void, // Triggers modal with alternative trips
|};

declare export default React.ComponentType<Props>;

Storybook.

Context needs:

Selectors data-test:

Throw-away ticket banner indicating savings in €.

Button

Import:

import Button from "@kiwicom/nitro/lib/components/Button";

Types:

type Props = {|
  ...$Diff<PropsOrbit, { children: ?React.Node }>,
  t: string,
  values?: { [key: string]: string | number },
  html?: boolean,
  transform?: (value: string) => string,
|};

declare export default React.ComponentType<Props>;

Storybook.

Context needs:

Our Translate wrapped in Orbit Button. Accepts both our and their props.

Button component shorter and nicer!

ClickOutside

Import:

import ClickOutside from "@kiwicom/nitro/lib/components/ClickOutside";

Types:

type Props = {|
  className?: string,
  onClickOutside: (ev: MouseEvent) => void,
  children: React.Node | React.Node[],
  // defaulted
  active?: boolean, // true
|};

declare export default React.ComponentType<Props>;

Storybook.

Fires a callback whenever a user clicks outside of this component.

Example:

const MyComponent = ({ open, onCloseModal }: Props) => (
  <ClickOutside active={open} onClickOutside={onCloseModal}>
    <MyModal open={open} />
  </ClickOutside>
);

ClientOnly

Import:

import ClientOnly from "@kiwicom/nitro/lib/components/ClientOnly";

Types:

type Props = {|
  children: React.Node,
  // defaulted
  loader?: React.Node, // null
|};

declare export default React.ComponentType<Props>;

Storybook.

Renders only on the client, useful for wrapping components that break server-side rendering.

Example:

const MyComponent = () => (
  <ClientOnly>
    <>
      <ComponentWithSideEffects />
      <ComponentUsingTheWindowObject />
    </>
  </ClientOnly>
);

CloseByKey

Import:

import CloseByKey from "@kiwicom/nitro/lib/components/CloseByKey";

Types:

type Props = {|
  onClose: (ev: KeyboardEvent) => void,
  children: React.Node,
  // defaulted
  closeKey?: string, // Escape
|};

declare export default React.ComponentType<Props>;

Storybook.

Fires a callback whenever a user presses the close button (Escape by default).

CookiesPopup

Import:

import CookiesPopup from "@kiwicom/nitro/lib/components/CookiesPopup";

Types:

type Props = {|
  onAccept: ({|
    performance: boolean,
    marketing: boolean,
    advertisement: boolean,
  |}) => void,
  type?: "popup" | "banner",
|};

declare export default React.ComponentType<Props>;

Storybook.

Context needs:

Selectors data-test:

Closeable cookies thingie #2.

CustomerBaggageTile

Import:

import CustomerBaggageTile from "@kiwicom/nitro/lib/components/CustomerBaggageTile";

Types:

type Props = {|
  firstName: string,
  middleName?: string,
  lastName: string,
  gender: Gender,
  dayOfBirth?: string,
  isProcessing: boolean,
  current?: {
    handBag: number,
    holdBag: number,
  },
  selected?: {
    handBag: number,
    holdBag: number,
  },
  newDefinitions?: Definition[],
  onClick?: () => void,
  baggage: BaggageType,
|};

declare export default React.ComponentType<Props>;

See types:

Storybook.

Context needs:

Selectors data-test:

Example:

<CustomerBaggageTile
  firstName="Vaclav"
  lastName="Havel"
  gender="male"
  isProcessing={false},
  current=
  selected=
  onClick={ () => {}}
  baggage={baggageData}
/>

DateInput

Import:

import DateInput from "@kiwicom/nitro/lib/components/DateInput";

Types:

type Props = {|
  label: string,
  value?: ?Date,
  error?: string,
  onChange: (?Date) => void,
|};

declare export default React.ComponentType<Props>;

Storybook.

Context needs:

Selectors data-test:

Desktop

Import:

import Desktop from "@kiwicom/nitro/lib/components/Desktop";

Types:

type Props = {|
  children: React.Node | React.Node[],
  // defaulted
  display?: "block" | "inline" | "inline-block" | "flex", // block
|};

declare export default React.ComponentType<Props>;

Storybook.

Renders only above tablet width.

Example:

const NavBar = () => (
  <>
    <Desktop>
      <Button>A desktop-only button</Button>
    </Desktop>
    <Menu />
  </>
);

InitAuth

Import:

import InitAuth from "@kiwicom/nitro/lib/components/InitAuth";

Types:

type MyBookingInput = {|
  bid: string,
  email: string,
  iata: string,
  departure: Date,
|};

type RegisterInput = {|
  firstName: string,
  lastName: string,
  email: string,
  password: string,
|};

type OnMyBookingArg = {|
  token: string,
  bid: number,
|};

type Arg = {|
  auth: Auth | null,
  loading: boolean,
  onMyBooking: (input: MyBookingInput) => Promise<void>,
  onRegister: (input: RegisterInput) => Promise<void>,
  onSocialAuth: (provider: SocialProvider) => Promise<void>,
  onSignIn: (email: string, password: string) => Promise<void>,
  onSetAuth: (auth: Auth) => void,
  onSignOut: () => void,
|};

type Props = {|
  brand: Brand,
  redirectURL: string,
  onMyBooking: (arg: OnMyBookingArg) => void,
  onRegister: () => void,
  onSocialAuth: (authURL: string) => void,
  onSignIn: (auth: Auth) => void,
  onSignOut: () => void,
  children: (arg: Arg) => React.Node,
|};

declare export default React.ComponentType<Props>;

See types:

Calls APIs for you, handles loading state and supplies context with Relay environment with the auth token. Supplied callbacks are only there for the side effects:

It also logs the user in on mount if you supply the token prop.

Saves or removes the AFFILIATE_ID cookie on sign in.

InitCurrency

Import:

import InitCurrency from "@kiwicom/nitro/lib/components/InitCurrency";

Types:

type Arg = {|
  currency: Currency,
  available: Currencies,
  recommended: Currency[],
  onChange: (code: string) => void,
|};

type Props = {|
  brand: Brand,
  countries: Countries,
  affiliate: string,
  ip: string,
  langCurrency: string,
  children: (arg: Arg) => React.Node,
  onChange: (currency: string) => void,
  // defaulted
  mostUsed?: string[],
  // DI
  getCurrencies?: () => Promise<FetchedCurrencies>,
  getGeoCountry?: (ip: string) => Promise<string>,
  url?: string,
|};

declare export default React.ComponentType<Props>;

See types:

TODO

InitIntl

Import:

import InitIntl from "@kiwicom/nitro/lib/components/InitIntl";

Types:

type Props = {|
  raw: IntlRaw,
  children: (arg: Context) => React.Node,
  // defaulted
  getLocale?: Promise<$FlowFixMe>, // resolves en-US by default
|};

declare export default React.ComponentType<Props>;

See types:

Context needs:

Useful for initiating the intl context from raw intl data.

import type { IntlRaw } from "@kiwicom/nitro/lib/records/Intl";

const raw: IntlRaw = window.__INTL__; // intl data from the server

const App = () => (
  <InitIntl raw={raw}>
    {intl => (
      <IntlProvider value={intl}>
        <Root />
      </IntlProvider>
    )}
  </InitIntl>
)

const node = document.getElementById("root");
if (node) {
  ReactDOM.hydrate(<App />, node);
}

On the server:

import type { IntlRaw } from "@kiwicom/nitro/lib/records/Intl";

import { locales } from "./data";

export default function render(locale: string) {
  const raw: IntlRaw = locales[locale];

  const markup = ReactDOM.renderToString(
    <InitIntl raw={raw}>
      {intl => (
        <IntlProvider value={intl}>
          <Root />
        </IntlProvider>
      )}
    </InitIntl>
  );

  // <Html /> puts the raw intl data into window.__INTL__
  return ReactDOM.renderToStaticNodeStream(<Html intl={raw} />);
}

InitLog

Import:

import InitLog from "@kiwicom/nitro/lib/components/InitLog";

Types:

type Props = {|
  children: (ctx: Context) => React.Node,
|};

declare export default React.ComponentType<Props>;

Context needs:

Initializes the log context.

Logs are logged using the log/logger service.

Example:

import { Provider as LogProvider } from "@kiwicom/nitro/lib/services/log/context";
import InitLog from "@kiwicom/nitro/lib/components/InitLog";
import * as logger from "@kiwicom/nitro/lib/services/log/logger";

logger.globals.userId = window.__SESSION__.userId;
logger.globals.langId = window.__INTL__.id;
// ...

ReactDOM.render(
  <InitLog>
    {ctx => (
      <LogProvider value={ctx}>
        <App />
      </LogProvider>
    )}
  </InitLog>,
  node,
);

InitRelayEnvironment

Import:

import InitRelayEnvironment from "@kiwicom/nitro/lib/components/InitRelayEnvironment";

Types:

type Props = {|
  clientID: string,
  uri?: string,
  children: React.Node,
|};

declare export default React.ComponentType<Props>;

Context needs:

Initializes RelayEnvironmentProvider from @kiwicom/relay with environment containing correct HTTP headers.

Note you must always specify clientID which should identify your application to helps us know who is sending the request.

InitStarred

Import:

import InitStarred from "@kiwicom/nitro/lib/components/InitStarred";

Types:

type Args = {|
  list: StarredItem[],
  onRemove: (arg: string, e: SyntheticEvent<HTMLDivElement>) => void,
  onAdd: (arg: StarredItem) => void,
  onClear: (e: SyntheticEvent<HTMLDivElement>) => void,
|};

type Props = {|
  children: (args: Args) => React.Node,
|};

declare export default React.ComponentType<Props>;

See types:

Just mount it and it works!

InputEmail

Import:

import InputEmail from "@kiwicom/nitro/lib/components/InputEmail";

Types:

type Props = {|
  ...SpaceAfter,
  size?: "small" | "normal",
  name?: string,
  label?: Translation,
  inlineLabel?: boolean,
  value?: (() => string | number) | string | number,
  placeholder?: Translation,
  help?: React.Node,
  prefix?: React$Node,
  suffix?: React$Node,
  tabIndex?: string,
  autoComplete?: string,
  id?: string,
  error: string,
  onChange: ({ value: string, error: string }) => void,
  onFocus?: (ev: SyntheticInputEvent<HTMLInputElement>) => void | Promise<any>,
  onBlur?: (ev: SyntheticInputEvent<HTMLInputElement>) => void | Promise<any>,
  onKeyDown?: (ev: SyntheticKeyboardEvent<HTMLInputElement>) => void | Promise<any>,
  onKeyUp?: (ev: SyntheticKeyboardEvent<HTMLInputElement>) => void | Promise<any>,
|};

declare export default React.ComponentType<Props>;

Storybook.

Context needs:

Nitro Email Wrapper for InputField from Orbit-components

InputPhone

Import:

import InputPhone from "@kiwicom/nitro/lib/components/InputPhone";

Types:

type Props = {|
  ...SpaceAfter,
  size?: "small" | "normal",
  name?: string,
  label?: Translation,
  inlineLabel?: boolean,
  value?: (() => string | number) | string | number,
  placeholder?: Translation,
  help?: React.Node,
  prefix?: React$Node,
  suffix?: React$Node,
  tabIndex?: string,
  autoComplete?: string,
  maxLength?: number,
  minLength?: number,
  id?: string,
  error: string,
  onChange: ({ error: string, value: string, code?: string }) => void,
  onFocus?: (ev: SyntheticInputEvent<HTMLInputElement>) => void | Promise<any>,
  onBlur?: (ev: SyntheticInputEvent<HTMLInputElement>) => void | Promise<any>,
  onKeyDown?: (ev: SyntheticKeyboardEvent<HTMLInputElement>) => void | Promise<any>,
  onKeyUp?: (ev: SyntheticKeyboardEvent<HTMLInputElement>) => void | Promise<any>,
|};

declare export default React.ComponentType<Props>;

Storybook.

Context needs:

Nitro Phone Wrapper for InputField from Orbit-components

Itinerary

Import:

import Itinerary from "@kiwicom/nitro/lib/components/Itinerary";

Types:

type Props = {|
  itinerary: ItineraryNormalized,
|};

declare export default React.ComponentType<Props>;

See types:

Storybook.

Context needs:

Itineray Sector Segment

To implement Itinerary you have to import flatten function.

Example:

import { flatten } from "@kiwicom/nitro/lib/records/Itinerary";

<Itinerary itinerary={flatten(ItineraryOneWay)} />;

LogMount

Import:

import LogMount from "@kiwicom/nitro/lib/components/LogMount";

Types:

type Props = {|
  event: Event,
  // defaulted
  props?: EventProps,
|};

declare export default React.ComponentType<Props>;

See types:

Storybook.

Context needs:

Logs the given event and props on mount.

Useful for declarative tracking of opening modals or page sections.

Mobile

Import:

import Mobile from "@kiwicom/nitro/lib/components/Mobile";

Types:

type Props = {|
  children: React.Node | React.Node[],
  // defaulted
  display?: "block" | "inline" | "inline-block" | "flex", // block
|};

declare export default React.ComponentType<Props>;

Storybook.

Renders only below tablet width.

Example:

const NavBar = () => (
  <>
    <Mobile>
      <Button>A mobile-only button</Button>
    </Mobile>
    <Menu />
  </>
);

Price

Import:

import Price from "@kiwicom/nitro/lib/components/Price";

Types:

type Props = {|
  value: number,
|};

declare export default React.ComponentType<Props>;

Storybook.

Context needs:

Renders a formatted price.

Example:

const Pay = ({ value }: Props) => (
  <Button>
    <TextNode
      t="Pay __x__"
      values={
        { x: <Price value={value} /> }
      }
    />
  </Button>
);

Starred

Import:

import Starred from "@kiwicom/nitro/lib/components/Starred";

Types:

type Props = {|
  positionMenuDesktop?: number,
  positionMenuTablet?: number,
  inverted?: boolean,
|};

declare export default React.ComponentType<Props>;

Storybook.

Context needs:

Text

Import:

import Text from "@kiwicom/nitro/lib/components/Text";

Types:

type Props = {|
  ...$Diff<PropsOrbit, { children: React.Node }>,
  t: string,
  values?: { [key: string]: string | number },
  html?: boolean,
  transform?: (value: string) => string,
|};

declare export default React.ComponentType<Props>;

Storybook.

Context needs:

Our Translate wrapped in Orbit’s Text. Accepts both our and their props.

Useful for both translating and making text nicer!

TextNode

Import:

import TextNode from "@kiwicom/nitro/lib/components/TextNode";

Types:

type Props = {|
  ...$Diff<PropsOrbit, { children: React.Node }>,
  t: string,
  values: { [key: string]: React.Node },
  transform?: (value: string) => string,
|};

declare export default React.ComponentType<Props>;

Storybook.

Context needs:

Our TranslateNode wrapped in Orbit’s Text. Accepts both our and their props.

Useful for both translating and making text nicer!

Toggle

Import:

import Toggle from "@kiwicom/nitro/lib/components/Toggle";

Types:

type Data = {|
  open: boolean,
  onToggle: () => void,
|};

type Props = {|
  children: (data: Data) => React.Node,
  // defaulted
  initial?: boolean, // false
|};

declare export default React.ComponentType<Props>;

Storybook.

A container that holds state of something being open.

Example:

const MyComponent = () => (
  <Toggle>
    {({ open, onToggle }) => (
      <>
        <h3>{open ? "Open" : "Closed"}</h3>
        <Button onClick={onToggle}>Toggle</Button>
      </>
    )}
  </Toggle>
);

Translate

Import:

import Translate from "@kiwicom/nitro/lib/components/Translate";

Types:

type Props = {|
  t: string,
  // defaulted
  values?: { [key: string]: string | number }, // {}
  html?: boolean, // false
  transform?: (value: string) => string, // identity
|};

declare export default React.ComponentType<Props>;

Storybook.

Context needs:

Translates the supplied key.

The text output can be transformed using the transform function. You can use arrow functions - the component does not implement pure render.

Example:

const Submit = () => (
  <Button>
    <Translate t="Submit" />
  </Button>
);

TranslateNode

Import:

import TranslateNode from "@kiwicom/nitro/lib/components/TranslateNode";

Types:

type Props = {|
  t: string,
  values: { [key: string]: React.Node },
  // defaulted
  transform?: (value: string) => string, // identity
|};

declare export default React.ComponentType<Props>;

Storybook.

Context needs:

The same as Translate, except values are React.Node. Useful when you need to inject elements with event handlers!

The text output can be transformed using the transform function. You can use arrow functions - the component does not implement pure render.

Example:

const MyComponent = () => (
  <TranslateNode
    t="Click this: __x__"
    values={
      { x: <button onClick={() => alert("Clicked")}>Yo</button> }
    }
  />
);

TranslateRef

Import:

import TranslateRef from "@kiwicom/nitro/lib/components/TranslateRef";

Types:

type Props = {|
  t: string,
  values?: Values,
  render: (ref: string, index: number) => React.Node,
  transform?: (value: string) => string,
|};

declare export default React.ComponentType<Props>;

Storybook.

Context needs:

The same as Translate, except it expects the translation to contain a <ref></ref> tag to be replaced with the result of the render function call. Useful for injecting event handlers!

The text output can be transformed using the transform function. You can use arrow functions - the component does not implement pure render.

Example:

const MyComponent = () => (
  <TranslateRef
    t="Some stuff, <ref>read more</ref>."
    render={text => <Link to="/about">{text}</Link>}
  />
);

Value

Import:

import Value from "@kiwicom/nitro/lib/components/Value";

Types:

type Data = {|
  value: string,
  onChange: (value?: string) => void, // 'value' defaults to ""
|};

type Props = {|
  children: (data: Data) => React.Node,
  // defaulted
  initial?: string, // ""
|};

declare export default React.ComponentType<Props>;

Storybook.

A render props container component that holds a string value. Useful for modals, for example.

Super useful when combined with the ValueBind component!

Example:

const AuthModals = ({ query }: Props) => (
  <Value initial={query.modal || ""}>
    {({ value, onChange }) => (
      <>
        <ModalLogin open={value === "login"} onClose={onChange} />
        <ModalRegister open={value === "register"} onClose={onChange} />
        
        <ValueBind value="login" onChange={onChange}>
          {({ onClick }) => <Button onClick={onClick}>Login</Button>}
        </ValueBind>
        <ValueBind value="register" onChange={onChange}>
          {({ onClick }) => <Button onClick={onClick}>Register</Button>}
        </ValueBind>
      </>
    )}
  </Value>
)

ValueBind

Import:

import ValueBind from "@kiwicom/nitro/lib/components/ValueBind";

Types:

type Data = {|
  onClick: () => void,
|};

type Props = {|
  value: string,
  onChange: (value: string) => void,
  children: (data: Data) => React.Node,
|};

declare export default React.ComponentType<Props>;

Storybook.

Binds a value to a callback, that’s it. Useful for changing onChange callbacks to onClick ones.

const OpenLogin = ({ onChange }: Props) => (
  <ValueBind value="login" onChange={onChange}>
    {({ onClick }) => (
      <Button onClick={onClick} />
    )}
  </ValueBind>
)