├── .all-contributorsrc
├── .babelrc
├── .circleci
└── config.yml
├── .eslintrc.json
├── .gitattributes
├── .github
├── CODEOWNERS
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── ISSUE_TEMPLATE.md
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
└── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── .npmignore
├── .npmrc
├── .prettierrc.json
├── .snyk
├── .storybook
├── config.yml
├── main.js
├── old-docs
│ ├── bundle.js
│ └── index.html
└── webpack.config.js
├── API
└── index.js
├── CHANGELOG.md
├── LICENSE
├── bot-usage.png
├── bundle.js
├── commitlint.config.js
├── index.html
├── ld-react-components.png
├── package.json
├── readme.md
├── src
└── lib
│ ├── FeatureCase
│ └── index.ts
│ ├── FeatureDefault
│ └── index.ts
│ ├── FeatureFalse
│ └── index.ts
│ ├── FeatureFlag
│ ├── FeatureFlag.stories.jsx
│ ├── README.md
│ ├── index.js
│ └── index.tsx
│ ├── FeatureSwitch
│ └── index.tsx
│ ├── FeatureTrue
│ └── index.ts
│ ├── LaunchDarklyClient
│ └── index.ts
│ └── index.js
├── test-reports
└── jest
│ └── results.xml
├── test
├── __snapshots__
│ └── react.test.js.snap
├── main.test.js
└── react.test.js
├── tsconfig.json
├── webpack.config.js
└── yarn.lock
/.all-contributorsrc:
--------------------------------------------------------------------------------
1 | {
2 | "projectName": "LD-React-Components",
3 | "projectOwner": "intuit",
4 | "repoType": "github",
5 | "repoHost": "https://github.com",
6 | "files": [
7 | "readme.md"
8 | ],
9 | "imageSize": 100,
10 | "commit": true,
11 | "commitConvention": "none",
12 | "contributors": [
13 | {
14 | "login": "poorpaddy",
15 | "name": "Dave Bergschneider",
16 | "avatar_url": "https://avatars3.githubusercontent.com/u/2213076?v=4",
17 | "profile": "http://www.cmscode.com",
18 | "contributions": [
19 | "code",
20 | "design",
21 | "doc",
22 | "example",
23 | "maintenance"
24 | ]
25 | },
26 | {
27 | "login": "hipstersmoothie",
28 | "name": "Andrew Lisowski",
29 | "avatar_url": "https://avatars3.githubusercontent.com/u/1192452?v=4",
30 | "profile": "http://hipstersmoothie.com",
31 | "contributions": [
32 | "infra"
33 | ]
34 | },
35 | {
36 | "login": "hjaintech",
37 | "name": "Harshit Jain",
38 | "avatar_url": "https://avatars2.githubusercontent.com/u/1290501?v=4",
39 | "profile": "http://www.harshitjain.in",
40 | "contributions": [
41 | "doc"
42 | ]
43 | },
44 | {
45 | "login": "zjael",
46 | "name": "Jakob S",
47 | "avatar_url": "https://avatars3.githubusercontent.com/u/13909277?s=460&v=4",
48 | "profile": "https://github.com/zjael",
49 | "contributions": [
50 | "maintenance"
51 | ]
52 | },
53 | {
54 | "login": "vvscode",
55 | "name": "Vasiliy Vanchuk",
56 | "avatar_url": "https://avatars1.githubusercontent.com/u/6904368?v=4",
57 | "profile": "http://bit.ly/vvscodeli",
58 | "contributions": [
59 | "infra"
60 | ]
61 | },
62 | {
63 | "login": "Buranch",
64 | "name": "Buranch",
65 | "avatar_url": "https://avatars2.githubusercontent.com/u/17932362?v=4",
66 | "profile": "https://github.com/Buranch",
67 | "contributions": [
68 | "code"
69 | ]
70 | },
71 | {
72 | "login": "ishubhamarora",
73 | "name": "Shubham Arora",
74 | "avatar_url": "https://avatars2.githubusercontent.com/u/55948973?v=4",
75 | "profile": "https://github.com/ishubhamarora",
76 | "contributions": [
77 | "code"
78 | ]
79 | },
80 | {
81 | "login": "ggrumbley",
82 | "name": "Gary Grumbley",
83 | "avatar_url": "https://avatars0.githubusercontent.com/u/15022042?v=4",
84 | "profile": "https://twitter.com/StumblinG",
85 | "contributions": [
86 | "infra",
87 | "doc"
88 | ]
89 | },
90 | {
91 | "login": "Hreherch",
92 | "name": "Bennett Hreherchuk",
93 | "avatar_url": "https://avatars1.githubusercontent.com/u/10092939?v=4",
94 | "profile": "https://github.com/Hreherch",
95 | "contributions": [
96 | "test"
97 | ]
98 | },
99 | {
100 | "login": "josediego",
101 | "name": "Jose Diego",
102 | "avatar_url": "https://avatars0.githubusercontent.com/u/5665920?v=4",
103 | "profile": "https://github.com/josediego",
104 | "contributions": [
105 | "infra",
106 | "code",
107 | "doc",
108 | "test"
109 | ]
110 | },
111 | {
112 | "login": "Swazimodo",
113 | "name": "Sam Nesbitt",
114 | "avatar_url": "https://avatars3.githubusercontent.com/u/10536879?v=4",
115 | "profile": "https://www.linkedin.com/in/sam-nesbitt-74ba6a34/",
116 | "contributions": [
117 | "code"
118 | ]
119 | },
120 | {
121 | "login": "pramodrhegde",
122 | "name": "Pramod",
123 | "avatar_url": "https://avatars1.githubusercontent.com/u/9020200?v=4",
124 | "profile": "https://github.com/pramodrhegde",
125 | "contributions": [
126 | "code"
127 | ]
128 | },
129 | {
130 | "login": "cueo",
131 | "name": "Mohit Mayank",
132 | "avatar_url": "https://avatars1.githubusercontent.com/u/13873846?v=4",
133 | "profile": "https://github.com/cueo",
134 | "contributions": [
135 | "code"
136 | ]
137 | },
138 | {
139 | "login": "anki08",
140 | "name": "ankita sinha",
141 | "avatar_url": "https://avatars2.githubusercontent.com/u/8593629?v=4",
142 | "profile": "https://github.com/anki08",
143 | "contributions": [
144 | "code"
145 | ]
146 | },
147 | {
148 | "login": "Kausam",
149 | "name": "Kausam",
150 | "avatar_url": "https://avatars2.githubusercontent.com/u/19550684?v=4",
151 | "profile": "https://github.com/Kausam",
152 | "contributions": [
153 | "code"
154 | ]
155 | },
156 | {
157 | "login": "rohan8594",
158 | "name": "Rohan Patel",
159 | "avatar_url": "https://avatars1.githubusercontent.com/u/23509745?v=4",
160 | "profile": "http://rohanpatel.xyz",
161 | "contributions": [
162 | "doc"
163 | ]
164 | },
165 | {
166 | "login": "tekgal",
167 | "name": "tekgal",
168 | "avatar_url": "https://avatars0.githubusercontent.com/u/23368862?v=4",
169 | "profile": "https://github.com/tekgal",
170 | "contributions": [
171 | "infra"
172 | ]
173 | },
174 | {
175 | "login": "funkadelic",
176 | "name": "Norman Yee",
177 | "avatar_url": "https://avatars2.githubusercontent.com/u/155019?v=4",
178 | "profile": "https://github.com/funkadelic",
179 | "contributions": [
180 | "infra"
181 | ]
182 | },
183 | {
184 | "login": "himanshupnt",
185 | "name": "Himanshu Pant",
186 | "avatar_url": "https://avatars3.githubusercontent.com/u/8342344?v=4",
187 | "profile": "https://himanshupnt.com",
188 | "contributions": [
189 | "doc"
190 | ]
191 | },
192 | {
193 | "login": "erwintj",
194 | "name": "Trevor Erwin",
195 | "avatar_url": "https://avatars0.githubusercontent.com/u/13356723?v=4",
196 | "profile": "https://github.com/erwintj",
197 | "contributions": [
198 | "bug"
199 | ]
200 | },
201 | {
202 | "login": "faulker",
203 | "name": "Winter Faulk",
204 | "avatar_url": "https://avatars0.githubusercontent.com/u/2238782?v=4",
205 | "profile": "http://faulk.me",
206 | "contributions": [
207 | "maintenance"
208 | ]
209 | },
210 | {
211 | "login": "skodamarthi",
212 | "name": "Susmitha Kodamarthi",
213 | "avatar_url": "https://avatars0.githubusercontent.com/u/4538858?v=4",
214 | "profile": "https://github.com/skodamarthi",
215 | "contributions": [
216 | "test"
217 | ]
218 | }
219 | ],
220 | "contributorsPerLine": 7,
221 | "skipCi": true
222 | }
223 |
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | "@babel/preset-typescript",
4 | "@babel/env",
5 | "@babel/react"
6 | ],
7 | "plugins": [
8 | "@babel/plugin-proposal-object-rest-spread",
9 | "@babel/plugin-proposal-class-properties"
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------
/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | version: 2.1
2 |
3 | defaults: &defaults
4 | working_directory: ~/ld-react-components
5 | docker:
6 | - image: circleci/node:12.14-browsers
7 | environment:
8 | TEST_REPORTS: ~/ld-react-components/test-reports
9 |
10 | aliases:
11 | # Circle related commands
12 | - &restore-cache
13 | keys:
14 | # Find a cache corresponding to this specific package.json checksum
15 | # when this file is changed, this key will fail
16 | - ld-react-components-{{ checksum "yarn.lock" }}-{{ checksum ".circleci/config.yml" }}
17 | - ld-react-components-{{ checksum "yarn.lock" }}
18 | # Find the most recent cache used from any branch
19 | - ld-react-components-
20 | - &save-cache
21 | key: ld-react-components-{{ checksum "yarn.lock" }}-{{ checksum ".circleci/config.yml" }}
22 | paths:
23 | - ~/.cache/yarn
24 | - node_modules
25 | # Yarn commands
26 | - &yarn
27 | name: Install Dependencies
28 | command: yarn install --frozen-lockfile --non-interactive --cache-folder=~/.cache/yarn
29 | - &lint
30 | name: Lint
31 | command: yarn lint
32 | - &test
33 | name: Test
34 | command: yarn test
35 | - &build
36 | name: Build
37 | command: yarn build
38 |
39 | jobs:
40 | install:
41 | <<: *defaults
42 | steps:
43 | - checkout
44 | - restore_cache: *restore-cache
45 | - run: *yarn
46 | - save_cache: *save-cache
47 | - persist_to_workspace:
48 | root: .
49 | paths:
50 | - .
51 |
52 | build:
53 | <<: *defaults
54 | steps:
55 | - attach_workspace:
56 | at: ~/ld-react-components
57 | - run: *build
58 | - persist_to_workspace:
59 | root: .
60 | paths:
61 | - .
62 |
63 | lint:
64 | <<: *defaults
65 | steps:
66 | - attach_workspace:
67 | at: ~/ld-react-components
68 | - run: *lint
69 |
70 | test:
71 | <<: *defaults
72 | steps:
73 | - attach_workspace:
74 | at: ~/ld-react-components
75 | - run:
76 | command: |
77 | mkdir -p ${TEST_REPORTS}
78 | - run: *test
79 | - run:
80 | name: Send CodeCov Results
81 | command: bash <(curl -s https://codecov.io/bash) -t $CODECOV_KEY
82 | - store_test_results:
83 | path: test-reports
84 |
85 | release:
86 | <<: *defaults
87 | steps:
88 | - attach_workspace:
89 | at: ~/ld-react-components
90 | - add_ssh_keys:
91 | fingerprints:
92 | - "23:b5:04:c6:6a:82:2b:c8:ae:25:39:90:6a:b7:de:cd"
93 | - run: git config user.email dave@cmscode.com
94 | - run: git config user.name "poorpaddy"
95 | - run: rm -rf ~/.ssh/ && mkdir ~/.ssh/ && echo -e "Host github.com\n\tStrictHostKeyChecking no\n" > ~/.ssh/config
96 | - run:
97 | name: Release
98 | command: yarn release
99 |
100 | publishDocs:
101 | <<: *defaults
102 | steps:
103 | - attach_workspace:
104 | at: ~/ld-react-components
105 | - add_ssh_keys:
106 | fingerprints:
107 | - "23:b5:04:c6:6a:82:2b:c8:ae:25:39:90:6a:b7:de:cd"
108 | - run: git config user.email dave@cmscode.com
109 | - run: git config user.name "poorpaddy"
110 | - run: rm -rf ~/.ssh/ && mkdir ~/.ssh/ && echo -e "Host github.com\n\tStrictHostKeyChecking no\n" > ~/.ssh/config
111 | - run:
112 | name: Build Docs
113 | command: yarn docs:build
114 | - run:
115 | name: Config Docs
116 | command: yarn docs:config
117 | - run:
118 | name: Publish Docs
119 | command: yarn docs:publish
120 |
121 | workflows:
122 | version: 2
123 | build_and_test:
124 | jobs:
125 | - install
126 |
127 | - build:
128 | requires:
129 | - install
130 | filters:
131 | branches:
132 | only:
133 | - master
134 | ignore:
135 | - gh-pages
136 |
137 | - lint:
138 | requires:
139 | - build
140 |
141 | - test:
142 | requires:
143 | - build
144 |
145 | - release:
146 | requires:
147 | - test
148 | - lint
149 |
150 | - publishDocs:
151 | requires:
152 | - release
153 | filters:
154 | branches:
155 | only:
156 | - master
157 | ignore:
158 | - gh-pages
159 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "airbnb",
4 | "plugin:prettier/recommended",
5 | "prettier/react"
6 | ],
7 | "env": {
8 | "browser": true,
9 | "commonjs": true,
10 | "es6": true,
11 | "jest": true,
12 | "node": true
13 | },
14 | "rules": {
15 | "jsx-a11y/href-no-hash": ["off"],
16 | "react/jsx-filename-extension": ["warn", { "extensions": [".js", ".jsx"] }],
17 | "max-len": [
18 | "warn",
19 | {
20 | "code": 100,
21 | "tabWidth": 2,
22 | "comments": 120,
23 | "ignoreComments": false,
24 | "ignoreTrailingComments": true,
25 | "ignoreUrls": true,
26 | "ignoreStrings": true,
27 | "ignoreTemplateLiterals": true,
28 | "ignoreRegExpLiterals": true
29 | }
30 | ],
31 | "import/extensions": [
32 | "error",
33 | "ignorePackages",
34 | {
35 | "js": "never",
36 | "jsx": "never",
37 | "ts": "never",
38 | "tsx": "never"
39 | }
40 | ]
41 | },
42 | "settings": {
43 | "import/resolver": {
44 | "node": {
45 | "extensions": [".js", ".jsx", ".ts", ".tsx"]
46 | }
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Handle line endings automatically for files detected as text
2 | # and leave all files detected as binary untouched.
3 | * text=auto
4 |
5 | #
6 | # The above will handle all files NOT found below
7 | # These files are text and should be normalized (Convert crlf => lf)
8 | #
9 |
10 | # source code
11 | *.php text
12 | *.css text
13 | *.sass text
14 | *.scss text
15 | *.less text
16 | *.styl text
17 | *.js text eol=lf
18 | *.coffee text
19 | *.json text
20 | *.htm text
21 | *.html text
22 | *.xml text
23 | *.svg text
24 | *.txt text
25 | *.ini text
26 | *.inc text
27 | *.pl text
28 | *.rb text
29 | *.py text
30 | *.scm text
31 | *.sql text
32 | *.sh text
33 | *.bat text
34 |
35 | # templates
36 | *.ejs text
37 | *.hbt text
38 | *.jade text
39 | *.haml text
40 | *.hbs text
41 | *.dot text
42 | *.tmpl text
43 | *.phtml text
44 |
45 | # server config
46 | .htaccess text
47 | .nginx.conf text
48 |
49 | # git config
50 | .gitattributes text
51 | .gitignore text
52 | .gitconfig text
53 |
54 | # code analysis config
55 | .jshintrc text
56 | .jscsrc text
57 | .jshintignore text
58 | .csslintrc text
59 |
60 | # misc config
61 | *.yaml text
62 | *.yml text
63 | .editorconfig text
64 |
65 | # build config
66 | *.npmignore text
67 | *.bowerrc text
68 |
69 | # Heroku
70 | Procfile text
71 | .slugignore text
72 |
73 | # Documentation
74 | *.md text
75 | LICENSE text
76 | AUTHORS text
77 |
78 |
79 | #
80 | ## These files are binary and should be left untouched
81 | #
82 |
83 | # (binary is a macro for -text -diff)
84 | *.png binary
85 | *.jpg binary
86 | *.jpeg binary
87 | *.gif binary
88 | *.ico binary
89 | *.mov binary
90 | *.mp4 binary
91 | *.mp3 binary
92 | *.flv binary
93 | *.fla binary
94 | *.swf binary
95 | *.gz binary
96 | *.zip binary
97 | *.7z binary
98 | *.ttf binary
99 | *.eot binary
100 | *.woff binary
101 | *.pyc binary
102 | *.pdf binary
103 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | @poorpaddy
--------------------------------------------------------------------------------
/.github/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | Open source projects are “living.” Contributions in the form of issues and pull requests are welcomed and encouraged. When you contribute, you explicitly say you are part of the community and abide by its Code of Conduct.
2 |
3 | # The Code
4 |
5 | At Intuit, we foster a kind, respectful, harassment-free cooperative community. Our open source community works to:
6 |
7 | - Be kind and respectful;
8 | - Act as a global community;
9 | - Conduct ourselves professionally.
10 |
11 | As members of this community, we will not tolerate behaviors including, but not limited to:
12 |
13 | - Violent threats or language;
14 | - Discriminatory or derogatory jokes or language;
15 | - Public or private harassment of any kind;
16 | - Other conduct considered inappropriate in a professional setting.
17 |
18 | ## Reporting Concerns
19 |
20 | If you see someone violating the Code of Conduct please email TechOpenSource@intuit.com
21 |
22 | ## Scope
23 |
24 | This code of conduct applies to:
25 |
26 | All repos and communities for Intuit-managed projects, whether or not the text is included in a Intuit-managed project’s repository;
27 |
28 | Individuals or teams representing projects in official capacity, such as via official social media channels or at in-person meetups.
29 |
30 | ## Attribution
31 |
32 | This Code of Conduct is partly inspired by and based on those of Amazon, CocoaPods, GitHub, Microsoft, thoughtbot, and on the Contributor Covenant version 1.4.1.
33 |
--------------------------------------------------------------------------------
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | [](# Contributing Guidelines
2 |
3 | So you're interested in giving us a hand? That's awesome! We are putting together some guidelines that should help you get started quickly and easily. If you need help with anything, please let us know. Thank you for stopping by!
4 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/intuit/LD-React-Components/2362c78f968b48ec8c8eeb6cea171a296cba15cb/.github/ISSUE_TEMPLATE.md
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: bug
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 |
12 |
13 |
14 | **To Reproduce**
15 |
16 |
17 |
18 | **Expected behavior**
19 |
20 |
21 |
22 | **Screenshots**
23 |
24 |
25 |
26 | **Desktop (please complete the following information):**
27 |
28 | - OS: [e.g. iOS]
29 | - Browser [e.g. chrome, safari]
30 | - Version [e.g. 22]
31 |
32 | **Additional context**
33 |
34 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: enhancement
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 |
12 |
13 |
14 | **Describe the solution you'd like**
15 |
16 |
17 |
18 | **Describe alternatives you've considered**
19 |
20 |
21 |
22 | **Additional context**
23 |
24 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | # What Changed
2 |
3 | # Why
4 |
5 | Todo:
6 |
7 | - [ ] Add tests
8 | - [ ] Add docs
9 | - [ ] Add yourself to contributors (run `yarn contributors:add`))
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Hidden Environment Files #
2 | .*
3 | !.eslintrc
4 | !.github
5 | !.gitignore
6 | !.babelrc
7 | !.npmrc
8 | !.npmignore
9 | !.circleci
10 | !.storybook
11 |
12 | # LOG Files #
13 | *.log
14 | log/
15 |
16 | # IDE #
17 | .idea/
18 | .vscode/
19 | *.swp
20 |
21 | # Node Files #
22 | /node_modules
23 |
24 | # Tests #
25 | /coverage/
26 | /errorShots/
27 | /screenshots/
28 | stats.json
29 | /test-results/
30 | # Build folder #
31 | local
32 | build
33 | dist
34 |
35 | #IDE Specific files
36 |
37 | #SublimeText
38 | *.sublime-project
39 | *.sublime-workspace
40 |
41 | #IntelliJ
42 | .idea/
43 | *.iml
44 | atlassian-ide-plugin.xml
45 | *.ipr
46 | *.iws
47 |
48 | #Eclipse
49 | .project
50 |
51 | #OSX
52 | .DS_Store
53 | .vscode
54 |
55 | # Docs
56 | /docs
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | package-lock.json
3 | docs
4 | .babelrc
5 | webpack.config.js
6 | .vscode
7 | .eslintrc
8 | .npmrc
9 | test
10 | src
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | registry=https://registry.yarnpkg.com
--------------------------------------------------------------------------------
/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 100,
3 | "singleQuote": true,
4 | "trailingComma": "none"
5 | }
6 |
--------------------------------------------------------------------------------
/.snyk:
--------------------------------------------------------------------------------
1 | # Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.
2 | version: v1.14.1
3 | ignore: {}
4 | # patches apply the minimum changes required to fix a vulnerability
5 | patch:
6 | SNYK-JS-LODASH-567746:
7 | - '@storybook/addon-knobs > @storybook/client-api > @storybook/addons > @storybook/api > @storybook/router > @storybook/csf > lodash':
8 | patched: '2020-05-19T19:43:54.266Z'
9 | - '@storybook/addon-knobs > lodash':
10 | patched: '2020-05-20T00:43:57.311Z'
11 | - '@storybook/addon-knobs > @storybook/api > lodash':
12 | patched: '2020-05-20T00:43:57.311Z'
13 | - '@storybook/addon-knobs > @storybook/client-api > lodash':
14 | patched: '2020-05-20T00:43:57.311Z'
15 | - '@storybook/addon-knobs > @storybook/components > lodash':
16 | patched: '2020-05-20T00:43:57.311Z'
17 | - '@storybook/addon-knobs > react-color > lodash':
18 | patched: '2020-05-20T00:43:57.311Z'
19 | - '@storybook/addon-knobs > @storybook/api > @storybook/csf > lodash':
20 | patched: '2020-05-20T00:43:57.311Z'
21 | - '@storybook/addon-knobs > @storybook/client-api > @storybook/csf > lodash':
22 | patched: '2020-05-20T00:43:57.311Z'
23 | - '@storybook/addon-knobs > @storybook/api > @storybook/router > lodash':
24 | patched: '2020-05-20T00:43:57.311Z'
25 | - '@storybook/addon-knobs > @storybook/api > telejson > lodash':
26 | patched: '2020-05-20T00:43:57.311Z'
27 | - '@storybook/addon-knobs > @storybook/addons > @storybook/api > lodash':
28 | patched: '2020-05-20T00:43:57.311Z'
29 | - '@storybook/addon-knobs > react-color > reactcss > lodash':
30 | patched: '2020-05-20T00:43:57.311Z'
31 | - '@storybook/addon-knobs > @storybook/api > @storybook/router > @storybook/csf > lodash':
32 | patched: '2020-05-20T00:43:57.311Z'
33 | - '@storybook/addon-knobs > @storybook/addons > @storybook/api > @storybook/csf > lodash':
34 | patched: '2020-05-20T00:43:57.311Z'
35 | - '@storybook/addon-knobs > @storybook/addons > @storybook/api > @storybook/router > lodash':
36 | patched: '2020-05-20T00:43:57.311Z'
37 | - '@storybook/addon-knobs > @storybook/addons > @storybook/api > telejson > lodash':
38 | patched: '2020-05-20T00:43:57.311Z'
39 | - '@storybook/addon-knobs > @storybook/client-api > @storybook/channel-postmessage > telejson > lodash':
40 | patched: '2020-05-20T00:43:57.311Z'
41 | - '@storybook/addon-knobs > @storybook/client-api > @storybook/addons > @storybook/api > lodash':
42 | patched: '2020-05-20T00:43:57.311Z'
43 | - '@storybook/addon-knobs > @storybook/addons > @storybook/api > @storybook/router > @storybook/csf > lodash':
44 | patched: '2020-05-20T00:43:57.311Z'
45 | - '@storybook/addon-knobs > @storybook/client-api > @storybook/addons > @storybook/api > @storybook/csf > lodash':
46 | patched: '2020-05-20T00:43:57.311Z'
47 | - '@storybook/addon-knobs > @storybook/client-api > @storybook/addons > @storybook/api > @storybook/router > lodash':
48 | patched: '2020-05-20T00:43:57.311Z'
49 | - '@storybook/addon-knobs > @storybook/client-api > @storybook/addons > @storybook/api > telejson > lodash':
50 | patched: '2020-05-20T00:43:57.311Z'
51 | - '@storybook/addon-knobs > @storybook/client-api > @storybook/addons > @storybook/api > @storybook/router > @storybook/csf > lodash':
52 | patched: '2020-05-20T00:43:57.311Z'
53 | - '@storybook/addon-knobs > react-select > @emotion/css > babel-plugin-emotion > @babel/helper-module-imports > @babel/types > lodash':
54 | patched: '2020-05-20T00:43:57.311Z'
55 | - '@storybook/addon-knobs > @storybook/theming > @emotion/styled > babel-plugin-emotion > @babel/helper-module-imports > @babel/types > lodash':
56 | patched: '2020-05-20T00:43:57.311Z'
57 | - '@storybook/addon-knobs > @storybook/theming > @emotion/core > @emotion/css > babel-plugin-emotion > @babel/helper-module-imports > @babel/types > lodash':
58 | patched: '2020-05-20T00:43:57.311Z'
59 | - '@storybook/addon-knobs > react-select > @emotion/core > @emotion/css > babel-plugin-emotion > @babel/helper-module-imports > @babel/types > lodash':
60 | patched: '2020-05-20T00:43:57.311Z'
61 | - '@storybook/addon-knobs > @storybook/api > @storybook/theming > @emotion/styled > babel-plugin-emotion > @babel/helper-module-imports > @babel/types > lodash':
62 | patched: '2020-05-20T00:43:57.311Z'
63 | - '@storybook/addon-knobs > @storybook/components > @storybook/theming > @emotion/styled > babel-plugin-emotion > @babel/helper-module-imports > @babel/types > lodash':
64 | patched: '2020-05-20T00:43:57.311Z'
65 | - '@storybook/addon-knobs > @storybook/api > @storybook/theming > @emotion/core > @emotion/css > babel-plugin-emotion > @babel/helper-module-imports > @babel/types > lodash':
66 | patched: '2020-05-20T00:43:57.311Z'
67 | - '@storybook/addon-knobs > @storybook/components > @storybook/theming > @emotion/core > @emotion/css > babel-plugin-emotion > @babel/helper-module-imports > @babel/types > lodash':
68 | patched: '2020-05-20T00:43:57.311Z'
69 | - '@storybook/addon-knobs > @storybook/addons > @storybook/api > @storybook/theming > @emotion/styled > babel-plugin-emotion > @babel/helper-module-imports > @babel/types > lodash':
70 | patched: '2020-05-20T00:43:57.311Z'
71 | - '@storybook/addon-knobs > @storybook/addons > @storybook/api > @storybook/theming > @emotion/core > @emotion/css > babel-plugin-emotion > @babel/helper-module-imports > @babel/types > lodash':
72 | patched: '2020-05-20T00:43:57.311Z'
73 | - '@storybook/addon-knobs > @storybook/client-api > @storybook/addons > @storybook/api > @storybook/theming > @emotion/styled > babel-plugin-emotion > @babel/helper-module-imports > @babel/types > lodash':
74 | patched: '2020-05-20T00:43:57.311Z'
75 | - '@storybook/addon-knobs > @storybook/client-api > @storybook/addons > @storybook/api > @storybook/theming > @emotion/core > @emotion/css > babel-plugin-emotion > @babel/helper-module-imports > @babel/types > lodash':
76 | patched: '2020-05-20T00:43:57.311Z'
77 |
--------------------------------------------------------------------------------
/.storybook/config.yml:
--------------------------------------------------------------------------------
1 | version: 2.1
2 |
3 | defaults: &defaults
4 | docker:
5 | - image: circleci/node:8.14-browsers
6 |
7 | jobs:
8 | install:
9 | <<: *defaults
10 | steps:
11 | - checkout
12 | - run: echo "dont build me"
13 |
14 | workflows:
15 | version: 2
16 | build_and_test:
17 | jobs:
18 | - install
--------------------------------------------------------------------------------
/.storybook/main.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | stories: ['../src/lib/**/*.stories.@(js|jsx|mdx)'],
3 | addons: [
4 | '@storybook/addon-docs',
5 | '@storybook/addon-knobs/register',
6 | '@storybook/addon-storysource/register',
7 | '@storybook/addon-actions/register',
8 | '@storybook/addon-links/register',
9 | '@storybook/addon-a11y/register'
10 | ],
11 | options: {
12 | panelPosition: 'bottom',
13 | name: 'Launch Darkly React Components',
14 | },
15 | backgrounds: [
16 | {
17 | name: 'white',
18 | value: '#fff',
19 | default: true,
20 | },
21 | {
22 | name: 'grey',
23 | value: '#f4f5f8',
24 | },
25 | ],
26 | a11y: {
27 | // ... axe options
28 | element: '#root', // optional selector which element to inspect
29 | config: {}, // axe-core configurationOptions (https://github.com/dequelabs/axe-core/blob/develop/doc/API.md#parameters-1)
30 | options: {}, // axe-core optionsParameter (https://github.com/dequelabs/axe-core/blob/develop/doc/API.md#options-parameter)
31 | },
32 | presets: [
33 | '@storybook/preset-create-react-app',
34 | ],
35 | };
36 |
--------------------------------------------------------------------------------
/.storybook/old-docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Example
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.storybook/webpack.config.js:
--------------------------------------------------------------------------------
1 | // you can use this file to add your custom webpack plugins, loaders and anything you like.
2 | // This is just the basic way to add additional webpack configurations.
3 | // For more information refer the docs: https://storybook.js.org/configurations/custom-webpack-config
4 |
5 | // IMPORTANT
6 | // When you add this file, we won't add the default configurations which is similar
7 | // to "React Create App". This only has babel loader to load JavaScript.
8 |
9 | module.exports = {
10 | optimization: {
11 | minimize: false,
12 | },
13 | plugins: [
14 | // your custom plugins
15 | ],
16 | module: {
17 | rules: [
18 | {
19 | test: /\.(ts|tsx)$/,
20 | use: [
21 | {
22 | loader: require.resolve('awesome-typescript-loader'),
23 | },
24 | // Optional
25 | {
26 | loader: require.resolve('react-docgen-typescript-loader'),
27 | },
28 | ],
29 | },
30 | {
31 | test: /\.stories\.jsx?$/,
32 | use: [
33 | {
34 | loaders: require.resolve('@storybook/source-loader'),
35 | },
36 | ],
37 | enforce: 'pre',
38 | },
39 | ],
40 | },
41 | resolve: {
42 | extensions: ['.ts', '.tsx'],
43 | },
44 | };
45 |
--------------------------------------------------------------------------------
/API/index.js:
--------------------------------------------------------------------------------
1 | var LDApi = require('../dist/LaunchDarklyClient/index.js');
2 | module.exports = new LDApi();
3 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # v1.0.83 (Tue Feb 15 2022)
2 |
3 | #### 🐛 Bug Fix
4 |
5 | - Bump shelljs from 0.8.4 to 0.8.5 [#121](https://github.com/intuit/LD-React-Components/pull/121) ([@dependabot[bot]](https://github.com/dependabot[bot]) [@poorpaddy](https://github.com/poorpaddy))
6 | - Bump ws from 5.2.2 to 5.2.3 [#120](https://github.com/intuit/LD-React-Components/pull/120) ([@dependabot[bot]](https://github.com/dependabot[bot]) [@poorpaddy](https://github.com/poorpaddy))
7 | - Bump trim-off-newlines from 1.0.1 to 1.0.3 [#119](https://github.com/intuit/LD-React-Components/pull/119) ([@dependabot[bot]](https://github.com/dependabot[bot]) [@poorpaddy](https://github.com/poorpaddy))
8 |
9 | #### Authors: 2
10 |
11 | - [@dependabot[bot]](https://github.com/dependabot[bot])
12 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
13 |
14 | ---
15 |
16 | # v1.0.82 (Tue Feb 15 2022)
17 |
18 | #### 🐛 Bug Fix
19 |
20 | - Bump follow-redirects from 1.11.0 to 1.14.8 [#118](https://github.com/intuit/LD-React-Components/pull/118) ([@dependabot[bot]](https://github.com/dependabot[bot]) [@poorpaddy](https://github.com/poorpaddy))
21 |
22 | #### Authors: 2
23 |
24 | - [@dependabot[bot]](https://github.com/dependabot[bot])
25 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
26 |
27 | ---
28 |
29 | # v1.0.81 (Tue Feb 15 2022)
30 |
31 | #### 🐛 Bug Fix
32 |
33 | - Bump ajv from 6.12.2 to 6.12.6 [#117](https://github.com/intuit/LD-React-Components/pull/117) ([@dependabot[bot]](https://github.com/dependabot[bot]))
34 | - Bump pathval from 1.1.0 to 1.1.1 [#116](https://github.com/intuit/LD-React-Components/pull/116) ([@dependabot[bot]](https://github.com/dependabot[bot]))
35 | - Bump tmpl from 1.0.4 to 1.0.5 [#114](https://github.com/intuit/LD-React-Components/pull/114) ([@dependabot[bot]](https://github.com/dependabot[bot]))
36 |
37 | #### Authors: 1
38 |
39 | - [@dependabot[bot]](https://github.com/dependabot[bot])
40 |
41 | ---
42 |
43 | # v1.0.80 (Wed Sep 01 2021)
44 |
45 | #### 🐛 Bug Fix
46 |
47 | - Bump package [#113](https://github.com/intuit/LD-React-Components/pull/113) ([@poorpaddy](https://github.com/poorpaddy))
48 | - Bump tar from 6.0.5 to 6.1.11 [#111](https://github.com/intuit/LD-React-Components/pull/111) ([@dependabot[bot]](https://github.com/dependabot[bot]) [@poorpaddy](https://github.com/poorpaddy))
49 | - Bump path-parse from 1.0.6 to 1.0.7 [#109](https://github.com/intuit/LD-React-Components/pull/109) ([@dependabot[bot]](https://github.com/dependabot[bot]) [@poorpaddy](https://github.com/poorpaddy))
50 | - Bump trim-newlines from 3.0.0 to 3.0.1 [#105](https://github.com/intuit/LD-React-Components/pull/105) ([@dependabot[bot]](https://github.com/dependabot[bot]) [@poorpaddy](https://github.com/poorpaddy))
51 | - Bump dns-packet from 1.3.1 to 1.3.4 [#104](https://github.com/intuit/LD-React-Components/pull/104) ([@dependabot[bot]](https://github.com/dependabot[bot]) [@poorpaddy](https://github.com/poorpaddy))
52 | - Bump url-parse from 1.4.7 to 1.5.1 [#102](https://github.com/intuit/LD-React-Components/pull/102) ([@dependabot[bot]](https://github.com/dependabot[bot]))
53 | - Bump ssri from 6.0.1 to 6.0.2 [#101](https://github.com/intuit/LD-React-Components/pull/101) ([@dependabot[bot]](https://github.com/dependabot[bot]))
54 | - Bump gitlog from 4.0.0 to 4.0.4 [#100](https://github.com/intuit/LD-React-Components/pull/100) ([@dependabot[bot]](https://github.com/dependabot[bot]) [@poorpaddy](https://github.com/poorpaddy))
55 | - Bump y18n from 3.2.1 to 3.2.2 [#98](https://github.com/intuit/LD-React-Components/pull/98) ([@dependabot[bot]](https://github.com/dependabot[bot]))
56 | - [Snyk] Security upgrade snyk from 1.436.0 to 1.465.0 [#97](https://github.com/intuit/LD-React-Components/pull/97) ([@snyk-bot](https://github.com/snyk-bot) [@poorpaddy](https://github.com/poorpaddy))
57 | - Bump elliptic from 6.5.3 to 6.5.4 [#96](https://github.com/intuit/LD-React-Components/pull/96) ([@dependabot[bot]](https://github.com/dependabot[bot]))
58 |
59 | #### Authors: 3
60 |
61 | - [@dependabot[bot]](https://github.com/dependabot[bot])
62 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
63 | - Snyk bot ([@snyk-bot](https://github.com/snyk-bot))
64 |
65 | ---
66 |
67 | # v1.0.79 (Thu Feb 25 2021)
68 |
69 | #### 🐛 Bug Fix
70 |
71 | - Bump ini from 1.3.5 to 1.3.8 [#95](https://github.com/intuit/LD-React-Components/pull/95) ([@dependabot[bot]](https://github.com/dependabot[bot]))
72 | - docs: add skodamarthi as a contributor [#92](https://github.com/intuit/LD-React-Components/pull/92) ([@allcontributors[bot]](https://github.com/allcontributors[bot]))
73 | - chore: added commitlint support [#89](https://github.com/intuit/LD-React-Components/pull/89) (susmitha_kodamarthi@intuit.com [@skodamarthi](https://github.com/skodamarthi))
74 | - docs: add faulker as a contributor [#90](https://github.com/intuit/LD-React-Components/pull/90) ([@allcontributors[bot]](https://github.com/allcontributors[bot]))
75 | - feat(storybook): updates storybook to v6 [#88](https://github.com/intuit/LD-React-Components/pull/88) (Winter_Faulk@intuit.com)
76 |
77 | #### Authors: 5
78 |
79 | - [@allcontributors[bot]](https://github.com/allcontributors[bot])
80 | - [@dependabot[bot]](https://github.com/dependabot[bot])
81 | - skodamarthi (susmitha_kodamarthi@intuit.com)
82 | - Susmitha Kodamarthi ([@skodamarthi](https://github.com/skodamarthi))
83 | - Winter Faulk ([@faulker](https://github.com/faulker))
84 |
85 | ---
86 |
87 | # v1.0.78 (Fri Aug 21 2020)
88 |
89 | #### 🐛 Bug Fix
90 |
91 | - Bump elliptic from 6.5.2 to 6.5.3 [#83](https://github.com/intuit/LD-React-Components/pull/83) ([@dependabot[bot]](https://github.com/dependabot[bot]))
92 | - Bump lodash from 4.17.15 to 4.17.19 [#82](https://github.com/intuit/LD-React-Components/pull/82) ([@dependabot[bot]](https://github.com/dependabot[bot]))
93 |
94 | #### Authors: 1
95 |
96 | - [@dependabot[bot]](https://github.com/dependabot[bot])
97 |
98 | ---
99 |
100 | # v1.0.77 (Tue Jun 09 2020)
101 |
102 | #### 🐛 Bug Fix
103 |
104 | - Bump websocket-extensions from 0.1.3 to 0.1.4 [#81](https://github.com/intuit/LD-React-Components/pull/81) ([@dependabot[bot]](https://github.com/dependabot[bot]))
105 |
106 | #### Authors: 1
107 |
108 | - [@dependabot[bot]](https://github.com/dependabot[bot])
109 |
110 | ---
111 |
112 | # v1.0.76 (Wed May 20 2020)
113 |
114 | #### 🐛 Bug Fix
115 |
116 | - [Snyk] Fix for 1 vulnerabilities [#80](https://github.com/intuit/LD-React-Components/pull/80) ([@snyk-bot](https://github.com/snyk-bot) [@poorpaddy](https://github.com/poorpaddy))
117 |
118 | #### Authors: 2
119 |
120 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
121 | - Snyk bot ([@snyk-bot](https://github.com/snyk-bot))
122 |
123 | ---
124 |
125 | # v1.0.75 (Wed May 20 2020)
126 |
127 | #### 🐛 Bug Fix
128 |
129 | - Second part of NPM updates [#79](https://github.com/intuit/LD-React-Components/pull/79) ([@poorpaddy](https://github.com/poorpaddy))
130 |
131 | #### Authors: 1
132 |
133 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
134 |
135 | ---
136 |
137 | # v1.0.74 (Tue May 19 2020)
138 |
139 | #### 🐛 Bug Fix
140 |
141 | - [Snyk] Fix for 1 vulnerabilities [#78](https://github.com/intuit/LD-React-Components/pull/78) ([@snyk-bot](https://github.com/snyk-bot) [@poorpaddy](https://github.com/poorpaddy))
142 |
143 | #### Authors: 2
144 |
145 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
146 | - Snyk bot ([@snyk-bot](https://github.com/snyk-bot))
147 |
148 | ---
149 |
150 | # v1.0.73 (Tue May 19 2020)
151 |
152 | #### 🐛 Bug Fix
153 |
154 | - First round of NPM Updates [#77](https://github.com/intuit/LD-React-Components/pull/77) ([@poorpaddy](https://github.com/poorpaddy))
155 |
156 | #### ⚠️ Pushed to master
157 |
158 | - fix for eslint ([@poorpaddy](https://github.com/poorpaddy))
159 |
160 | #### Authors: 1
161 |
162 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
163 |
164 | ---
165 |
166 | # v1.0.72 (Mon Apr 13 2020)
167 |
168 | #### ⚠️ Pushed to master
169 |
170 | - updating minor dependency to force build in circleci (dave_bergschneider@intuit.com)
171 |
172 | #### Authors: 1
173 |
174 | - Bergschneider, Dave (dave_bergschneider@intuit.com)
175 |
176 | ---
177 |
178 | # v1.0.65 (Wed Nov 20 2019)
179 |
180 | #### 🐛 Bug Fix
181 |
182 | - updated the count [#73](https://github.com/intuit/LD-React-Components/pull/73) (dave_bergschneider@intuit.com [@poorpaddy](https://github.com/poorpaddy))
183 | - Fix/payload [#70](https://github.com/intuit/LD-React-Components/pull/70) ([@Buranch](https://github.com/Buranch))
184 | - Changing the entry to the index.js instead of .ts [#72](https://github.com/intuit/LD-React-Components/pull/72) ([@Buranch](https://github.com/Buranch))
185 | - fix the typescript build [#71](https://github.com/intuit/LD-React-Components/pull/71) ([@Buranch](https://github.com/Buranch))
186 |
187 | #### ⚠️ Pushed to master
188 |
189 | - manual ssh key (dave_bergschneider@intuit.com)
190 |
191 | #### Authors: 3
192 |
193 | - Buranch ([@Buranch](https://github.com/Buranch))
194 | - Bergschneider, Dave (dave_bergschneider@intuit.com)
195 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
196 |
197 | ---
198 |
199 | # v1.0.64 (Thu Oct 31 2019)
200 |
201 | #### 🐛 Bug Fix
202 |
203 | - docs: add erwintj as a contributor [#69](https://github.com/intuit/LD-React-Components/pull/69) ([@allcontributors[bot]](https://github.com/allcontributors[bot]) [@poorpaddy](https://github.com/poorpaddy))
204 |
205 | #### Authors: 2
206 |
207 | - [@allcontributors[bot]](https://github.com/allcontributors[bot])
208 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
209 |
210 | ---
211 |
212 | # v1.0.63 (Thu Oct 31 2019)
213 |
214 | #### 🐛 Bug Fix
215 |
216 | - Updating import extension from js to ts [#68](https://github.com/intuit/LD-React-Components/pull/68) ([@erwintj](https://github.com/erwintj))
217 |
218 | #### Authors: 1
219 |
220 | - Trevor Erwin ([@erwintj](https://github.com/erwintj))
221 |
222 | ---
223 |
224 | # v1.0.62 (Thu Oct 31 2019)
225 |
226 | #### 🐛 Bug Fix
227 |
228 | - Follow-up to pull#59 (saving CircleCI test summaries) [#62](https://github.com/intuit/LD-React-Components/pull/62) ([@funkadelic](https://github.com/funkadelic) [@poorpaddy](https://github.com/poorpaddy))
229 |
230 | #### Authors: 2
231 |
232 | - Norman Yee ([@funkadelic](https://github.com/funkadelic))
233 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
234 |
235 | ---
236 |
237 | # v1.0.61 (Wed Oct 30 2019)
238 |
239 | #### 🐛 Bug Fix
240 |
241 | - docs: add himanshupnt as a contributor [#66](https://github.com/intuit/LD-React-Components/pull/66) ([@allcontributors[bot]](https://github.com/allcontributors[bot]) [@poorpaddy](https://github.com/poorpaddy))
242 |
243 | #### Authors: 2
244 |
245 | - [@allcontributors[bot]](https://github.com/allcontributors[bot])
246 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
247 |
248 | ---
249 |
250 | # v1.0.60 (Wed Oct 30 2019)
251 |
252 | #### 🐛 Bug Fix
253 |
254 | - ISSUE# 52 - add storybook stories [#65](https://github.com/intuit/LD-React-Components/pull/65) ([@himanshupnt](https://github.com/himanshupnt))
255 |
256 | #### Authors: 1
257 |
258 | - Himanshu Pant ([@himanshupnt](https://github.com/himanshupnt))
259 |
260 | ---
261 |
262 | # v1.0.59 (Wed Oct 30 2019)
263 |
264 | #### 🐛 Bug Fix
265 |
266 | - docs: add funkadelic as a contributor [#64](https://github.com/intuit/LD-React-Components/pull/64) ([@allcontributors[bot]](https://github.com/allcontributors[bot]))
267 |
268 | #### Authors: 1
269 |
270 | - [@allcontributors[bot]](https://github.com/allcontributors[bot])
271 |
272 | ---
273 |
274 | # v1.0.58 (Wed Oct 30 2019)
275 |
276 | #### 🐛 Bug Fix
277 |
278 | - docs: add tekgal as a contributor [#63](https://github.com/intuit/LD-React-Components/pull/63) ([@allcontributors[bot]](https://github.com/allcontributors[bot]) [@poorpaddy](https://github.com/poorpaddy))
279 |
280 | #### Authors: 2
281 |
282 | - [@allcontributors[bot]](https://github.com/allcontributors[bot])
283 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
284 |
285 | ---
286 |
287 | # v1.0.57 (Wed Oct 30 2019)
288 |
289 | #### 🐛 Bug Fix
290 |
291 | - Add test summary to circleci [#61](https://github.com/intuit/LD-React-Components/pull/61) (puja_baid@intuit.com [@tekgal](https://github.com/tekgal))
292 |
293 | #### Authors: 2
294 |
295 | - [@tekgal](https://github.com/tekgal)
296 | - pbaid (puja_baid@intuit.com)
297 |
298 | ---
299 |
300 | # v1.0.56 (Wed Oct 30 2019)
301 |
302 | #### 🐛 Bug Fix
303 |
304 | - Revert "feat(build): use webpack to compile build (#57)" [#60](https://github.com/intuit/LD-React-Components/pull/60) ([@poorpaddy](https://github.com/poorpaddy))
305 |
306 | #### Authors: 1
307 |
308 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
309 |
310 | ---
311 |
312 | # v1.0.55 (Wed Oct 30 2019)
313 |
314 | #### 🐛 Bug Fix
315 |
316 | - Add test summaries for CircleCI [#59](https://github.com/intuit/LD-React-Components/pull/59) ([@funkadelic](https://github.com/funkadelic))
317 |
318 | #### Authors: 1
319 |
320 | - Norman Yee ([@funkadelic](https://github.com/funkadelic))
321 |
322 | ---
323 |
324 | # v1.0.54 (Mon Oct 28 2019)
325 |
326 | #### 🐛 Bug Fix
327 |
328 | - feat(build): use webpack to compile build [#57](https://github.com/intuit/LD-React-Components/pull/57) ([@Hreherch](https://github.com/Hreherch) [@poorpaddy](https://github.com/poorpaddy))
329 |
330 | #### Authors: 2
331 |
332 | - Bennett Hreherchuk ([@Hreherch](https://github.com/Hreherch))
333 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
334 |
335 | ---
336 |
337 | # v1.0.53 (Mon Oct 28 2019)
338 |
339 | #### 🐛 Bug Fix
340 |
341 | - docs: add rohan8594 as a contributor [#56](https://github.com/intuit/LD-React-Components/pull/56) ([@allcontributors[bot]](https://github.com/allcontributors[bot]) [@poorpaddy](https://github.com/poorpaddy))
342 |
343 | #### Authors: 2
344 |
345 | - [@allcontributors[bot]](https://github.com/allcontributors[bot])
346 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
347 |
348 | ---
349 |
350 | # v1.0.52 (Mon Oct 28 2019)
351 |
352 | #### 🐛 Bug Fix
353 |
354 | - All Contributors Bot [#55](https://github.com/intuit/LD-React-Components/pull/55) ([@rohan8594](https://github.com/rohan8594))
355 |
356 | #### Authors: 1
357 |
358 | - Rohan Patel ([@rohan8594](https://github.com/rohan8594))
359 |
360 | ---
361 |
362 | # v1.0.51 (Thu Oct 24 2019)
363 |
364 | #### 🐛 Bug Fix
365 |
366 | - Refactor for TypeScript: LaunchDarklyClient [#54](https://github.com/intuit/LD-React-Components/pull/54) ([@Kausam](https://github.com/Kausam))
367 |
368 | #### Authors: 1
369 |
370 | - [@Kausam](https://github.com/Kausam)
371 |
372 | ---
373 |
374 | # v1.0.50 (Fri Oct 18 2019)
375 |
376 | #### ⚠️ Pushed to master
377 |
378 | - added old docs for examples in storybook ([@poorpaddy](https://github.com/poorpaddy))
379 |
380 | #### Authors: 1
381 |
382 | - poorpaddy ([@poorpaddy](https://github.com/poorpaddy))
383 |
384 | ---
385 |
386 | # v1.0.49 (Thu Oct 17 2019)
387 |
388 | #### ⚠️ Pushed to master
389 |
390 | - Pushing old docs for example of upcoming hacktoberfest issues ([@poorpaddy](https://github.com/poorpaddy))
391 |
392 | #### Authors: 1
393 |
394 | - poorpaddy ([@poorpaddy](https://github.com/poorpaddy))
395 |
396 | ---
397 |
398 | # v1.0.48 (Fri Oct 11 2019)
399 |
400 | #### 🐛 Bug Fix
401 |
402 | - fix: somehow unminifying storybook fixes the static build [#49](https://github.com/intuit/LD-React-Components/pull/49) ([@mmissey](https://github.com/mmissey))
403 |
404 | #### Authors: 1
405 |
406 | - Marc Missey ([@mmissey](https://github.com/mmissey))
407 |
408 | ---
409 |
410 | # v1.0.47 (Mon Oct 07 2019)
411 |
412 | #### 🐛 Bug Fix
413 |
414 | - Refactor for TypeScript: FeatureCase Component #32 [#46](https://github.com/intuit/LD-React-Components/pull/46) ([@anki08](https://github.com/anki08) [@poorpaddy](https://github.com/poorpaddy))
415 |
416 | #### Authors: 2
417 |
418 | - ankita sinha ([@anki08](https://github.com/anki08))
419 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
420 |
421 | ---
422 |
423 | # v1.0.46 (Mon Oct 07 2019)
424 |
425 | #### 🐛 Bug Fix
426 |
427 | - Fix TS2367 : No overlap for comparison [#47](https://github.com/intuit/LD-React-Components/pull/47) ([@cueo](https://github.com/cueo))
428 |
429 | #### Authors: 1
430 |
431 | - Mohit Mayank ([@cueo](https://github.com/cueo))
432 |
433 | ---
434 |
435 | # v1.0.45 (Sun Oct 06 2019)
436 |
437 | #### 🐛 Bug Fix
438 |
439 | - Refactor FeatureDefault to use TS [#45](https://github.com/intuit/LD-React-Components/pull/45) ([@cueo](https://github.com/cueo) [@poorpaddy](https://github.com/poorpaddy))
440 |
441 | #### Authors: 2
442 |
443 | - Mohit Mayank ([@cueo](https://github.com/cueo))
444 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
445 |
446 | ---
447 |
448 | # v1.0.44 (Sun Oct 06 2019)
449 |
450 | #### 🐛 Bug Fix
451 |
452 | - Refactor FeatureFalse to use TS [#44](https://github.com/intuit/LD-React-Components/pull/44) ([@cueo](https://github.com/cueo) [@poorpaddy](https://github.com/poorpaddy))
453 |
454 | #### Authors: 2
455 |
456 | - Mohit Mayank ([@cueo](https://github.com/cueo))
457 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
458 |
459 | ---
460 |
461 | # v1.0.43 (Sun Oct 06 2019)
462 |
463 | #### 🐛 Bug Fix
464 |
465 | - Refactor LaunchDarklyClient to use TypeScript [#43](https://github.com/intuit/LD-React-Components/pull/43) ([@cueo](https://github.com/cueo))
466 |
467 | #### Authors: 1
468 |
469 | - Mohit Mayank ([@cueo](https://github.com/cueo))
470 |
471 | ---
472 |
473 | # v1.0.42 (Sun Oct 06 2019)
474 |
475 | #### 🐛 Bug Fix
476 |
477 | - Moved FeatureTrue component to typescript. Issue #37 [#42](https://github.com/intuit/LD-React-Components/pull/42) (pramod_hegde@intuit.com [@pramodrhegde](https://github.com/pramodrhegde))
478 |
479 | #### Authors: 2
480 |
481 | - Pramod ([@pramodrhegde](https://github.com/pramodrhegde))
482 | - phegde2 (pramod_hegde@intuit.com)
483 |
484 | ---
485 |
486 | # v1.0.41 (Sat Oct 05 2019)
487 |
488 | #### 🐛 Bug Fix
489 |
490 | - Feature/type switch [#41](https://github.com/intuit/LD-React-Components/pull/41) ([@Swazimodo](https://github.com/Swazimodo))
491 |
492 | #### Authors: 1
493 |
494 | - Sam Nesbitt ([@Swazimodo](https://github.com/Swazimodo))
495 |
496 | ---
497 |
498 | # v1.0.40 (Fri Oct 04 2019)
499 |
500 | #### ⚠️ Pushed to master
501 |
502 | - Add @josediego as a contributor ([@poorpaddy](https://github.com/poorpaddy))
503 |
504 | #### Authors: 1
505 |
506 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
507 |
508 | ---
509 |
510 | # v1.0.39 (Fri Oct 04 2019)
511 |
512 | #### ⚠️ Pushed to master
513 |
514 | - Merge branch 'master' of https://github.com/intuit/LD-React-Components ([@poorpaddy](https://github.com/poorpaddy))
515 | - Add @Hreherch as a contributor ([@poorpaddy](https://github.com/poorpaddy))
516 |
517 | #### Authors: 1
518 |
519 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
520 |
521 | ---
522 |
523 | # v1.0.38 (Fri Oct 04 2019)
524 |
525 | #### 🐛 Bug Fix
526 |
527 | - Add configuration for Typescript support on Storybook, build and Jest [#40](https://github.com/intuit/LD-React-Components/pull/40) ([@josediego](https://github.com/josediego))
528 |
529 | #### Authors: 1
530 |
531 | - Jose Diego ([@josediego](https://github.com/josediego))
532 |
533 | ---
534 |
535 | # v1.0.37 (Fri Oct 04 2019)
536 |
537 | #### ⚠️ Pushed to master
538 |
539 | - testing ignore of gh-pages ([@poorpaddy](https://github.com/poorpaddy))
540 |
541 | #### Authors: 1
542 |
543 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
544 |
545 | ---
546 |
547 | # v1.0.36 (Fri Oct 04 2019)
548 |
549 | #### ⚠️ Pushed to master
550 |
551 | - testing ignore of gh-pages ([@poorpaddy](https://github.com/poorpaddy))
552 |
553 | #### Authors: 1
554 |
555 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
556 |
557 | ---
558 |
559 | # v1.0.35 (Fri Oct 04 2019)
560 |
561 | #### ⚠️ Pushed to master
562 |
563 | - testing ignore of gh-pages ([@poorpaddy](https://github.com/poorpaddy))
564 |
565 | #### Authors: 1
566 |
567 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
568 |
569 | ---
570 |
571 | # v1.0.34 (Fri Oct 04 2019)
572 |
573 | #### ⚠️ Pushed to master
574 |
575 | - testing ignore of gh-pages ([@poorpaddy](https://github.com/poorpaddy))
576 |
577 | #### Authors: 1
578 |
579 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
580 |
581 | ---
582 |
583 | # v1.0.33 (Thu Oct 03 2019)
584 |
585 | #### ⚠️ Pushed to master
586 |
587 | - testing ignore of gh-pages ([@poorpaddy](https://github.com/poorpaddy))
588 |
589 | #### Authors: 1
590 |
591 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
592 |
593 | ---
594 |
595 | # v1.0.32 (Thu Oct 03 2019)
596 |
597 | #### ⚠️ Pushed to master
598 |
599 | - testing ignore of gh-pages ([@poorpaddy](https://github.com/poorpaddy))
600 |
601 | #### Authors: 1
602 |
603 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
604 |
605 | ---
606 |
607 | # v1.0.31 (Thu Oct 03 2019)
608 |
609 | #### ⚠️ Pushed to master
610 |
611 | - testing ignore of gh-pages ([@poorpaddy](https://github.com/poorpaddy))
612 |
613 | #### Authors: 1
614 |
615 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
616 |
617 | ---
618 |
619 | # v1.0.30 (Thu Oct 03 2019)
620 |
621 | #### ⚠️ Pushed to master
622 |
623 | - testing ignore of gh-pages ([@poorpaddy](https://github.com/poorpaddy))
624 | - Merge branch 'master' of https://github.com/intuit/LD-React-Components ([@poorpaddy](https://github.com/poorpaddy))
625 |
626 | #### Authors: 1
627 |
628 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
629 |
630 | ---
631 |
632 | # v1.0.29 (Thu Oct 03 2019)
633 |
634 | #### ⚠️ Pushed to master
635 |
636 | - testing ignore of gh-pages ([@poorpaddy](https://github.com/poorpaddy))
637 |
638 | #### Authors: 1
639 |
640 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
641 |
642 | ---
643 |
644 | # v1.0.28 (Thu Oct 03 2019)
645 |
646 | #### 🐛 Bug Fix
647 |
648 | - Increased code coverage :) [#39](https://github.com/intuit/LD-React-Components/pull/39) ([@Hreherch](https://github.com/Hreherch))
649 |
650 | #### Authors: 1
651 |
652 | - Bennett Hreherchuk ([@Hreherch](https://github.com/Hreherch))
653 |
654 | ---
655 |
656 | # v1.0.27 (Thu Oct 03 2019)
657 |
658 | #### ⚠️ Pushed to master
659 |
660 | - forcing build ([@poorpaddy](https://github.com/poorpaddy))
661 |
662 | #### Authors: 1
663 |
664 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
665 |
666 | ---
667 |
668 | # v1.0.26 (Thu Oct 03 2019)
669 |
670 | #### ⚠️ Pushed to master
671 |
672 | - Add @ggrumbley as a contributor ([@poorpaddy](https://github.com/poorpaddy))
673 |
674 | #### Authors: 1
675 |
676 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
677 |
678 | ---
679 |
680 | # v1.0.25 (Thu Oct 03 2019)
681 |
682 | #### ⚠️ Pushed to master
683 |
684 | - forcing push ([@poorpaddy](https://github.com/poorpaddy))
685 |
686 | #### Authors: 1
687 |
688 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
689 |
690 | ---
691 |
692 | # v1.0.24 (Thu Oct 03 2019)
693 |
694 | #### 🐛 Bug Fix
695 |
696 | - 18 setup docs ci [#31](https://github.com/intuit/LD-React-Components/pull/31) (gary_grumbley@intuit.com [@poorpaddy](https://github.com/poorpaddy))
697 |
698 | #### ⚠️ Pushed to master
699 |
700 | - fixed frozen lock file ([@poorpaddy](https://github.com/poorpaddy))
701 |
702 | #### Authors: 2
703 |
704 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
705 | - gary (gary_grumbley@intuit.com)
706 |
707 | ---
708 |
709 | # v1.0.23 (Thu Oct 03 2019)
710 |
711 | #### ⚠️ Pushed to master
712 |
713 | - Merge branch 'master' of https://github.com/intuit/LD-React-Components ([@poorpaddy](https://github.com/poorpaddy))
714 | - remove storybook directory ([@poorpaddy](https://github.com/poorpaddy))
715 |
716 | #### Authors: 1
717 |
718 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
719 |
720 | ---
721 |
722 | # v1.0.22 (Thu Oct 03 2019)
723 |
724 | #### ⚠️ Pushed to master
725 |
726 | - remove storybook directory ([@poorpaddy](https://github.com/poorpaddy))
727 |
728 | #### Authors: 1
729 |
730 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
731 |
732 | ---
733 |
734 | # v1.0.21 (Thu Oct 03 2019)
735 |
736 | #### ⚠️ Pushed to master
737 |
738 | - remove storybook director ([@poorpaddy](https://github.com/poorpaddy))
739 |
740 | #### Authors: 1
741 |
742 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
743 |
744 | ---
745 |
746 | # v1.0.20 (Thu Oct 03 2019)
747 |
748 | #### ⚠️ Pushed to master
749 |
750 | - troubleshooting docs ([@poorpaddy](https://github.com/poorpaddy))
751 |
752 | #### Authors: 1
753 |
754 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
755 |
756 | ---
757 |
758 | # v1.0.19 (Wed Oct 02 2019)
759 |
760 | #### 🐛 Bug Fix
761 |
762 | - 18 Update CircleCI yaml to build storybook docs [#28](https://github.com/intuit/LD-React-Components/pull/28) (gary_grumbley@intuit.com [@ggrumbley](https://github.com/ggrumbley))
763 | - Adding @ishubhamarora to contributor list [#29](https://github.com/intuit/LD-React-Components/pull/29) (shubham_arora@intuit.com)
764 | - updating ESLinting rules and fixing the linting issues [#27](https://github.com/intuit/LD-React-Components/pull/27) (shubham_arora@intuit.com)
765 | - 18 Add Storybook dependencies [#26](https://github.com/intuit/LD-React-Components/pull/26) (gary_grumbley@intuit.com [@ggrumbley](https://github.com/ggrumbley))
766 |
767 | #### ⚠️ Pushed to master
768 |
769 | - corrected lockfile ([@poorpaddy](https://github.com/poorpaddy))
770 |
771 | #### Authors: 4
772 |
773 | - Shubham Arora ([@ishubhamarora](https://github.com/ishubhamarora))
774 | - poorpaddy ([@poorpaddy](https://github.com/poorpaddy))
775 | - Gary Grumbley ([@ggrumbley](https://github.com/ggrumbley))
776 | - gary (gary_grumbley@intuit.com)
777 |
778 | ---
779 |
780 | # v1.0.18 (Tue Oct 01 2019)
781 |
782 | #### ⚠️ Pushed to master
783 |
784 | - Add @Buranch as a contributor ([@poorpaddy](https://github.com/poorpaddy))
785 | - Add @vvscode as a contributor ([@poorpaddy](https://github.com/poorpaddy))
786 |
787 | #### Authors: 1
788 |
789 | - poorpaddy ([@poorpaddy](https://github.com/poorpaddy))
790 |
791 | ---
792 |
793 | # v1.0.17 (Tue Oct 01 2019)
794 |
795 | #### ⚠️ Pushed to master
796 |
797 | - readme formatting changes (dave_bergschneider@intuit.com)
798 |
799 | #### Authors: 1
800 |
801 | - Bergschneider, Dave (dave_bergschneider@intuit.com)
802 |
803 | ---
804 |
805 | # v1.0.16 (Tue Oct 01 2019)
806 |
807 | #### ⚠️ Pushed to master
808 |
809 | - updated package.json and readme to reflect correct contributor commands. ([@poorpaddy](https://github.com/poorpaddy))
810 |
811 | #### Authors: 1
812 |
813 | - poorpaddy ([@poorpaddy](https://github.com/poorpaddy))
814 |
815 | ---
816 |
817 | # v1.0.15 (Tue Oct 01 2019)
818 |
819 | #### 🐛 Bug Fix
820 |
821 | - Fixing Contribution Generation issue [#24](https://github.com/intuit/LD-React-Components/pull/24) ([@hjaintech](https://github.com/hjaintech))
822 |
823 | #### Authors: 1
824 |
825 | - Harshit Jain ([@hjaintech](https://github.com/hjaintech))
826 |
827 | ---
828 |
829 | # v1.0.13 (Tue Oct 01 2019)
830 |
831 | #### 🐛 Bug Fix
832 |
833 | - updated all dependencies [#21](https://github.com/intuit/LD-React-Components/pull/21) ([@zjael](https://github.com/zjael) dave_bergschneider@intuit.com)
834 |
835 | #### ⚠️ Pushed to master
836 |
837 | - fixes lock file (dave_bergschneider@intuit.com)
838 | - Merge branch 'master' of https://github.com/intuit/LD-React-Components (dave_bergschneider@intuit.com)
839 |
840 | #### Authors: 2
841 |
842 | - Jakob S ([@zjael](https://github.com/zjael))
843 | - Bergschneider, Dave (dave_bergschneider@intuit.com)
844 |
845 | ---
846 |
847 | # v1.0.12 (Fri Sep 27 2019)
848 |
849 | #### 🐛 Bug Fix
850 |
851 | - Update readme badge [#17](https://github.com/intuit/LD-React-Components/pull/17) ([@poorpaddy](https://github.com/poorpaddy))
852 |
853 | #### Authors: 1
854 |
855 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
856 |
857 | ---
858 |
859 | # v1.0.11 (Fri Sep 27 2019)
860 |
861 | #### ⚠️ Pushed to master
862 |
863 | - custom commit message ([@hipstersmoothie](https://github.com/hipstersmoothie))
864 | - fix docs ([@hipstersmoothie](https://github.com/hipstersmoothie))
865 |
866 | #### Authors: 1
867 |
868 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
869 |
870 | ---
871 |
872 | # v1.0.10 (Fri Sep 27 2019)
873 |
874 | #### ⚠️ Pushed to master
875 |
876 | - corrected script name ([@poorpaddy](https://github.com/poorpaddy))
877 |
878 | #### Authors: 1
879 |
880 | - poorpaddy ([@poorpaddy](https://github.com/poorpaddy))
881 |
882 | ---
883 |
884 | # v1.0.9 (Fri Sep 27 2019)
885 |
886 | #### ⚠️ Pushed to master
887 |
888 | - correct json for gh-pages ([@poorpaddy](https://github.com/poorpaddy))
889 | - changed docs publish command ([@poorpaddy](https://github.com/poorpaddy))
890 |
891 | #### Authors: 1
892 |
893 | - poorpaddy ([@poorpaddy](https://github.com/poorpaddy))
894 |
895 | ---
896 |
897 | # v1.0.8 (Fri Sep 27 2019)
898 |
899 | #### ⚠️ Pushed to master
900 |
901 | - Merge branch 'master' of https://github.com/intuit/LD-React-Components ([@poorpaddy](https://github.com/poorpaddy))
902 | - changed docs publish command ([@poorpaddy](https://github.com/poorpaddy))
903 |
904 | #### Authors: 1
905 |
906 | - poorpaddy ([@poorpaddy](https://github.com/poorpaddy))
907 |
908 | ---
909 |
910 | # v1.0.6 (Wed Sep 25 2019)
911 |
912 | #### 🐛 Bug Fix
913 |
914 | - --force for push-dir [#15](https://github.com/intuit/LD-React-Components/pull/15) ([@vvscode](https://github.com/vvscode))
915 |
916 | #### Authors: 1
917 |
918 | - Vasiliy Vanchuk ([@vvscode](https://github.com/vvscode))
919 |
920 | ---
921 |
922 | # v1.0.5 (Mon Sep 23 2019)
923 |
924 | #### ⚠️ Pushed to master
925 |
926 | - NPM Dependencies ` (dave@cmscode.com)
927 |
928 | #### Authors: 1
929 |
930 | - poorpaddy (dave@cmscode.com)
931 |
932 | ---
933 |
934 | # v1.0.3 (Sat Sep 21 2019)
935 |
936 | #### 🐛 Bug Fix
937 |
938 | - Bump version to: 1.0.3 [#13](https://github.com/intuit/LD-React-Components/pull/13) ([@Buranch](https://github.com/Buranch))
939 |
940 | #### Authors: 1
941 |
942 | - Buranch ([@Buranch](https://github.com/Buranch))
943 |
944 | ---
945 |
946 | # v1.0.2 (Sat Sep 21 2019)
947 |
948 | #### 🐛 Bug Fix
949 |
950 | - gh-pages [#12](https://github.com/intuit/LD-React-Components/pull/12) ([@poorpaddy](https://github.com/poorpaddy))
951 |
952 | #### Authors: 1
953 |
954 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
955 |
956 | ---
957 |
958 | # v1.0.1 (Fri Sep 20 2019)
959 |
960 | #### 🐛 Bug Fix
961 |
962 | - re-added gh-pages packages to troubleshoot doc builds [#9](https://github.com/intuit/LD-React-Components/pull/9) ([@poorpaddy](https://github.com/poorpaddy))
963 |
964 | #### Authors: 1
965 |
966 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
967 |
968 | ---
969 |
970 | # v1.0.0 (Fri Sep 20 2019)
971 |
972 | #### 💥 Breaking Change
973 |
974 | - updated npm dependencies and correct package link on npm badge [#6](https://github.com/intuit/LD-React-Components/pull/6) ([@poorpaddy](https://github.com/poorpaddy))
975 |
976 | #### Authors: 1
977 |
978 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
979 |
980 | ---
981 |
982 | # v0.0.10 (Wed Sep 11 2019)
983 |
984 | #### 🐛 Bug Fix
985 |
986 | - feat: update the plugin for the new feature flag payload and update tests [#4](https://github.com/intuit/LD-React-Components/pull/4) ([@Buranch](https://github.com/Buranch))
987 |
988 | #### Authors: 1
989 |
990 | - Buranch ([@Buranch](https://github.com/Buranch))
991 |
992 | ---
993 |
994 | # v0.0.9 (Fri Jul 19 2019)
995 |
996 | #### ⚠️ Pushed to master
997 |
998 | - corrected linting errors (dave@cmscode.com)
999 | - updated dependencies (dave@cmscode.com)
1000 |
1001 | #### Authors: 2
1002 |
1003 | - poorpaddy (dave@cmscode.com)
1004 | - poorpaddu (dave@cmscode.com)
1005 |
1006 | ---
1007 |
1008 | # v0.0.8 (Tue Jun 11 2019)
1009 |
1010 | #### ⚠️ Pushed to master
1011 |
1012 | - updated circleci config (dave_bergschneider@intuit.com)
1013 |
1014 | #### Authors: 1
1015 |
1016 | - Bergschneider, Dave (dave_bergschneider@intuit.com)
1017 |
1018 | ---
1019 |
1020 | # v0.0.7 (Tue Jun 11 2019)
1021 |
1022 | #### 🐛 Bug Fix
1023 |
1024 | - Added contributors section, license and updated some badges [#3](https://github.com/intuit/LD-React-Components/pull/3) ([@poorpaddy](https://github.com/poorpaddy))
1025 |
1026 | #### Authors: 1
1027 |
1028 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
1029 |
1030 | ---
1031 |
1032 | # v0.0.6 (Tue Jun 11 2019)
1033 |
1034 | #### ⚠️ Pushed to master
1035 |
1036 | - initial commit (dave@cmscode.com)
1037 |
1038 | #### Authors: 1
1039 |
1040 | - poorpaddy (dave@cmscode.com)
1041 |
1042 | ---
1043 |
1044 | # v0.0.1 (Mon Jun 10 2019)
1045 |
1046 | #### 🐛 Bug Fix
1047 |
1048 | - Removing intuit [#1](https://github.com/intuit/LD-React-Components/pull/1) ([@poorpaddy](https://github.com/poorpaddy))
1049 |
1050 | #### ⚠️ Pushed to master
1051 |
1052 | - [FP-] - testing docs (dave@cmscode.com)
1053 | - add auto ([@hipstersmoothie](https://github.com/hipstersmoothie))
1054 | - guhhh ([@hipstersmoothie](https://github.com/hipstersmoothie))
1055 | - more debug ([@hipstersmoothie](https://github.com/hipstersmoothie))
1056 | - remove debug info ([@hipstersmoothie](https://github.com/hipstersmoothie))
1057 | - need to build the docs first ([@hipstersmoothie](https://github.com/hipstersmoothie))
1058 | - get rid of unneeded config ([@hipstersmoothie](https://github.com/hipstersmoothie))
1059 | - debug ([@hipstersmoothie](https://github.com/hipstersmoothie))
1060 | - reverted (dave@cmscode.com)
1061 | - testing (dave@cmscode.com)
1062 | - reverting everything back (dave@cmscode.com)
1063 | - another approach (dave@cmscode.com)
1064 | - adding docs to build command (dave@cmscode.com)
1065 | - adding verbose (dave@cmscode.com)
1066 | - testing build and publish of docs (dave@cmscode.com)
1067 | - remved gh-pages from package (dave@cmscode.com)
1068 | - trying gh-pages (dave@cmscode.com)
1069 | - running both scripts (dave@cmscode.com)
1070 | - testing publsih (dave@cmscode.com)
1071 | - adding build command (dave@cmscode.com)
1072 | - reverting my stupid changes (dave@cmscode.com)
1073 | - ensure we can push to github ([@hipstersmoothie](https://github.com/hipstersmoothie))
1074 | - adding build to publish docs step (dave@cmscode.com)
1075 | - testing publish docs (dave@cmscode.com)
1076 | - updated dependencies and ensured both yarn and package lock is available (dave@cmscode.com)
1077 | - fixed tests (dave@cmscode.com)
1078 | - fixed linting (dave@cmscode.com)
1079 | - added clean script (dave@cmscode.com)
1080 | - set public path for dev ([@hipstersmoothie](https://github.com/hipstersmoothie))
1081 | - hmmm ([@hipstersmoothie](https://github.com/hipstersmoothie))
1082 | - nvm ([@hipstersmoothie](https://github.com/hipstersmoothie))
1083 | - set public path for publish ([@hipstersmoothie](https://github.com/hipstersmoothie))
1084 | - set up built docs + publishing ([@hipstersmoothie](https://github.com/hipstersmoothie))
1085 | - audit deps ([@hipstersmoothie](https://github.com/hipstersmoothie))
1086 | - set version to 0 while setting up ([@hipstersmoothie](https://github.com/hipstersmoothie))
1087 | - fix circle link ([@hipstersmoothie](https://github.com/hipstersmoothie))
1088 | - wiped yarn lock file due to intuit registry (dave@cmscode.com)
1089 | - troubleshooting circleci (dave@cmscode.com)
1090 | - now I'm just being silly (dave@cmscode.com)
1091 | - changed to image badge (dave@cmscode.com)
1092 | - added token to badge (dave@cmscode.com)
1093 | - adding circleci badge to readme (dave@cmscode.com)
1094 | - updating a first draft of circleci config (dave@cmscode.com)
1095 |
1096 | #### Authors: 2
1097 |
1098 | - Dave Bergschneider ([@poorpaddy](https://github.com/poorpaddy))
1099 | - Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2019 Intuit
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
15 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
18 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
19 | OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/bot-usage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/intuit/LD-React-Components/2362c78f968b48ec8c8eeb6cea171a296cba15cb/bot-usage.png
--------------------------------------------------------------------------------
/commitlint.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {extends: ['@commitlint/config-conventional']}
2 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Example
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/ld-react-components.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/intuit/LD-React-Components/2362c78f968b48ec8c8eeb6cea171a296cba15cb/ld-react-components.png
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ld-react-components",
3 | "version": "1.0.84",
4 | "description": "Semantic component helpers to support LaunchDarkly in your react app.",
5 | "main": "dist/index.js",
6 | "author": {
7 | "name": "Dave Bergschneider",
8 | "email": "dave@cmscode.com"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "https://github.com/intuit/LD-React-Components"
13 | },
14 | "publishConfig": {
15 | "registry": "https://registry.npmjs.com/"
16 | },
17 | "scripts": {
18 | "start": "start-storybook -p 6010",
19 | "prepare": "npm run snyk-protect && yarn build",
20 | "clean": "rimraf ./dist ./coverage ./docs ./test-results",
21 | "test": "yarn add --dev jest-junit && yarn build && jest --coverage --reporters=default --reporters=jest-junit && mkdir -p test-reports/jest && mv junit.xml test-reports/jest/results.xml",
22 | "lint": "eslint src/",
23 | "build": "babel src/lib -d dist --copy-files && tsc",
24 | "build:watch": "babel src/lib -w -d lib --copy-files",
25 | "docs:build": "build-storybook -o docs",
26 | "docs:config": "mkdirp ./docs/.circleci/ && cp .storybook/config.yml docs/.circleci/ && cp -R .storybook/old-docs docs/",
27 | "docs:publish": "push-dir --cleanup --dir=docs --branch=gh-pages --force",
28 | "release": "auto shipit",
29 | "snyk-protect": "snyk protect"
30 | },
31 | "husky": {
32 | "hooks": {
33 | "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
34 | }
35 | },
36 | "keywords": [
37 | "launch-darkly",
38 | "feature",
39 | "flags",
40 | "react",
41 | "open source"
42 | ],
43 | "license": "MIT",
44 | "devDependencies": {
45 | "@babel/cli": "^7.8.4",
46 | "@babel/core": "^7.9.6",
47 | "@babel/plugin-proposal-class-properties": "^7.8.3",
48 | "@babel/plugin-proposal-object-rest-spread": "^7.9.6",
49 | "@babel/preset-env": "^7.9.6",
50 | "@babel/preset-react": "^7.9.4",
51 | "@babel/preset-typescript": "^7.9.0",
52 | "@commitlint/cli": "^11.0.0",
53 | "@commitlint/config-conventional": "^11.0.0",
54 | "@storybook/addon-a11y": "^6.0.26",
55 | "@storybook/addon-actions": "^6.0.26",
56 | "@storybook/addon-docs": "^6.0.26",
57 | "@storybook/addon-knobs": "^6.0.26",
58 | "@storybook/addon-links": "^6.0.26",
59 | "@storybook/addon-storysource": "^6.0.26",
60 | "@storybook/addons": "^6.0.26",
61 | "@storybook/preset-create-react-app": "^3.1.4",
62 | "@storybook/react": "^6.0.26",
63 | "@types/enzyme": "^3.10.5",
64 | "@types/enzyme-adapter-react-16": "^1.0.5",
65 | "@types/jest": "^24.0.18",
66 | "@types/node": "^12.7.10",
67 | "@types/react": "^16.9.4",
68 | "@types/react-dom": "^16.9.1",
69 | "@types/storybook__react": "^5.2.1",
70 | "all-contributors-cli": "^6.14.2",
71 | "auto": "^9.34.1",
72 | "awesome-typescript-loader": "^5.2.1",
73 | "babel-eslint": "^10.1.0",
74 | "babel-jest": "^26.0.1",
75 | "babel-loader": "^8.1.0",
76 | "chai": "^4.2.0",
77 | "concurrently": "^5.2.0",
78 | "css-loader": "^3.5.3",
79 | "enzyme": "^3.11.0",
80 | "enzyme-adapter-react-16": "^1.15.2",
81 | "eslint": "^7.0.0",
82 | "eslint-config-airbnb": "^18.1.0",
83 | "eslint-config-prettier": "^6.11.0",
84 | "eslint-config-standard": "~14.1.1",
85 | "eslint-plugin-import": "^2.20.2",
86 | "eslint-plugin-jsx-a11y": "^6.2.3",
87 | "eslint-plugin-node": "~11.1.0",
88 | "eslint-plugin-prettier": "^3.1.3",
89 | "eslint-plugin-promise": "~4.2.1",
90 | "eslint-plugin-react": "^7.20.0",
91 | "eslint-plugin-standard": "~4.0.1",
92 | "expect": "^26.0.1",
93 | "gh-pages": "^2.2.0",
94 | "html-webpack-plugin": "^4.3.0",
95 | "husky": "^4.3.0",
96 | "jest": "^26.0.1",
97 | "jest-junit": "^12.0.0",
98 | "jsdom": "16.2.2",
99 | "jsdom-global": "3.0.2",
100 | "mkdirp": "^1.0.4",
101 | "mocha": "^7.1.2",
102 | "nyc": "^15.0.1",
103 | "prettier": "^2.0.5",
104 | "push-dir": "^0.4.1",
105 | "react": "^16.10.1",
106 | "react-docgen-typescript-loader": "^3.7.2",
107 | "react-dom": "^16.3.2",
108 | "react-hot-loader": "^4.12.21",
109 | "react-scripts": "^3.4.3",
110 | "react-test-renderer": "^16.13.1",
111 | "sinon": "^9.0.2",
112 | "source-map-loader": "^0.2.4",
113 | "style-loader": "^1.2.1",
114 | "ts-jest": "^26.0.0",
115 | "typescript": "^3.9.3",
116 | "webpack": "^4.43.0",
117 | "webpack-cli": "^3.3.11",
118 | "webpack-dev-server": "^3.11.0"
119 | },
120 | "dependencies": {
121 | "hash.js": "~1.1.7",
122 | "ldclient-js": "^2.10.2",
123 | "prop-types": "^15.7.2",
124 | "snyk": "^1.518.0"
125 | },
126 | "peerDependencies": {
127 | "react": "^16.13.1",
128 | "react-dom": "^16.13.1"
129 | },
130 | "snyk": true
131 | }
132 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 |
2 |
4 |
LD React Components
5 |
Semantic component helpers to support LaunchDarkly in your react app.
6 |
7 |
8 | [](https://circleci.com/gh/intuit/LD-React-Components)
9 | [](https://codecov.io/gh/intuit/LD-React-Components)
10 | [](#contributors)
11 | [](https://www.npmjs.com/package/ld-react-components)
12 | [](https://www.npmjs.com/package/ld-react-components)
13 | [](https://app.snyk.io/org/poorpaddy/project/c1415dab-3e6f-4438-8e73-26a3e5ce9f55)
14 | [](https://app.fossa.com/projects/git%2Bgithub.com%2Fintuit%2FLD-React-Components?ref=badge_shield)
15 | [](https://github.com/intuit/LD-React-Components)
16 | [](https://intuit.github.io/LD-React-Components/)
17 |
18 |
19 | ## Usage
20 |
21 | Install node module
22 |
23 | You can use `npm` or `yarn` however it is advised to choose one and stick with it. For the purposes of documentation `yarn` is being used.
24 |
25 | ```shell
26 | yarn add ld-react-components
27 | ```
28 |
29 | ### Importing the components
30 |
31 | ```js
32 | import {
33 | FeatureFlag,
34 | FeatureSwitch,
35 | FeatureCase,
36 | FeatureTrue,
37 | FeatureFalse
38 | } from 'ld-react-components';
39 | ```
40 |
41 | #### API initialization
42 |
43 | ```js
44 | this._ldclientPromise = launchDarklyClient.initWithPromise(
45 | user,
46 | this._sdkKey,
47 | 500
48 | );
49 |
50 | const endpoints = {
51 | baseUrl: 'https://app.launchdarkly.com',
52 | eventsUrl: 'https://events.launchdarkly.com',
53 | streamUrl: 'https://stream.launchdarkly.com',
54 | baseTimeout: 100
55 | };
56 |
57 | this._ldclientPromise = launchDarklyClient.initWithPromise(
58 | user,
59 | this._sdkKey,
60 | endpoints,
61 | 500
62 | );
63 | ```
64 |
65 | ### FeatureFlag
66 |
67 | Takes `flagKey` and `appFlags` as `props`, which is an object containing list of features.
68 |
69 | ```jsx
70 | const applicationKeys = {
71 | 'integration-test': { value: true, version: 3 },
72 | 'multivariate-test': { value: 'multivariate-test-1', version: 5 }
73 | }
74 |
75 | ```
76 |
77 | ### FeatureSwitch, FeatureCase and FeatureDefault
78 |
79 | `FeatureSwitch` should be a child of `FeatureFlag` and can take `FeatureCase` and `FeatureDefault` as children.
80 |
81 | `FeatureCase` component takes `condition` and `allowBreak`(a boolean) as props,
82 | `condition` is the `case` feature, while `allowBreak` used as a `break`. The reason for name change is `case` and `break` are reserved words on JS.
83 |
84 | ```jsx
85 |
86 |
87 |
88 | Multivariate Test 1 Rendered
89 |
90 |
91 | Multivariate Test 2 Rendered
92 |
93 |
94 | Multivariate Test 3 Rendered
95 |
96 |
97 | Multivariate Test 4 Rendered
98 |
99 |
100 | If no conditions are met then render the default
101 |
102 |
103 |
104 | ```
105 |
106 | ### FeatureTrue and FeatureFalse
107 |
108 | ```jsx
109 |
110 |
111 | If feature flag is true, then is content will render.
112 |
113 |
114 | If feature flag is false, then is content will render.
115 |
116 |
117 | ```
118 |
119 | ### Another Use Case
120 |
121 | ```js
122 | const applicationKeys = {
123 | 'multivariate-test': { value: 'multivariate-test-2', version: 1},
124 | 'integration-test': { value: true }
125 | };
126 | ```
127 |
128 | ```jsx
129 |
130 | This non-component should get rendered
131 | This is also should get rendered.
132 | This one should throw a warning and wont be rendred
133 |
134 | this one should throw a warning and wont be rendred
135 |
136 |
137 |
138 | This one should throw an error and wont be rendred
139 |
140 |
141 |
142 | ```
143 |
144 | ### Nested FeatureFlag
145 |
146 | ```js
147 | const applicationKeys = {
148 | 'multivariate-test': { value: 'multivariate-test-2' },
149 | 'integration-test': { value: true }
150 | };
151 | ```
152 |
153 | ```jsx
154 |
155 | This non-component will get rendered
156 |
157 |
158 |
159 | Multivariate Test 1 Rendered
160 |
161 |
162 | This one will get rendered(Multivariate Test 2 Rendered)
163 |
164 |
165 | Multivariate Test 3 Rendered
166 |
167 |
168 | This is the default content if no other cases are matched.
169 |
170 |
171 |
172 |
173 | ```
174 |
175 | ## Using the React Hooks
176 |
177 | ```jsx
178 | const appFlags = {
179 | a: { value: 'a' },
180 | b: { value: 'b' },
181 | c: { value: 'c' },
182 | d: { value: 'd' },
183 | e: { value: 'e' }
184 | };
185 |
186 | const UsingHooks = () => {
187 | const [count, setCount] = useState(65);
188 | return (
189 |
190 | setCount(count + 1)}>Add count
191 |
195 |
196 |
197 | A is being rendered
198 |
199 |
200 | B is being rendered
201 |
202 |
203 | C is being rendered
204 |
205 |
206 | D is being rendered
207 |
208 |
209 | E is being rendered
210 |
211 | No value matches, this is default
212 |
213 |
214 |
215 | );
216 | };
217 | ```
218 |
219 | ## Using the API
220 |
221 | ### Importing
222 |
223 | ```js
224 | import launchDarklyClient from 'ld-react-components/API';
225 |
226 | const endpoints = {
227 | baseUrl: 'https://app.launchdarkly.com',
228 | eventsUrl: 'https://events.launchdarkly.com',
229 | streamUrl: 'https://stream.launchdarkly.com',
230 | baseTimeout: 100
231 | };
232 | this._ldclientPromise = launchDarklyClient.initWithPromise(user, this._sdkKey, endpoints, 500);
233 |
234 | getFeatureFlag(featureId, defaultValue = false) {
235 | if (typeof window !== 'undefined') {
236 | return new Promise((resolve, reject) => {
237 | this._ldclientPromise
238 | .then((client) => {
239 | resolve(client.getFeatureFlag(featureId, defaultValue));
240 | })
241 | .catch((error) => {
242 | reject(error);
243 | });
244 | });
245 | }
246 | }
247 | ```
248 |
249 | ## For development
250 |
251 | ### For the API
252 |
253 | #### Testing
254 |
255 | ```shell
256 | yarn
257 | yarn test
258 | ```
259 |
260 | ### For React
261 |
262 | The module includes a demo demonstrating how to use the components
263 |
264 | ```shell
265 | yarn
266 | yarn dev
267 | ```
268 |
269 | To see the demo go to http://localhost:8080
270 |
271 | ## Contributors ✨
272 |
273 |
274 |
275 |
276 |
308 |
309 |
310 |
311 |
312 | Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
313 |
314 |
315 |
316 |
317 |
318 | This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
319 |
320 |
321 |
322 |
323 | ### Adding a Contributor
324 |
325 | To add a contributor comment on Issue or Pull Request, asking @all-contributors to add a contributor:
326 | Example: `@all-contributors please add for `
327 | **`:`** See the [Emoji Key (Contribution Types Reference)](https://allcontributors.org/docs/en/emoji-key) for a list of valid contribution types.
328 |
329 | The bot will then create a Pull Request to add the contributor, then reply with the pull request details.
330 |
331 |
332 |
333 | ## License
334 |
335 | [](https://app.fossa.com/projects/git%2Bgithub.com%2Fintuit%2FLD-React-Components?ref=badge_large)
336 |
--------------------------------------------------------------------------------
/src/lib/FeatureCase/index.ts:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | /**
3 | * FeatureCase
4 | */
5 | function FeatureCase(props) {
6 | const { children } = props;
7 | return React.Children.map(children, child => child);
8 | }
9 |
10 | export default FeatureCase;
11 |
--------------------------------------------------------------------------------
/src/lib/FeatureDefault/index.ts:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | /**
3 | * FeatureDefault
4 | */
5 | function FeatureDefault(props) {
6 | const { children } = props;
7 | return React.Children.map(children, child => child);
8 | }
9 |
10 | export default FeatureDefault;
11 |
--------------------------------------------------------------------------------
/src/lib/FeatureFalse/index.ts:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | /**
3 | * FeatureFalse
4 | */
5 | function FeatureFalse(props) {
6 | const { children } = props;
7 | return React.Children.map(children, child => child);
8 | }
9 |
10 | export default FeatureFalse;
11 |
--------------------------------------------------------------------------------
/src/lib/FeatureFlag/FeatureFlag.stories.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { withKnobs, text, object } from '@storybook/addon-knobs';
3 |
4 | import FeatureFlag from './index.tsx';
5 | import FeatureSwitch from '../FeatureSwitch';
6 | import FeatureCase from '../FeatureCase';
7 | import FeatureDefault from '../FeatureDefault';
8 | import FeatureTrue from '../FeatureTrue';
9 | import FeatureFalse from '../FeatureFalse';
10 |
11 | import notes from './README.md';
12 |
13 | export default {
14 | title: 'Component|Feature Flag',
15 | decorators: [withKnobs],
16 | component: FeatureFlag,
17 | parameters: { notes }
18 | };
19 |
20 | const applicationKeys = {
21 | 'integration-test': true,
22 | 'multivariate-test': 'multivariate-test-1'
23 | };
24 |
25 | export const standardUsage = () => (
26 |
30 |
31 |
32 | Multivariate Test 1 Rendered
33 |
34 |
35 | Multivariate Test 2 Rendered
36 |
37 |
38 | Multivariate Test 3 Rendered
39 |
40 |
41 | Multivariate Test 4 Rendered
42 |
43 |
44 | If no conditions are met then render the default
45 |
46 |
47 |
48 | );
49 |
50 | export const withFeatureTrueAndFeatureFalse = () => (
51 |
52 | Output: FeatureTrue being rendered
53 | Output: FeatureFalse being rendered
54 |
55 | );
56 |
57 | export const withNesting = () => {
58 | const flags = {
59 | 'nested-flag-key': 'nested-flag-key-1'
60 | };
61 | return (
62 |
63 |
64 | A non-component (in this case, a p tag) is being rendered, under the parent FeatureFlag
65 | component. Check out the story below to see the code.
66 |
67 |
68 |
69 |
70 | Nested feature 1 Rendered
71 |
72 |
73 | Nested feature 2 Rendered
74 |
75 |
76 | Nested feature 3 Rendered
77 |
78 |
79 | This is the default content if no other cases are matched.
80 |
81 |
82 |
83 |
84 | );
85 | };
86 |
--------------------------------------------------------------------------------
/src/lib/FeatureFlag/README.md:
--------------------------------------------------------------------------------
1 | ### FeatureFlag
2 |
3 | Takes `flagKey` and `appFlags` as `props`, which is an object containing list of features.
4 |
5 | ### FeatureSwitch, FeatureCase and FeatureDefault
6 |
7 | `FeatureSwitch` should be a child of `FeatureFlag` and can take `FeatureCase` and `FeatureDefault` as children.
8 |
9 | `FeatureCase` component takes `condition` and `allowBreak`(a boolean) as props,
10 | `condition` is the `case` feature, while `allowBreak` used as a `break`. The reason for name change is `case` and `break` are reserved words on JS.
--------------------------------------------------------------------------------
/src/lib/FeatureFlag/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | /**
4 | * FeatureFlag
5 | */
6 | function FeatureFlag(props) {
7 | const { children, flagKey, appFlags } = props;
8 | // isChildPluginComponent is true if the child is one of
9 | // [ FeatureFlag, FeatureTrue, FeatureSwitch, FeatureFalse, FeatureDefault]
10 | let isChildPluginComponent = false;
11 | // isNonPluginComponent is true if the child is not a component from this plugin.
12 | let isNonPluginComponent = false;
13 | // childArray to render
14 | const childArray = [];
15 | React.Children.forEach(children, (element) => {
16 | if (
17 | React.isValidElement(element) &&
18 | (element.type.displayName === 'FeatureTrue' || element.type.name === 'FeatureTrue')
19 | ) {
20 | if (isNonPluginComponent) {
21 | // telling the developer to not use NonPlugin components under FeatureFlag.
22 | // eslint-disable-next-line no-console
23 | console.warn(
24 | 'Dont Use among other elements/components under only use it with , No mix allowed'
25 | );
26 | return;
27 | }
28 | // if the appFlags has the flagKey, render the child
29 | if (appFlags[flagKey]) {
30 | childArray.push(element);
31 | }
32 | isChildPluginComponent = true;
33 | }
34 |
35 | if (
36 | React.isValidElement(element) &&
37 | (element.type.displayName === 'FeatureFalse' || element.type.name === 'FeatureFalse')
38 | ) {
39 | if (isNonPluginComponent) {
40 | // eslint-disable-next-line no-console
41 | console.warn(
42 | 'Dont Use among other elements/components under only use it with , No mix allowed'
43 | );
44 | return;
45 | }
46 | if (!appFlags[flagKey]) {
47 | childArray.push(element);
48 | }
49 | isChildPluginComponent = true;
50 | }
51 | // }
52 |
53 | if (
54 | React.isValidElement(element) &&
55 | (element.type.displayName === 'FeatureSwitch' || element.type.name === 'FeatureSwitch')
56 | ) {
57 | if (isNonPluginComponent) {
58 | // eslint-disable-next-line no-console
59 | console.warn(
60 | 'Dont Use unless its the immediate children of , No mix allowed'
61 | );
62 | return;
63 | }
64 | childArray.push(
65 | React.cloneElement(element, {
66 | flagKey,
67 | appFlags
68 | })
69 | );
70 | isChildPluginComponent = true;
71 | }
72 | // if the component is neither of the above components it must be NonPlugin Component,
73 | // therefore, we simply render it as its under FeatureTrue
74 | if (!isChildPluginComponent) {
75 | isNonPluginComponent = true;
76 | if (appFlags[flagKey]) {
77 | childArray.push(element);
78 | }
79 | }
80 | });
81 |
82 | return React.Children.map(childArray, (child) => child);
83 | }
84 |
85 | FeatureFlag.propTypes = {
86 | flagKey: PropTypes.string.isRequired,
87 | // eslint-disable-next-line react/forbid-prop-types
88 | appFlags: PropTypes.object.isRequired
89 | };
90 |
91 | export default FeatureFlag;
92 |
--------------------------------------------------------------------------------
/src/lib/FeatureFlag/index.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | /**
4 | * FeatureFlag Props
5 | */
6 | type FeatureFlagProps = {
7 | children?: React.ReactNode;
8 | flagKey: string;
9 | appFlags: object;
10 | }
11 |
12 | /**
13 | * FeatureFlag renders your child components based on LD flags
14 | */
15 | function FeatureFlag({ children, flagKey, appFlags }: FeatureFlagProps) {
16 | function elementMatchPluginName(element: any, name: string) {
17 | return (element.type.displayName === name || element.type.name === name)
18 | }
19 | // isChildPluginComponent is true if the child is one of
20 | // [ FeatureFlag, FeatureTrue, FeatureSwitch, FeatureFalse, FeatureDefault]
21 | let isChildPluginComponent = false;
22 | // isNonPluginComponent is true if the child is not a component from this plugin.
23 | let isNonPluginComponent = false;
24 | // childArray to render
25 | const childArray: React.ReactNode[] = [];
26 | React.Children.forEach(children, element => {
27 | if (
28 | React.isValidElement(element) && elementMatchPluginName(element, 'FeatureTrue')
29 | ) {
30 | if (isNonPluginComponent) {
31 | // telling the developer to not use NonPlugin components under FeatureFlag.
32 | // eslint-disable-next-line no-console
33 | console.warn(
34 | 'Dont Use among other elements/components under only use it with , No mix allowed'
35 | );
36 | return;
37 | }
38 | // if the appFlags has the flagKey, render the child
39 | if (appFlags[flagKey]) {
40 | childArray.push(element);
41 | }
42 | isChildPluginComponent = true;
43 | }
44 |
45 | if (
46 | React.isValidElement(element) && elementMatchPluginName(element, 'FeatureFalse')
47 | ) {
48 | if (isNonPluginComponent) {
49 | // eslint-disable-next-line no-console
50 | console.warn(
51 | 'Dont Use among other elements/components under only use it with , No mix allowed'
52 | );
53 | return;
54 | }
55 | if (!appFlags[flagKey]) {
56 | childArray.push(element);
57 | }
58 | isChildPluginComponent = true;
59 | }
60 | // }
61 |
62 | if (
63 | React.isValidElement(element) && elementMatchPluginName(element, 'FeatureSwitch')
64 | ) {
65 | if (isNonPluginComponent) {
66 | // eslint-disable-next-line no-console
67 | console.warn(
68 | 'Dont Use unless its the immediate children of , No mix allowed'
69 | );
70 | return;
71 | }
72 | const partial: Partial<{}> = {};
73 | partial['flagKey'] = flagKey;
74 | partial['appFlags'] = appFlags;
75 | childArray.push(
76 | React.cloneElement(element, partial)
77 | );
78 | isChildPluginComponent = true;
79 | }
80 | // if the component is neither of the above components it must be NonPlugin Component,
81 | // therefore, we simply render it as its under FeatureTrue
82 | if (!isChildPluginComponent) {
83 | isNonPluginComponent = true;
84 | if (appFlags[flagKey]) {
85 | childArray.push(element);
86 | }
87 | }
88 | });
89 |
90 | return React.Children.map(childArray, child => child);
91 | }
92 |
93 | export default FeatureFlag;
--------------------------------------------------------------------------------
/src/lib/FeatureSwitch/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import FeatureCase from '../FeatureCase';
3 | import FeatureDefault from '../FeatureDefault';
4 |
5 | interface IAppFlag {
6 | value: any,
7 | version: number,
8 | variation: number,
9 | trackEvents: boolean
10 | }
11 |
12 | interface IComponentProps {
13 | flagKey: string;
14 | appFlags: {
15 | [x: string]: IAppFlag;
16 | };
17 | }
18 |
19 | /**
20 | * FeatureSwitch
21 | */
22 | const FeatureSwitch: React.FC = (props) => {
23 | const { children, flagKey, appFlags } = props;
24 |
25 | const childArray: React.ReactNode[] = [];
26 |
27 | let breakIt = false;
28 |
29 | React.Children.forEach(children, element => {
30 | // if the Component is FeatureCase and break is false, compare the feature flag and render the element if its true
31 | if (React.isValidElement(element) && (element as any).type === FeatureCase && !breakIt) {
32 | // TODO use proper type cast here once they are defined
33 | const { condition, allowBreak } = (element as any).props;
34 | if (appFlags[flagKey] === condition) {
35 | childArray.push(element);
36 | breakIt = allowBreak;
37 | }
38 | }
39 | // if its Default and it is not breaked yet, render the element.
40 | if (React.isValidElement(element) && (element as any).type === FeatureDefault && !breakIt) {
41 | childArray.push(element);
42 | }
43 | });
44 |
45 | return {childArray} ;
46 | };
47 |
48 | export default FeatureSwitch;
49 |
--------------------------------------------------------------------------------
/src/lib/FeatureTrue/index.ts:
--------------------------------------------------------------------------------
1 | import React, { ReactNode } from 'react';
2 | /**
3 | * FeatureTrue
4 | */
5 |
6 | type FeatureTrueProps = {
7 | children: ReactNode
8 | }
9 |
10 | const FeatureTrue = ({ children }: FeatureTrueProps) => React.Children.map(children, (child: ReactNode) => child);
11 |
12 | export default FeatureTrue;
13 |
--------------------------------------------------------------------------------
/src/lib/LaunchDarklyClient/index.ts:
--------------------------------------------------------------------------------
1 | import hash from 'hash.js';
2 | import * as LDClient from 'ldclient-js';
3 |
4 | interface IUser extends LDClient.LDUser {
5 | authId: string
6 | }
7 | interface IOptions extends LDClient.LDOptions {
8 | baseTimeout: number
9 | }
10 | interface IClientParams {
11 | user: IUser
12 | envClientKey: string
13 | options: IOptions
14 | }
15 | interface IInitParams {
16 | clientParams: IClientParams
17 | timeout: number
18 | logUpdates?: boolean
19 | }
20 |
21 |
22 | class LDApi {
23 |
24 | private ldClient: LDClient.LDClient;
25 | private readonly env: String;
26 |
27 | constructor(env: string) {
28 | this.env = env;
29 | }
30 |
31 | init({clientParams:{user, envClientKey, options}, timeout, logUpdates=false}: IInitParams) {
32 | // makes the flags available to the client
33 | this.ldClient = this.createClient({user, envClientKey, options});
34 | if (!options) {
35 | // eslint-disable-next-line no-console
36 | return console.log('Endpoint Options is not provided');
37 | }
38 | // returns the library and it's methods to use outside of the module
39 | // eslint-disable-next-line no-param-reassign
40 | this.handleEvents((timeout = options.baseTimeout), this.ldClient, logUpdates);
41 | return this;
42 | }
43 |
44 | /**
45 | * Initializes the launch darkly client and returns a promise to ensure that
46 | * methods won't be called until the client emits the 'ready' event
47 | */
48 | initWithPromise({clientParams:{user, envClientKey, options}, timeout, logUpdates=false}: IInitParams): Promise {
49 | this.ldClient = this.createClient({user, envClientKey, options});
50 |
51 | return new Promise((resolve, reject) => {
52 | return this.handleEvents(timeout, this.ldClient, logUpdates, resolve, reject);
53 | });
54 | }
55 |
56 | /**
57 | * Create the LD client
58 | *
59 | * @param user user object
60 | * @param envClientKey SDK key for the env
61 | * @returns {LDClient.LDClient} fresh instance of launch darkly client
62 | */
63 | createClient({user, envClientKey, options}: IClientParams): LDClient.LDClient {
64 | if (typeof user.authId === 'undefined') {
65 | throw new Error('AuthId was not passed to launchDarkly client');
66 | }
67 |
68 | if (!envClientKey) {
69 | throw new Error('There was no environment key provided.');
70 | }
71 |
72 | const ldUser = {
73 | key: hash
74 | .sha256()
75 | .update(user.authId)
76 | .digest('hex'),
77 | custom: {}
78 | };
79 |
80 | // take whatever is in the tags object and put it into the user object
81 | /* eslint-disable no-restricted-syntax, guard-for-in */
82 | // TO-DO: check if inherited properties of obj 'user' has to iterated or not
83 | // and remove these eslint-disable as per that.
84 | for (const key in user) {
85 | let userKey = key;
86 | if (key.indexOf('_') > -1) {
87 | userKey = key.replace('_', '');
88 | }
89 |
90 | if (key === 'authId') {
91 | // eslint-disable-next-line no-param-reassign
92 | user[key] = hash
93 | .sha256()
94 | .update(user[key])
95 | .digest('hex');
96 | }
97 |
98 | ldUser.custom[userKey] = user[key];
99 | }
100 | /* eslint-enable */
101 |
102 | return this.env === 'test'
103 | ? LDClient.default.initialize(envClientKey, ldUser, options)
104 | : LDClient.initialize(envClientKey, ldUser, options);
105 | }
106 |
107 | /**
108 | * LD client posts events. This function handles them.
109 | * First set a timeout for the ready event.
110 | * If it takes too long time out.
111 | * Log updates when they happen
112 | *
113 | * @param timeout LD client timeout
114 | * @param ldClient initialized client
115 | * @param logUpdates Set to true if you want to see the update events
116 | */
117 | // eslint-disable-next-line no-unused-vars
118 | handleEvents(timeout:number, ldClient:LDClient.LDClient, logUpdates = false, resolve?, reject?) {
119 | if (ldClient === undefined) {
120 | const error = new Error('ERROR: ldClient is undefined');
121 | if (reject !== undefined) {
122 | return reject(error);
123 | }
124 | throw error;
125 | }
126 |
127 | const initTimeout = setTimeout(() => {
128 | clearTimeout(initTimeout);
129 | const error = new Error('ERROR: Creation of Launch Darkly client has timed out');
130 | if (reject !== undefined) {
131 | return reject(error);
132 | }
133 | throw error;
134 | }, timeout);
135 |
136 | ldClient.on('error', error => {
137 | if (reject !== undefined) {
138 | return reject(error);
139 | }
140 | throw error;
141 | });
142 |
143 | ldClient.on('ready', () => {
144 | clearTimeout(initTimeout);
145 |
146 | if (resolve !== undefined) {
147 | return resolve(this);
148 | }
149 | return undefined;
150 | });
151 | return undefined;
152 | }
153 |
154 | /**
155 | * Grab the feature flag value. If the LD client does not exist return the default
156 | * value.
157 | *
158 | * @param featureId LD feature flag id
159 | * @param defaultValue boolean value that is the default (this is used we can get the feature flag from LD)
160 | * @returns {any} Value of feature flag. Flags can be boolean or enums, depending on their configuration
161 | */
162 | getFeatureFlag(featureId: string, defaultValue: boolean) {
163 | if (defaultValue === undefined) {
164 | throw new Error('Default value must be passed to getPromiseFeatureFlag');
165 | }
166 | if (!this.ldClient) {
167 | return defaultValue;
168 | }
169 | // eslint-disable-next-line no-console
170 | console.log('featureId ', featureId);
171 | if (!featureId) {
172 | throw new Error('ERROR: featureId is undefined');
173 | }
174 | return this.ldClient.variation(featureId, defaultValue);
175 | }
176 |
177 | /**
178 | * Grab the feature flag value resolved as a Promise If the LD client does not exist return the default
179 | * value.
180 | *
181 | * @param featureFlag LD feature flag id
182 | * @param defaultValue boolean value (this is used we can get the feature flag from LD)
183 | * @returns {Promise} Value of feature flag as a promise.
184 | * Flags can be boolean or enums, depending on their configuration
185 | */
186 | getPromiseFeatureFlag(featureFlag: string, defaultValue: boolean): Promise {
187 | return new Promise(resolve => {
188 | resolve(this.getFeatureFlag(featureFlag, defaultValue));
189 | });
190 | }
191 |
192 | /**
193 | * Grab All feature flags for the user. If the LD client does not exist, return the default
194 | * value.
195 | *
196 | * @returns {LDClient.LDFlagSet} Value of feature flags. Flags can be boolean or enums, depending on their configuration
197 | */
198 |
199 | getAllFlags(): LDClient.LDFlagSet {
200 | if (!this.ldClient) {
201 | return {};
202 | }
203 |
204 | return this.ldClient.allFlags();
205 | }
206 | }
207 |
208 | module.exports = LDApi;
209 |
--------------------------------------------------------------------------------
/src/lib/index.js:
--------------------------------------------------------------------------------
1 | import FeatureDefault from './FeatureDefault';
2 | import FeatureTrue from './FeatureTrue';
3 | import FeatureSwitch from './FeatureSwitch';
4 | import FeatureCase from './FeatureCase';
5 | import FeatureFalse from './FeatureFalse';
6 | import FeatureFlag from './FeatureFlag';
7 | import launchDarklyClient from './LaunchDarklyClient';
8 |
9 | module.exports = {
10 | FeatureDefault,
11 | FeatureTrue,
12 | FeatureSwitch,
13 | FeatureFalse,
14 | FeatureFlag,
15 | FeatureCase,
16 | launchDarklyClient
17 | };
18 |
--------------------------------------------------------------------------------
/test-reports/jest/results.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/test/__snapshots__/react.test.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Launch Darkly Plugin FeatureFlag: should not render component if flagKey does not exist in appFlags object 1`] = `""`;
4 |
5 | exports[`Launch Darkly Plugin FeatureFlag: should not render component if flagKey value is false in appFlags object 1`] = `""`;
6 |
7 | exports[`Launch Darkly Plugin FeatureFlag: should not render either FeatureTrue or FeatureFalse when it gets mixed with NonPluginElement and should throw a warnring 1`] = `
8 | "
9 | Non Plugin Element
10 |
"
11 | `;
12 |
13 | exports[`Launch Darkly Plugin FeatureFlag: should not render the FeatureSwitch and throw a warning when FeatureSwitch gets mixed with NonPlugin elements 1`] = `
14 | "
15 |
16 | Hello
17 |
18 | "
19 | `;
20 |
21 | exports[`Launch Darkly Plugin FeatureFlag: should render component if flagKey value is true in appFlags object 1`] = `
22 | "
23 | hello
24 |
"
25 | `;
26 |
27 | exports[`Launch Darkly Plugin FeatureFlag: should render only the FeatureFalse when flagKey value is false 1`] = `
28 | "
29 |
30 |
31 | Gets rendered when flagKey value is false
32 |
33 |
34 | "
35 | `;
36 |
37 | exports[`Launch Darkly Plugin FeatureFlag: should render only the FeatureTrue when flagKey value is true 1`] = `
38 | "
39 |
40 |
41 | Gets rendered when flagKey value is true
42 |
43 |
44 | "
45 | `;
46 |
47 | exports[`Launch Darkly Plugin FeatureSwitch: renders the FeatureCase component that matches the flagKey 1`] = `
48 | "
49 |
50 |
51 |
52 | Multivariate Test 1 Rendered
53 |
54 |
55 |
56 | "
57 | `;
58 |
59 | exports[`Launch Darkly Plugin FeatureSwitch: renders the FeatureDefault component when the no FeatureCase found that matches the flagKey 1`] = `
60 | "
61 |
62 |
63 |
64 | If no conditions are met then render the default
65 |
66 |
67 |
68 | "
69 | `;
70 |
--------------------------------------------------------------------------------
/test/main.test.js:
--------------------------------------------------------------------------------
1 | import sinon from 'sinon';
2 | import { expect } from 'chai';
3 | import LDClient from 'ldclient-js';
4 | import LDApi from '../src/lib/LaunchDarklyClient';
5 |
6 | const config = {
7 | environment: 'development',
8 | features: {
9 | default: {
10 | client_key: 'somekey'
11 | },
12 | development: {
13 | client_key: 'somekey'
14 | },
15 | user: {
16 | key: 'test_user'
17 | },
18 | timeout: 500
19 | }
20 | };
21 |
22 | const options = {
23 | baseUrl: 'https://app.launchdarkly.com',
24 | eventsUrl: 'https://events.launchdarkly.com',
25 | streamUrl: 'https://stream.launchdarkly.com',
26 | baseTimeout: 100
27 | };
28 |
29 | // mock values to return from mocked functions
30 | const featureValue = true;
31 |
32 | const flags = {
33 | 'forms-mode': false,
34 | 'other-forms-mode': false
35 | };
36 |
37 | const user = { authId: 'ode_user', country: 'USA' };
38 |
39 | const envClientKey = '59x74xxxx9x1x30x6x0x3xxx';
40 |
41 | // mock func to init launch darkly
42 | // let ldInit = () => {};
43 | let ldClient;
44 |
45 | const variation = () => featureValue;
46 |
47 | // Call the callback after 250ms to simulate the delay launch darkly has
48 | const on = (event, cb) => {
49 | setTimeout(() => {
50 | if (event === 'ready') {
51 | cb();
52 | }
53 | }, 10);
54 | };
55 |
56 | const allFlags = () => flags;
57 |
58 | const errorMessage = 'ERROR: Creation of Launch Darkly client has timed out';
59 | const timeout = 500;
60 |
61 | describe('Launch Darkly:', () => {
62 | beforeEach(() => {
63 | ldClient = sinon.stub(LDClient, 'initialize').callsFake(() => {
64 | return {
65 | allFlags,
66 | variation,
67 | on
68 | };
69 | });
70 | });
71 |
72 | afterEach(() => {
73 | if (ldClient !== undefined) {
74 | ldClient.restore();
75 | }
76 | });
77 |
78 | it('init', () => {
79 | const ldApi = new LDApi('test');
80 | const client = ldApi.init({clientParams:{user, envClientKey, options}, timeout});
81 | expect(client !== undefined).to.equal(true);
82 | });
83 |
84 | it('init without option should throw warning', () => {
85 | const ldApi = new LDApi('test');
86 | const client = ldApi.init({clientParams:{user, envClientKey, options:null}, timeout});
87 | console.log('client on without ', client);
88 | expect(client === undefined).to.equal(true);
89 | });
90 |
91 | it('initPromise', done => {
92 | const ldApi = new LDApi('test');
93 |
94 | ldApi.initWithPromise({clientParams:{user, envClientKey, options}, timeout}).then(client => {
95 | expect(client !== undefined).to.equal(true);
96 | done();
97 | });
98 | });
99 |
100 | it('createClient', done => {
101 | const ldApi = new LDApi('test');
102 |
103 | const client = ldApi.createClient({user, envClientKey, options});
104 | expect(client !== undefined).to.equal(true);
105 | done();
106 | });
107 |
108 | it('createClient accepts underscored user keys', done => {
109 | const ldApi = new LDApi('test');
110 | const usser = { ...user, key_With_Underscore: 'test' };
111 | const client = ldApi.createClient({user:usser, envClientKey, options});
112 | expect(client !== undefined).to.equal(true);
113 | done();
114 | });
115 |
116 | it('createClient no user', done => {
117 | const ldApi = new LDApi('test');
118 |
119 | try {
120 | ldApi.createClient({user:undefined, envClientKey, options});
121 | } catch (ex) {
122 | expect(ex !== null).to.equal(true);
123 | done();
124 | }
125 | });
126 |
127 | it('createClient no client key', done => {
128 | const ldApi = new LDApi('test');
129 |
130 | try {
131 | ldApi.createClient({user, envClientKey:null, options});
132 | } catch (ex) {
133 | expect(ex !== null).to.equal(true);
134 | done();
135 | }
136 | });
137 |
138 | it('createClient no user authID key', done => {
139 | const ldApi = new LDApi('test');
140 |
141 | const userr = {};
142 | try {
143 | ldApi.createClient({user:userr, envClientKey:null, options});
144 | } catch (ex) {
145 | expect(ex !== null).to.equal(true);
146 | done();
147 | }
148 | });
149 |
150 | it('handleEvents', done => {
151 | const ldApi = new LDApi('test');
152 |
153 | const client = ldApi.createClient({user, envClientKey, options});
154 | ldApi.handleEvents(timeout, client);
155 | expect(true).to.equal(true);
156 | done();
157 | });
158 |
159 | it('handleEvents promise', done => {
160 | const ldApi = new LDApi('test');
161 |
162 | new Promise((resolve, reject) => {
163 | const client = ldApi.createClient({user, envClientKey, options});
164 | ldApi.handleEvents(timeout, client, false, resolve, reject);
165 | }).then(
166 | resolve => {
167 | expect(true).to.equal(true);
168 | done();
169 | },
170 | reject => {
171 | expect(reject !== undefined).to.equal(true);
172 | done();
173 | }
174 | );
175 | });
176 |
177 | it('handleEvents no client', done => {
178 | const ldApi = new LDApi('test');
179 |
180 | try {
181 | ldApi.handleEvents(timeout);
182 | } catch (ex) {
183 | expect(ex !== null).to.equal(true);
184 | expect(ex.message === 'ERROR: ldClient is undefined').to.equal(true);
185 | done();
186 | }
187 | });
188 |
189 | it('handleEvents no client with reject callback', done => {
190 | const ldApi = new LDApi('test');
191 | const reject = error => {
192 | expect(error !== null).to.equal(true);
193 | expect(error.message === 'ERROR: ldClient is undefined').to.equal(true);
194 | done();
195 | };
196 |
197 | ldApi.handleEvents(timeout, undefined, undefined, undefined, reject);
198 | });
199 |
200 | it('handleEvents timeout with reject callback', done => {
201 | const ldApi = new LDApi('test');
202 |
203 | new Promise((resolve, reject) => {
204 | const client = ldApi.createClient({user, envClientKey, options});
205 | ldApi.handleEvents(1, client, false, resolve, reject);
206 | }).then(
207 | resolve => {},
208 | reject => {
209 | expect(reject.message).to.equal('ERROR: Creation of Launch Darkly client has timed out');
210 | done();
211 | }
212 | );
213 | });
214 |
215 | it('handleEvents error event', done => {
216 | const events = {};
217 | const ldApi = new LDApi();
218 | const mockClient = {
219 | emit: (event, ...args) => (events[event] ? events[event](...args) : null),
220 | on: (event, cb) => {
221 | events[event] = cb;
222 | }
223 | };
224 | ldApi.handleEvents(timeout, mockClient, false, null, error => {
225 | expect(error.message).to.equal('Testing Error');
226 | done();
227 | });
228 | mockClient.emit('error', Error('Testing Error'));
229 | });
230 |
231 | it('getFeatureFlag throws and error when there is no default value provided', done => {
232 | const noClientLDAPI = new LDApi('test');
233 | noClientLDAPI.init({clientParams:{user, envClientKey, options}, timeout:500, LDClient});
234 |
235 | try {
236 | noClientLDAPI.getFeatureFlag(undefined, 'defaultValue');
237 | done();
238 | } catch (ex) {
239 | expect(ex !== null).to.equal(true);
240 | // eslint-disable
241 | expect(ex.message === 'ERROR: featureId is undefined').to.equal(true);
242 | done();
243 | }
244 | try {
245 | noClientLDAPI.getFeatureFlag(config.features);
246 | done();
247 | } catch (ex) {
248 | expect(ex !== null).to.equal(true);
249 | // eslint-disable
250 | expect(ex.message).to.equal('Default value must be passed to getPromiseFeatureFlag');
251 | }
252 | });
253 |
254 | it('getFeatureFlag returns default value when there is no ldClient but a default value(false) is provided', done => {
255 | const noClientLDAPI = new LDApi('test');
256 | const expected = false;
257 | const actual = noClientLDAPI.getFeatureFlag(config.features, false);
258 | // t.is(actual, expected);
259 | expect(actual).to.equal(expected);
260 | done();
261 | });
262 |
263 | it("getAllFlags returns an empty object if the ldclient doesn't exist", done => {
264 | const noClientLDAPI = new LDApi('test');
265 | const expected = {};
266 | const actual = noClientLDAPI.getAllFlags();
267 | expect(actual).to.deep.equal(expected);
268 | done();
269 | });
270 |
271 | it('LD API initializes with appropriate api', done => {
272 | // Initialize the api with the mocked LDClient and the config
273 | const ldApi = new LDApi('test');
274 |
275 | ldApi.init({clientParams:{user, envClientKey, options}, timeout:500});
276 | expect(typeof ldApi.getFeatureFlag).to.equal('function');
277 | expect(typeof ldApi.getAllFlags).to.equal('function');
278 | done();
279 | });
280 |
281 | it('LD API returns promise that will return a ready client', done => {
282 | const ldApi = new LDApi('test');
283 |
284 | // The 'ready' event will be emitted within 500ms, resolving the promise and returning the client
285 | ldApi.initWithPromise({clientParams:{user, envClientKey, options}, timeout:500}).then(client => {
286 | expect(typeof client.getFeatureFlag).to.equal('function');
287 | expect(typeof client.getAllFlags).to.equal('function');
288 | done();
289 | });
290 | });
291 |
292 | it('LD API returns promise that rejects if the client does not initialize in time', done => {
293 | const ldApi = new LDApi('test');
294 |
295 | // Only wait 100ms for the on ready event, the promise will reject
296 | ldApi.initWithPromise({clientParams:{user, envClientKey, options}, timeout:1}).catch(err => {
297 | expect(err.message).to.deep.equal(errorMessage);
298 | done();
299 | // t.deepEqual(err.message, errorMessage);
300 | });
301 | });
302 |
303 | it('getFeatureFlag returns the feature value', done => {
304 | const ldApi = new LDApi('test');
305 | ldApi.init({clientParams:{user, envClientKey, options}, timeout:500, LDClient});
306 | const expected = true;
307 | const actual = ldApi.getFeatureFlag(config.features, false);
308 | expect(actual).to.equal(expected);
309 | done();
310 | });
311 |
312 | it('getPromiseFeatureFlag returns reject when there is no default value is provided', done => {
313 | const noClientLDAPI = new LDApi('test');
314 | // const expected = false;
315 |
316 | noClientLDAPI.getPromiseFeatureFlag(config.features).catch(err => {
317 | // t.deepEqual(err.message, 'Default value must be passed to getPromiseFeatureFlag');
318 | // eslint-disable
319 | expect(err.message).to.equal('Default value must be passed to getPromiseFeatureFlag');
320 | done();
321 | });
322 | });
323 |
324 | it('getAllFlags returns all flags belonging to that userKey', done => {
325 | const ldApi = new LDApi('test');
326 | ldApi.init({clientParams:{user, envClientKey, options}, timeout:500, LDClient});
327 | const expected = {
328 | 'forms-mode': false,
329 | 'other-forms-mode': false
330 | };
331 | const actual = ldApi.getAllFlags();
332 | // t.deepEqual(actual, expected);
333 | expect(actual).to.deep.equal(expected);
334 | done();
335 | });
336 | });
337 |
--------------------------------------------------------------------------------
/test/react.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Enzyme, { mount, shallow } from 'enzyme';
3 | import Adapter from 'enzyme-adapter-react-16';
4 | import {
5 | FeatureTrue,
6 | FeatureFlag,
7 | FeatureFalse,
8 | FeatureSwitch,
9 | FeatureCase,
10 | FeatureDefault
11 | } from '../src/lib/index';
12 |
13 | Enzyme.configure({ adapter: new Adapter() });
14 |
15 | const appFlags = {
16 | a: true,
17 | b: false,
18 | switcher: 'switch'
19 | };
20 |
21 | describe('Launch Darkly Plugin ', () => {
22 | it.only('FeatureFlag: should render component if flagKey value is true in appFlags object ', () => {
23 | const component = shallow(
24 |
25 | hello
26 |
27 | );
28 | expect(component.exists()).toBe(true);
29 | expect(component.find('#hello').exists()).toBe(true);
30 | expect(component.debug()).toMatchSnapshot();
31 | });
32 |
33 | it.only('FeatureFlag: should not render component if flagKey value is false in appFlags object ', () => {
34 | const component = shallow(
35 |
36 | hello
37 |
38 | );
39 | expect(component.exists()).toBe(false);
40 | expect(component.debug()).toMatchSnapshot();
41 | });
42 |
43 | it.only('FeatureFlag: should not render component if flagKey does not exist in appFlags object ', () => {
44 | const component = shallow(
45 |
46 | hello
47 |
48 | );
49 | expect(component.exists()).toBe(false);
50 | expect(component.debug()).toMatchSnapshot();
51 | });
52 |
53 | it.only('FeatureFlag: should render only the FeatureTrue when flagKey value is true', () => {
54 | const component = mount(
55 |
56 |
57 | Gets rendered when flagKey value is true
58 |
59 |
60 | Gets rendered when flagKey value is false
61 |
62 |
63 | );
64 | expect(component.exists()).toBe(true);
65 | expect(component.find('FeatureTrue').exists()).toBe(true);
66 | expect(component.debug()).toMatchSnapshot();
67 | });
68 |
69 | it.only('FeatureFlag: should render only the FeatureFalse when flagKey value is false', () => {
70 | const component = mount(
71 |
72 |
73 | Gets rendered when flagKey value is true
74 |
75 |
76 | Gets rendered when flagKey value is false
77 |
78 |
79 | );
80 | expect(component.exists()).toBe(true);
81 | expect(component.find('FeatureFalse').exists()).toBe(true);
82 | expect(component.debug()).toMatchSnapshot();
83 | });
84 |
85 | it.only('FeatureFlag: should not render either FeatureTrue or FeatureFalse when it gets mixed with NonPluginElement and should throw a warnring', () => {
86 | const component = shallow(
87 |
88 | Non Plugin Element
89 |
90 | Hello there
91 |
92 |
93 | Hello there
94 |
95 |
96 | );
97 | expect(component.exists()).toBe(true);
98 | expect(component.debug()).toMatchSnapshot();
99 | });
100 |
101 | it.only('FeatureSwitch: renders the FeatureCase component that matches the flagKey ', () => {
102 | const component = mount(
103 |
104 |
105 |
106 | Multivariate Test 1 Rendered
107 |
108 |
109 | Multivariate Test 2 Rendered
110 |
111 |
112 | If no conditions are met then render the default
113 |
114 |
115 |
116 | );
117 | expect(component.exists()).toBe(true);
118 | expect(component.find({ condition: 'switch' }).exists()).toBe(true);
119 | expect(component.debug()).toMatchSnapshot();
120 | });
121 |
122 | it.only('FeatureSwitch: renders the FeatureDefault component when the no FeatureCase found that matches the flagKey ', () => {
123 | const component = mount(
124 |
125 |
126 |
127 | Multivariate Test 1 Rendered
128 |
129 |
130 | Multivariate Test 2 Rendered
131 |
132 |
133 | If no conditions are met then render the default
134 |
135 |
136 |
137 | );
138 | expect(component.exists()).toBe(true);
139 | expect(component.find('FeatureDefault').exists()).toBe(true);
140 | expect(component.debug()).toMatchSnapshot();
141 | });
142 |
143 | it.only('FeatureFlag: should not render the FeatureSwitch and throw a warning when FeatureSwitch gets mixed with NonPlugin elements', () => {
144 | const component = mount(
145 |
146 | Hello
147 |
148 |
149 | Multivariate Test 1 Rendered
150 |
151 |
152 | Multivariate Test 2 Rendered
153 |
154 |
155 | If no conditions are met then render the default
156 |
157 |
158 |
159 | );
160 | expect(component.exists()).toBe(true);
161 | expect(component.find({ id: 'hello' }).exists()).toBe(true);
162 | expect(component.debug()).toMatchSnapshot();
163 | });
164 | });
165 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "allowSyntheticDefaultImports": true,
4 | "baseUrl": "src",
5 | "declaration": true,
6 | "emitDecoratorMetadata": true,
7 | "esModuleInterop": true,
8 | "experimentalDecorators": true,
9 | "forceConsistentCasingInFileNames": true,
10 | "jsx": "react",
11 | "lib": ["dom", "dom.iterable", "esnext"],
12 | "module": "commonjs",
13 | "moduleResolution": "node",
14 | "noImplicitReturns": true,
15 | "noImplicitThis": true,
16 | "noImplicitAny": false,
17 | "noUnusedLocals": true,
18 | "outDir": "dist",
19 | "resolveJsonModule": true,
20 | "rootDirs": ["src", "stories"],
21 | "sourceMap": true,
22 | "strictNullChecks": true,
23 | "target": "es5"
24 | },
25 | "include": ["src/**/*"],
26 | "exclude": ["node_modules", "build", "scripts"]
27 | }
28 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | import path from 'path';
2 |
3 | export default () => ({
4 | mode: 'production',
5 | entry: {
6 | index: path.join(__dirname, 'src/docs/index.js')
7 | },
8 | output: {
9 | path: path.join(__dirname, 'src/dist'),
10 | filename: '[name].js',
11 | libraryTarget: 'umd',
12 | globalObject: 'this'
13 | },
14 |
15 | module: {
16 | rules: [
17 | // All files with a '.ts' or '.tsx' extension will be handled by 'awesome-typescript-loader'.
18 | {
19 | test: /\.tsx?$/,
20 | loader: 'awesome-typescript-loader'
21 | },
22 | // All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
23 | {
24 | enforce: 'pre',
25 | test: /\.js$/,
26 | loader: 'source-map-loader'
27 | },
28 | {
29 | test: /.jsx?$/,
30 | exclude: /node_modules/,
31 | include: path.join(__dirname, 'src'),
32 | use: [
33 | {
34 | loader: 'babel-loader',
35 | options: {
36 | presets: ['@babel/preset-env', '@babel/preset-react']
37 | }
38 | }
39 | ]
40 | },
41 | {
42 | test: /\.(scss)$/,
43 | loader: 'style-loader!css-loader!sass-loader'
44 | }
45 | ]
46 | },
47 |
48 | resolve: {
49 | extensions: ['.js', '.jsx', '.ts', '.tsx', '.scss']
50 | },
51 |
52 | externals: {
53 | react: 'react',
54 | reactDOM: 'react-dom'
55 | }
56 | });
57 |
--------------------------------------------------------------------------------