├── .nvmrc
├── .yarnrc
├── .node-version
├── .prettierignore
├── .stylelintignore
├── CODEOWNERS
├── assets
├── css
│ └── tailwind.css
├── scss
│ ├── components
│ │ ├── _appBadges.scss
│ │ ├── _chunk.scss
│ │ ├── _adminBar.scss
│ │ ├── _infoToggle.scss
│ │ ├── _tooltip.scss
│ │ ├── _dropdown.scss
│ │ ├── _lockedBadge.scss
│ │ ├── _signup.scss
│ │ ├── _bounds.scss
│ │ ├── _inlineblockList.scss
│ │ ├── _toggleSwitch.scss
│ │ ├── _accentHeader.scss
│ │ ├── _footer.scss
│ │ ├── _radio.scss
│ │ ├── _checkbox.scss
│ │ ├── _section.scss
│ │ ├── _loading.scss
│ │ ├── _typeahead.scss
│ │ ├── _all.scss
│ │ ├── _toast.scss
│ │ ├── _textInput.scss
│ │ ├── _icon.scss
│ │ ├── _togglePill.scss
│ │ ├── _popover.scss
│ │ └── _accordion.scss
│ ├── util
│ │ ├── _vars.scss
│ │ └── _color-mappings.scss
│ ├── main.scss
│ └── storybook.scss
├── images
│ └── app_download
│ │ ├── ios
│ │ ├── download_de.png
│ │ ├── download_en.png
│ │ ├── download_es.png
│ │ ├── download_fr.png
│ │ ├── download_it.png
│ │ ├── download_ja.png
│ │ ├── download_ko.png
│ │ ├── download_nl.png
│ │ ├── download_pl.png
│ │ ├── download_pt.png
│ │ ├── download_ru.png
│ │ ├── download_th.png
│ │ └── download_tr.png
│ │ └── android
│ │ ├── download_de.png
│ │ ├── download_en.png
│ │ ├── download_es.png
│ │ ├── download_fr.png
│ │ ├── download_it.png
│ │ ├── download_ja.png
│ │ ├── download_ko.png
│ │ ├── download_nl.png
│ │ ├── download_pl.png
│ │ ├── download_pt.png
│ │ ├── download_ru.png
│ │ ├── download_th.png
│ │ └── download_tr.png
└── svg
│ ├── facebook.svg
│ ├── email.svg
│ ├── message.svg
│ ├── proDashboard.svg
│ ├── apple.svg
│ ├── google.svg
│ ├── host-badge.svg
│ └── notification.svg
├── .eslintignore
├── Makefile
├── .github
├── PULL_REQUEST_TEMPLATE.md
└── dependabot.yml
├── src
├── layout
│ ├── __snapshots__
│ │ ├── chunk.test.jsx.snap
│ │ ├── stripe.test.jsx.snap
│ │ ├── flex.test.jsx.snap
│ │ ├── section.test.jsx.snap
│ │ ├── bounds.test.jsx.snap
│ │ ├── card.test.jsx.snap
│ │ └── formSection.test.jsx.snap
│ ├── chunk.test.jsx
│ ├── formSection.test.jsx
│ ├── bounds.test.jsx
│ ├── SectionTitle.jsx
│ ├── Chunk.jsx
│ ├── flexItem.test.jsx
│ ├── inlineBlockList.test.jsx
│ ├── Bounds.jsx
│ └── FormSection.jsx
├── forms
│ ├── __snapshots__
│ │ ├── typeahead.test.jsx.snap
│ │ ├── charCounter.test.jsx.snap
│ │ ├── timeInput.test.jsx.snap
│ │ ├── button.test.jsx.snap
│ │ ├── toggleSwitch.test.jsx.snap
│ │ ├── LockedBadge.test.jsx.snap
│ │ ├── errorList.test.jsx.snap
│ │ ├── selectInput.test.jsx.snap
│ │ ├── radioButtonGroup.test.jsx.snap
│ │ ├── inputTime.test.jsx.snap
│ │ ├── togglePill.test.jsx.snap
│ │ ├── numberInput.test.jsx.snap
│ │ └── checkbox.test.jsx.snap
│ ├── redux-form
│ │ ├── RadioButtonGroup.jsx
│ │ ├── __snapshots__
│ │ │ ├── checkbox.test.jsx.snap
│ │ │ ├── numberInput.test.jsx.snap
│ │ │ ├── timeInput.test.jsx.snap
│ │ │ ├── togglePill.test.jsx.snap
│ │ │ ├── textInput.test.jsx.snap
│ │ │ ├── textarea.test.jsx.snap
│ │ │ ├── RadioButtonGroup.test.jsx.snap
│ │ │ ├── calendarComponent.test.jsx.snap
│ │ │ └── selectInput.test.jsx.snap
│ │ ├── Checkbox.jsx
│ │ ├── checkbox.test.jsx
│ │ ├── RadioButtonGroup.test.jsx
│ │ ├── numberInput.test.jsx
│ │ ├── textarea.test.jsx
│ │ ├── textInput.test.jsx
│ │ ├── timeInput.test.jsx
│ │ ├── calendarComponent.test.jsx
│ │ ├── selectInput.test.jsx
│ │ ├── Textarea.jsx
│ │ ├── TimeInput.jsx
│ │ ├── TextInput.jsx
│ │ ├── SelectInput.jsx
│ │ ├── NumberInput.jsx
│ │ ├── TogglePill.jsx
│ │ ├── togglePill.test.jsx
│ │ └── CalendarComponent.jsx
│ ├── TypeaheadItem.jsx
│ ├── timeInput.test.jsx
│ ├── charCounter.test.jsx
│ ├── LockedBadge.story.jsx
│ ├── errorList.test.jsx
│ ├── CharCounter.jsx
│ ├── errorList.story.jsx
│ ├── radioButton.story.jsx
│ ├── togglePill.test.jsx
│ ├── ErrorList.jsx
│ ├── LockedBadge.test.jsx
│ ├── radioButton.test.jsx
│ ├── togglepill.story.jsx
│ ├── inputTime.test.jsx
│ ├── toggleSwitch.story.jsx
│ ├── select.test.jsx
│ ├── RadioButton.jsx
│ ├── checkbox.story.jsx
│ ├── TogglePill.jsx
│ └── NumberInput.jsx
├── utils
│ ├── components
│ │ ├── ConditionalWrap.jsx
│ │ ├── __snapshots__
│ │ │ ├── toggleWrapper.test.jsx.snap
│ │ │ ├── withLoading.test.jsx.snap
│ │ │ └── withErrorList.test.jsx.snap
│ │ ├── DeprecationWarning.jsx
│ │ ├── withLoading.jsx
│ │ └── withLoading.test.jsx
│ ├── a11yPassThrough.js
│ ├── bindAll.js
│ ├── storyComponents.js
│ ├── decorators.jsx
│ ├── designConstants.js
│ ├── testUtils.js
│ └── getSocialLinks.js
├── types.js
├── __snapshots__
│ ├── accentHeader.test.jsx.snap
│ └── hscroll.test.jsx.snap
├── media
│ ├── appBadges.story.jsx
│ ├── __snapshots__
│ │ ├── loading.test.jsx.snap
│ │ └── appBadges.test.jsx.snap
│ ├── avatar.story.jsx
│ ├── loading.test.jsx
│ ├── appBadges.test.jsx
│ └── icon.story.jsx
├── navigation
│ └── components
│ │ ├── notifications
│ │ ├── __snapshots__
│ │ │ ├── NotificationsDropdown.test.jsx.snap
│ │ │ └── Notifications.test.jsx.snap
│ │ ├── NotificationsDropdown.test.jsx
│ │ └── Notifications.test.jsx
│ │ ├── groupDraftItem
│ │ ├── __snapshots__
│ │ │ └── GroupDraftItem.test.jsx.snap
│ │ ├── GroupDraftItem.jsx
│ │ └── GroupDraftItem.test.jsx
│ │ ├── profile
│ │ └── ProfileDropdown.test.jsx
│ │ └── dashboard
│ │ └── DashboardDropdown.test.jsx
├── interactive
│ ├── __snapshots__
│ │ └── toast.test.jsx.snap
│ └── InfoToggle.jsx
├── accentHeader.test.jsx
├── AccentHeader.jsx
├── signupModal.story.jsx
├── AccentHeader.story.jsx
├── SignupModal.test.jsx
├── hscroll.story.jsx
└── Hscroll.jsx
├── .stylelintrc
├── .storybook
├── addons.js
├── config.js
└── webpack.config.js
├── .babelrc
├── __mocks__
├── emptyString.js
├── base64-image-loader.js
└── textContentMocks.js
├── util
├── setupTest.js
├── sassRelativeImporter.js
└── jestSystemShim.js
├── flow-typed
├── npm
│ ├── flow-bin_v0.x.x.js
│ ├── @storybook
│ │ ├── addon-actions_v3.x.x.js
│ │ ├── addon-knobs_v3.x.x.js
│ │ └── react_v3.x.x.js
│ ├── @alrra
│ │ └── travis-scripts_vx.x.x.js
│ ├── classnames_v2.x.x.js
│ ├── raf-schd_vx.x.x.js
│ ├── babel-jest_vx.x.x.js
│ ├── raw-loader_vx.x.x.js
│ ├── eslint-loader_vx.x.x.js
│ ├── babel-preset-flow_vx.x.x.js
│ ├── babel-preset-react_vx.x.x.js
│ ├── babel-preset-es2015_vx.x.x.js
│ ├── @meetup
│ │ └── swarm-styles_vx.x.x.js
│ ├── babel-preset-stage-2_vx.x.x.js
│ ├── react-portal_v4.1.x.js
│ ├── babel-plugin-transform-class-properties_vx.x.x.js
│ ├── babel-plugin-transform-flow-strip-types_vx.x.x.js
│ ├── file-loader_vx.x.x.js
│ ├── storybook-react-router_vx.x.x.js
│ ├── babel-plugin-react-intl_vx.x.x.js
│ ├── eslint-import-resolver-webpack_vx.x.x.js
│ ├── autosize_vx.x.x.js
│ ├── babel-register_vx.x.x.js
│ ├── raf_vx.x.x.js
│ ├── react-flatpickr_vx.x.x.js
│ ├── prop-types_v15.x.x.js
│ ├── swarm-sasstools_vx.x.x.js
│ ├── eslint-plugin-meetup_vx.x.x.js
│ ├── stylelint-config-prettier_vx.x.x.js
│ ├── babel-register_v6.x.x.js
│ └── react-helmet_v5.x.x.js
└── design-system.js
├── .flowconfig
├── .prettierrc
├── .npmignore
├── .gitignore
├── .eslintrc.airbnb.js
├── .editorconfig
├── jest.config.json
├── tailwind.config.js
└── .eslintrc.js
/.nvmrc:
--------------------------------------------------------------------------------
1 | 10.24.1
2 |
--------------------------------------------------------------------------------
/.yarnrc:
--------------------------------------------------------------------------------
1 | save-exact true
--------------------------------------------------------------------------------
/.node-version:
--------------------------------------------------------------------------------
1 | 10.24.1
2 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | package.json
2 |
--------------------------------------------------------------------------------
/.stylelintignore:
--------------------------------------------------------------------------------
1 | /assets/scss/storybook.scss
--------------------------------------------------------------------------------
/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @meetup/revenue-guardians
2 |
--------------------------------------------------------------------------------
/assets/css/tailwind.css:
--------------------------------------------------------------------------------
1 | @tailwind components;
2 | @tailwind utilities;
3 |
--------------------------------------------------------------------------------
/assets/scss/components/_appBadges.scss:
--------------------------------------------------------------------------------
1 | .getTheApp-downloadImage {
2 | max-width: 160px;
3 | }
4 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | build/
2 | coverage/
3 | flow-typed/
4 | infrastructure/
5 | node_modules/
6 | svg/
7 | *.log
8 | tests/
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | CI_BUILD_NUMBER ?= $(USER)-snapshot
2 | VERSION ?= 8.1.$(CI_BUILD_NUMBER)
3 |
4 | version:
5 | @echo $(VERSION)
6 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | #### Related issues
2 | Fixes PIVOTAL-xxx
3 |
4 | #### Description
5 |
6 | #### Screenshots (if applicable)
7 |
--------------------------------------------------------------------------------
/assets/images/app_download/ios/download_de.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/meetuparchive/meetup-web-components/HEAD/assets/images/app_download/ios/download_de.png
--------------------------------------------------------------------------------
/assets/images/app_download/ios/download_en.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/meetuparchive/meetup-web-components/HEAD/assets/images/app_download/ios/download_en.png
--------------------------------------------------------------------------------
/assets/images/app_download/ios/download_es.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/meetuparchive/meetup-web-components/HEAD/assets/images/app_download/ios/download_es.png
--------------------------------------------------------------------------------
/assets/images/app_download/ios/download_fr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/meetuparchive/meetup-web-components/HEAD/assets/images/app_download/ios/download_fr.png
--------------------------------------------------------------------------------
/assets/images/app_download/ios/download_it.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/meetuparchive/meetup-web-components/HEAD/assets/images/app_download/ios/download_it.png
--------------------------------------------------------------------------------
/assets/images/app_download/ios/download_ja.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/meetuparchive/meetup-web-components/HEAD/assets/images/app_download/ios/download_ja.png
--------------------------------------------------------------------------------
/assets/images/app_download/ios/download_ko.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/meetuparchive/meetup-web-components/HEAD/assets/images/app_download/ios/download_ko.png
--------------------------------------------------------------------------------
/assets/images/app_download/ios/download_nl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/meetuparchive/meetup-web-components/HEAD/assets/images/app_download/ios/download_nl.png
--------------------------------------------------------------------------------
/assets/images/app_download/ios/download_pl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/meetuparchive/meetup-web-components/HEAD/assets/images/app_download/ios/download_pl.png
--------------------------------------------------------------------------------
/assets/images/app_download/ios/download_pt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/meetuparchive/meetup-web-components/HEAD/assets/images/app_download/ios/download_pt.png
--------------------------------------------------------------------------------
/assets/images/app_download/ios/download_ru.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/meetuparchive/meetup-web-components/HEAD/assets/images/app_download/ios/download_ru.png
--------------------------------------------------------------------------------
/assets/images/app_download/ios/download_th.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/meetuparchive/meetup-web-components/HEAD/assets/images/app_download/ios/download_th.png
--------------------------------------------------------------------------------
/assets/images/app_download/ios/download_tr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/meetuparchive/meetup-web-components/HEAD/assets/images/app_download/ios/download_tr.png
--------------------------------------------------------------------------------
/assets/images/app_download/android/download_de.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/meetuparchive/meetup-web-components/HEAD/assets/images/app_download/android/download_de.png
--------------------------------------------------------------------------------
/assets/images/app_download/android/download_en.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/meetuparchive/meetup-web-components/HEAD/assets/images/app_download/android/download_en.png
--------------------------------------------------------------------------------
/assets/images/app_download/android/download_es.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/meetuparchive/meetup-web-components/HEAD/assets/images/app_download/android/download_es.png
--------------------------------------------------------------------------------
/assets/images/app_download/android/download_fr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/meetuparchive/meetup-web-components/HEAD/assets/images/app_download/android/download_fr.png
--------------------------------------------------------------------------------
/assets/images/app_download/android/download_it.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/meetuparchive/meetup-web-components/HEAD/assets/images/app_download/android/download_it.png
--------------------------------------------------------------------------------
/assets/images/app_download/android/download_ja.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/meetuparchive/meetup-web-components/HEAD/assets/images/app_download/android/download_ja.png
--------------------------------------------------------------------------------
/assets/images/app_download/android/download_ko.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/meetuparchive/meetup-web-components/HEAD/assets/images/app_download/android/download_ko.png
--------------------------------------------------------------------------------
/assets/images/app_download/android/download_nl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/meetuparchive/meetup-web-components/HEAD/assets/images/app_download/android/download_nl.png
--------------------------------------------------------------------------------
/assets/images/app_download/android/download_pl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/meetuparchive/meetup-web-components/HEAD/assets/images/app_download/android/download_pl.png
--------------------------------------------------------------------------------
/assets/images/app_download/android/download_pt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/meetuparchive/meetup-web-components/HEAD/assets/images/app_download/android/download_pt.png
--------------------------------------------------------------------------------
/assets/images/app_download/android/download_ru.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/meetuparchive/meetup-web-components/HEAD/assets/images/app_download/android/download_ru.png
--------------------------------------------------------------------------------
/assets/images/app_download/android/download_th.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/meetuparchive/meetup-web-components/HEAD/assets/images/app_download/android/download_th.png
--------------------------------------------------------------------------------
/assets/images/app_download/android/download_tr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/meetuparchive/meetup-web-components/HEAD/assets/images/app_download/android/download_tr.png
--------------------------------------------------------------------------------
/src/layout/__snapshots__/chunk.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Chunk exists 1`] = `
4 |
7 | `;
8 |
--------------------------------------------------------------------------------
/src/forms/__snapshots__/typeahead.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`TypeaheadItem exists 1`] = `
4 |
5 | matters
6 |
7 | `;
8 |
--------------------------------------------------------------------------------
/src/layout/__snapshots__/stripe.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Stripe exists 1`] = `
4 |
7 | `;
8 |
--------------------------------------------------------------------------------
/src/layout/__snapshots__/flex.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Flex exists 1`] = `
4 |
7 | `;
8 |
--------------------------------------------------------------------------------
/src/layout/__snapshots__/section.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Section exists 1`] = `
4 |
7 | `;
8 |
--------------------------------------------------------------------------------
/src/utils/components/ConditionalWrap.jsx:
--------------------------------------------------------------------------------
1 | const ConditionalWrap = ({ condition, wrap, children }) =>
2 | condition ? wrap(children) : children;
3 |
4 | export default ConditionalWrap;
5 |
--------------------------------------------------------------------------------
/src/layout/__snapshots__/bounds.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Bounds exists 1`] = `
4 |
7 | `;
8 |
--------------------------------------------------------------------------------
/.stylelintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "mwp-config/stylelint/stylelint-config-base",
4 | "mwp-config/stylelint/stylelint-config-swarmProject",
5 | "stylelint-config-prettier"
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/.storybook/addons.js:
--------------------------------------------------------------------------------
1 | import '@storybook/addon-knobs/register';
2 | import '@storybook/addon-actions/register';
3 | import '@storybook/addon-notes/register';
4 | import '@storybook/addon-options/register';
--------------------------------------------------------------------------------
/src/types.js:
--------------------------------------------------------------------------------
1 | import { bool, shape } from 'prop-types';
2 |
3 | export const Media = shape({
4 | isAtSmallUp: bool,
5 | isAtMediumUp: bool,
6 | isAtLargeUp: bool,
7 | isAtHugeUp: bool,
8 | });
9 |
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | "es2015",
4 | "react",
5 | "flow",
6 | "stage-2"
7 | ],
8 | "plugins": [
9 | "transform-class-properties",
10 | "react-docgen"
11 | ]
12 | }
--------------------------------------------------------------------------------
/__mocks__/emptyString.js:
--------------------------------------------------------------------------------
1 | /**
2 | * This module can be used to map certain module names to an empty string in
3 | * Jest if you just want the module to output an empty string
4 | */
5 | module.exports = '';
6 |
--------------------------------------------------------------------------------
/util/setupTest.js:
--------------------------------------------------------------------------------
1 | require('raf/polyfill');
2 | require('./jestSystemShim');
3 | const Enzyme = require('enzyme');
4 | const Adapter = require('enzyme-adapter-react-16');
5 |
6 | Enzyme.configure({ adapter: new Adapter() });
7 |
--------------------------------------------------------------------------------
/flow-typed/npm/flow-bin_v0.x.x.js:
--------------------------------------------------------------------------------
1 | // flow-typed signature: 6a5610678d4b01e13bbfbbc62bdaf583
2 | // flow-typed version: 3817bc6980/flow-bin_v0.x.x/flow_>=v0.25.x
3 |
4 | declare module "flow-bin" {
5 | declare module.exports: string;
6 | }
7 |
--------------------------------------------------------------------------------
/.flowconfig:
--------------------------------------------------------------------------------
1 | [ignore]
2 | ./build/*
3 | ./coverage/*
4 | ./node_modules/radium/*
5 | ./node_modules/stylelint/*
6 | .*.json
7 | ./node_modules/radium/*
8 | ./node_modules/@meetup/swarm-components/*
9 |
10 | [include]
11 |
12 | [libs]
13 |
14 | [options]
15 |
--------------------------------------------------------------------------------
/src/forms/__snapshots__/charCounter.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`CharCounter exists 1`] = `
4 |
8 | 60
9 |
10 | `;
11 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "trailingComma": "es5",
3 | "useTabs": true,
4 | "semi": true,
5 | "singleQuote": true,
6 | "overrides": [
7 | {
8 | "files": "assets/scss/**/*.scss",
9 | "options": {
10 | "singleQuote": false,
11 | "trailingComma": "none"
12 | }
13 | }
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/assets/scss/components/_chunk.scss:
--------------------------------------------------------------------------------
1 | /*doc
2 | ---
3 | title: Chunk
4 | ---
5 | Adds bottom space to an element
6 | or a group of elements.
7 | ```
8 | */
9 |
10 | %chunk,
11 | .chunk {
12 | @extend %clearfix;
13 | display: block;
14 | padding-bottom: var(--responsive-space) !important;
15 | }
16 |
--------------------------------------------------------------------------------
/src/layout/__snapshots__/card.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Card and variants renders a card 1`] = `
4 |
7 |
8 | Lorem Ipsum is simply dummy text of the printing and typesetting industry.
9 |
10 |
11 | `;
12 |
--------------------------------------------------------------------------------
/src/forms/__snapshots__/timeInput.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`TimeInput TimeInput, with input[time] support renders a time html input with expected props 1`] = `
4 |
10 | `;
11 |
--------------------------------------------------------------------------------
/src/layout/chunk.test.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow } from 'enzyme';
3 |
4 | import { ChunkComponent } from './Chunk';
5 |
6 | describe('Chunk', function() {
7 | const chunk = shallow();
8 |
9 | it('exists', function() {
10 | expect(chunk).toMatchSnapshot();
11 | });
12 | });
13 |
--------------------------------------------------------------------------------
/assets/scss/components/_adminBar.scss:
--------------------------------------------------------------------------------
1 | .groupAdminLinks {
2 | bottom: 0;
3 | padding: var(--space-1);
4 | position: fixed;
5 | right: 0;
6 | z-index: 9999;
7 | }
8 |
9 | .redbar {
10 | background-color: var(--c-red);
11 | width: 100%;
12 | }
13 |
14 | .greenbar {
15 | background-color: var(--c-teal);
16 | width: 100%;
17 | }
18 |
--------------------------------------------------------------------------------
/assets/scss/util/_vars.scss:
--------------------------------------------------------------------------------
1 | // shadow for "interactive" elements,
2 | // like popover or dropdown menus
3 | $interactiveShadow: 0 2px 2px 0 $C_border, 0 3px 1px -2px $C_separator,
4 | 0 1px 5px 0 $C_border;
5 | $animate_easeOutQuad: cubic-bezier(
6 | 0.165,
7 | 0.84,
8 | 0.44,
9 | 1
10 | ); // stylelint-disable-line number-max-precision
11 |
--------------------------------------------------------------------------------
/assets/scss/components/_infoToggle.scss:
--------------------------------------------------------------------------------
1 | .infoToggle {
2 | &-trigger {
3 | background-color: var(--c-textSecondary);
4 | border-radius: 50%;
5 | color: var(--c-white);
6 | font-size: 10px;
7 | height: 15px;
8 | width: 15px;
9 | }
10 | &-label {
11 | display: inline-block;
12 | margin-right: var(--space-quarter);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/forms/redux-form/RadioButtonGroup.jsx:
--------------------------------------------------------------------------------
1 | import { mapProps } from 'recompose';
2 |
3 | import RadioButtonGroup from '../RadioButtonGroup';
4 |
5 | export const propMapper = ({ input, meta, ...other }) => ({
6 | selectedValue: input.value,
7 | ...input,
8 | ...other,
9 | });
10 |
11 | export default mapProps(propMapper)(RadioButtonGroup);
12 |
--------------------------------------------------------------------------------
/src/forms/redux-form/__snapshots__/checkbox.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`redux-form Textarea renders a Checkbox component with expected attributes from mock data, should be checked 1`] = `
4 |
10 | `;
11 |
--------------------------------------------------------------------------------
/src/layout/formSection.test.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow } from 'enzyme';
3 |
4 | import FormSection from './FormSection';
5 |
6 | describe('FormSection', () => {
7 | it('exists and contains form section wrapping elements with proper attributes', () => {
8 | expect(shallow()).toMatchSnapshot();
9 | });
10 | });
11 |
--------------------------------------------------------------------------------
/assets/scss/components/_tooltip.scss:
--------------------------------------------------------------------------------
1 | .tooltip-bubble {
2 | background-color: $C_darkGray;
3 |
4 | &::after {
5 | border-bottom-color: $C_darkGray;
6 | border-top-color: $C_darkGray;
7 | }
8 | }
9 |
10 | .tooltip-closeBtn {
11 | float: right;
12 | padding: 5px !important;
13 |
14 | .svg-icon {
15 | height: 24px;
16 | width: 24px;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/__snapshots__/accentHeader.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`AccentHeader exists 1`] = `
4 |
16 | `;
17 |
--------------------------------------------------------------------------------
/src/forms/__snapshots__/button.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Button is a HTML button element exists 1`] = `
4 |
13 | `;
14 |
--------------------------------------------------------------------------------
/src/forms/redux-form/__snapshots__/numberInput.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`redux-form NumberInput renders a NumberInput component with expected attributes from mock data 1`] = `
4 |
10 | `;
11 |
--------------------------------------------------------------------------------
/src/forms/redux-form/__snapshots__/timeInput.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`redux-form TimeInput renders a TimeInput component with expected attributes from mock data 1`] = `
4 |
11 | `;
12 |
--------------------------------------------------------------------------------
/src/forms/__snapshots__/toggleSwitch.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`ToggleSwitch basic renders checked toggle switch 1`] = `
4 |
8 | `;
9 |
10 | exports[`ToggleSwitch basic renders inactive toggle switch 1`] = `
11 |
14 | `;
15 |
--------------------------------------------------------------------------------
/assets/scss/components/_dropdown.scss:
--------------------------------------------------------------------------------
1 | .dropdownMenu-item {
2 | border-bottom: 1px solid $C_border;
3 | box-sizing: border-box;
4 | cursor: pointer;
5 | justify-content: flex-start;
6 | padding: calc(var(--responsive-space) / 2);
7 |
8 | &:hover,
9 | &:focus {
10 | background-color: $C_coolGrayLight;
11 | }
12 |
13 | &:last-child {
14 | border-bottom: 0;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/__mocks__/base64-image-loader.js:
--------------------------------------------------------------------------------
1 | const base64String = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNNyA3YTUgNSAwIDEgMSAxMCAwQTUgNSAwIDAgMSA3IDd6bTUgN2MtNCAwLTkgMy41LTkgNiAwIC44MjguNjU2IDIgMiAyaDE0YzEuMzI4IDAgMi0xLjE3MiAyLTIgMC0yLjUtNS02LTktNnoiLz48L3N2Zz4=';
2 |
3 | module.exports = base64String;
4 |
--------------------------------------------------------------------------------
/src/forms/redux-form/__snapshots__/togglePill.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`redux-form TogglePill renders a TogglePill component with expected attributes from mock data 1`] = `
4 |
11 | Parenting!
12 |
13 | `;
14 |
--------------------------------------------------------------------------------
/src/forms/redux-form/__snapshots__/textInput.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`redux-form TextInput renders a TextInput component with expected attributes from mock data 1`] = `
4 |
12 | `;
13 |
--------------------------------------------------------------------------------
/src/utils/a11yPassThrough.js:
--------------------------------------------------------------------------------
1 | import cx from 'classnames';
2 |
3 | // needed to allow for a11y cases for screen readers with mutli step forms where inputs are
4 | // conditionally rendered
5 | export default (className = '') =>
6 | cx('tw-pb-1 tw-block', {
7 | 'visibility--a11yHide': className.includes('visibility--a11yHide'),
8 | 'visibility--a11yShow': className.includes('visiblity--a11yShow'),
9 | });
10 |
--------------------------------------------------------------------------------
/assets/scss/components/_lockedBadge.scss:
--------------------------------------------------------------------------------
1 | .lockedBadge-container {
2 | border-radius: 8px;
3 | cursor: pointer;
4 | padding: 0;
5 | }
6 |
7 | .lockedBadge-label {
8 | font-size: 14px;
9 | line-height: 1.43;
10 | padding-left: 6px;
11 | }
12 |
13 | .lockedBadge-icon-container {
14 | display: inline-flex;
15 | }
16 |
17 | .lockedBadge-badge {
18 | align-items: center;
19 | display: flex;
20 | padding: 6px 8px;
21 | }
22 |
--------------------------------------------------------------------------------
/src/forms/redux-form/__snapshots__/textarea.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`redux-form Textarea renders a Textarea component with expected attributes from mock data 1`] = `
4 |
13 | `;
14 |
--------------------------------------------------------------------------------
/util/sassRelativeImporter.js:
--------------------------------------------------------------------------------
1 | // node-sass importer to resolve path names locally of imports from
2 | // node_modules the same way css-loader does with ~ as a prefix
3 | // used in build:css to build css from sass
4 |
5 | const path = require('path');
6 |
7 | module.exports = function(url, prev, done) {
8 | if (url[0] === '~') {
9 | url = path.resolve('node_modules', url.substr(1));
10 | }
11 | return { file: url };
12 | };
13 |
--------------------------------------------------------------------------------
/src/forms/redux-form/__snapshots__/RadioButtonGroup.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`redux-form RadioButtonGroup propMapper should map the props as expected 1`] = `
4 | Object {
5 | "name": "test-name",
6 | "onBlur": "onBlur",
7 | "onChange": "onChange",
8 | "onFocus": "onFocus",
9 | "otherProp": "otherProp",
10 | "selectedValue": "test-value",
11 | "value": "test-value",
12 | }
13 | `;
14 |
--------------------------------------------------------------------------------
/assets/svg/facebook.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/forms/redux-form/Checkbox.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Checkbox from '../Checkbox';
3 |
4 | const ReduxFormCheckbox = props => {
5 | const {
6 | meta, // eslint-disable-line no-unused-vars
7 | input,
8 | ...other
9 | } = props;
10 |
11 | return ;
12 | };
13 |
14 | ReduxFormCheckbox.displayName = 'ReduxFormCheckbox';
15 |
16 | export default ReduxFormCheckbox;
17 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | # Runtime data
2 | pids
3 | *.pid
4 | *.seed
5 |
6 | # node-waf configuration
7 | .lock-wscript
8 |
9 | # Dependency directory
10 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
11 | node_modules
12 |
13 | .DS_Store
14 | coverage
15 | npm-debug.log
16 | .swo
17 | .swp
18 | .*.swp
19 | .npmrc
20 |
21 | # Generated icon library file
22 | /src/media/iconLibrary.story.jsx
23 |
24 | github_deploy_key
25 |
--------------------------------------------------------------------------------
/assets/scss/components/_signup.scss:
--------------------------------------------------------------------------------
1 | .meetup-signupModal-wrapper {
2 | margin: $space $space-2;
3 | }
4 |
5 | .meetup-signupModal-facebook {
6 | background-color: $C_facebook;
7 |
8 | &:hover {
9 | background-color: $C_facebook;
10 | }
11 | }
12 |
13 | .meetup-signupModal-apple img {
14 | margin: -14px -14px;
15 | }
16 |
17 | .meetup-signupModal-apple div {
18 | align-items: center;
19 | }
20 |
21 | .meetup-signupModal-or {
22 | text-transform: uppercase;
23 | }
24 |
--------------------------------------------------------------------------------
/src/forms/redux-form/__snapshots__/calendarComponent.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`redux-form Calendar Component renders a Calendar component with expected attributes from mock data 1`] = `
4 |
14 | `;
15 |
--------------------------------------------------------------------------------
/assets/scss/components/_bounds.scss:
--------------------------------------------------------------------------------
1 | /*doc
2 | ---
3 | title: Bounds
4 | ---
5 | Used as a non-visual content container that manages content measure.
6 |
7 | Centers children with auto margin, clears floats, applies
8 | padding, and sets a max-width.
9 | */
10 |
11 | .bounds {
12 | @extend %clearfix;
13 | box-sizing: border-box;
14 | margin-left: auto;
15 | margin-right: auto;
16 | max-width: $bounds;
17 | width: 100%;
18 | }
19 |
20 | .bounds--wide {
21 | max-width: $bounds-wide;
22 | }
23 |
--------------------------------------------------------------------------------
/assets/svg/email.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/forms/TypeaheadItem.jsx:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 |
3 | /**
4 | * @module TypeaheadItem
5 | */
6 | const TypeaheadItem = ({ value, className, children }) => children;
7 |
8 | export default TypeaheadItem;
9 |
10 | TypeaheadItem.propTypes = {
11 | value: PropTypes.oneOfType([
12 | PropTypes.string,
13 | PropTypes.array,
14 | PropTypes.object,
15 | ]).isRequired,
16 | className: PropTypes.string,
17 | children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]).isRequired,
18 | };
19 |
--------------------------------------------------------------------------------
/src/forms/__snapshots__/LockedBadge.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`LockedBadge renders locked badge with default styles 1`] = `
4 |
9 | `;
10 |
11 | exports[`LockedBadge renders locked badge with neutral styles 1`] = `
12 |
18 | `;
19 |
--------------------------------------------------------------------------------
/flow-typed/npm/@storybook/addon-actions_v3.x.x.js:
--------------------------------------------------------------------------------
1 | // flow-typed signature: 2f5b0f18c5b5b31b01f63163429685c7
2 | // flow-typed version: 5edd39ab2e/@storybook/addon-actions_v3.x.x/flow_>=v0.25.x
3 |
4 | declare module '@storybook/addon-actions' {
5 | declare type Action = (name: string) => (...args: Array) => void;
6 | declare type DecorateFn = (args: Array) => Array;
7 |
8 | declare module.exports: {
9 | action: Action,
10 | decorateAction(args: Array): Action;
11 | };
12 | }
13 |
--------------------------------------------------------------------------------
/assets/scss/main.scss:
--------------------------------------------------------------------------------
1 | @import "~swarm-constants/dist/scss/colors";
2 |
3 | @import url("//a248.e.akamai.net/secure.meetupstatic.com/s/fonts/402715706936963211631/graphik.css");
4 |
5 | // sasstools CSS reset
6 |
7 | @import "~swarm-sasstools/scss/reset/all";
8 |
9 | // all meetup-web-components component partials
10 |
11 | @import "./components/all";
12 |
13 | // sasstools modifier classes
14 |
15 | @import "~swarm-sasstools/scss/modifierClasses/all";
16 |
17 | // tailwind
18 |
19 | @import "../css/tailwind.min";
20 |
--------------------------------------------------------------------------------
/src/forms/timeInput.test.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow } from 'enzyme';
3 | import TimeInput from './TimeInput';
4 |
5 | describe('TimeInput', function() {
6 | const props = {
7 | name: 'time',
8 | value: '11:15',
9 | onChange: () => {},
10 | required: true,
11 | };
12 |
13 | describe('TimeInput, with input[time] support', () => {
14 | it('renders a time html input with expected props', function() {
15 | expect(shallow()).toMatchSnapshot();
16 | });
17 | });
18 | });
19 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Runtime data
2 | pids
3 | *.pid
4 | *.seed
5 |
6 | # node-waf configuration
7 | .lock-wscript
8 |
9 | # Dependency directory
10 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
11 | node_modules
12 |
13 | .DS_Store
14 | .sass-cache/
15 | coverage
16 | lib
17 | .swo
18 | .swp
19 | .*.swp
20 | *.log
21 | .vscode/
22 | .idea
23 |
24 | # Generated icon library file
25 | /src/media/iconLibrary.story.jsx
26 |
27 | # static build of storybook
28 | .storybook-out
29 |
30 | github_deploy_key
31 |
--------------------------------------------------------------------------------
/src/utils/bindAll.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @function bindAll
3 | * helper for binding prototype methods to class context
4 | *
5 | * for example, instead of doing this in a class `constructor`:
6 | * `this.handleClick = this.handleClick.bind(this)`
7 | *
8 | * you can use `bindAll`:
9 | * ```
10 | * bindAll(this,
11 | * handleClick,
12 | * someOtherMethod,
13 | * anotherMethod);
14 | * ```
15 | */
16 | const bindAll = (context, ...names) => {
17 | names.forEach(name => (context[name] = context[name].bind(context)));
18 | };
19 | export default bindAll;
20 |
--------------------------------------------------------------------------------
/src/forms/redux-form/checkbox.test.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow } from 'enzyme';
3 | import ReduxFormCheckbox from './Checkbox';
4 |
5 | describe('redux-form Textarea', () => {
6 | const props = {
7 | input: {
8 | label: 'Do you want more?',
9 | name: 'want_more',
10 | value: true,
11 | },
12 | };
13 |
14 | it('renders a Checkbox component with expected attributes from mock data, should be checked', () => {
15 | const component = shallow();
16 | expect(component).toMatchSnapshot();
17 | });
18 | });
19 |
--------------------------------------------------------------------------------
/.eslintrc.airbnb.js:
--------------------------------------------------------------------------------
1 | const config = {
2 | root: true,
3 | parser: 'babel-eslint',
4 | extends: ['airbnb', 'prettier', 'prettier/flowtype', 'prettier/react'],
5 | parserOptions: {
6 | ecmaVersion: 6,
7 | ecmaFeatures: {
8 | jsx: true,
9 | experimentalObjectRestSpread: true,
10 | },
11 | sourceType: 'module',
12 | },
13 | env: {
14 | browser: true,
15 | node: true,
16 | jest: true,
17 | jasmine: true,
18 | es6: true,
19 | },
20 | plugins: ['flowtype', 'react', 'meetup'],
21 | rules: {
22 | 'no-tabs': 0,
23 | },
24 | };
25 |
26 | module.exports = config;
27 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # To get started with Dependabot version updates, you'll need to specify which
2 | # package ecosystems to update and where the package manifests are located.
3 | # Please see the documentation for all configuration options:
4 | # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5 |
6 | version: 2
7 | updates:
8 | - package-ecosystem: npm
9 | directory: "/"
10 | schedule:
11 | interval: daily
12 | commit-message:
13 | prefix: "chore"
14 | include: "scope"
15 | open-pull-requests-limit: 0
16 |
--------------------------------------------------------------------------------
/src/forms/charCounter.test.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow } from 'enzyme';
3 |
4 | import { CharCounter } from './CharCounter';
5 |
6 | describe('CharCounter', () => {
7 | it('exists', () => {
8 | const component = shallow();
9 | expect(component).toMatchSnapshot();
10 | });
11 |
12 | it('uses error color when over the character limit', () => {
13 | const component = shallow();
14 | expect(component.prop('className')).toContain('text--error');
15 | });
16 | });
17 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # editorconfig.org
4 |
5 | root = true
6 |
7 |
8 | [*]
9 |
10 | # Change these settings to your own preference
11 | indent_style = tab
12 | indent_size = 4
13 | max_line_length = 90
14 |
15 | # We recommend you to keep these unchanged
16 | end_of_line = lf
17 | charset = utf-8
18 | trim_trailing_whitespace = true
19 | insert_final_newline = true
20 |
21 | [*.md]
22 | trim_trailing_whitespace = false
23 |
24 | [*.json]
25 | indent_style = space
26 |
27 |
--------------------------------------------------------------------------------
/src/layout/__snapshots__/formSection.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`FormSection exists and contains form section wrapping elements with proper attributes 1`] = `
4 |
7 |
12 |
15 |
19 |
20 |
21 |
22 | `;
23 |
--------------------------------------------------------------------------------
/src/media/appBadges.story.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { storiesOf } from '@storybook/react';
3 |
4 | import { decorateWithBasics, decorateWithInfo } from '../utils/decorators';
5 | import AppBadges from './AppBadges';
6 |
7 | storiesOf('Media/AppBadges', module)
8 | .addDecorator(decorateWithBasics)
9 | .addDecorator(decorateWithInfo)
10 | .add('default', () => )
11 | .add('only Google Play button', () => (
12 |
13 | ))
14 | .add('only App Store button', () => );
15 |
--------------------------------------------------------------------------------
/assets/svg/message.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/forms/__snapshots__/errorList.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`ErrorList matches snapshot for input without id 1`] = `
4 |
7 | -
10 | This is an error message
11 |
12 |
13 | `;
14 |
15 | exports[`ErrorList matches snapshot for single error 1`] = `
16 |
20 | -
23 | This is an error message
24 |
25 |
26 | `;
27 |
--------------------------------------------------------------------------------
/assets/scss/components/_inlineblockList.scss:
--------------------------------------------------------------------------------
1 | %inlineblockList,
2 | .inlineblockList {
3 | margin: 0;
4 | padding: 0;
5 |
6 | > li {
7 | display: inline-block;
8 | padding-right: var(--responsive-space);
9 |
10 | &:last-child {
11 | padding-right: 0;
12 | }
13 | }
14 | }
15 |
16 | .inlineblockList--separated > li {
17 | padding-right: calc(var(--responsive-space) / 2);
18 |
19 | &::after {
20 | content: attr(data-separator);
21 | padding-left: calc(var(--responsive-space) / 2);
22 | speak: none;
23 | }
24 |
25 | &:last-child {
26 | &::after {
27 | display: none;
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/flow-typed/design-system.js:
--------------------------------------------------------------------------------
1 | // a list of all constants related to design systems
2 |
3 | declare type MediaSizes = 'xxs' | 'xs' | 's' | 'm' | 'l' | 'xl' | 'xxl';
4 |
5 | declare type MediaSizeMap = {|
6 | xxs: '12',
7 | xs: '16',
8 | s: '24',
9 | m: '36',
10 | l: '48',
11 | xl: '72',
12 | xxl: '120',
13 | |};
14 |
15 | declare type MediaQuerySize = 'small' | 'medium' | 'large' | 'huge';
16 |
17 | declare type MediaQueryMap = {|
18 | small: 'screen and (min-width: 440px)',
19 | medium: 'screen and (min-width: 640px)',
20 | large: 'screen and (min-width: 840px)',
21 | huge: 'screen and (min-width: 1024px)',
22 | |}
--------------------------------------------------------------------------------
/flow-typed/npm/@alrra/travis-scripts_vx.x.x.js:
--------------------------------------------------------------------------------
1 | // flow-typed signature: febad60289e1b817e6fddff33cc021b8
2 | // flow-typed version: <>/@alrra/travis-scripts_v3.0.1/flow_v0.76.0
3 |
4 | /**
5 | * This is an autogenerated libdef stub for:
6 | *
7 | * '@alrra/travis-scripts'
8 | *
9 | * Fill this stub out by replacing all the `any` types.
10 | *
11 | * Once filled out, we encourage you to share your work with the
12 | * community by sending a pull request to:
13 | * https://github.com/flowtype/flow-typed
14 | */
15 |
16 | declare module '@alrra/travis-scripts' {
17 | declare module.exports: any;
18 | }
19 |
--------------------------------------------------------------------------------
/assets/scss/components/_toggleSwitch.scss:
--------------------------------------------------------------------------------
1 | .toggleSwitch {
2 | /* stylelint-disable */
3 | /* stylelint disabling is a temporary solution to override styles from swarm ui */
4 | &[data-swarm-toggle="unchecked"]:not(:disabled) {
5 | border-color: #707070 !important;
6 | [data-swarm-toggle-switch-disc] {
7 | border-color: inherit;
8 | margin-left: -1px;
9 | margin-top: 0;
10 | svg {
11 | fill: #707070 !important;
12 | }
13 | }
14 | }
15 |
16 | &[data-swarm-toggle="checked"] [data-swarm-toggle-switch-disc] {
17 | border-color: #707070;
18 | margin-top: 0;
19 | }
20 | /* stylelint-enable */
21 | }
22 |
--------------------------------------------------------------------------------
/src/forms/redux-form/RadioButtonGroup.test.jsx:
--------------------------------------------------------------------------------
1 | import { propMapper } from './RadioButtonGroup';
2 |
3 | describe('redux-form RadioButtonGroup', () => {
4 | describe('propMapper', () => {
5 | it('should map the props as expected', () => {
6 | const input = {
7 | value: 'test-value',
8 | onChange: 'onChange',
9 | onBlur: 'onBlur',
10 | name: 'test-name',
11 | onFocus: 'onFocus',
12 | };
13 | const meta = {
14 | error: 'error',
15 | };
16 | expect(
17 | propMapper({
18 | input,
19 | meta,
20 | otherProp: 'otherProp',
21 | })
22 | ).toMatchSnapshot();
23 | });
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/src/forms/__snapshots__/selectInput.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`SelectInput basic renders into the DOM 1`] = `
4 |
36 | `;
37 |
--------------------------------------------------------------------------------
/src/forms/redux-form/__snapshots__/selectInput.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`redux-form SelectInput renders a SelectInput component with expected attributes from mock data 1`] = `
4 |
26 | `;
27 |
--------------------------------------------------------------------------------
/assets/scss/util/_color-mappings.scss:
--------------------------------------------------------------------------------
1 | $C_accent: $C_blue;
2 | $C_secondary: #707070;
3 | $C_viridian: #00798a;
4 | $C_meetupRed: #e32359;
5 |
6 | $C_buttonBGNeutral: $C_coolGrayLightTransp;
7 | $C_buttonBGNeutral--disabled: transparentize($C_coolGrayLightTransp, 0.04);
8 |
9 | $C_buttonBGNeutralInverted: $C_borderInverted;
10 | $C_buttonBGNeutralInverted--disabled: transparentize($C_borderInverted, 0.17);
11 |
12 | $C_svgIcon: rgba(46, 62, 72, 0.75);
13 | $C_svgIconInverted: rgba(255, 255, 255, 0.7);
14 |
15 | :root {
16 | --color-meetup-red: #{$C_meetupRed} !important;
17 | --color-viridian: #{$C_viridian} !important;
18 | --color-gray-6: #{$C_secondary} !important;
19 | }
20 |
--------------------------------------------------------------------------------
/src/forms/redux-form/numberInput.test.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow } from 'enzyme';
3 | import ReduxFormNumberInput from './NumberInput';
4 |
5 | describe('redux-form NumberInput', function() {
6 | // props structured to match what redux-form provides to `component`
7 | const props = {
8 | meta: {},
9 | input: {
10 | label: 'Number of internets',
11 | name: 'internets',
12 | value: 10,
13 | },
14 | };
15 |
16 | it('renders a NumberInput component with expected attributes from mock data', () => {
17 | const component = shallow();
18 | expect(component).toMatchSnapshot();
19 | });
20 | });
21 |
--------------------------------------------------------------------------------
/flow-typed/npm/classnames_v2.x.x.js:
--------------------------------------------------------------------------------
1 | // flow-typed signature: cf86673cc32d185bdab1d2ea90578d37
2 | // flow-typed version: 614bf49aa8/classnames_v2.x.x/flow_>=v0.25.x
3 |
4 | type $npm$classnames$Classes =
5 | | string
6 | | { [className: string]: * }
7 | | false
8 | | void
9 | | null;
10 |
11 | declare module "classnames" {
12 | declare module.exports: (
13 | ...classes: Array<$npm$classnames$Classes | $npm$classnames$Classes[]>
14 | ) => string;
15 | }
16 |
17 | declare module "classnames/bind" {
18 | declare module.exports: $Exports<"classnames">;
19 | }
20 |
21 | declare module "classnames/dedupe" {
22 | declare module.exports: $Exports<"classnames">;
23 | }
24 |
--------------------------------------------------------------------------------
/src/forms/LockedBadge.story.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { storiesOf } from '@storybook/react';
3 | import { action } from '@storybook/addon-actions';
4 | import { decorateWithBasics, decorateWithInfo } from '../utils/decorators';
5 |
6 | import LockedBadge from './LockedBadge';
7 |
8 | const callbackAction = () => action('Click event');
9 |
10 | storiesOf('Forms/LockedBadge', module)
11 | .addDecorator(decorateWithBasics)
12 | .addDecorator(decorateWithInfo)
13 | .add('Default', () => )
14 | .add('Neutral', () => (
15 |
16 | ));
17 |
--------------------------------------------------------------------------------
/src/forms/errorList.test.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ErrorList from './ErrorList';
3 | import { shallow } from 'enzyme';
4 |
5 | const MOCK_ERROR = 'This is an error message';
6 | const MOCK_ERROR_ID = 'name';
7 |
8 | describe('ErrorList', () => {
9 | const componentWithId = shallow(
10 |
11 | );
12 | const componentWithoutId = shallow();
13 |
14 | it('matches snapshot for single error', () => {
15 | expect(componentWithId).toMatchSnapshot();
16 | });
17 | it('matches snapshot for input without id', () => {
18 | expect(componentWithoutId).toMatchSnapshot();
19 | });
20 | });
21 |
--------------------------------------------------------------------------------
/src/navigation/components/notifications/__snapshots__/NotificationsDropdown.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Notifications Dropdown should match the snapshot with an empty notifications 1`] = `
4 |
7 |
10 |
11 |
12 | `;
13 |
14 | exports[`Notifications Dropdown should match the snapshot with notifications 1`] = `
15 |
18 |
21 |
22 |
23 | `;
24 |
--------------------------------------------------------------------------------
/src/forms/redux-form/textarea.test.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow } from 'enzyme';
3 | import ReduxFormTextarea from './Textarea';
4 |
5 | describe('redux-form Textarea', () => {
6 | const formAttrs = {
7 | input: {
8 | id: 'heroField',
9 | label: 'Super Hero',
10 | name: 'superhero',
11 | value: 'Wonder Woman and Robin',
12 | maxLength: 20,
13 | required: true,
14 | },
15 | meta: {
16 | error: 'Did you mean Batman and Robin?',
17 | },
18 | };
19 |
20 | it('renders a Textarea component with expected attributes from mock data', () => {
21 | const component = shallow();
22 | expect(component).toMatchSnapshot();
23 | });
24 | });
25 |
--------------------------------------------------------------------------------
/src/navigation/components/groupDraftItem/__snapshots__/GroupDraftItem.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Profile Dropdown should match snapshot 1`] = `
4 |
8 |
9 | Name of the group
10 |
11 |
30 |
31 | `;
32 |
--------------------------------------------------------------------------------
/src/forms/redux-form/textInput.test.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow } from 'enzyme';
3 | import ReduxFormTextInput from './TextInput';
4 |
5 | describe('redux-form TextInput', function() {
6 | const MOCK_ERROR = 'Did you mean Batman and Robin?';
7 | const formAttrs = {
8 | input: {
9 | label: 'Super Hero',
10 | name: 'superhero',
11 | value: 'Wonder Woman and Robin',
12 | maxLength: 20,
13 | required: true,
14 | },
15 | meta: {
16 | error: MOCK_ERROR,
17 | },
18 | };
19 |
20 | it('renders a TextInput component with expected attributes from mock data', () => {
21 | const component = shallow();
22 | expect(component).toMatchSnapshot();
23 | });
24 | });
25 |
--------------------------------------------------------------------------------
/src/utils/components/__snapshots__/toggleWrapper.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`withLoading when this.props.type is checkbox matches snapshot 1`] = `
4 |
8 |
9 |
10 | `;
11 |
12 | exports[`withLoading when this.props.type is not checkbox or radio matches snapshot 1`] = `
13 |
17 |
18 |
19 | `;
20 |
21 | exports[`withLoading when this.props.type is radio matches snapshot 1`] = `
22 |
26 |
27 |
28 | `;
29 |
--------------------------------------------------------------------------------
/src/forms/__snapshots__/radioButtonGroup.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`RadioButtonGroup should match the snapshot 1`] = `
4 |
8 |
12 |
19 |
20 |
24 |
31 |
32 |
33 | `;
34 |
--------------------------------------------------------------------------------
/src/forms/redux-form/timeInput.test.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow } from 'enzyme';
3 | import ReduxFormTimeInput from './TimeInput';
4 |
5 | describe('redux-form TimeInput', function() {
6 | // props given in the structure that
7 | // redux form would
8 | const reduxFormProps = {
9 | input: {
10 | label: 'What time is it?',
11 | name: 'partytime',
12 | value: '22:00',
13 | required: true,
14 | },
15 | meta: {
16 | error: 'Now approaching midnight!!?',
17 | },
18 | };
19 |
20 | it('renders a TimeInput component with expected attributes from mock data', () => {
21 | const component = shallow();
22 |
23 | expect(component).toMatchSnapshot();
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/src/layout/bounds.test.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow } from 'enzyme';
3 |
4 | import { BoundsComponent } from './Bounds';
5 |
6 | const WIDE_CLASS = 'bounds--wide';
7 |
8 | describe('Bounds', function() {
9 | const bounds = shallow();
10 |
11 | it('exists', function() {
12 | expect(bounds).toMatchSnapshot();
13 | });
14 | it(`check that default component has '${WIDE_CLASS}' class`, function() {
15 | expect(bounds.find(`.${WIDE_CLASS}`).length).not.toBe(0);
16 | });
17 | it("check that narrow component does not have the 'bounds--wide' class", function() {
18 | const boundsNarrow = shallow();
19 | expect(boundsNarrow.find(`.${WIDE_CLASS}`).length).toBe(0);
20 | });
21 | });
22 |
--------------------------------------------------------------------------------
/src/forms/CharCounter.jsx:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React from 'react';
3 | import cx from 'classnames';
4 | import DeprecationWarning from '../utils/components/DeprecationWarning';
5 |
6 | export const CharCounter = ({ maxLength, valueLength }) => {
7 | const remainingChars = maxLength - valueLength;
8 |
9 | const classNames = cx('text--tiny', 'text--secondary', 'align--right', 'charCount', {
10 | 'text--error': remainingChars < 0,
11 | });
12 |
13 | return (
14 |
15 | {remainingChars}
16 |
17 | );
18 | };
19 |
20 | CharCounter.propTypes = {
21 | maxLength: PropTypes.number.isRequired,
22 | valueLength: PropTypes.number.isRequired,
23 | };
24 |
25 | export default DeprecationWarning(CharCounter);
26 |
--------------------------------------------------------------------------------
/jest.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "collectCoverageFrom": [
3 | "src/**/*.{js,jsx}",
4 | "!**/{node_modules,lib,coverage,assets,utils}/**",
5 | "!**/*.story.{js,jsx}"
6 | ],
7 | "coverageDirectory": "/coverage",
8 | "setupFiles": [
9 | "/util/setupTest.js"
10 | ],
11 | "moduleFileExtensions": [
12 | "js",
13 | "jsx"
14 | ],
15 | "moduleNameMapper": {
16 | "\\.(ico|inc|jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "/__mocks__/emptyString.js"
17 | },
18 | "testRegex": "src/.*\\.test\\.jsx?$",
19 | "transformIgnorePatterns": [
20 | "node_modules(?!\/meetup-web-components)"
21 | ],
22 | "snapshotSerializers": [
23 | "/node_modules/enzyme-to-json/serializer"
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/src/forms/redux-form/calendarComponent.test.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow } from 'enzyme';
3 | import ReduxFormCalendarComponent from './CalendarComponent';
4 |
5 | describe('redux-form Calendar Component', function() {
6 | const attrs = {
7 | input: {
8 | id: 'beyonce',
9 | name: 'halo',
10 | className: 'beyonce-halo',
11 | value: new Date(2012, 9, 12),
12 | },
13 | meta: {
14 | error: 'pick a different album',
15 | },
16 | onFocus: jest.fn(),
17 | onBlur: jest.fn(),
18 | onChange: jest.fn(),
19 | };
20 |
21 | it('renders a Calendar component with expected attributes from mock data', () => {
22 | const component = shallow();
23 | expect(component).toMatchSnapshot();
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/assets/scss/components/_accentHeader.scss:
--------------------------------------------------------------------------------
1 | .accentHeader,
2 | .accentHeaderWrapper {
3 | padding-bottom: calc(var(--responsive-space) * 2);
4 | }
5 |
6 | .accentHeader {
7 | font-size: $font-size-big2;
8 | position: relative;
9 |
10 | &::after {
11 | background-color: $C_blue;
12 | bottom: 0;
13 | content: "";
14 | height: 3px;
15 | position: absolute;
16 | width: calc(var(--responsive-space) * 2);
17 | }
18 |
19 | @include atMediaUp(medium) {
20 | font-size: $font-size-title;
21 | }
22 | }
23 |
24 | .accentHeader--left {
25 | &::after {
26 | left: 0;
27 | }
28 | }
29 |
30 | .accentHeader--right {
31 | &::after {
32 | right: 0;
33 | }
34 | }
35 |
36 | .accentHeader--center {
37 | &::after {
38 | left: 50%;
39 | transform: translateX(-50%);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/interactive/__snapshots__/toast.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Toast renders into the DOM 1`] = `
4 |
10 |
14 |
20 |
27 | Your toast is ready
28 |
29 |
30 |
31 |
32 | `;
33 |
--------------------------------------------------------------------------------
/__mocks__/textContentMocks.js:
--------------------------------------------------------------------------------
1 | export const textContent1 = 'Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source.';
2 | export const textContent2 = 'Classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source.';
3 |
--------------------------------------------------------------------------------
/src/forms/errorList.story.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ErrorList from './ErrorList';
3 | import Bounds from '../layout/Bounds';
4 | import { decorateWithInfo } from '../utils/decorators';
5 | import { storiesOf } from '@storybook/react';
6 |
7 | storiesOf('Forms/ErrorList', module)
8 | .addDecorator(decorateWithInfo)
9 | .addParameters({ info: { propTablesExclude: [Bounds] } })
10 | .add(
11 | 'Single Error',
12 | () => (
13 |
14 |
15 |
16 | ),
17 | {
18 | info: {
19 | text:
20 | 'ErrorList ensures the error container is always rendered with ARIA attributes. It is rendered using the `withErrorList` higher-order component',
21 | },
22 | }
23 | );
24 |
--------------------------------------------------------------------------------
/.storybook/config.js:
--------------------------------------------------------------------------------
1 | import { configure, setAddon } from '@storybook/react';
2 | import '../assets/scss/storybook.scss';
3 | import infoAddon from '@storybook/addon-info';
4 | import { setOptions } from '@storybook/addon-options';
5 |
6 | import '@meetup/swarm-styles/dist/global.css';
7 | import '@meetup/swarm-styles/dist/main.css';
8 |
9 | const componentStories = require.context('../src', true, /\.story\.jsx$/);
10 |
11 | function loadStories() {
12 | componentStories.keys().forEach(componentStories);
13 | }
14 |
15 | setAddon(infoAddon);
16 |
17 | // Storybook runtime configuration
18 | setOptions({
19 | name: 'Meetup Web Components',
20 | // url the button will take people to
21 | url: 'https://meetup.github.io/swarm-design-system',
22 | showStoriesPanel: true,
23 | showAddonPanel: true,
24 | });
25 |
26 | configure(loadStories, module);
27 |
--------------------------------------------------------------------------------
/src/forms/redux-form/selectInput.test.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow } from 'enzyme';
3 | import ReduxFormSelectInput from './SelectInput';
4 |
5 | describe('redux-form SelectInput', () => {
6 | const testOptions = [
7 | { label: 'One', value: '1' },
8 | { label: 'Two', value: '2' },
9 | { label: 'Three', value: '3' },
10 | ];
11 | const formAttrs = {
12 | required: true,
13 | meta: {
14 | touched: false,
15 | error: 'Did you mean Batman and Robin?',
16 | },
17 | input: {
18 | label: 'Countries',
19 | name: 'formSelectCountries',
20 | options: testOptions,
21 | },
22 | };
23 |
24 | it('renders a SelectInput component with expected attributes from mock data', () => {
25 | const component = shallow();
26 | expect(component).toMatchSnapshot();
27 | });
28 | });
29 |
--------------------------------------------------------------------------------
/assets/scss/components/_footer.scss:
--------------------------------------------------------------------------------
1 | .footerStripe--main,
2 | .footerStripe-legal {
3 | -webkit-font-smoothing: antialiased;
4 | -moz-osx-font-smoothing: grayscale;
5 | }
6 |
7 | .footerStripe-main {
8 | background-color: $C_darkGray;
9 | }
10 |
11 | .footerStripe-main--isLight {
12 | background-color: $C_collectionBG;
13 | }
14 |
15 | .footerList-legal li::after {
16 | content: "";
17 |
18 | @include atMediaUp(medium) {
19 | content: attr(data-separator);
20 | }
21 | }
22 |
23 | .footerStripe-legal {
24 | background-color: darken($C_darkGray, 03%);
25 | }
26 |
27 | .footerStripe-legal--isLight {
28 | background-color: darken($C_collectionBG, 03%);
29 | }
30 |
31 | .bounds--footer {
32 | max-width: 320px;
33 |
34 | @include atMediaUp(medium) {
35 | max-width: $bounds-wide;
36 | }
37 | }
38 |
39 | .footer-item {
40 | padding-bottom: $space-half;
41 | }
42 |
--------------------------------------------------------------------------------
/src/utils/storyComponents.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | /**
4 | * Inverted
5 | *
6 | * Creates an inverted stripe for use in a story
7 | */
8 | export const Inverted = props => (
9 |
19 | {props.children}
20 |
21 | );
22 |
23 | /**
24 | * StoryLink
25 | *
26 | * `Link` component for use in stories
27 | * where a router context is not necessary
28 | *
29 | * Also disables link from being followed on click
30 | */
31 | export const StoryLink = props => (
32 |
37 | {props.children}
38 |
39 | );
40 |
--------------------------------------------------------------------------------
/assets/scss/components/_radio.scss:
--------------------------------------------------------------------------------
1 | .radio-container {
2 | align-items: center;
3 | display: flex;
4 | input {
5 | display: none;
6 | }
7 | }
8 |
9 | .radio {
10 | align-items: center;
11 | border: 1px solid $C_secondary;
12 | border-radius: 50%;
13 | box-sizing: border-box;
14 | cursor: pointer;
15 | display: flex;
16 | height: 19px;
17 | justify-content: center;
18 | margin: 0 $space-half 0 0;
19 | width: 19px;
20 |
21 | @include browser-lessThanIE(10) {
22 | top: $space / 2;
23 | }
24 |
25 | &.checked {
26 | background-color: $C_viridian;
27 | }
28 | &.disabled {
29 | background-color: var(--color-gray-3);
30 | border-color: var(--color-gray-3);
31 | span {
32 | background-color: var(--color-gray-3);
33 | }
34 | }
35 | }
36 |
37 | .radio-indicator {
38 | background-color: white;
39 | display: block;
40 | height: 7px;
41 | width: 7px;
42 | }
43 |
--------------------------------------------------------------------------------
/src/forms/__snapshots__/inputTime.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`InputTime InputTime, with input[time] support renders a with expected props 1`] = `
4 |
5 |
14 |
15 | `;
16 |
17 | exports[`InputTime InputTime, with input[time] support renders error state as expected 1`] = `
18 |
19 |
30 |
31 | `;
32 |
--------------------------------------------------------------------------------
/src/utils/decorators.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { withInfo } from '@storybook/addon-info';
3 |
4 | export const decorateWithBasics = story => {
5 | /*
6 | * -- Inline SVG icon sprite --
7 | *
8 | * raw SVG sprite from `swarm-icons`
9 | */
10 | const iconSpriteStyle = { display: 'none' };
11 | const iconSprite = require('raw-loader!swarm-icons/dist/sprite/sprite.inc');
12 | const styles = {
13 | display: 'flex',
14 | alignItems: 'center',
15 | justifyContent: 'center',
16 | height: '100%',
17 | width: '100%',
18 | };
19 |
20 | return (
21 |
28 | );
29 | };
30 |
31 | export const decorateWithInfo = (story, context) =>
32 | withInfo(`${context.story} ${context.kind}`)(story)(context);
33 |
--------------------------------------------------------------------------------
/assets/svg/proDashboard.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/forms/radioButton.story.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { storiesOf } from '@storybook/react';
3 | import { decorateWithBasics, decorateWithInfo } from '../utils/decorators';
4 | import { withKnobs, text, boolean } from '@storybook/addon-knobs';
5 |
6 | import RadioButton from './RadioButton';
7 |
8 | storiesOf('Forms/RadioButton', module)
9 | .addDecorator(withKnobs)
10 | .addDecorator(decorateWithBasics)
11 | .addDecorator(decorateWithInfo)
12 | .add(
13 | 'Basic usage',
14 | () => (
15 |
23 | ),
24 | {
25 | info: {
26 | text: 'A single radio input with a label. Demonstrates the basic usage',
27 | },
28 | }
29 | );
30 |
--------------------------------------------------------------------------------
/src/media/__snapshots__/loading.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Loading exists 1`] = `
4 |
12 |
40 |
41 | `;
42 |
--------------------------------------------------------------------------------
/src/utils/components/__snapshots__/withLoading.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`withLoading matches snapshot with 0 children 1`] = ``;
4 |
5 | exports[`withLoading matches snapshot with 1 child 1`] = `
6 |
7 |
8 | World
9 |
10 |
11 | `;
12 |
13 | exports[`withLoading matches snapshot with 2 children 1`] = `
14 |
15 |
16 | Hello
17 |
18 |
19 | World
20 |
21 |
22 | `;
23 |
24 | exports[`withLoading matches snapshot with isLoading 1`] = `
25 |
29 |
36 |
37 | `;
38 |
--------------------------------------------------------------------------------
/assets/scss/components/_checkbox.scss:
--------------------------------------------------------------------------------
1 | .checkbox-container {
2 | align-items: center;
3 | display: flex;
4 |
5 | input {
6 | display: none;
7 | }
8 | }
9 |
10 | .checkbox {
11 | align-items: center;
12 | background-color: white;
13 | border: 1px solid $C_secondary;
14 | border-radius: 4px;
15 | box-sizing: border-box;
16 | cursor: pointer;
17 | display: flex;
18 | font-size: $font-size;
19 | height: 20px;
20 | justify-content: center;
21 | line-height: $line-height;
22 | margin: 0 8px 0 0 !important;
23 | width: 20px;
24 |
25 | @include browser-lessThanIE(10) {
26 | top: $space / 2;
27 | }
28 |
29 | &:disabled {
30 | background-color: var(--color-gray-3);
31 | border: 1px solid var(--color-gray-3);
32 | }
33 | }
34 |
35 | .checkbox:focus {
36 | outline: 1px solid black;
37 | }
38 |
39 | [data-swarm-checkbox]:focus-within > span:first-of-type {
40 | box-shadow: 0 0 1px 2px #426b8f !important;
41 | }
42 |
--------------------------------------------------------------------------------
/src/forms/redux-form/Textarea.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import Textarea from '../Textarea';
4 |
5 | /**
6 | * This component wraps the standard Textarea component for use with redux-form.
7 | * It deconstructs props that redux-form sets and re-sets them on Textarea.
8 | * @param {object} props React component props
9 | * @return {React.Component} Textarea
10 | */
11 | const ReduxFormTextarea = props => {
12 | const { meta, input, ...other } = props;
13 | const error = meta.touched || meta.submitFailed ? meta.error : null;
14 |
15 | return ;
16 | };
17 |
18 | ReduxFormTextarea.propTypes = {
19 | meta: PropTypes.object.isRequired,
20 | input: PropTypes.oneOfType([PropTypes.element, PropTypes.object]).isRequired,
21 | };
22 |
23 | ReduxFormTextarea.displayName = 'ReduxFormTextarea';
24 |
25 | export default ReduxFormTextarea;
26 |
--------------------------------------------------------------------------------
/src/forms/redux-form/TimeInput.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import TimeInput from '../TimeInput';
4 |
5 | /**
6 | * This component wraps the standard TimeInput for use with redux-form.
7 | * It deconstructs props that redux-form sets and re-sets them on TimeInput.
8 | * @param {object} props React component props
9 | * @return {React.Component} TimeInput
10 | */
11 | const ReduxFormTimeInput = props => {
12 | const { input, meta, ...other } = props;
13 | const error = meta.touched || meta.submitFailed ? meta.error : null;
14 |
15 | return ;
16 | };
17 |
18 | ReduxFormTimeInput.propTypes = {
19 | meta: PropTypes.object.isRequired,
20 | input: PropTypes.oneOfType([PropTypes.element, PropTypes.object]).isRequired,
21 | };
22 |
23 | ReduxFormTimeInput.displayName = 'ReduxFormTimeInput';
24 |
25 | export default ReduxFormTimeInput;
26 |
--------------------------------------------------------------------------------
/src/forms/redux-form/TextInput.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import TextInput from '../TextInput';
4 |
5 | /**
6 | * @param {Object} props - props passed in from parent and redux-form
7 | * @description wraps standard TextInput web component for use with redux-form
8 | * deconstructs props that redux-forms sets and sets them on TextInput
9 | * @return {Component} TextInput
10 | */
11 | const ReduxFormTextInput = props => {
12 | const { meta, input, ...other } = props;
13 | const error = meta.touched || meta.submitFailed ? meta.error : null;
14 |
15 | return ;
16 | };
17 |
18 | ReduxFormTextInput.propTypes = {
19 | meta: PropTypes.object.isRequired,
20 | input: PropTypes.oneOfType([PropTypes.element, PropTypes.object]).isRequired,
21 | };
22 |
23 | ReduxFormTextInput.displayName = 'ReduxFormTextInput';
24 |
25 | export default ReduxFormTextInput;
26 |
--------------------------------------------------------------------------------
/src/forms/redux-form/SelectInput.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import SelectInput from '../SelectInput';
4 |
5 | /**
6 | * This component wraps the standard SelectInput component for use with redux-form.
7 | * It deconstructs props that redux-form sets and re-sets them on SelectInput.
8 | * @param {object} props React component props
9 | * @return {React.Component} SelectInput
10 | */
11 | const ReduxFormSelectInput = props => {
12 | const { meta, input, ...other } = props;
13 | const error = meta.touched || meta.submitFailed ? meta.error : null;
14 |
15 | return ;
16 | };
17 |
18 | ReduxFormSelectInput.propTypes = {
19 | meta: PropTypes.object.isRequired,
20 | input: PropTypes.oneOfType([PropTypes.element, PropTypes.object]).isRequired,
21 | };
22 |
23 | ReduxFormSelectInput.displayName = 'ReduxFormSelectInput';
24 |
25 | export default ReduxFormSelectInput;
26 |
--------------------------------------------------------------------------------
/assets/scss/storybook.scss:
--------------------------------------------------------------------------------
1 | //storybook styles
2 | html,
3 | body,
4 | #root {
5 | height: 100%;
6 | }
7 |
8 | #root {
9 | display: flex;
10 | align-items: center;
11 | justify-content: center;
12 |
13 | > div {
14 | width: 100%;
15 | }
16 | }
17 |
18 | div[data-reactroot] {
19 | width: 100%;
20 |
21 | div {
22 | width: 100%;
23 | }
24 | }
25 |
26 | //
27 | // SASS BASE FILE
28 | //
29 | // include any additional scss from
30 | // `src/assets/scss/` as sass partials
31 | //
32 |
33 | // webfont
34 |
35 | @import url("//a248.e.akamai.net/secure.meetupstatic.com/s/fonts/402715706936963211631/graphik.css");
36 |
37 | // sasstools CSS reset
38 |
39 | @import "~swarm-sasstools/scss/reset/all";
40 |
41 | // all meetup-web-components component partials
42 |
43 | @import "./components/all";
44 |
45 | // sasstools modifier classes
46 |
47 | @import "~swarm-sasstools/scss/modifierClasses/all";
48 |
49 | // tailwind
50 |
51 | @import "../css/tailwind.min";
52 |
--------------------------------------------------------------------------------
/src/utils/designConstants.js:
--------------------------------------------------------------------------------
1 | import {
2 | BREAKPOINT_S,
3 | BREAKPOINT_M,
4 | BREAKPOINT_L,
5 | BREAKPOINT_XL,
6 | } from 'swarm-constants/dist/js/constants.js';
7 |
8 | export const MEDIA_QUERIES = {
9 | small: `screen and (min-width: ${BREAKPOINT_S})`,
10 | medium: `screen and (min-width: ${BREAKPOINT_M})`,
11 | large: `screen and (min-width: ${BREAKPOINT_L})`,
12 | huge: `screen and (min-width: ${BREAKPOINT_XL})`,
13 | };
14 |
15 | //
16 | // TODO: we should import these from swarm-constants,
17 | // but since these are responsive values, we don't
18 | // export them to the JS dist in swarm-constants.
19 | //
20 | // A fine solution would be to export the default
21 | // sizes (which are currently the same as below)
22 | // to JS and not worry about the sizes for viewports
23 | // larger than mobile.
24 | //
25 | export const MEDIA_SIZES = {
26 | xxs: '12',
27 | xs: '16',
28 | s: '24',
29 | m: '36',
30 | l: '48',
31 | xl: '72',
32 | xxl: '120',
33 | };
34 |
--------------------------------------------------------------------------------
/assets/svg/apple.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/assets/scss/components/_section.scss:
--------------------------------------------------------------------------------
1 | /*doc
2 | ---
3 | title: Section
4 | ---
5 | Used to group sets of related components
6 | into discrete sections by adding padding
7 | around it's children.
8 | */
9 |
10 | $sectionSpaceMultiple: 2;
11 |
12 | .section {
13 | margin: 0 var(--responsive-space);
14 | padding: calc(var(--responsive-space) * #{$sectionSpaceMultiple}) 0 0 0;
15 | }
16 |
17 | @include _bpModifier(section, hasSeparator) {
18 | border-bottom-width: 0;
19 | padding-bottom: 0;
20 | }
21 |
22 | .section--hasSeparator {
23 | border-bottom: 1px solid $C_border;
24 | padding: calc(var(--responsive-space) * #{$sectionSpaceMultiple}) 0
25 | calc(var(--responsive-space) * #{$sectionSpaceMultiple} - var(--responsive-space))
26 | 0;
27 |
28 | .inverted & {
29 | border-bottom: 1px solid $C_borderInverted;
30 | }
31 | }
32 |
33 | .section--flush {
34 | margin: 0;
35 | }
36 |
37 | @include _bpModifier(section, flush) {
38 | margin: 0 var(--responsive-space);
39 | }
40 |
--------------------------------------------------------------------------------
/src/forms/togglePill.test.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { mount } from 'enzyme';
3 | import TogglePill from './TogglePill';
4 |
5 | describe('TogglePill', () => {
6 | const id = 'hikingCategory',
7 | name = 'meetupCategories',
8 | label = 'Hiking!',
9 | value = 'hiking';
10 |
11 | let togglePillComponent;
12 | const onChangeMock = jest.fn();
13 |
14 | beforeEach(() => {
15 | togglePillComponent = mount(
16 |
17 | {label}
18 |
19 | );
20 | });
21 |
22 | afterEach(() => {
23 | togglePillComponent = null;
24 | });
25 |
26 | it('renders a component with expected attributes', () => {
27 | expect(togglePillComponent).toMatchSnapshot();
28 | });
29 |
30 | it('executes onChange when clicked', () => {
31 | expect(onChangeMock).not.toHaveBeenCalled();
32 | togglePillComponent.simulate('click');
33 | expect(onChangeMock).toHaveBeenCalled();
34 | });
35 | });
36 |
--------------------------------------------------------------------------------
/flow-typed/npm/raf-schd_vx.x.x.js:
--------------------------------------------------------------------------------
1 | // flow-typed signature: b77d5a7eb759add07179547ff6fa7a2a
2 | // flow-typed version: <>/raf-schd_v2.1.0/flow_v0.76.0
3 |
4 | /**
5 | * This is an autogenerated libdef stub for:
6 | *
7 | * 'raf-schd'
8 | *
9 | * Fill this stub out by replacing all the `any` types.
10 | *
11 | * Once filled out, we encourage you to share your work with the
12 | * community by sending a pull request to:
13 | * https://github.com/flowtype/flow-typed
14 | */
15 |
16 | declare module 'raf-schd' {
17 | declare module.exports: any;
18 | }
19 |
20 | /**
21 | * We include stubs for each file inside this npm package in case you need to
22 | * require those files directly. Feel free to delete any files that aren't
23 | * needed.
24 | */
25 | declare module 'raf-schd/lib/index' {
26 | declare module.exports: any;
27 | }
28 |
29 | // Filename aliases
30 | declare module 'raf-schd/lib/index.js' {
31 | declare module.exports: $Exports<'raf-schd/lib/index'>;
32 | }
33 |
--------------------------------------------------------------------------------
/src/forms/redux-form/NumberInput.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import NumberInput from '../NumberInput';
4 |
5 | /**
6 | * @param {Object} props - props passed in from parent and redux-form
7 | * @description wraps standard NumberInput web component for use with redux-form
8 | * deconstructs props that redux-forms sets and sets them on NumberInput
9 | * @return {Component} NumberInput
10 | */
11 | const ReduxFormNumberInput = props => {
12 | const { meta, input, ...other } = props;
13 |
14 | const error = meta.touched || meta.submitFailed ? meta.error : null;
15 |
16 | return ;
17 | };
18 |
19 | ReduxFormNumberInput.propTypes = {
20 | meta: PropTypes.object.isRequired,
21 | input: PropTypes.oneOfType([PropTypes.element, PropTypes.object]).isRequired,
22 | };
23 |
24 | ReduxFormNumberInput.displayName = 'ReduxFormNumberInput';
25 |
26 | export default ReduxFormNumberInput;
27 |
--------------------------------------------------------------------------------
/src/media/__snapshots__/appBadges.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`App Badges exists 1`] = `
4 |
8 |
11 |
16 |
21 |
22 |
23 |
26 |
31 |
36 |
37 |
38 |
39 | `;
40 |
--------------------------------------------------------------------------------
/flow-typed/npm/babel-jest_vx.x.x.js:
--------------------------------------------------------------------------------
1 | // flow-typed signature: c880c47173584f435c1412e4babd6ac1
2 | // flow-typed version: <>/babel-jest_v23.4.2/flow_v0.76.0
3 |
4 | /**
5 | * This is an autogenerated libdef stub for:
6 | *
7 | * 'babel-jest'
8 | *
9 | * Fill this stub out by replacing all the `any` types.
10 | *
11 | * Once filled out, we encourage you to share your work with the
12 | * community by sending a pull request to:
13 | * https://github.com/flowtype/flow-typed
14 | */
15 |
16 | declare module 'babel-jest' {
17 | declare module.exports: any;
18 | }
19 |
20 | /**
21 | * We include stubs for each file inside this npm package in case you need to
22 | * require those files directly. Feel free to delete any files that aren't
23 | * needed.
24 | */
25 | declare module 'babel-jest/build/index' {
26 | declare module.exports: any;
27 | }
28 |
29 | // Filename aliases
30 | declare module 'babel-jest/build/index.js' {
31 | declare module.exports: $Exports<'babel-jest/build/index'>;
32 | }
33 |
--------------------------------------------------------------------------------
/flow-typed/npm/raw-loader_vx.x.x.js:
--------------------------------------------------------------------------------
1 | // flow-typed signature: 7f4451cbef40910ee211379135fa8c22
2 | // flow-typed version: <>/raw-loader_v0.5.1/flow_v0.76.0
3 |
4 | /**
5 | * This is an autogenerated libdef stub for:
6 | *
7 | * 'raw-loader'
8 | *
9 | * Fill this stub out by replacing all the `any` types.
10 | *
11 | * Once filled out, we encourage you to share your work with the
12 | * community by sending a pull request to:
13 | * https://github.com/flowtype/flow-typed
14 | */
15 |
16 | declare module 'raw-loader' {
17 | declare module.exports: any;
18 | }
19 |
20 | /**
21 | * We include stubs for each file inside this npm package in case you need to
22 | * require those files directly. Feel free to delete any files that aren't
23 | * needed.
24 | */
25 |
26 |
27 | // Filename aliases
28 | declare module 'raw-loader/index' {
29 | declare module.exports: $Exports<'raw-loader'>;
30 | }
31 | declare module 'raw-loader/index.js' {
32 | declare module.exports: $Exports<'raw-loader'>;
33 | }
34 |
--------------------------------------------------------------------------------
/src/navigation/components/notifications/NotificationsDropdown.test.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow } from 'enzyme';
3 |
4 | import {
5 | MOCK_NOTIFICATION_COMMENT,
6 | MOCK_NOTIFICATIONS_LIST,
7 | } from 'meetup-web-mocks/lib/notifications/api';
8 |
9 | import { NotificationsDropdownComponent } from './NotificationsDropdown';
10 |
11 | const notifs = [
12 | ...MOCK_NOTIFICATIONS_LIST,
13 | {
14 | ...MOCK_NOTIFICATION_COMMENT,
15 | photo: null,
16 | },
17 | ];
18 |
19 | describe('Notifications Dropdown', () => {
20 | const wrapper = (props = {}) =>
21 | shallow(
22 |
27 | );
28 |
29 | it('should match the snapshot with notifications ', () => {
30 | expect(wrapper()).toMatchSnapshot();
31 | });
32 | it('should match the snapshot with an empty notifications', () => {
33 | expect(wrapper({ notifications: [] })).toMatchSnapshot();
34 | });
35 | });
36 |
--------------------------------------------------------------------------------
/src/accentHeader.test.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow } from 'enzyme';
3 |
4 | import AccentHeader, { ALIGN_VALUES } from './AccentHeader';
5 |
6 | describe('AccentHeader', () => {
7 | const accentHeaderComponent = shallow(Test);
8 |
9 | it('exists', () => {
10 | expect(accentHeaderComponent).toMatchSnapshot();
11 | });
12 |
13 | it('applies correct alignment className to dropdown content', () => {
14 | ALIGN_VALUES.forEach(alignment => {
15 | const accentHeaderComponent = shallow(
16 | Test
17 | );
18 | expect(accentHeaderComponent.find('h2').prop('className')).toContain(
19 | `accentHeader--${alignment}`
20 | );
21 | });
22 | });
23 |
24 | it('renders with whatever HTML tag is passed in', () => {
25 | const accentHeaderComponent = shallow(
26 | Test
27 | );
28 | expect(accentHeaderComponent.find('h1').length).toBe(1);
29 | });
30 | });
31 |
--------------------------------------------------------------------------------
/src/forms/ErrorList.jsx:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React from 'react';
3 | import cx from 'classnames';
4 |
5 | const ERROR_CLASSNAME = 'text--error text--small';
6 |
7 | /**
8 | * ErrorList
9 | *
10 | * Accessible list of errors for a form input.
11 | *
12 | * Currently supports only a single error due to a
13 | * limitation with `redux-form`.
14 | */
15 | const ErrorList = props => {
16 | const { errorId, error, ...other } = props;
17 |
18 | if (errorId) {
19 | other.id = errorId;
20 | }
21 |
22 | return (
23 |
24 | {error && - {error}
}
25 |
26 | );
27 | };
28 | ErrorList.propTypes = {
29 | /** Unique identifier for the errors - used to associate form field with error */
30 | errorId: PropTypes.string,
31 |
32 | /** Error content to render */
33 | error: PropTypes.oneOfType([PropTypes.string, PropTypes.element, PropTypes.bool]),
34 | };
35 |
36 | export default ErrorList;
37 |
--------------------------------------------------------------------------------
/src/AccentHeader.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import cx from 'classnames';
4 |
5 | export const ALIGN_VALUES = ['left', 'right', 'center'];
6 |
7 | const AccentHeader = ({ align, headingTag, children, className, ...other }) => {
8 | const HeadingTagEl = headingTag;
9 | return (
10 |
11 |
20 | {children}
21 |
22 |
23 | );
24 | };
25 |
26 | AccentHeader.defaultProps = {
27 | align: 'left',
28 | headingTag: 'h2',
29 | };
30 |
31 | AccentHeader.propTypes = {
32 | /** Controls text alignment */
33 | align: PropTypes.oneOf(ALIGN_VALUES),
34 |
35 | /** Which level of HTML heading tag to use */
36 | headingTag: PropTypes.oneOf(['h1', 'h2', 'h3', 'h4', 'h5', 'h6']),
37 | };
38 |
39 | export default AccentHeader;
40 |
--------------------------------------------------------------------------------
/src/utils/components/__snapshots__/withErrorList.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`withErrorList wrapped component matches snapshot for component with id and error props 1`] = `
4 |
5 |
11 |
15 |
16 | `;
17 |
18 | exports[`withErrorList wrapped component matches snapshot for component without error prop 1`] = `
19 |
20 |
25 |
28 |
29 | `;
30 |
31 | exports[`withErrorList wrapped component matches snapshot for component without id or error props 1`] = `
32 |
33 |
36 |
37 |
38 | `;
39 |
--------------------------------------------------------------------------------
/flow-typed/npm/eslint-loader_vx.x.x.js:
--------------------------------------------------------------------------------
1 | // flow-typed signature: d92166a7bbf7934aa572327b22cbd1f8
2 | // flow-typed version: <>/eslint-loader_v2.1.2/flow_v0.76.0
3 |
4 | /**
5 | * This is an autogenerated libdef stub for:
6 | *
7 | * 'eslint-loader'
8 | *
9 | * Fill this stub out by replacing all the `any` types.
10 | *
11 | * Once filled out, we encourage you to share your work with the
12 | * community by sending a pull request to:
13 | * https://github.com/flowtype/flow-typed
14 | */
15 |
16 | declare module 'eslint-loader' {
17 | declare module.exports: any;
18 | }
19 |
20 | /**
21 | * We include stubs for each file inside this npm package in case you need to
22 | * require those files directly. Feel free to delete any files that aren't
23 | * needed.
24 | */
25 |
26 |
27 | // Filename aliases
28 | declare module 'eslint-loader/index' {
29 | declare module.exports: $Exports<'eslint-loader'>;
30 | }
31 | declare module 'eslint-loader/index.js' {
32 | declare module.exports: $Exports<'eslint-loader'>;
33 | }
34 |
--------------------------------------------------------------------------------
/flow-typed/npm/babel-preset-flow_vx.x.x.js:
--------------------------------------------------------------------------------
1 | // flow-typed signature: b456a4b4ed851bbfaf006fab26aea1b7
2 | // flow-typed version: <>/babel-preset-flow_v6.23.0/flow_v0.76.0
3 |
4 | /**
5 | * This is an autogenerated libdef stub for:
6 | *
7 | * 'babel-preset-flow'
8 | *
9 | * Fill this stub out by replacing all the `any` types.
10 | *
11 | * Once filled out, we encourage you to share your work with the
12 | * community by sending a pull request to:
13 | * https://github.com/flowtype/flow-typed
14 | */
15 |
16 | declare module 'babel-preset-flow' {
17 | declare module.exports: any;
18 | }
19 |
20 | /**
21 | * We include stubs for each file inside this npm package in case you need to
22 | * require those files directly. Feel free to delete any files that aren't
23 | * needed.
24 | */
25 | declare module 'babel-preset-flow/lib/index' {
26 | declare module.exports: any;
27 | }
28 |
29 | // Filename aliases
30 | declare module 'babel-preset-flow/lib/index.js' {
31 | declare module.exports: $Exports<'babel-preset-flow/lib/index'>;
32 | }
33 |
--------------------------------------------------------------------------------
/flow-typed/npm/babel-preset-react_vx.x.x.js:
--------------------------------------------------------------------------------
1 | // flow-typed signature: b4023626de00b4ea48ed31d8c1f3cfa9
2 | // flow-typed version: <>/babel-preset-react_v6.24.1/flow_v0.76.0
3 |
4 | /**
5 | * This is an autogenerated libdef stub for:
6 | *
7 | * 'babel-preset-react'
8 | *
9 | * Fill this stub out by replacing all the `any` types.
10 | *
11 | * Once filled out, we encourage you to share your work with the
12 | * community by sending a pull request to:
13 | * https://github.com/flowtype/flow-typed
14 | */
15 |
16 | declare module 'babel-preset-react' {
17 | declare module.exports: any;
18 | }
19 |
20 | /**
21 | * We include stubs for each file inside this npm package in case you need to
22 | * require those files directly. Feel free to delete any files that aren't
23 | * needed.
24 | */
25 | declare module 'babel-preset-react/lib/index' {
26 | declare module.exports: any;
27 | }
28 |
29 | // Filename aliases
30 | declare module 'babel-preset-react/lib/index.js' {
31 | declare module.exports: $Exports<'babel-preset-react/lib/index'>;
32 | }
33 |
--------------------------------------------------------------------------------
/flow-typed/npm/babel-preset-es2015_vx.x.x.js:
--------------------------------------------------------------------------------
1 | // flow-typed signature: f6122ac89f5b5091478b3566552a74b1
2 | // flow-typed version: <>/babel-preset-es2015_v6.24.1/flow_v0.76.0
3 |
4 | /**
5 | * This is an autogenerated libdef stub for:
6 | *
7 | * 'babel-preset-es2015'
8 | *
9 | * Fill this stub out by replacing all the `any` types.
10 | *
11 | * Once filled out, we encourage you to share your work with the
12 | * community by sending a pull request to:
13 | * https://github.com/flowtype/flow-typed
14 | */
15 |
16 | declare module 'babel-preset-es2015' {
17 | declare module.exports: any;
18 | }
19 |
20 | /**
21 | * We include stubs for each file inside this npm package in case you need to
22 | * require those files directly. Feel free to delete any files that aren't
23 | * needed.
24 | */
25 | declare module 'babel-preset-es2015/lib/index' {
26 | declare module.exports: any;
27 | }
28 |
29 | // Filename aliases
30 | declare module 'babel-preset-es2015/lib/index.js' {
31 | declare module.exports: $Exports<'babel-preset-es2015/lib/index'>;
32 | }
33 |
--------------------------------------------------------------------------------
/flow-typed/npm/@meetup/swarm-styles_vx.x.x.js:
--------------------------------------------------------------------------------
1 | // flow-typed signature: 3df0ff97861e61cdde3d3addc4a909b6
2 | // flow-typed version: <>/@meetup/swarm-styles_v0.2.1/flow_v0.76.0
3 |
4 | /**
5 | * This is an autogenerated libdef stub for:
6 | *
7 | * '@meetup/swarm-styles'
8 | *
9 | * Fill this stub out by replacing all the `any` types.
10 | *
11 | * Once filled out, we encourage you to share your work with the
12 | * community by sending a pull request to:
13 | * https://github.com/flowtype/flow-typed
14 | */
15 |
16 | declare module '@meetup/swarm-styles' {
17 | declare module.exports: any;
18 | }
19 |
20 | /**
21 | * We include stubs for each file inside this npm package in case you need to
22 | * require those files directly. Feel free to delete any files that aren't
23 | * needed.
24 | */
25 | declare module '@meetup/swarm-styles/lib/styles' {
26 | declare module.exports: any;
27 | }
28 |
29 | // Filename aliases
30 | declare module '@meetup/swarm-styles/lib/styles.js' {
31 | declare module.exports: $Exports<'@meetup/swarm-styles/lib/styles'>;
32 | }
33 |
--------------------------------------------------------------------------------
/flow-typed/npm/babel-preset-stage-2_vx.x.x.js:
--------------------------------------------------------------------------------
1 | // flow-typed signature: 087c26838ec8039b19299fdf8ac676fc
2 | // flow-typed version: <>/babel-preset-stage-2_v6.24.1/flow_v0.76.0
3 |
4 | /**
5 | * This is an autogenerated libdef stub for:
6 | *
7 | * 'babel-preset-stage-2'
8 | *
9 | * Fill this stub out by replacing all the `any` types.
10 | *
11 | * Once filled out, we encourage you to share your work with the
12 | * community by sending a pull request to:
13 | * https://github.com/flowtype/flow-typed
14 | */
15 |
16 | declare module 'babel-preset-stage-2' {
17 | declare module.exports: any;
18 | }
19 |
20 | /**
21 | * We include stubs for each file inside this npm package in case you need to
22 | * require those files directly. Feel free to delete any files that aren't
23 | * needed.
24 | */
25 | declare module 'babel-preset-stage-2/lib/index' {
26 | declare module.exports: any;
27 | }
28 |
29 | // Filename aliases
30 | declare module 'babel-preset-stage-2/lib/index.js' {
31 | declare module.exports: $Exports<'babel-preset-stage-2/lib/index'>;
32 | }
33 |
--------------------------------------------------------------------------------
/src/forms/LockedBadge.test.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow } from 'enzyme';
3 | import LockedBadge from './LockedBadge';
4 |
5 | describe('LockedBadge', function() {
6 | const onClickCallbackMock = jest.fn();
7 |
8 | const MOCK_PROPS = {
9 | label: 'Default label',
10 | onClick: onClickCallbackMock,
11 | };
12 |
13 | const render = (props = MOCK_PROPS) => {
14 | const wrapper = shallow();
15 |
16 | return wrapper;
17 | };
18 |
19 | afterEach(() => {
20 | onClickCallbackMock.mockClear();
21 | });
22 |
23 | it('renders locked badge with default styles', () => {
24 | expect(render()).toMatchSnapshot();
25 | });
26 | it('renders locked badge with neutral styles', () => {
27 | expect(render({ ...MOCK_PROPS, variant: 'neutral' })).toMatchSnapshot();
28 | });
29 | it('calls onClickCallback when user clicks on badge', () => {
30 | const badge = render();
31 | expect(onClickCallbackMock).not.toHaveBeenCalled();
32 | badge.simulate('click');
33 | expect(onClickCallbackMock).toHaveBeenCalledTimes(1);
34 | });
35 | });
36 |
--------------------------------------------------------------------------------
/src/forms/redux-form/TogglePill.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import TogglePill from '../TogglePill';
3 |
4 | /**
5 | * @param {Object} props - props passed in from parent and redux-form
6 | * @description wraps standard TogglePill web component for use with redux-form
7 | * deconstructs props that redux-forms sets and sets them on TogglePill
8 | *
9 | * NOTE: redux-form expects checkboxes value to be true/false and will set them as so
10 | * https://github.com/erikras/redux-form/issues/2922, therefore using the value here to
11 | * set isActive
12 | *
13 | * @return {Component} TogglePill
14 | */
15 | const ReduxFormTogglePill = props => {
16 | // not adding meta error to TogglePill prop for now
17 | // since TogglePills should function in a group with one error
18 | const {
19 | meta, // eslint-disable-line no-unused-vars
20 | input,
21 | ...other
22 | } = props;
23 |
24 | return ;
25 | };
26 |
27 | ReduxFormTogglePill.displayName = 'ReduxFormTogglePill';
28 |
29 | export default ReduxFormTogglePill;
30 |
--------------------------------------------------------------------------------
/src/navigation/components/groupDraftItem/GroupDraftItem.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import cx from 'classnames';
3 | import PropTypes from 'prop-types';
4 | import Icon from '../../../media/Icon';
5 |
6 | export const PROFILE_GROUP_DRAFT_LIST_ITEM_CLASS = 'profileDropdown-draft-group';
7 |
8 | export const GroupDraftItem = ({ groupDraft }) => {
9 | return (
10 |
14 | {groupDraft.name}
15 |
22 |
23 | );
24 | };
25 |
26 | export default GroupDraftItem;
27 |
28 | GroupDraftItem.propTypes = {
29 | groupDraft: PropTypes.shape({
30 | editLink: PropTypes.string,
31 | name: PropTypes.string,
32 | status: PropTypes.string,
33 | actionTitle: PropTypes.string,
34 | }),
35 | };
36 |
--------------------------------------------------------------------------------
/src/signupModal.story.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { storiesOf } from '@storybook/react';
3 |
4 | import { decorateWithBasics, decorateWithInfo } from './utils/decorators';
5 | import { SignupModal } from './SignupModal';
6 |
7 | export const signupOptions = {
8 | orLabel: 'Or',
9 | title: 'Sign up',
10 | apple: {
11 | link: 'apple.com',
12 | label: 'Continue with Apple',
13 | shouldRender: true,
14 | },
15 | google: {
16 | link: 'google.com',
17 | label: 'Continue with Google',
18 | },
19 | facebook: {
20 | link: 'facebook.com',
21 | label: 'Continue with Facebook',
22 | },
23 | email: {
24 | link: 'meetup.com/email',
25 | label: 'Sign up with email',
26 | },
27 | login: {
28 | text: 'Already a member?',
29 | label: 'Login',
30 | link: 'meetup.com/login',
31 | },
32 | };
33 |
34 | storiesOf('Uncategorized/SignupModal', module)
35 | .addDecorator(decorateWithBasics)
36 | .addDecorator(decorateWithInfo)
37 | .add('default', () => (
38 | {}}
41 | focusTrapActive={false}
42 | />
43 | ));
44 |
--------------------------------------------------------------------------------
/assets/scss/components/_loading.scss:
--------------------------------------------------------------------------------
1 | .loading {
2 | align-items: center;
3 | display: flex;
4 | justify-content: center;
5 | }
6 |
7 | .loading--cover {
8 | bottom: 0;
9 | left: 0;
10 | right: 0;
11 | top: 0;
12 | z-index: var(--zindex-popup);
13 | }
14 |
15 | .loading--partialCover {
16 | position: absolute;
17 | }
18 |
19 | .loading--fullCover {
20 | position: fixed;
21 | }
22 |
23 | .loadingShape {
24 | animation: rotate 1750ms linear infinite;
25 | height: auto;
26 | }
27 |
28 |
29 | .loadingShape-path {
30 | animation: dash 1250ms ease-in-out infinite;
31 | stroke-dasharray: 1,200;
32 | stroke-dashoffset: 0;
33 | stroke-linecap: round;
34 | }
35 |
36 | .component--isLoading {
37 | position: relative;
38 | }
39 |
40 | @keyframes rotate {
41 | 100% {
42 | transform: rotate(360deg);
43 | }
44 | }
45 |
46 | @keyframes dash {
47 | 0% {
48 | stroke-dasharray: 1,200;
49 | stroke-dashoffset: 0;
50 | }
51 |
52 | 50% {
53 | stroke-dasharray: 89,200;
54 | stroke-dashoffset: -35;
55 | }
56 |
57 | 100% {
58 | stroke-dasharray: 89,200;
59 | stroke-dashoffset: -124;
60 | }
61 | }
62 |
63 |
--------------------------------------------------------------------------------
/assets/scss/components/_typeahead.scss:
--------------------------------------------------------------------------------
1 | .typeahead {
2 | position: relative;
3 | }
4 |
5 | .typeahead-input {
6 | margin-bottom: 0;
7 | }
8 |
9 | .typeahead-dropdown {
10 | background-color: $C_contentBG;
11 | border: 1px solid $C_textPrimary; // match `input` focus border color
12 | border-radius: 0 0 $largeRadius $largeRadius;
13 | left: 0;
14 | // $defaultRadius/2 : equal to the whitespace left around a $defaultRadius rounded corner
15 | // $space-quarter : equal to the bottom margin on an input
16 | // .5px : nudge up a little to hide a remaining subpixel of whitespace
17 | margin-top: -#{$defaultRadius / 2 + $space-quarter + 0.5px};
18 | position: absolute;
19 | right: 0;
20 | z-index: map-get($zindex-map, "floating-content");
21 | }
22 |
23 | .typeahead-dropdown--inline {
24 | position: relative;
25 | }
26 |
27 | .typeahead-item {
28 | cursor: pointer;
29 | padding: $space-half $space;
30 |
31 | [type="checkbox"],
32 | [type="radio"],
33 | label {
34 | pointer-events: none;
35 | }
36 | }
37 |
38 | .typeahead-item--isActive {
39 | background-color: $C_coolGrayLightTransp;
40 | }
41 |
--------------------------------------------------------------------------------
/src/navigation/components/groupDraftItem/GroupDraftItem.test.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow } from 'enzyme';
3 |
4 | import GroupDraftItem from './GroupDraftItem';
5 |
6 | const MOCK_PROPS = {
7 | groupHome: jest.fn(),
8 | groupDraft: {
9 | editLink: 'create',
10 | name: 'Name of the group',
11 | status: 'In progress',
12 | actionTitle: 'Finish group',
13 | },
14 | };
15 |
16 | describe('Profile Dropdown', () => {
17 | const wrapper = shallow();
18 | it('should match snapshot', () => {
19 | expect(wrapper).toMatchSnapshot();
20 | });
21 |
22 | it('should show the draft group at the top ProfileDropdown for authenticated screens', () => {
23 | const wrapperWithDrafts = shallow();
24 |
25 | expect(wrapperWithDrafts.find('.profileDropdown-draft-group').length).toBe(1);
26 | });
27 |
28 | it('should has the class for the tracking integration', () => {
29 | const wrapperWithDrafts = shallow();
30 |
31 | expect(wrapperWithDrafts.find('.draftprofiledropdown').length).toBe(1);
32 | });
33 | });
34 |
--------------------------------------------------------------------------------
/src/AccentHeader.story.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { decorateWithInfo } from './utils/decorators';
3 | import { storiesOf } from '@storybook/react';
4 |
5 | import AccentHeader from './AccentHeader';
6 |
7 | storiesOf('Uncategorized/AccentHeader', module)
8 | .addDecorator(decorateWithInfo)
9 | .add('default', () => (
10 |
11 |
I have something to say
12 |
This text is evenly spaced from the border
13 |
14 | ))
15 | .add('right-aligned', () => (
16 |
17 |
I have something to say
18 |
This text is evenly spaced from the border
19 |
20 | ))
21 | .add('center-aligned', () => (
22 |
23 |
I have something to say
24 |
This text is evenly spaced from the border
25 |
26 | ))
27 | .add('custom heading tag', () => (
28 |
29 |
I'm wrapped in h1
30 |
This text is evenly spaced from the border
31 |
32 | ));
33 |
--------------------------------------------------------------------------------
/src/__snapshots__/hscroll.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Default Hscroll exists 1`] = `
4 |
8 |
11 |
14 |
17 | item
18 |
19 |
22 | item
23 |
24 |
27 | item
28 |
29 |
32 | item
33 |
34 |
37 | item
38 |
39 |
42 | item
43 |
44 |
47 | item
48 |
49 |
52 | item
53 |
54 |
57 | item
58 |
59 |
60 |
61 |
62 | `;
63 |
--------------------------------------------------------------------------------
/src/forms/__snapshots__/togglePill.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`TogglePill renders a component with expected attributes 1`] = `
4 |
10 |
17 |
24 |
39 |
40 |
41 |
42 | `;
43 |
--------------------------------------------------------------------------------
/flow-typed/npm/react-portal_v4.1.x.js:
--------------------------------------------------------------------------------
1 | // flow-typed signature: 288bf61535247baaec569a9566b1aa60
2 | // flow-typed version: 5e634ef02e/react-portal_v4.1.x/flow_>=v0.53.x
3 |
4 | declare module 'react-portal' {
5 | declare type PortalProps = {
6 | children: React$Node,
7 | node?: Element | null,
8 | };
9 |
10 | declare class Portal extends React$Component {}
11 |
12 | declare type RenderFunctionParams = {
13 | openPortal: (event?: SyntheticEvent<>) => void,
14 | closePortal: () => void,
15 | portal: (children: React$Node) => React$Element,
16 | isOpen: boolean,
17 | };
18 |
19 | declare type PortalWithStateProps = {
20 | children: (params: RenderFunctionParams) => React$Node,
21 | node?: Element | null,
22 | defaultOpen?: boolean,
23 | closeOnEsc?: boolean,
24 | closeOnOutsideClick?: boolean,
25 | onOpen?: () => void,
26 | onClose?: () => void,
27 | };
28 |
29 | declare class PortalWithState extends React$Component {}
30 |
31 | declare module.exports: {
32 | Portal: typeof Portal,
33 | PortalWithState: typeof PortalWithState,
34 | };
35 | }
36 |
--------------------------------------------------------------------------------
/src/forms/radioButton.test.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow } from 'enzyme';
3 |
4 | import RadioButton from './RadioButton';
5 |
6 | describe('RadioButton', () => {
7 | const DEFAULT_PROPS = {
8 | label: 'This is a label',
9 | className: 'some-class',
10 | otherProp: 'other',
11 | value: 'value',
12 | name: 'name',
13 | };
14 |
15 | const getWrapper = (props = {}) =>
16 | shallow();
17 |
18 | describe('checked', () => {
19 | it('should render an enabled radio button', () => {
20 | expect(getWrapper({ disabled: true, checked: true })).toMatchSnapshot();
21 | });
22 |
23 | it('should render an disabled radio button', () => {
24 | expect(getWrapper({ disabled: false, checked: true })).toMatchSnapshot();
25 | });
26 | });
27 |
28 | describe('unchecked', () => {
29 | it('should render an enabled radio button', () => {
30 | expect(getWrapper({ disabled: true, checked: false })).toMatchSnapshot();
31 | });
32 |
33 | it('should render an disabled radio button', () => {
34 | expect(getWrapper({ disabled: false, checked: false })).toMatchSnapshot();
35 | });
36 | });
37 | });
38 |
--------------------------------------------------------------------------------
/src/media/avatar.story.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { storiesOf, action } from '@storybook/react';
3 | import { decorateWithBasics, decorateWithInfo } from '../utils/decorators';
4 | import Avatar from './Avatar.jsx';
5 |
6 | const MOCK_IMAGE_SRC = 'http://placekitten.com/g/400/400';
7 |
8 | storiesOf('Media/Avatar', module)
9 | .addDecorator(decorateWithBasics)
10 | .addDecorator(decorateWithInfo)
11 | .add('default', () => , {
12 | info: { text: 'This is the basic usage with the component.' },
13 | })
14 | .add('small', () => )
15 | .add('large', () => )
16 | .add('xxlarge', () => )
17 | .add(
18 | 'link to external URL',
19 | () => (
20 | {
23 | e.preventDefault();
24 | return action('go to http://google.com')(e);
25 | }}
26 | src={MOCK_IMAGE_SRC}
27 | alt="kitten"
28 | />
29 | ),
30 | { info: { text: 'To link within the app, supply a `to` prop instead of `href`' } }
31 | )
32 | .add('no photo', () => );
33 |
--------------------------------------------------------------------------------
/flow-typed/npm/@storybook/addon-knobs_v3.x.x.js:
--------------------------------------------------------------------------------
1 | // flow-typed signature: 1d070c8c148bbd6cffdd01bd531ba221
2 | // flow-typed version: be6afbe662/@storybook/addon-knobs_v3.x.x/flow_vx.x.x
3 |
4 | declare module "@storybook/addon-knobs/react" {
5 | declare type Renderable = React$Element;
6 | declare type GroupId = string;
7 |
8 | declare function array(string, (Array | {}), ?string, ?GroupId): Array;
9 | declare function boolean(string, boolean, ?GroupId): boolean;
10 | declare function button(string, ((?{}) => void), ?GroupId): void;
11 | declare function color(string, string, ?GroupId): string;
12 | declare function date(string, Date, ?GroupId): Date;
13 | declare function number(string, number, ?{ range?: boolean, min?: number, max?: number, step?: number }, ?GroupId): number;
14 | declare function object(string, any, ?GroupId): any;
15 | declare function select(string, Array | { [T]: string }, T, ?GroupId): T;
16 | declare function selectV2(string, Array | { [string]: T }, T, ?GroupId): T;
17 | declare function text(string, string, ?GroupId): string;
18 | declare function withKnobs(() => Renderable, { kind: string, story: string }): Renderable;
19 | }
20 |
--------------------------------------------------------------------------------
/flow-typed/npm/babel-plugin-transform-class-properties_vx.x.x.js:
--------------------------------------------------------------------------------
1 | // flow-typed signature: 1196524df10fd93c6d26eed35417a975
2 | // flow-typed version: <>/babel-plugin-transform-class-properties_v6.24.1/flow_v0.76.0
3 |
4 | /**
5 | * This is an autogenerated libdef stub for:
6 | *
7 | * 'babel-plugin-transform-class-properties'
8 | *
9 | * Fill this stub out by replacing all the `any` types.
10 | *
11 | * Once filled out, we encourage you to share your work with the
12 | * community by sending a pull request to:
13 | * https://github.com/flowtype/flow-typed
14 | */
15 |
16 | declare module 'babel-plugin-transform-class-properties' {
17 | declare module.exports: any;
18 | }
19 |
20 | /**
21 | * We include stubs for each file inside this npm package in case you need to
22 | * require those files directly. Feel free to delete any files that aren't
23 | * needed.
24 | */
25 | declare module 'babel-plugin-transform-class-properties/lib/index' {
26 | declare module.exports: any;
27 | }
28 |
29 | // Filename aliases
30 | declare module 'babel-plugin-transform-class-properties/lib/index.js' {
31 | declare module.exports: $Exports<'babel-plugin-transform-class-properties/lib/index'>;
32 | }
33 |
--------------------------------------------------------------------------------
/flow-typed/npm/babel-plugin-transform-flow-strip-types_vx.x.x.js:
--------------------------------------------------------------------------------
1 | // flow-typed signature: 3befa6518a03bf5215a77d4b0dd33c2d
2 | // flow-typed version: <>/babel-plugin-transform-flow-strip-types_v6.22.0/flow_v0.76.0
3 |
4 | /**
5 | * This is an autogenerated libdef stub for:
6 | *
7 | * 'babel-plugin-transform-flow-strip-types'
8 | *
9 | * Fill this stub out by replacing all the `any` types.
10 | *
11 | * Once filled out, we encourage you to share your work with the
12 | * community by sending a pull request to:
13 | * https://github.com/flowtype/flow-typed
14 | */
15 |
16 | declare module 'babel-plugin-transform-flow-strip-types' {
17 | declare module.exports: any;
18 | }
19 |
20 | /**
21 | * We include stubs for each file inside this npm package in case you need to
22 | * require those files directly. Feel free to delete any files that aren't
23 | * needed.
24 | */
25 | declare module 'babel-plugin-transform-flow-strip-types/lib/index' {
26 | declare module.exports: any;
27 | }
28 |
29 | // Filename aliases
30 | declare module 'babel-plugin-transform-flow-strip-types/lib/index.js' {
31 | declare module.exports: $Exports<'babel-plugin-transform-flow-strip-types/lib/index'>;
32 | }
33 |
--------------------------------------------------------------------------------
/src/layout/SectionTitle.jsx:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import React from 'react';
4 | import cx from 'classnames';
5 | import Chunk from './Chunk';
6 | import Flex from './Flex';
7 | import FlexItem from './FlexItem';
8 |
9 | export const SECTIONTITLE_CLASS = 'sectionTitle';
10 |
11 | type Props = {
12 | /** Text to display */
13 | title: React$Element<*> | string,
14 |
15 | /** A button-like element to associate an action with the Section */
16 | action: React$Element<*>,
17 |
18 | /** Nearest DOM element's class name */
19 | className?: string,
20 | };
21 | /**
22 | * @module SectionTitle
23 | */
24 | class SectionTitle extends React.Component {
25 | render() {
26 | const { action, className, title, ...other } = this.props;
27 |
28 | const classNames = cx(SECTIONTITLE_CLASS, className);
29 |
30 | return (
31 |
32 |
33 |
34 | {title}
35 |
36 |
37 | {action && (
38 |
39 | {action}
40 |
41 | )}
42 |
43 | );
44 | }
45 | }
46 |
47 | export default SectionTitle;
48 |
--------------------------------------------------------------------------------
/src/utils/testUtils.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow } from 'enzyme';
3 | // import TestUtils from 'react-dom/test-utils';
4 |
5 | export const variantTest = (FoundationComponent, className, variants) => {
6 | variants.forEach(variant => {
7 | const props = {
8 | [variant]: true,
9 | };
10 |
11 | const component = shallow();
12 | expect(component.find(`.${className}--${variant}`).exists()).toBe(true);
13 | });
14 | };
15 |
16 | export const hasChildByClassName = (el, className) => {
17 | const hasClass = !!el.getElementsByClassName(className).length;
18 | expect(hasClass).toBe(true);
19 | };
20 |
21 | export const hasAttribute = (el, attr, value) => {
22 | const elAttrValue = el.getAttribute(attr);
23 | expect(elAttrValue).not.toBeNull();
24 | if (value !== undefined) {
25 | expect(` ${elAttrValue} `.indexOf(` ${value} `)).not.toBe(-1);
26 | }
27 | };
28 |
29 | export const hasRoleAttribute = (el, roleName) => {
30 | hasAttribute(el, 'role', roleName);
31 | };
32 |
33 | export const componentHasProperty = (component, prop, value) => {
34 | expect(component && component.props && component.props[prop] === value).toBe(
35 | true
36 | );
37 | };
38 |
--------------------------------------------------------------------------------
/flow-typed/npm/file-loader_vx.x.x.js:
--------------------------------------------------------------------------------
1 | // flow-typed signature: 13baa6359b79ee5bd20fab5e5d74fd5b
2 | // flow-typed version: <>/file-loader_v1.1.11/flow_v0.76.0
3 |
4 | /**
5 | * This is an autogenerated libdef stub for:
6 | *
7 | * 'file-loader'
8 | *
9 | * Fill this stub out by replacing all the `any` types.
10 | *
11 | * Once filled out, we encourage you to share your work with the
12 | * community by sending a pull request to:
13 | * https://github.com/flowtype/flow-typed
14 | */
15 |
16 | declare module 'file-loader' {
17 | declare module.exports: any;
18 | }
19 |
20 | /**
21 | * We include stubs for each file inside this npm package in case you need to
22 | * require those files directly. Feel free to delete any files that aren't
23 | * needed.
24 | */
25 | declare module 'file-loader/dist/cjs' {
26 | declare module.exports: any;
27 | }
28 |
29 | declare module 'file-loader/dist/index' {
30 | declare module.exports: any;
31 | }
32 |
33 | // Filename aliases
34 | declare module 'file-loader/dist/cjs.js' {
35 | declare module.exports: $Exports<'file-loader/dist/cjs'>;
36 | }
37 | declare module 'file-loader/dist/index.js' {
38 | declare module.exports: $Exports<'file-loader/dist/index'>;
39 | }
40 |
--------------------------------------------------------------------------------
/assets/svg/google.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/assets/scss/components/_all.scss:
--------------------------------------------------------------------------------
1 | //
2 | // color vars
3 | //
4 | @import "../util/color-mappings";
5 | @import "../util/vars";
6 |
7 | //
8 | // Layout
9 | //
10 | @import "bounds";
11 | @import "chunk";
12 | @import "flex";
13 | @import "stripe";
14 | @import "section";
15 | @import "hscroll";
16 | @import "gridList";
17 | @import "inlineblockList";
18 |
19 | //
20 | // Animation
21 | //
22 | @import "~swarm-animation/src/constants";
23 | @import "~swarm-animation/src/fade";
24 |
25 | //
26 | // Helpers
27 | //
28 | @import "../helpers/popup";
29 |
30 | //
31 | // UI Components
32 | //
33 | @import "accentHeader";
34 | @import "appBadges";
35 | @import "accordion";
36 | @import "avatar";
37 | @import "button";
38 | @import "card";
39 | @import "calendar";
40 | @import "checkbox";
41 | @import "radio";
42 | @import "dropdown";
43 | @import "footer";
44 | @import "forms";
45 | @import "icon";
46 | @import "infoToggle";
47 | @import "loading";
48 | @import "modal";
49 | @import "popover";
50 | @import "tabs";
51 | @import "toast";
52 | @import "togglePill";
53 | @import "toggleSwitch";
54 | @import "tooltip";
55 | @import "typeahead";
56 | @import "navbar";
57 | @import "signup";
58 | @import "adminBar";
59 | @import "lockedBadge";
60 | @import "textInput";
61 |
--------------------------------------------------------------------------------
/src/layout/Chunk.jsx:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import React from 'react';
4 | import cx from 'classnames';
5 |
6 | import withLoading from '../utils/components/withLoading';
7 |
8 | type Props = {|
9 | /** The child elements of the component */
10 | children: React$Node,
11 | className?: string,
12 | /** Whether the component is in a loading state */
13 | isLoading?: boolean,
14 | /** Props to pass to the `` component */
15 | loadingProps?: {
16 | color?: string,
17 | scrimColor?: string,
18 | size?: MediaSizes,
19 | },
20 | |};
21 | /**
22 | * Design System Component: Provides `stripe` styled container for components
23 | * @module ChunkComponent
24 | */
25 | export class ChunkComponent extends React.Component {
26 | render() {
27 | const {
28 | children,
29 | className,
30 | loadingProps = {}, // eslint-disable-line no-unused-vars
31 | isLoading,
32 | ...other
33 | } = this.props;
34 |
35 | const classNames = cx('chunk', { 'component--isLoading': isLoading }, className);
36 |
37 | return (
38 |
39 | {children}
40 |
41 | );
42 | }
43 | }
44 |
45 | const Chunk = withLoading(ChunkComponent);
46 | Chunk.displayName = 'Chunk';
47 | export default Chunk;
48 |
--------------------------------------------------------------------------------
/src/forms/togglepill.story.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { storiesOf, action } from '@storybook/react';
3 | import { decorateWithBasics, decorateWithInfo } from '../utils/decorators';
4 | import TogglePill from './TogglePill';
5 |
6 | const onChange = e => {
7 | action(`The value of the Toggle Pill clicked is: ${e.target.value}`)(e);
8 | };
9 |
10 | storiesOf('Forms/TogglePill', module)
11 | .addDecorator(decorateWithBasics)
12 | .addDecorator(decorateWithInfo)
13 | .addParameters({ info: { propTables: [TogglePill] } })
14 | .add('default', () => (
15 |
16 |
22 | Toggle Pill Label
23 |
24 |
25 | ))
26 | .add('Default Selected', () => (
27 |
34 | Toggle Pill Label
35 |
36 | ))
37 | .add('reset', () => (
38 |
39 |
46 | Toggle Pill Label
47 |
48 |
49 | ));
50 |
--------------------------------------------------------------------------------
/assets/svg/host-badge.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/navigation/components/notifications/__snapshots__/Notifications.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Notification component should match snapshot 1`] = `
4 |
8 |
9 |
13 |
18 |
19 |
22 | Meetup Engineering just announced a new Meetup for Apr 6. Only 13 spots.",
27 | }
28 | }
29 | />
30 |
33 |
37 |
42 |
43 |
44 |
45 |
46 | `;
47 |
--------------------------------------------------------------------------------
/assets/scss/components/_toast.scss:
--------------------------------------------------------------------------------
1 | .toaster {
2 | box-sizing: border-box;
3 | position: absolute;
4 | top: 0;
5 | width: 100%;
6 | }
7 |
8 | .toast {
9 | background-color: $C_blue;
10 | box-sizing: border-box;
11 | display: block;
12 | margin-bottom: $space-half;
13 | padding: $space-3 $space;
14 |
15 | @include atMediaUp(large) {
16 | padding: $space-3;
17 | }
18 | }
19 |
20 | .toast--error {
21 | background-color: $C_orange;
22 | }
23 |
24 | .toast--success {
25 | background-color: $C_teal;
26 | }
27 |
28 | .toast-action {
29 | text-decoration: underline;
30 | }
31 |
32 | .toast-dismissBtn {
33 | cursor: pointer;
34 | }
35 |
36 | //
37 | // Toast transitions
38 | //
39 | .slide-appear,
40 | .slide-enter {
41 | opacity: 0.01;
42 | transform: translateY(-100px);
43 | }
44 |
45 | .slide-appear.slide-appear-active,
46 | .slide-enter.slide-enter-active {
47 | opacity: 1;
48 | transform: translateY(0);
49 | transition: opacity $duration--medium $easing--enter, transform $duration--medium $easing--enter;
50 | }
51 |
52 | .slide-exit {
53 | opacity: 1;
54 | transform: translateY(0);
55 | }
56 |
57 | .slide-exit.slide-exit-active {
58 | opacity: 0.01;
59 | transform: translateY(-100px);
60 | transition: opacity $duration--medium $easing--exit, transform $duration--medium $easing--exit;
61 | }
62 |
--------------------------------------------------------------------------------
/flow-typed/npm/storybook-react-router_vx.x.x.js:
--------------------------------------------------------------------------------
1 | // flow-typed signature: 8d57a9fdb289639c587c80488eb35577
2 | // flow-typed version: <>/storybook-react-router_v1.0.1/flow_v0.76.0
3 |
4 | /**
5 | * This is an autogenerated libdef stub for:
6 | *
7 | * 'storybook-react-router'
8 | *
9 | * Fill this stub out by replacing all the `any` types.
10 | *
11 | * Once filled out, we encourage you to share your work with the
12 | * community by sending a pull request to:
13 | * https://github.com/flowtype/flow-typed
14 | */
15 |
16 | declare module 'storybook-react-router' {
17 | declare module.exports: any;
18 | }
19 |
20 | /**
21 | * We include stubs for each file inside this npm package in case you need to
22 | * require those files directly. Feel free to delete any files that aren't
23 | * needed.
24 | */
25 | declare module 'storybook-react-router/dist/react' {
26 | declare module.exports: any;
27 | }
28 |
29 | declare module 'storybook-react-router/react' {
30 | declare module.exports: any;
31 | }
32 |
33 | // Filename aliases
34 | declare module 'storybook-react-router/dist/react.js' {
35 | declare module.exports: $Exports<'storybook-react-router/dist/react'>;
36 | }
37 | declare module 'storybook-react-router/react.js' {
38 | declare module.exports: $Exports<'storybook-react-router/react'>;
39 | }
40 |
--------------------------------------------------------------------------------
/flow-typed/npm/@storybook/react_v3.x.x.js:
--------------------------------------------------------------------------------
1 | // flow-typed signature: c2e1b132d2729c977d6b3e54e0134de5
2 | // flow-typed version: 1709d3212d/@storybook/react_v3.x.x/flow_>=v0.28.x
3 |
4 | type NodeModule = typeof module;
5 |
6 | declare module '@storybook/react' {
7 | declare type Renderable = React$Element;
8 | declare type RenderFunction = () => Renderable;
9 |
10 | declare type StoryDecorator = (
11 | story: RenderFunction,
12 | context: { kind: string, story: string }
13 | ) => Renderable | null;
14 |
15 | declare interface Story {
16 | add(storyName: string, callback: RenderFunction): Story,
17 | addDecorator(decorator: StoryDecorator): Story,
18 | }
19 |
20 | declare interface StoryObject {
21 | name: string,
22 | render: RenderFunction,
23 | }
24 |
25 | declare interface StoryBucket {
26 | kind: string,
27 | stories: Array,
28 | }
29 |
30 | declare function addDecorator(decorator: StoryDecorator): void;
31 | declare function configure(fn: () => void, module: NodeModule): void;
32 | declare function setAddon(addon: Object): void;
33 | declare function storiesOf(name: string, module: NodeModule): Story;
34 | declare function storiesOf(name: string, module: NodeModule): Story & T;
35 |
36 | declare function getStorybook(): Array;
37 | }
38 |
--------------------------------------------------------------------------------
/assets/scss/components/_textInput.scss:
--------------------------------------------------------------------------------
1 | .text-input-container {
2 | display: flex !important;
3 | }
4 |
5 | .input-with-currency-label {
6 | border-bottom-right-radius: 0 !important;
7 | border-right: 0 !important;
8 | border-top-right-radius: 0 !important;
9 | margin-bottom: 0;
10 | }
11 |
12 | .currency-label {
13 | align-items: center;
14 | background-color: var(--color-gray-2);
15 | border: 1px solid var(--color-gray-5);
16 | border-bottom-right-radius: 4px;
17 | border-left: 0;
18 | border-top-right-radius: 4px;
19 | display: flex;
20 | font-weight: 500;
21 | justify-items: center;
22 | padding: 0 calc(var(--responsive-space) / 2);
23 | }
24 |
25 | [data-swarm-text-input]:hover + .currency-label {
26 | border-color: var(--color-gray-6);
27 | outline: none; // stylelint-disable-line declaration-property-value-blacklist
28 | }
29 |
30 | [data-swarm-text-input]:focus + .currency-label {
31 | border-color: var(--color-viridian);
32 | outline: none; // stylelint-disable-line declaration-property-value-blacklist
33 | }
34 |
35 | [data-swarm-text-input="disabled"] + .currency-label {
36 | background-color: var(--color-gray-3);
37 | border-color: var(--color-gray-3) !important;
38 | color: var(--color-gray-6);
39 | }
40 |
41 | [data-swarm-text-input="error"] + .currency-label {
42 | border-color: var(--color-alert-red);
43 | }
44 |
--------------------------------------------------------------------------------
/src/forms/redux-form/togglePill.test.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow, mount } from 'enzyme';
3 | import ReduxFormTogglePill from './TogglePill';
4 | import TogglePill from '../TogglePill';
5 |
6 | describe('redux-form TogglePill', function() {
7 | // props given in the structure that
8 | // redux form would
9 | const togglePillProps = {
10 | input: {
11 | id: 'parenting',
12 | label: 'Parenting',
13 | name: 'parenting',
14 | children: 'Parenting!',
15 | value: false, // as a checkbox, redux form will pass true / false for values
16 | },
17 | };
18 |
19 | it('renders a TogglePill component with expected attributes from mock data', () => {
20 | const component = shallow();
21 | expect(component).toMatchSnapshot();
22 | });
23 |
24 | it('renders a TogglePill with isActive prop as false when value is false', () => {
25 | const component = mount();
26 | expect(component.find(TogglePill).prop('isActive')).toBe(false);
27 | });
28 |
29 | it('renders a TogglePill with isActive prop as true when value is true', () => {
30 | togglePillProps.input.value = true;
31 | const component = mount();
32 | expect(component.find(TogglePill).prop('isActive')).toBe(true);
33 | });
34 | });
35 |
--------------------------------------------------------------------------------
/util/jestSystemShim.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const System = {
3 | import: function(pathRelToCallingScript) {
4 | // we can't pass `pathRelToCallingScript` directly to `require` because it
5 | // will be resolved relative to this shim - instead, we need to find out
6 | // the path of the calling script and use that to get the absolute
7 | // path of pathRelToCallingScript
8 |
9 | // easiest access to the call stack is through the `Error` object
10 | const stack = new Error().stack;
11 | // in the error stack, the calling script will be on the third line
12 | const stackLineIndexOfCallingScript = 2;
13 | // in the calling script line, we can get the absolute path from inside the
14 | // parens, before the `:line:char` info
15 | const matchPathFromStack = /\(([^:]+)/;
16 |
17 | const pathToCallingScript = stack
18 | .split('\n')[stackLineIndexOfCallingScript]
19 | .match(matchPathFromStack)[1];
20 |
21 | // we want to resolve the imported module relative to the directory
22 | const absoluteDir = path.dirname(pathToCallingScript);
23 |
24 | // resolve the absolute path
25 | const absolutePath = path.resolve(absoluteDir, pathRelToCallingScript);
26 |
27 | // **now** we can require it and return a Promise
28 | return Promise.resolve(require(absolutePath));
29 | }
30 | };
31 |
32 | global.System = System;
33 |
34 |
--------------------------------------------------------------------------------
/flow-typed/npm/babel-plugin-react-intl_vx.x.x.js:
--------------------------------------------------------------------------------
1 | // flow-typed signature: d99adc710547ada3b6f808d1a6d01bc8
2 | // flow-typed version: <>/babel-plugin-react-intl_v2.3.1/flow_v0.76.0
3 |
4 | /**
5 | * This is an autogenerated libdef stub for:
6 | *
7 | * 'babel-plugin-react-intl'
8 | *
9 | * Fill this stub out by replacing all the `any` types.
10 | *
11 | * Once filled out, we encourage you to share your work with the
12 | * community by sending a pull request to:
13 | * https://github.com/flowtype/flow-typed
14 | */
15 |
16 | declare module 'babel-plugin-react-intl' {
17 | declare module.exports: any;
18 | }
19 |
20 | /**
21 | * We include stubs for each file inside this npm package in case you need to
22 | * require those files directly. Feel free to delete any files that aren't
23 | * needed.
24 | */
25 | declare module 'babel-plugin-react-intl/lib/index' {
26 | declare module.exports: any;
27 | }
28 |
29 | declare module 'babel-plugin-react-intl/lib/print-icu-message' {
30 | declare module.exports: any;
31 | }
32 |
33 | // Filename aliases
34 | declare module 'babel-plugin-react-intl/lib/index.js' {
35 | declare module.exports: $Exports<'babel-plugin-react-intl/lib/index'>;
36 | }
37 | declare module 'babel-plugin-react-intl/lib/print-icu-message.js' {
38 | declare module.exports: $Exports<'babel-plugin-react-intl/lib/print-icu-message'>;
39 | }
40 |
--------------------------------------------------------------------------------
/src/forms/__snapshots__/numberInput.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`NumberInput basic can be initialized to 0 1`] = `
4 | Object {
5 | "id": "amountCount",
6 | "max": 10,
7 | "min": 1,
8 | "name": "amountCount",
9 | "onChange": [MockFunction],
10 | "required": true,
11 | "step": 1,
12 | "value": 0,
13 | }
14 | `;
15 |
16 | exports[`NumberInput basic exists 1`] = `
17 |
18 |
22 | Are you bringing any guests?
23 |
24 |
34 |
35 | `;
36 |
37 | exports[`NumberInput basic input should have expected props 1`] = `
38 | Object {
39 | "id": "amountCount",
40 | "max": 10,
41 | "min": 1,
42 | "name": "amountCount",
43 | "onChange": [MockFunction],
44 | "required": true,
45 | "step": 1,
46 | "value": 2,
47 | }
48 | `;
49 |
50 | exports[`NumberInput basic should specify attributes that are passed in 1`] = `
51 |
59 | `;
60 |
--------------------------------------------------------------------------------
/assets/svg/notification.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/flow-typed/npm/eslint-import-resolver-webpack_vx.x.x.js:
--------------------------------------------------------------------------------
1 | // flow-typed signature: 1f513b8b49fd584e76d740ea6154e310
2 | // flow-typed version: <>/eslint-import-resolver-webpack_v0.10.1/flow_v0.76.0
3 |
4 | /**
5 | * This is an autogenerated libdef stub for:
6 | *
7 | * 'eslint-import-resolver-webpack'
8 | *
9 | * Fill this stub out by replacing all the `any` types.
10 | *
11 | * Once filled out, we encourage you to share your work with the
12 | * community by sending a pull request to:
13 | * https://github.com/flowtype/flow-typed
14 | */
15 |
16 | declare module 'eslint-import-resolver-webpack' {
17 | declare module.exports: any;
18 | }
19 |
20 | /**
21 | * We include stubs for each file inside this npm package in case you need to
22 | * require those files directly. Feel free to delete any files that aren't
23 | * needed.
24 | */
25 | declare module 'eslint-import-resolver-webpack/config' {
26 | declare module.exports: any;
27 | }
28 |
29 | // Filename aliases
30 | declare module 'eslint-import-resolver-webpack/config.js' {
31 | declare module.exports: $Exports<'eslint-import-resolver-webpack/config'>;
32 | }
33 | declare module 'eslint-import-resolver-webpack/index' {
34 | declare module.exports: $Exports<'eslint-import-resolver-webpack'>;
35 | }
36 | declare module 'eslint-import-resolver-webpack/index.js' {
37 | declare module.exports: $Exports<'eslint-import-resolver-webpack'>;
38 | }
39 |
--------------------------------------------------------------------------------
/src/forms/redux-form/CalendarComponent.jsx:
--------------------------------------------------------------------------------
1 | // @flow
2 | import React from 'react';
3 | import { convert, LocalDate, nativeJs } from '@js-joda/core';
4 | import CalendarComponent from '../CalendarComponent';
5 |
6 | type FieldProps = {
7 | input: {
8 | value?: Date,
9 | onChange?: (Date, ?string, ?FlatpickrInstance) => void,
10 | },
11 | meta: {
12 | touched?: boolean,
13 | submitFailed?: boolean,
14 | error?: string,
15 | },
16 | };
17 |
18 | /*
19 | * wraps standard TextInput web component for use with redux-form
20 | * deconstructs props that redux-forms sets and sets them on TextInput
21 | */
22 | const ReduxFormCalendarComponent = (props: FieldProps): React$Element<*> => {
23 | const { meta, input, ...other } = props;
24 | const error = meta.touched || meta.submitFailed ? meta.error : null;
25 |
26 | const jodaVal = input.value && LocalDate.from(nativeJs(input.value));
27 | const jodaOnChange = (localDate: LocalDate, dateString, flatpickr) => {
28 | const date: Date = convert(localDate).toDate();
29 | if (input.onChange) {
30 | input.onChange(date, dateString, flatpickr);
31 | }
32 | };
33 | return (
34 |
41 | );
42 | };
43 |
44 | ReduxFormCalendarComponent.displayName = 'ReduxFormCalendarComponent';
45 |
46 | export default ReduxFormCalendarComponent;
47 |
--------------------------------------------------------------------------------
/src/media/loading.test.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { variantTest } from '../utils/testUtils';
3 | import { shallow } from 'enzyme';
4 |
5 | import Loading, {
6 | LOADING_CLASS,
7 | LOADING_SHAPE_CLASS,
8 | LOADING_SHAPE_PATH_CLASS,
9 | } from './Loading';
10 |
11 | const CUSTOM_COLOR = '#000';
12 | const CUSTOM_SCRIM_COLOR = '#FFF';
13 | const CUSTOM_SIZE = '42px';
14 |
15 | describe('Loading', () => {
16 | const loadingComponent = shallow(
17 |
23 | );
24 | it('exists', () => {
25 | expect(loadingComponent).toMatchSnapshot();
26 | });
27 |
28 | it('applies variant classes for each variant prop', () => {
29 | const variants = ['fullCover', 'partialCover'];
30 |
31 | variantTest(Loading, LOADING_CLASS, variants);
32 | });
33 |
34 | it('colors the loader', () => {
35 | const shapePath = loadingComponent.find(`.${LOADING_SHAPE_PATH_CLASS}`);
36 | expect(shapePath.prop('stroke')).toBe(CUSTOM_COLOR);
37 | });
38 |
39 | it('colors the scrim', () => {
40 | expect(loadingComponent.prop('style').backgroundColor).toBe(
41 | CUSTOM_SCRIM_COLOR
42 | );
43 | });
44 |
45 | it('resizes when a custom size is passed', () => {
46 | const shape = loadingComponent.find(`.${LOADING_SHAPE_CLASS}`);
47 | expect(shape.prop('style').width).toBe(CUSTOM_SIZE);
48 | });
49 | });
50 |
--------------------------------------------------------------------------------
/assets/scss/components/_icon.scss:
--------------------------------------------------------------------------------
1 | @mixin _iconColor($color, $invertedColor) {
2 | @include color-svg($color);
3 |
4 | .inverted & {
5 | @include color-svg($invertedColor);
6 | }
7 | }
8 |
9 | @keyframes spin {
10 | 0% {
11 | transform: rotate(0deg);
12 | }
13 |
14 | 100% {
15 | transform: rotate(360deg);
16 | }
17 | }
18 |
19 | //
20 | // Base icon styles
21 | //
22 | .svg {
23 | // SVG wrapping span
24 | display: inline-block;
25 | }
26 |
27 | .svg-icon {
28 | // SVG element
29 | @include _iconColor($C_svgIcon, $C_svgIconInverted);
30 | display: inline-flex;
31 | font-size: 0;
32 |
33 | // click handling on svg elements
34 | // (ensures the entire element is clickable, not just the drawn bits
35 | position: relative;
36 | vertical-align: bottom;
37 |
38 | use {
39 | pointer-events: none;
40 | }
41 | }
42 |
43 | //
44 | // Icons with enclosing circle
45 | //
46 | .svg--circled {
47 | position: relative;
48 |
49 | &::before {
50 | background-color: $C_lightGray;
51 | border: 1px solid $C_border;
52 | border-radius: 100%;
53 | bottom: 0;
54 | content: "";
55 | left: 0;
56 | position: absolute;
57 | right: 0;
58 | top: 0;
59 | }
60 |
61 | svg {
62 | transform: scale(0.4);
63 | }
64 | }
65 |
66 | //
67 | // Specific icon shape styles
68 | //
69 | .svg--updates {
70 | animation: spin 400ms linear;
71 | animation-iteration-count: infinite;
72 | transform-origin: center center;
73 | }
74 |
--------------------------------------------------------------------------------
/flow-typed/npm/autosize_vx.x.x.js:
--------------------------------------------------------------------------------
1 | // flow-typed signature: 8777ba63a978f18aa373d297421012d1
2 | // flow-typed version: <>/autosize_v3.0.21/flow_v0.76.0
3 |
4 | /**
5 | * This is an autogenerated libdef stub for:
6 | *
7 | * 'autosize'
8 | *
9 | * Fill this stub out by replacing all the `any` types.
10 | *
11 | * Once filled out, we encourage you to share your work with the
12 | * community by sending a pull request to:
13 | * https://github.com/flowtype/flow-typed
14 | */
15 |
16 | declare module 'autosize' {
17 | declare module.exports: any;
18 | }
19 |
20 | /**
21 | * We include stubs for each file inside this npm package in case you need to
22 | * require those files directly. Feel free to delete any files that aren't
23 | * needed.
24 | */
25 | declare module 'autosize/dist/autosize' {
26 | declare module.exports: any;
27 | }
28 |
29 | declare module 'autosize/dist/autosize.min' {
30 | declare module.exports: any;
31 | }
32 |
33 | declare module 'autosize/src/autosize' {
34 | declare module.exports: any;
35 | }
36 |
37 | // Filename aliases
38 | declare module 'autosize/dist/autosize.js' {
39 | declare module.exports: $Exports<'autosize/dist/autosize'>;
40 | }
41 | declare module 'autosize/dist/autosize.min.js' {
42 | declare module.exports: $Exports<'autosize/dist/autosize.min'>;
43 | }
44 | declare module 'autosize/src/autosize.js' {
45 | declare module.exports: $Exports<'autosize/src/autosize'>;
46 | }
47 |
--------------------------------------------------------------------------------
/src/utils/components/DeprecationWarning.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | // Swarm Usage & Expectations Doc -> https://docs.google.com/document/d/1aj8FGlpoXQbDzvFgVpaWHzlGn4DfiexHzx96r63Me_4/edit#heading=h.ozjf42vcdlpq
4 |
5 | // List of components to be removed from meetup-web-components on October 3, 2019 ->
6 | // + Button
7 | // + Checkbox
8 | // + TextInput
9 | // + CharCounter
10 | // + NumberInput
11 | // + RadioButton
12 | // + RadioButtonGroup
13 | // + Select
14 | // + SelectInput
15 | // + TogglePill
16 | // + ToggleSwitch
17 |
18 | // All questions and concerns should be directed to #swarm in slack
19 |
20 | // 'global' record of which components have already logged a warning
21 | const hasBeenWarned = {};
22 |
23 | function DeprecationWarning(WrappedComponent) {
24 | class Wrapped extends React.Component {
25 | componentDidMount() {
26 | if (!hasBeenWarned[WrappedComponent.name]) {
27 | console.warn(
28 | `The ${
29 | WrappedComponent.name
30 | } component has been deprecated and will be removed from meetup-web-components on October 21, 2019. Please upgrade to the latest from https://github.com/meetup/swarm-ui`
31 | );
32 | hasBeenWarned[WrappedComponent.name] = true;
33 | }
34 | }
35 |
36 | render() {
37 | return ;
38 | }
39 | }
40 | Wrapped.displayName = WrappedComponent.name;
41 | return Wrapped;
42 | }
43 |
44 | export default DeprecationWarning;
45 |
--------------------------------------------------------------------------------
/src/utils/components/withLoading.jsx:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React from 'react';
3 |
4 | import Loading from '../../media/Loading';
5 |
6 | const getDisplayName = WrappedComponent => {
7 | return WrappedComponent.displayName || WrappedComponent.name || 'Component';
8 | };
9 |
10 | const withLoading = WrappedComponent => {
11 | /**
12 | * @module WithLoading
13 | */
14 | class WithLoading extends React.Component {
15 | render() {
16 | const { children, isLoading, loadingProps, ...other } = this.props;
17 |
18 | return (
19 |
24 | {this.props.dangerouslySetInnerHTML
25 | ? null
26 | : [
27 | children,
28 | isLoading && (
29 |
34 | ),
35 | ]}
36 |
37 | );
38 | }
39 | }
40 |
41 | WithLoading.displayName = getDisplayName(WrappedComponent);
42 | return WithLoading;
43 | };
44 |
45 | withLoading.defaultProps = {
46 | isLoading: false,
47 | };
48 | withLoading.propTypes = {
49 | isLoading: PropTypes.bool,
50 | loadingProps: PropTypes.shape({
51 | color: PropTypes.string,
52 | scrimColor: PropTypes.string,
53 | size: PropTypes.string,
54 | }),
55 | };
56 |
57 | export default withLoading;
58 |
--------------------------------------------------------------------------------
/src/forms/inputTime.test.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow } from 'enzyme';
3 | import { InputTimeComponent } from './InputTime';
4 |
5 | describe('InputTime', function() {
6 | const MOCK_PROPS = {
7 | name: 'mocktime',
8 | value: '12:15',
9 | onChange: jest.fn(),
10 | required: 'what fools these mortals be',
11 | };
12 |
13 | const render = (props = MOCK_PROPS) => {
14 | const wrapper = shallow();
15 | // shallow rendering doesn't set up `ref`, so force state change
16 | wrapper.instance().setState({ forceTextInput: false });
17 | wrapper.update();
18 | return wrapper;
19 | };
20 | describe('InputTime, with input[time] support', () => {
21 | it('renders a with expected props', () => {
22 | expect(render()).toMatchSnapshot();
23 | });
24 | it('renders error state as expected', () => {
25 | expect(
26 | render({ ...MOCK_PROPS, error: 'what just happened' })
27 | ).toMatchSnapshot();
28 | });
29 |
30 | it('calls props.onChange when value is changed', () => {
31 | MOCK_PROPS.onChange.mockClear();
32 | const newValue = '23:00';
33 | const wrapper = render();
34 | const inputWrap = wrapper.find('input');
35 | expect(MOCK_PROPS.onChange).not.toHaveBeenCalled();
36 | inputWrap.simulate('change', { currentTarget: { value: newValue } });
37 | expect(MOCK_PROPS.onChange).toHaveBeenCalledWith(newValue);
38 | });
39 | });
40 | });
41 |
--------------------------------------------------------------------------------
/assets/scss/components/_togglePill.scss:
--------------------------------------------------------------------------------
1 | .toggleButton-icon {
2 | margin-left: $space-half; // relative sizing because icon could be 's' or 'xs'
3 | }
4 |
5 | .toggleButton-label {
6 | @include buttonBase();
7 | @include standardBorder(all);
8 | @include buttonColor(
9 | $bgColor: transparentize($C_accent, 1),
10 | $hoverColor: transparentize($C_accent, 0.9),
11 | $activeColor: transparentize($C_accent, 0.8),
12 | $textTransition: false
13 | );
14 | @include color-all($C_accent);
15 | align-items: center;
16 | border-color: $C_accent;
17 | border-radius: 999px;
18 | display: inline-flex;
19 | flex-direction: row;
20 | font-weight: $W_normal;
21 | justify-content: center;
22 | margin: $space-quarter 0;
23 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
24 |
25 | .inverted & {
26 | @include buttonColor(
27 | $bgColor: transparentize($C_lightBlue, 1),
28 | $hoverColor: transparentize($C_lightBlue, 0.75),
29 | $activeColor: transparentize($C_lightBlue, 0.65),
30 | $textTransition: false
31 | );
32 | @include color-all($C_accent);
33 | border-color: $C_accent;
34 | }
35 | }
36 |
37 | .toggleButton-label--small {
38 | padding: $space-half $space;
39 | }
40 |
41 | .toggleButton-input {
42 | &:checked + .toggleButton-label {
43 | @include buttonColor($bgColor: $C_blue, $textTransition: false);
44 | font-weight: $W_medium;
45 | }
46 |
47 | &:focus + .toggleButton-label {
48 | outline: 1px dotted $C_borderDark;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/layout/flexItem.test.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow } from 'enzyme';
3 |
4 | import {
5 | FlexItemComponent,
6 | FLEX_ITEM_CLASS,
7 | FLEX_ITEM_SHRINK_CLASS,
8 | FLEX_ITEM_GROW_CLASS,
9 | FLEX_GROW_FACTORS,
10 | } from './FlexItem';
11 |
12 | describe('FlexItem', function() {
13 | it('exists', function() {
14 | const flexItem = shallow();
15 | expect(flexItem).toMatchSnapshot;
16 | });
17 | describe('default', () => {
18 | it(`check that the component has '${FLEX_ITEM_CLASS}' class`, function() {
19 | const flexItem = shallow();
20 | expect(flexItem.hasClass(FLEX_ITEM_CLASS)).toBe(true);
21 | });
22 | });
23 | describe('shrink', () => {
24 | it(`check that the component has '${FLEX_ITEM_SHRINK_CLASS}' class`, function() {
25 | const flexItem = shallow();
26 | expect(flexItem.hasClass(FLEX_ITEM_CLASS)).toBe(true);
27 | expect(flexItem.hasClass(FLEX_ITEM_SHRINK_CLASS)).toBe(true);
28 | });
29 | });
30 | describe('growFactor', () => {
31 | it("check that component has correct 'growFactor' class", function() {
32 | FLEX_GROW_FACTORS.forEach(growFactor => {
33 | const flexItem = shallow();
34 | expect(flexItem.hasClass(FLEX_ITEM_CLASS)).toBe(true);
35 | expect(flexItem.hasClass(`${FLEX_ITEM_GROW_CLASS}${growFactor}`)).toBe(
36 | true
37 | );
38 | });
39 | });
40 | });
41 | });
42 |
--------------------------------------------------------------------------------
/flow-typed/npm/babel-register_vx.x.x.js:
--------------------------------------------------------------------------------
1 | // flow-typed signature: b894da58885f01ea526bf66ef6cb411f
2 | // flow-typed version: <>/babel-register_v6.24.1/flow_v0.74.0
3 |
4 | /**
5 | * This is an autogenerated libdef stub for:
6 | *
7 | * 'babel-register'
8 | *
9 | * Fill this stub out by replacing all the `any` types.
10 | *
11 | * Once filled out, we encourage you to share your work with the
12 | * community by sending a pull request to:
13 | * https://github.com/flowtype/flow-typed
14 | */
15 |
16 | declare module 'babel-register' {
17 | declare module.exports: any;
18 | }
19 |
20 | /**
21 | * We include stubs for each file inside this npm package in case you need to
22 | * require those files directly. Feel free to delete any files that aren't
23 | * needed.
24 | */
25 | declare module 'babel-register/lib/browser' {
26 | declare module.exports: any;
27 | }
28 |
29 | declare module 'babel-register/lib/cache' {
30 | declare module.exports: any;
31 | }
32 |
33 | declare module 'babel-register/lib/node' {
34 | declare module.exports: any;
35 | }
36 |
37 | // Filename aliases
38 | declare module 'babel-register/lib/browser.js' {
39 | declare module.exports: $Exports<'babel-register/lib/browser'>;
40 | }
41 | declare module 'babel-register/lib/cache.js' {
42 | declare module.exports: $Exports<'babel-register/lib/cache'>;
43 | }
44 | declare module 'babel-register/lib/node.js' {
45 | declare module.exports: $Exports<'babel-register/lib/node'>;
46 | }
47 |
--------------------------------------------------------------------------------
/flow-typed/npm/raf_vx.x.x.js:
--------------------------------------------------------------------------------
1 | // flow-typed signature: f8a5495565a54ffd316e54faf4c358ed
2 | // flow-typed version: <>/raf_v3.4.0/flow_v0.76.0
3 |
4 | /**
5 | * This is an autogenerated libdef stub for:
6 | *
7 | * 'raf'
8 | *
9 | * Fill this stub out by replacing all the `any` types.
10 | *
11 | * Once filled out, we encourage you to share your work with the
12 | * community by sending a pull request to:
13 | * https://github.com/flowtype/flow-typed
14 | */
15 |
16 | declare module 'raf' {
17 | declare module.exports: any;
18 | }
19 |
20 | /**
21 | * We include stubs for each file inside this npm package in case you need to
22 | * require those files directly. Feel free to delete any files that aren't
23 | * needed.
24 | */
25 | declare module 'raf/polyfill' {
26 | declare module.exports: any;
27 | }
28 |
29 | declare module 'raf/test' {
30 | declare module.exports: any;
31 | }
32 |
33 | declare module 'raf/window' {
34 | declare module.exports: any;
35 | }
36 |
37 | // Filename aliases
38 | declare module 'raf/index' {
39 | declare module.exports: $Exports<'raf'>;
40 | }
41 | declare module 'raf/index.js' {
42 | declare module.exports: $Exports<'raf'>;
43 | }
44 | declare module 'raf/polyfill.js' {
45 | declare module.exports: $Exports<'raf/polyfill'>;
46 | }
47 | declare module 'raf/test.js' {
48 | declare module.exports: $Exports<'raf/test'>;
49 | }
50 | declare module 'raf/window.js' {
51 | declare module.exports: $Exports<'raf/window'>;
52 | }
53 |
--------------------------------------------------------------------------------
/src/forms/__snapshots__/checkbox.test.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Checkbox basic renders checked checkbox 1`] = `
4 |
36 | `;
37 |
38 | exports[`Checkbox basic renders unchecked checkbox 1`] = `
39 |
64 | `;
65 |
--------------------------------------------------------------------------------
/src/media/appBadges.test.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow } from 'enzyme';
3 |
4 | import AppBadges, { IOS_DOWNLOAD_LINK, ANDROID_DOWNLOAD_LINK } from './AppBadges';
5 |
6 | const testLanguage = 'fr';
7 | const isAndroidPhone = false;
8 | const isIosPhone = false;
9 | const IsMobile = false;
10 |
11 | describe('App Badges', () => {
12 | const appBadgesComponent = shallow(
13 |
19 | );
20 | it('exists', () => {
21 | expect(appBadgesComponent).toMatchSnapshot();
22 | });
23 | it('should link to the itunes store', () => {
24 | const itunesStoreLink = appBadgesComponent.find(`a[href="${IOS_DOWNLOAD_LINK}"]`);
25 | expect(itunesStoreLink.exists()).toBe(true);
26 | });
27 | it('should link to the google play store', () => {
28 | const googlePlayStoreLink = appBadgesComponent.find(
29 | `a[href="${ANDROID_DOWNLOAD_LINK}"]`
30 | );
31 | expect(googlePlayStoreLink.exists()).toBe(true);
32 | });
33 | it('should render the correct itunes and google play store images based on language', () => {
34 | const getAppStorePhoto = jest.fn();
35 | shallow(
36 |
37 | );
38 | expect(getAppStorePhoto).toHaveBeenCalledWith('android', testLanguage);
39 | expect(getAppStorePhoto).toHaveBeenCalledWith('ios', testLanguage);
40 | });
41 | });
42 |
--------------------------------------------------------------------------------
/flow-typed/npm/react-flatpickr_vx.x.x.js:
--------------------------------------------------------------------------------
1 | // flow-typed signature: 92e39d5169cbe963ceef76b96fceec6f
2 | // flow-typed version: <>/react-flatpickr_v3.6.4/flow_v0.76.0
3 |
4 | /**
5 | * This is an autogenerated libdef stub for:
6 | *
7 | * 'react-flatpickr'
8 | *
9 | * Fill this stub out by replacing all the `any` types.
10 | *
11 | * Once filled out, we encourage you to share your work with the
12 | * community by sending a pull request to:
13 | * https://github.com/flowtype/flow-typed
14 | */
15 |
16 | declare module 'react-flatpickr' {
17 | declare module.exports: any;
18 | }
19 |
20 | /**
21 | * We include stubs for each file inside this npm package in case you need to
22 | * require those files directly. Feel free to delete any files that aren't
23 | * needed.
24 | */
25 | declare module 'react-flatpickr/build/example' {
26 | declare module.exports: any;
27 | }
28 |
29 | declare module 'react-flatpickr/build/index' {
30 | declare module.exports: any;
31 | }
32 |
33 | declare module 'react-flatpickr/lib/index' {
34 | declare module.exports: any;
35 | }
36 |
37 | // Filename aliases
38 | declare module 'react-flatpickr/build/example.js' {
39 | declare module.exports: $Exports<'react-flatpickr/build/example'>;
40 | }
41 | declare module 'react-flatpickr/build/index.js' {
42 | declare module.exports: $Exports<'react-flatpickr/build/index'>;
43 | }
44 | declare module 'react-flatpickr/lib/index.js' {
45 | declare module.exports: $Exports<'react-flatpickr/lib/index'>;
46 | }
47 |
--------------------------------------------------------------------------------
/src/layout/inlineBlockList.test.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow } from 'enzyme';
3 | import {
4 | InlineBlockListComponent,
5 | INLINEBLOCKLIST_SEPERATED_CLASS,
6 | } from './InlineBlockList';
7 |
8 | const ITEMS = [
9 | 'English',
10 | 'English (Australian)',
11 | 'Deutsch',
12 | 'Español',
13 | 'Español (España)',
14 | 'Français',
15 | 'Italiano',
16 | 'Nederlands',
17 | 'Português',
18 | '日本語',
19 | '한국어',
20 | ],
21 | SEPARATOR = '☃';
22 |
23 | let inlineblockList, inlineblockListSeparated;
24 |
25 | describe('InlineBlockList', function() {
26 | beforeEach(() => {
27 | inlineblockList = shallow();
28 | inlineblockListSeparated = shallow(
29 |
30 | );
31 | });
32 | afterEach(() => {
33 | inlineblockList = null;
34 | inlineblockListSeparated = null;
35 | });
36 |
37 | it('exists', function() {
38 | expect(inlineblockList).toMatchSnapshot();
39 | });
40 |
41 | it(`should have a class of '${INLINEBLOCKLIST_SEPERATED_CLASS}' when a separator is defined`, () => {
42 | expect(
43 | inlineblockListSeparated.find('ul').hasClass(INLINEBLOCKLIST_SEPERATED_CLASS)
44 | ).toBe(true);
45 | });
46 |
47 | it('should set the data-separator attribute on item elements when a separator is defined', () => {
48 | const itemEl = inlineblockListSeparated.find('li').first();
49 | expect(itemEl.prop('data-separator')).toEqual(SEPARATOR);
50 | });
51 | });
52 |
--------------------------------------------------------------------------------
/src/layout/Bounds.jsx:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import React from 'react';
4 | import cx from 'classnames';
5 |
6 | import withLoading from '../utils/components/withLoading';
7 |
8 | export const BOUNDS_CLASS = 'bounds';
9 |
10 | type Props = {
11 | /** The child elements of the component */
12 | children: React$Node,
13 | className?: string,
14 | /** Whether the bounds max-width should use the narrow variant */
15 | narrow?: boolean,
16 | /** Props to pass to the `` component */
17 | loadingProps?: {
18 | color?: string,
19 | scrimColor?: string,
20 | size?: MediaSizes,
21 | },
22 | /** Whether the component is in a loading state */
23 | isLoading?: boolean,
24 | };
25 |
26 | /**
27 | * Design System Component: Provides `bounds` container for components
28 | * @module BoundsComponent
29 | */
30 |
31 | export class BoundsComponent extends React.PureComponent {
32 | render() {
33 | const {
34 | children,
35 | className,
36 | narrow,
37 | loadingProps = {}, // eslint-disable-line no-unused-vars
38 | isLoading,
39 | ...other
40 | } = this.props;
41 |
42 | const classNames = cx(
43 | BOUNDS_CLASS,
44 | {
45 | 'bounds--wide': !narrow,
46 | 'component--isLoading': isLoading,
47 | },
48 | className
49 | );
50 |
51 | return (
52 |
53 | {children}
54 |
55 | );
56 | }
57 | }
58 |
59 | const Bounds = withLoading(BoundsComponent);
60 | Bounds.displayName = 'Bounds';
61 | export default Bounds;
62 |
--------------------------------------------------------------------------------
/src/navigation/components/profile/ProfileDropdown.test.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { MOCK_GROUP } from 'meetup-web-mocks/lib/api';
3 | import { shallow } from 'enzyme';
4 |
5 | import ProfileDropdown from './ProfileDropdown';
6 |
7 | const MOCK_PROPS = {
8 | groupHome: jest.fn(),
9 | groups: [
10 | { ...MOCK_GROUP, name: 'hello 1', urlname: '1111', id: '1111' },
11 | { ...MOCK_GROUP, name: 'hello 2', urlname: '2222', id: '2222' },
12 | { ...MOCK_GROUP, name: 'hello 3', urlname: '3333', id: '3333' },
13 | { ...MOCK_GROUP, name: 'hello 4', urlname: '4444', id: '4444' },
14 | ],
15 | allGroupsLabel: 'All Groups',
16 | allGroupsLink: 'meetup.com/find',
17 | profile: {
18 | link: 'meetup.com',
19 | label: 'Profile',
20 | },
21 | payments: {
22 | link: 'meetup.com',
23 | label: 'Payments made',
24 | },
25 | settings: {
26 | link: 'meetup.com',
27 | label: 'Settings',
28 | },
29 | help: {
30 | link: 'meetup.com',
31 | label: 'Help',
32 | },
33 | logout: {
34 | link: 'meetup.com',
35 | label: 'Logout',
36 | },
37 | savedEvents: {
38 | link: 'meetup.com',
39 | label: 'Saved events',
40 | },
41 | yourGroups: {
42 | link: 'meetup.com',
43 | label: 'Your groups',
44 | },
45 | yourEvents: {
46 | link: 'meetup.com',
47 | label: 'Your events',
48 | },
49 | };
50 |
51 | describe('Profile Dropdown', () => {
52 | const wrapper = shallow();
53 | it('should match snapshot', () => {
54 | expect(wrapper).toMatchSnapshot();
55 | });
56 | });
57 |
--------------------------------------------------------------------------------
/flow-typed/npm/prop-types_v15.x.x.js:
--------------------------------------------------------------------------------
1 | // flow-typed signature: d9a983bb1ac458a256c31c139047bdbb
2 | // flow-typed version: 927687984d/prop-types_v15.x.x/flow_>=v0.41.x
3 |
4 | type $npm$propTypes$ReactPropsCheckType = (
5 | props: any,
6 | propName: string,
7 | componentName: string,
8 | href?: string) => ?Error;
9 |
10 | declare module 'prop-types' {
11 | declare var array: React$PropType$Primitive>;
12 | declare var bool: React$PropType$Primitive;
13 | declare var func: React$PropType$Primitive;
14 | declare var number: React$PropType$Primitive;
15 | declare var object: React$PropType$Primitive