├── README.md ├── example ├── .babelrc ├── demo.js ├── index.html ├── index.js ├── main.css ├── package.json ├── src │ ├── Input.js │ └── Todos.js └── styles │ ├── lib │ ├── align.scss │ ├── buttons.scss │ ├── display.scss │ ├── flexbox.scss │ ├── floats.scss │ ├── forms.scss │ ├── lists.scss │ ├── positioning.scss │ ├── spacing.scss │ ├── tables.scss │ ├── typography.scss │ └── z-index.scss │ └── main.scss ├── package ├── .babelrc ├── .gitignore ├── .npmignore ├── README.md ├── index.js └── package.json └── static └── basic.gif /README.md: -------------------------------------------------------------------------------- 1 | # microstate 2 | Co-located, functional state management for React. `seState` syntatic sugar. **1.3kb** 3 | 4 | [![js-standard-style](https://cdn.rawgit.com/feross/standard/master/badge.svg)](http://standardjs.com) 5 | 6 | ## Usage 7 | Wrap your application with the `Provider`. 8 | ```javascript 9 | import { Provider } from 'microstate' 10 | 11 | const App = props => ( 12 | 13 |

My App

14 |
15 | ) 16 | 17 | render(, root) 18 | ``` 19 | 20 | Connect your component to the provider state using `connect`. The function signature for connect looks like this: 21 | ``` 22 | connect(mapStateToProps[, mapDispatchToProps, initialState])(MyComp) 23 | ``` 24 | 25 | ```javascript 26 | import { connect } from 'microstate' 27 | 28 | const initialState = { 29 | count: 0 30 | } 31 | 32 | const mapStateToProps = state => ({ 33 | count: state.count 34 | }) 35 | 36 | const mapDispatchToProps = dispatch => ({ 37 | inc: () => dispatch(state => { 38 | count: state.count + 1 39 | }) 40 | }) 41 | 42 | const Component = ({ inc, count }) => ( 43 |
44 | 45 | {count} 46 |
47 | ) 48 | 49 | export default connect( 50 | mapStateToProps, 51 | mapDispatchToProps, 52 | initialState 53 | )(Component) 54 | ``` 55 | 56 | Then render your component within the Provider context. 57 | ```javascript 58 | import { Provider } from 'microstate' 59 | import Component from './Component.js' 60 | 61 | const App = props => ( 62 | 63 | 64 | 65 | ) 66 | 67 | render(, root) 68 | ``` 69 | 70 | Note: the state is availabe at a component level and below during first render. However, since an initial render is required to evaluate the `connect` function, state will only be availabe at the application level *after* that first render. 71 | 72 | ## Subscribing to state 73 | Subscribing to another component's state is easy. Let's pretend the below is a different component than the counter above. 74 | ```javascript 75 | // Output.js 76 | export default connect( 77 | state => ({ 78 | count: state.count, 79 | text: state.text 80 | }, 81 | null, 82 | { 83 | text: 'The count is' 84 | } 85 | )(({ count, text }) => ( 86 |
{text + ' ' + count}
87 | )) 88 | ``` 89 | 90 | Then add it to the rendered `App` from above. 91 | ```javascript 92 | import { Provider } from 'microstate' 93 | import Component from './Component.js' 94 | import Output from './Output.js' 95 | 96 | export default props => ( 97 | 98 | 99 | 100 | 101 | ) 102 | 103 | render(, root) 104 | ``` 105 | 106 | ## Note on Usage 107 | This library is functional and has been used in production. However, the co-located nature of it means that the parent scope (and any other component subscribing to state that is external to itself) does not have access to the individual component state until **after the first render.** This is because the function hasn't fired (components are just functions) and so the co-located state hasn't been evaluated. The answer to this is to define all your state up front, at the top level, which this library doesn't do. 108 | 109 | For similar (and better) options, I'd recommend [refunk](https://github.com/jxnblk/refunk) by [@jxnblk](https://github.com/jxnblk) or [react-organism](https://github.com/RoyalIcing/react-organism) by [@RoyalIcing](https://github.com/RoyalIcing). 110 | 111 | * * * 112 | 113 | **MIT License** 114 | -------------------------------------------------------------------------------- /example/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "es2015", 4 | "react" 5 | ] 6 | } 7 | 8 | -------------------------------------------------------------------------------- /example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | microstate 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /example/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { render } from 'react-dom' 3 | import { Provider } from 'microstate' 4 | 5 | import Input from './src/Input.js' 6 | import Todos from './src/Todos.js' 7 | 8 | const App = props => ( 9 | 10 |
11 |
12 | 13 | 14 |
15 |
16 |
17 | ) 18 | 19 | render(, document.getElementById('root')) 20 | 21 | -------------------------------------------------------------------------------- /example/main.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | .block { 3 | display: block; } 4 | 5 | .inline { 6 | display: inline; } 7 | 8 | .inline-block { 9 | display: inline-block; } 10 | 11 | .hide { 12 | display: none; } 13 | 14 | .relative { 15 | position: relative; } 16 | 17 | .absolute { 18 | position: absolute; } 19 | 20 | .fixed { 21 | position: fixed; } 22 | 23 | .fit-t, .fit-x { 24 | top: 0; } 25 | 26 | .fit-b, .fit-x { 27 | bottom: 0; } 28 | 29 | .fit-l, .fit-x { 30 | left: 0; } 31 | 32 | .fit-r, .fit-x { 33 | right: 0; } 34 | 35 | .flex { 36 | display: -webkit-box; 37 | display: -ms-flexbox; 38 | display: flex; } 39 | 40 | .flex-wrap { 41 | -ms-flex-wrap: wrap; 42 | flex-wrap: wrap; } 43 | 44 | .flex-items-start { 45 | -webkit-box-align: start; 46 | -ms-flex-align: start; 47 | align-items: flex-start; } 48 | 49 | .flex-items-end { 50 | -webkit-box-align: end; 51 | -ms-flex-align: end; 52 | align-items: flex-end; } 53 | 54 | .flex-items-center { 55 | -webkit-box-align: center; 56 | -ms-flex-align: center; 57 | align-items: center; } 58 | 59 | .flex-items-baseline { 60 | -webkit-box-align: baseline; 61 | -ms-flex-align: baseline; 62 | align-items: baseline; } 63 | 64 | .flex-items-stretch { 65 | -webkit-box-align: stretch; 66 | -ms-flex-align: stretch; 67 | align-items: stretch; } 68 | 69 | .flex-justify-start { 70 | -webkit-box-pack: start; 71 | -ms-flex-pack: start; 72 | justify-content: flex-start; } 73 | 74 | .flex-justify-end { 75 | -webkit-box-pack: end; 76 | -ms-flex-pack: end; 77 | justify-content: flex-end; } 78 | 79 | .flex-justify-center { 80 | -webkit-box-pack: center; 81 | -ms-flex-pack: center; 82 | justify-content: center; } 83 | 84 | .flex-justify-between { 85 | -webkit-box-pack: justify; 86 | -ms-flex-pack: justify; 87 | justify-content: space-between; } 88 | 89 | .flex-justify-around { 90 | -ms-flex-pack: distribute; 91 | justify-content: space-around; } 92 | 93 | .flex-auto { 94 | -webkit-box-flex: 1; 95 | -ms-flex: 1 1 auto; 96 | flex: 1 1 auto; 97 | min-width: 0; 98 | min-height: 0; } 99 | 100 | .align-l { 101 | text-align: left; } 102 | 103 | .align-c { 104 | text-align: center; } 105 | 106 | .align-r { 107 | text-align: right; } 108 | 109 | .align-j { 110 | text-align: justify; } 111 | 112 | .align-m { 113 | vertical-align: middle; } 114 | 115 | .align-t { 116 | vertical-align: top; } 117 | 118 | .align-b { 119 | vertical-align: baseline; } 120 | 121 | .float-l { 122 | float: left; } 123 | 124 | .float-r { 125 | float: right; } 126 | 127 | .clearfix::before, .clearfix::after { 128 | content: ' '; 129 | display: table; } 130 | 131 | .clearfix::after { 132 | clear: both; } 133 | 134 | .z0 { 135 | z-index: 0; } 136 | 137 | .z1 { 138 | z-index: 100; } 139 | 140 | .z2 { 141 | z-index: 200; } 142 | 143 | .z3 { 144 | z-index: 300; } 145 | 146 | .z5 { 147 | z-index: 500; } 148 | 149 | .z6 { 150 | z-index: 600; } 151 | 152 | .z7 { 153 | z-index: 700; } 154 | 155 | .z8 { 156 | z-index: 800; } 157 | 158 | .z9 { 159 | z-index: 900; } 160 | 161 | .z10 { 162 | z-index: 1000; } 163 | 164 | body { 165 | color: #000; 166 | font-family: Helvetica, Arial, sans-serif; 167 | font-size: 120%; 168 | line-height: 1.7; 169 | font-weight: 400; 170 | -webkit-font-smoothing: antialiased; } 171 | 172 | h1, h2, h3, h4, h5, h6 { 173 | margin: 1em 0 .6em; } 174 | 175 | .scale1, 176 | h1, .h1 { 177 | font-size: 4rem; } 178 | 179 | h1, .h1 { 180 | line-height: 1.1; } 181 | 182 | .scale2, 183 | h2, .h2 { 184 | font-size: 3rem; } 185 | 186 | h2, .h2 { 187 | line-height: 1.3; } 188 | 189 | .scale3, 190 | h3, .h3 { 191 | font-size: 2rem; } 192 | 193 | h3, .h3 { 194 | line-height: 1.5; } 195 | 196 | .scale4, 197 | h4, .h4 { 198 | font-size: 1.5rem; } 199 | 200 | h4, .h4 { 201 | line-height: 1.5; } 202 | 203 | .scale5, 204 | h5, .h5 { 205 | font-size: 1rem; } 206 | 207 | h5, .h5 { 208 | line-height: 1.6; } 209 | 210 | .scale6, 211 | h6, .h6 { 212 | font-size: 0.875rem; } 213 | 214 | h6, .h6 { 215 | line-height: 1.6; } 216 | 217 | .scale0, 218 | p, .p { 219 | font-size: 1rem; } 220 | 221 | p, .p { 222 | line-height: 1.7; } 223 | 224 | p { 225 | margin: 1.5em 0; } 226 | 227 | a { 228 | color: inherit; } 229 | 230 | blockquote { 231 | margin: 3rem 0; 232 | padding-left: 2rem; 233 | border-left: 4px solid #148ECC; } 234 | 235 | hr { 236 | display: block; 237 | margin: 0; 238 | border: 0; 239 | height: 1px; 240 | width: 100%; 241 | background-color: currentColor; 242 | color: inherit; } 243 | 244 | small { 245 | font-size: 0.8em; } 246 | 247 | strong { 248 | font-weight: bold; } 249 | 250 | .type--reset { 251 | margin: 0; 252 | line-height: 1; } 253 | 254 | .italic { 255 | font-style: italic; } 256 | 257 | .light { 258 | font-weight: 100; } 259 | 260 | .medium { 261 | font-weight: 500; } 262 | 263 | .bold { 264 | font-weight: 900; } 265 | 266 | .uppercase { 267 | text-transform: uppercase; } 268 | 269 | .underline { 270 | text-decoration: underline; } 271 | 272 | .decoration--none { 273 | text-decoration: none; } 274 | 275 | /** 276 | * Buttons should be button.button or 277 | * .button[role="button"] for accessibility 278 | */ 279 | button.button, 280 | .button[role="button"], 281 | input.button[type="submit"] { 282 | border: 0; 283 | border-radius: 0; 284 | display: inline-block; 285 | background-color: #000; 286 | color: white; 287 | cursor: pointer; 288 | padding: 0.7em 2em; 289 | line-height: inherit; 290 | text-decoration: none; 291 | text-align: center; 292 | -webkit-appearance: none; } 293 | 294 | button[disabled], 295 | input[disabled] { 296 | cursor: default; } 297 | 298 | form { 299 | margin: 0; } 300 | 301 | input, 302 | label, 303 | select, 304 | textarea { 305 | outline: 0; 306 | border: 0; 307 | border-radius: 0; 308 | font-size: inherit; 309 | position: relative; 310 | background-color: transparent; } 311 | 312 | input, 313 | textarea, 314 | select { 315 | border: 1px solid #000; 316 | padding: .35em .65em; 317 | -webkit-appearance: none; } 318 | 319 | select::-ms-expand { 320 | display: none; } 321 | 322 | textarea { 323 | max-width: 100%; 324 | overflow: auto; 325 | resize: vertical; } 326 | 327 | ol, ul { 328 | list-style: none; } 329 | 330 | /* To achieve list styling, */ 331 | /* add the .list class */ 332 | /* i.e ol.list, ul.list */ 333 | .list ul, 334 | .list ol { 335 | margin: 0; 336 | padding-left: 2em; } 337 | 338 | .list ol { 339 | list-style: lower-alpha inside; } 340 | 341 | .list li { 342 | position: relative; 343 | margin: .33em 0; 344 | padding-left: 1.5em; } 345 | 346 | ol.list { 347 | counter-reset: num; } 348 | 349 | ol.list li::before { 350 | content: counter(num) "."; 351 | counter-increment: num; 352 | display: block; 353 | position: absolute; 354 | left: 0; 355 | top: 0; } 356 | 357 | ul.list li::before { 358 | content: '•'; 359 | display: block; 360 | position: absolute; 361 | left: 0; 362 | top: 0; } 363 | 364 | .table--fixed { 365 | table-layout: fixed; } 366 | 367 | .table__row-header { 368 | display: table-header-group; } 369 | 370 | .table__row-footer { 371 | display: table-footer-group; } 372 | 373 | .table__row-group { 374 | display: table-row-group; } 375 | 376 | .table__row { 377 | display: table-row; } 378 | 379 | .table__cell { 380 | display: table-cell; } 381 | 382 | table, 383 | .table { 384 | border-collapse: collapse; 385 | border-spacing: 0; 386 | display: table; 387 | width: 100%; } 388 | 389 | td, 390 | th { 391 | display: table-cell; 392 | border-bottom: 1px solid #000; 393 | padding: .66em 1.33em; } 394 | 395 | th { 396 | font-weight: 100; 397 | text-align: left; } 398 | 399 | .mla, .mha, .mxa { 400 | margin-left: auto; } 401 | 402 | .mra, .mha, .mxa { 403 | margin-right: auto; } 404 | 405 | .mta, .mva, .mxa { 406 | margin-top: auto; } 407 | 408 | .mba, .mva, .mxa { 409 | margin-bottom: auto; } 410 | 411 | .mt0, .mv0, .mx0 { 412 | margin-top: 0; } 413 | 414 | .mb0, .mv0, .mx0 { 415 | margin-bottom: 0; } 416 | 417 | .ml0, .mh0, .mx0 { 418 | margin-left: 0; } 419 | 420 | .mr0, .mh0, .mx0 { 421 | margin-right: 0; } 422 | 423 | .pt0, .pv0, .px0 { 424 | padding-top: 0; } 425 | 426 | .pb0, .pv0, .px0 { 427 | padding-bottom: 0; } 428 | 429 | .pl0, .ph0, .px0 { 430 | padding-left: 0; } 431 | 432 | .pr0, .ph0, .px0 { 433 | padding-right: 0; } 434 | 435 | .mt025, .mv025, .mx025 { 436 | margin-top: 0.25em; } 437 | 438 | .mb025, .mv025, .mx025 { 439 | margin-bottom: 0.25em; } 440 | 441 | .ml025, .mh025, .mx025 { 442 | margin-left: 0.25em; } 443 | 444 | .mr025, .mh025, .mx025 { 445 | margin-right: 0.25em; } 446 | 447 | .mhn025 { 448 | margin-left: -0.25em; 449 | margin-right: -0.25em; } 450 | 451 | .pt025, .pv025, .px025 { 452 | padding-top: 0.25em; } 453 | 454 | .pb025, .pv025, .px025 { 455 | padding-bottom: 0.25em; } 456 | 457 | .pl025, .ph025, .px025 { 458 | padding-left: 0.25em; } 459 | 460 | .pr025, .ph025, .px025 { 461 | padding-right: 0.25em; } 462 | 463 | .mt05, .mv05, .mx05 { 464 | margin-top: 0.5em; } 465 | 466 | .mb05, .mv05, .mx05 { 467 | margin-bottom: 0.5em; } 468 | 469 | .ml05, .mh05, .mx05 { 470 | margin-left: 0.5em; } 471 | 472 | .mr05, .mh05, .mx05 { 473 | margin-right: 0.5em; } 474 | 475 | .mhn05 { 476 | margin-left: -0.5em; 477 | margin-right: -0.5em; } 478 | 479 | .pt05, .pv05, .px05 { 480 | padding-top: 0.5em; } 481 | 482 | .pb05, .pv05, .px05 { 483 | padding-bottom: 0.5em; } 484 | 485 | .pl05, .ph05, .px05 { 486 | padding-left: 0.5em; } 487 | 488 | .pr05, .ph05, .px05 { 489 | padding-right: 0.5em; } 490 | 491 | .mt075, .mv075, .mx075 { 492 | margin-top: 0.75em; } 493 | 494 | .mb075, .mv075, .mx075 { 495 | margin-bottom: 0.75em; } 496 | 497 | .ml075, .mh075, .mx075 { 498 | margin-left: 0.75em; } 499 | 500 | .mr075, .mh075, .mx075 { 501 | margin-right: 0.75em; } 502 | 503 | .mhn075 { 504 | margin-left: -0.75em; 505 | margin-right: -0.75em; } 506 | 507 | .pt075, .pv075, .px075 { 508 | padding-top: 0.75em; } 509 | 510 | .pb075, .pv075, .px075 { 511 | padding-bottom: 0.75em; } 512 | 513 | .pl075, .ph075, .px075 { 514 | padding-left: 0.75em; } 515 | 516 | .pr075, .ph075, .px075 { 517 | padding-right: 0.75em; } 518 | 519 | .mt1, .mv1, .mx1 { 520 | margin-top: 1em; } 521 | 522 | .mb1, .mv1, .mx1 { 523 | margin-bottom: 1em; } 524 | 525 | .ml1, .mh1, .mx1 { 526 | margin-left: 1em; } 527 | 528 | .mr1, .mh1, .mx1 { 529 | margin-right: 1em; } 530 | 531 | .mhn1 { 532 | margin-left: -1em; 533 | margin-right: -1em; } 534 | 535 | .pt1, .pv1, .px1 { 536 | padding-top: 1em; } 537 | 538 | .pb1, .pv1, .px1 { 539 | padding-bottom: 1em; } 540 | 541 | .pl1, .ph1, .px1 { 542 | padding-left: 1em; } 543 | 544 | .pr1, .ph1, .px1 { 545 | padding-right: 1em; } 546 | 547 | .mt2, .mv2, .mx2 { 548 | margin-top: 2em; } 549 | 550 | .mb2, .mv2, .mx2 { 551 | margin-bottom: 2em; } 552 | 553 | .ml2, .mh2, .mx2 { 554 | margin-left: 2em; } 555 | 556 | .mr2, .mh2, .mx2 { 557 | margin-right: 2em; } 558 | 559 | .mhn2 { 560 | margin-left: -2em; 561 | margin-right: -2em; } 562 | 563 | .pt2, .pv2, .px2 { 564 | padding-top: 2em; } 565 | 566 | .pb2, .pv2, .px2 { 567 | padding-bottom: 2em; } 568 | 569 | .pl2, .ph2, .px2 { 570 | padding-left: 2em; } 571 | 572 | .pr2, .ph2, .px2 { 573 | padding-right: 2em; } 574 | 575 | html, body { 576 | margin: 0; 577 | padding: 0; } 578 | 579 | .theme { 580 | color: #00C9FC; } 581 | 582 | .bg-theme { 583 | background: #00C9FC; } 584 | 585 | .white { 586 | color: white; } 587 | 588 | .relative { 589 | position: relative; } 590 | 591 | .absolute { 592 | position: absolute; } 593 | 594 | .fixed { 595 | position: fixed; } 596 | 597 | .fit-t, .fit-x { 598 | top: 0; } 599 | 600 | .fit-b, .fit-x { 601 | bottom: 0; } 602 | 603 | .fit-l, .fit-x { 604 | left: 0; } 605 | 606 | .fit-r, .fit-x { 607 | right: 0; } 608 | 609 | .fill-v { 610 | height: 100vh; } 611 | 612 | .fill-v05 { 613 | height: 50vh; } 614 | 615 | .fill-h { 616 | width: 100%; } 617 | 618 | .container { 619 | max-width: 550px; } 620 | 621 | ::-moz-selection { 622 | background: #00C9FC; } 623 | 624 | ::selection { 625 | background: #00C9FC; } 626 | 627 | .root p { 628 | color: rgba(0, 0, 0, 0.4); } 629 | .root p.sharable { 630 | color: black; } 631 | 632 | .sshare { 633 | position: absolute; 634 | visibility: hidden; 635 | top: 0; 636 | left: 0; 637 | opacity: 0; 638 | -webkit-transition-property: opacity, -webkit-transform; 639 | transition-property: opacity, -webkit-transform; 640 | transition-property: transform, opacity; 641 | transition-property: transform, opacity, -webkit-transform; 642 | -webkit-transition-duration: 200ms; 643 | transition-duration: 200ms; 644 | -webkit-transition-timing-function: cubic-bezier(0.24, 0.82, 0.35, 1); 645 | transition-timing-function: cubic-bezier(0.24, 0.82, 0.35, 1); } 646 | 647 | .sshare:focus { 648 | outline: 0; } 649 | 650 | .sshare.is-tacked { 651 | visibility: visible; } 652 | 653 | .sshare.is-active { 654 | opacity: 1; } 655 | 656 | .sshare.is-hiding { 657 | opacity: 0; } 658 | 659 | .sshare__inner { 660 | display: -webkit-box; 661 | display: -ms-flexbox; 662 | display: flex; 663 | background: white; 664 | border-radius: 3px; 665 | overflow: hidden; 666 | -webkit-box-shadow: 0 3px 12px rgba(0, 0, 0, 0.2); 667 | box-shadow: 0 3px 12px rgba(0, 0, 0, 0.2); } 668 | 669 | .sshare__inner::before { 670 | content: ''; 671 | display: block; 672 | position: absolute; 673 | left: 0; 674 | right: 0; 675 | bottom: 0; 676 | margin: auto; 677 | width: 10px; 678 | height: 10px; 679 | -webkit-transform: translateY(40%) rotate(45deg); 680 | transform: translateY(40%) rotate(45deg); 681 | background-color: white; } 682 | 683 | .sshare__inner a { 684 | position: relative; 685 | width: 35px; 686 | height: 35px; 687 | line-height: 35px; 688 | color: black; } 689 | 690 | .sshare__inner a:hover { 691 | color: #00C9FC; } 692 | 693 | .sshare__inner a:focus { 694 | color: #00C9FC; 695 | outline: 0; } 696 | 697 | .sshare__inner a svg { 698 | display: block; 699 | position: absolute; 700 | top: 0; 701 | left: 0; 702 | right: 0; 703 | bottom: 0; 704 | margin: auto; 705 | width: 14px; 706 | height: 14px; } 707 | 708 | /*# sourceMappingURL=data:application/json;base64,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RUFDRSxXQUFXLEVBQUU7O0FBRWY7RUFDRSxvQkFBb0IsRUFBRTs7QUFFeEI7RUFDRSxXQUFXLEVBQUU7O0FBRWY7RUFDRSxXQUFXLEVBQUU7O0FBRWY7RUFDRSxxQkFBYztFQUFkLHFCQUFjO0VBQWQsY0FBYztFQUNkLGtCQUFrQjtFQUNsQixtQkFBbUI7RUFDbkIsaUJBQWlCO0VBQ2pCLGtEQUEwQztVQUExQywwQ0FBMEMsRUFBRTs7QUFFOUM7RUFDRSxZQUFZO0VBQ1osZUFBZTtFQUNmLG1CQUFtQjtFQUNuQixRQUFRO0VBQ1IsU0FBUztFQUNULFVBQVU7RUFDVixhQUFhO0VBQ2IsWUFBWTtFQUNaLGFBQWE7RUFDYixpREFBeUM7VUFBekMseUNBQXlDO0VBQ3pDLHdCQUF3QixFQUFFOztBQUU1QjtFQUNFLG1CQUFtQjtFQUNuQixZQUFZO0VBQ1osYUFBYTtFQUNiLGtCQUFrQjtFQUNsQixhQUFhLEVBQUU7O0FBRWpCO0VBQ0UsZUFBZSxFQUFFOztBQUVuQjtFQUNFLGVBQWU7RUFDZixXQUFXLEVBQUU7O0FBRWY7RUFDRSxlQUFlO0VBQ2YsbUJBQW1CO0VBQ25CLE9BQU87RUFDUCxRQUFRO0VBQ1IsU0FBUztFQUNULFVBQVU7RUFDVixhQUFhO0VBQ2IsWUFBWTtFQUNaLGFBQWEsRUFBRSIsImZpbGUiOiJzdGRpbiIsInNvdXJjZXNDb250ZW50IjpbIkBjaGFyc2V0IFwiVVRGLThcIjtcbi5ibG9jayB7XG4gIGRpc3BsYXk6IGJsb2NrOyB9XG5cbi5pbmxpbmUge1xuICBkaXNwbGF5OiBpbmxpbmU7IH1cblxuLmlubGluZS1ibG9jayB7XG4gIGRpc3BsYXk6IGlubGluZS1ibG9jazsgfVxuXG4uaGlkZSB7XG4gIGRpc3BsYXk6IG5vbmU7IH1cblxuLnJlbGF0aXZlIHtcbiAgcG9zaXRpb246IHJlbGF0aXZlOyB9XG5cbi5hYnNvbHV0ZSB7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTsgfVxuXG4uZml4ZWQge1xuICBwb3NpdGlvbjogZml4ZWQ7IH1cblxuLmZpdC10LCAuZml0LXgge1xuICB0b3A6IDA7IH1cblxuLmZpdC1iLCAuZml0LXgge1xuICBib3R0b206IDA7IH1cblxuLmZpdC1sLCAuZml0LXgge1xuICBsZWZ0OiAwOyB9XG5cbi5maXQtciwgLmZpdC14IHtcbiAgcmlnaHQ6IDA7IH1cblxuLmZsZXgge1xuICBkaXNwbGF5OiBmbGV4OyB9XG5cbi5mbGV4LXdyYXAge1xuICBmbGV4LXdyYXA6IHdyYXA7IH1cblxuLmZsZXgtaXRlbXMtc3RhcnQge1xuICBhbGlnbi1pdGVtczogZmxleC1zdGFydDsgfVxuXG4uZmxleC1pdGVtcy1lbmQge1xuICBhbGlnbi1pdGVtczogZmxleC1lbmQ7IH1cblxuLmZsZXgtaXRlbXMtY2VudGVyIHtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjsgfVxuXG4uZmxleC1pdGVtcy1iYXNlbGluZSB7XG4gIGFsaWduLWl0ZW1zOiBiYXNlbGluZTsgfVxuXG4uZmxleC1pdGVtcy1zdHJldGNoIHtcbiAgYWxpZ24taXRlbXM6IHN0cmV0Y2g7IH1cblxuLmZsZXgtanVzdGlmeS1zdGFydCB7XG4gIGp1c3RpZnktY29udGVudDogZmxleC1zdGFydDsgfVxuXG4uZmxleC1qdXN0aWZ5LWVuZCB7XG4gIGp1c3RpZnktY29udGVudDogZmxleC1lbmQ7IH1cblxuLmZsZXgtanVzdGlmeS1jZW50ZXIge1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjsgfVxuXG4uZmxleC1qdXN0aWZ5LWJldHdlZW4ge1xuICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47IH1cblxuLmZsZXgtanVzdGlmeS1hcm91bmQge1xuICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWFyb3VuZDsgfVxuXG4uZmxleC1hdXRvIHtcbiAgZmxleDogMSAxIGF1dG87XG4gIG1pbi13aWR0aDogMDtcbiAgbWluLWhlaWdodDogMDsgfVxuXG4uYWxpZ24tbCB7XG4gIHRleHQtYWxpZ246IGxlZnQ7IH1cblxuLmFsaWduLWMge1xuICB0ZXh0LWFsaWduOiBjZW50ZXI7IH1cblxuLmFsaWduLXIge1xuICB0ZXh0LWFsaWduOiByaWdodDsgfVxuXG4uYWxpZ24taiB7XG4gIHRleHQtYWxpZ246IGp1c3RpZnk7IH1cblxuLmFsaWduLW0ge1xuICB2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlOyB9XG5cbi5hbGlnbi10IHtcbiAgdmVydGljYWwtYWxpZ246IHRvcDsgfVxuXG4uYWxpZ24tYiB7XG4gIHZlcnRpY2FsLWFsaWduOiBiYXNlbGluZTsgfVxuXG4uZmxvYXQtbCB7XG4gIGZsb2F0OiBsZWZ0OyB9XG5cbi5mbG9hdC1yIHtcbiAgZmxvYXQ6IHJpZ2h0OyB9XG5cbi5jbGVhcmZpeDo6YmVmb3JlLCAuY2xlYXJmaXg6OmFmdGVyIHtcbiAgY29udGVudDogJyAnO1xuICBkaXNwbGF5OiB0YWJsZTsgfVxuXG4uY2xlYXJmaXg6OmFmdGVyIHtcbiAgY2xlYXI6IGJvdGg7IH1cblxuLnowIHtcbiAgei1pbmRleDogMDsgfVxuXG4uejEge1xuICB6LWluZGV4OiAxMDA7IH1cblxuLnoyIHtcbiAgei1pbmRleDogMjAwOyB9XG5cbi56MyB7XG4gIHotaW5kZXg6IDMwMDsgfVxuXG4uejUge1xuICB6LWluZGV4OiA1MDA7IH1cblxuLno2IHtcbiAgei1pbmRleDogNjAwOyB9XG5cbi56NyB7XG4gIHotaW5kZXg6IDcwMDsgfVxuXG4uejgge1xuICB6LWluZGV4OiA4MDA7IH1cblxuLno5IHtcbiAgei1pbmRleDogOTAwOyB9XG5cbi56MTAge1xuICB6LWluZGV4OiAxMDAwOyB9XG5cbmJvZHkge1xuICBjb2xvcjogIzAwMDtcbiAgZm9udC1mYW1pbHk6IEhlbHZldGljYSwgQXJpYWwsIHNhbnMtc2VyaWY7XG4gIGZvbnQtc2l6ZTogMTIwJTtcbiAgbGluZS1oZWlnaHQ6IDEuNztcbiAgZm9udC13ZWlnaHQ6IDQwMDtcbiAgLXdlYmtpdC1mb250LXNtb290aGluZzogYW50aWFsaWFzZWQ7IH1cblxuaDEsIGgyLCBoMywgaDQsIGg1LCBoNiB7XG4gIG1hcmdpbjogMWVtIDAgLjZlbTsgfVxuXG4uc2NhbGUxLFxuaDEsIC5oMSB7XG4gIGZvbnQtc2l6ZTogNHJlbTsgfVxuXG5oMSwgLmgxIHtcbiAgbGluZS1oZWlnaHQ6IDEuMTsgfVxuXG4uc2NhbGUyLFxuaDIsIC5oMiB7XG4gIGZvbnQtc2l6ZTogM3JlbTsgfVxuXG5oMiwgLmgyIHtcbiAgbGluZS1oZWlnaHQ6IDEuMzsgfVxuXG4uc2NhbGUzLFxuaDMsIC5oMyB7XG4gIGZvbnQtc2l6ZTogMnJlbTsgfVxuXG5oMywgLmgzIHtcbiAgbGluZS1oZWlnaHQ6IDEuNTsgfVxuXG4uc2NhbGU0LFxuaDQsIC5oNCB7XG4gIGZvbnQtc2l6ZTogMS41cmVtOyB9XG5cbmg0LCAuaDQge1xuICBsaW5lLWhlaWdodDogMS41OyB9XG5cbi5zY2FsZTUsXG5oNSwgLmg1IHtcbiAgZm9udC1zaXplOiAxcmVtOyB9XG5cbmg1LCAuaDUge1xuICBsaW5lLWhlaWdodDogMS42OyB9XG5cbi5zY2FsZTYsXG5oNiwgLmg2IHtcbiAgZm9udC1zaXplOiAwLjg3NXJlbTsgfVxuXG5oNiwgLmg2IHtcbiAgbGluZS1oZWlnaHQ6IDEuNjsgfVxuXG4uc2NhbGUwLFxucCwgLnAge1xuICBmb250LXNpemU6IDFyZW07IH1cblxucCwgLnAge1xuICBsaW5lLWhlaWdodDogMS43OyB9XG5cbnAge1xuICBtYXJnaW46IDEuNWVtIDA7IH1cblxuYSB7XG4gIGNvbG9yOiBpbmhlcml0OyB9XG5cbmJsb2NrcXVvdGUge1xuICBtYXJnaW46IDNyZW0gMDtcbiAgcGFkZGluZy1sZWZ0OiAycmVtO1xuICBib3JkZXItbGVmdDogNHB4IHNvbGlkICMxNDhFQ0M7IH1cblxuaHIge1xuICBkaXNwbGF5OiBibG9jaztcbiAgbWFyZ2luOiAwO1xuICBib3JkZXI6IDA7XG4gIGhlaWdodDogMXB4O1xuICB3aWR0aDogMTAwJTtcbiAgYmFja2dyb3VuZC1jb2xvcjogY3VycmVudENvbG9yO1xuICBjb2xvcjogaW5oZXJpdDsgfVxuXG5zbWFsbCB7XG4gIGZvbnQtc2l6ZTogMC44ZW07IH1cblxuc3Ryb25nIHtcbiAgZm9udC13ZWlnaHQ6IGJvbGQ7IH1cblxuLnR5cGUtLXJlc2V0IHtcbiAgbWFyZ2luOiAwO1xuICBsaW5lLWhlaWdodDogMTsgfVxuXG4uaXRhbGljIHtcbiAgZm9udC1zdHlsZTogaXRhbGljOyB9XG5cbi5saWdodCB7XG4gIGZvbnQtd2VpZ2h0OiAxMDA7IH1cblxuLm1lZGl1bSB7XG4gIGZvbnQtd2VpZ2h0OiA1MDA7IH1cblxuLmJvbGQge1xuICBmb250LXdlaWdodDogOTAwOyB9XG5cbi51cHBlcmNhc2Uge1xuICB0ZXh0LXRyYW5zZm9ybTogdXBwZXJjYXNlOyB9XG5cbi51bmRlcmxpbmUge1xuICB0ZXh0LWRlY29yYXRpb246IHVuZGVybGluZTsgfVxuXG4uZGVjb3JhdGlvbi0tbm9uZSB7XG4gIHRleHQtZGVjb3JhdGlvbjogbm9uZTsgfVxuXG4vKipcbiAqIEJ1dHRvbnMgc2hvdWxkIGJlIGJ1dHRvbi5idXR0b24gb3JcbiAqIC5idXR0b25bcm9sZT1cImJ1dHRvblwiXSBmb3IgYWNjZXNzaWJpbGl0eVxuICovXG5idXR0b24uYnV0dG9uLFxuLmJ1dHRvbltyb2xlPVwiYnV0dG9uXCJdLFxuaW5wdXQuYnV0dG9uW3R5cGU9XCJzdWJtaXRcIl0ge1xuICBib3JkZXI6IDA7XG4gIGJvcmRlci1yYWRpdXM6IDA7XG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgYmFja2dyb3VuZC1jb2xvcjogIzAwMDtcbiAgY29sb3I6IHdoaXRlO1xuICBjdXJzb3I6IHBvaW50ZXI7XG4gIHBhZGRpbmc6IDAuN2VtIDJlbTtcbiAgbGluZS1oZWlnaHQ6IGluaGVyaXQ7XG4gIHRleHQtZGVjb3JhdGlvbjogbm9uZTtcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xuICAtd2Via2l0LWFwcGVhcmFuY2U6IG5vbmU7IH1cblxuYnV0dG9uW2Rpc2FibGVkXSxcbmlucHV0W2Rpc2FibGVkXSB7XG4gIGN1cnNvcjogZGVmYXVsdDsgfVxuXG5mb3JtIHtcbiAgbWFyZ2luOiAwOyB9XG5cbmlucHV0LFxubGFiZWwsXG5zZWxlY3QsXG50ZXh0YXJlYSB7XG4gIG91dGxpbmU6IDA7XG4gIGJvcmRlcjogMDtcbiAgYm9yZGVyLXJhZGl1czogMDtcbiAgZm9udC1zaXplOiBpbmhlcml0O1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gIGJhY2tncm91bmQtY29sb3I6IHRyYW5zcGFyZW50OyB9XG5cbmlucHV0LFxudGV4dGFyZWEsXG5zZWxlY3Qge1xuICBib3JkZXI6IDFweCBzb2xpZCAjMDAwO1xuICBwYWRkaW5nOiAuMzVlbSAuNjVlbTtcbiAgLXdlYmtpdC1hcHBlYXJhbmNlOiBub25lOyB9XG5cbnNlbGVjdDo6LW1zLWV4cGFuZCB7XG4gIGRpc3BsYXk6IG5vbmU7IH1cblxudGV4dGFyZWEge1xuICBtYXgtd2lkdGg6IDEwMCU7XG4gIG92ZXJmbG93OiBhdXRvO1xuICByZXNpemU6IHZlcnRpY2FsOyB9XG5cbm9sLCB1bCB7XG4gIGxpc3Qtc3R5bGU6IG5vbmU7IH1cblxuLyogVG8gYWNoaWV2ZSBsaXN0IHN0eWxpbmcsICovXG4vKiBhZGQgdGhlIC5saXN0IGNsYXNzICovXG4vKiBpLmUgb2wubGlzdCwgdWwubGlzdCAqL1xuLmxpc3QgdWwsXG4ubGlzdCBvbCB7XG4gIG1hcmdpbjogMDtcbiAgcGFkZGluZy1sZWZ0OiAyZW07IH1cblxuLmxpc3Qgb2wge1xuICBsaXN0LXN0eWxlOiBsb3dlci1hbHBoYSBpbnNpZGU7IH1cblxuLmxpc3QgbGkge1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gIG1hcmdpbjogLjMzZW0gMDtcbiAgcGFkZGluZy1sZWZ0OiAxLjVlbTsgfVxuXG5vbC5saXN0IHtcbiAgY291bnRlci1yZXNldDogbnVtOyB9XG5cbm9sLmxpc3QgbGk6OmJlZm9yZSB7XG4gIGNvbnRlbnQ6IGNvdW50ZXIobnVtKSBcIi5cIjtcbiAgY291bnRlci1pbmNyZW1lbnQ6IG51bTtcbiAgZGlzcGxheTogYmxvY2s7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgbGVmdDogMDtcbiAgdG9wOiAwOyB9XG5cbnVsLmxpc3QgbGk6OmJlZm9yZSB7XG4gIGNvbnRlbnQ6ICfigKInO1xuICBkaXNwbGF5OiBibG9jaztcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICBsZWZ0OiAwO1xuICB0b3A6IDA7IH1cblxuLnRhYmxlLS1maXhlZCB7XG4gIHRhYmxlLWxheW91dDogZml4ZWQ7IH1cblxuLnRhYmxlX19yb3ctaGVhZGVyIHtcbiAgZGlzcGxheTogdGFibGUtaGVhZGVyLWdyb3VwOyB9XG5cbi50YWJsZV9fcm93LWZvb3RlciB7XG4gIGRpc3BsYXk6IHRhYmxlLWZvb3Rlci1ncm91cDsgfVxuXG4udGFibGVfX3Jvdy1ncm91cCB7XG4gIGRpc3BsYXk6IHRhYmxlLXJvdy1ncm91cDsgfVxuXG4udGFibGVfX3JvdyB7XG4gIGRpc3BsYXk6IHRhYmxlLXJvdzsgfVxuXG4udGFibGVfX2NlbGwge1xuICBkaXNwbGF5OiB0YWJsZS1jZWxsOyB9XG5cbnRhYmxlLFxuLnRhYmxlIHtcbiAgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTtcbiAgYm9yZGVyLXNwYWNpbmc6IDA7XG4gIGRpc3BsYXk6IHRhYmxlO1xuICB3aWR0aDogMTAwJTsgfVxuXG50ZCxcbnRoIHtcbiAgZGlzcGxheTogdGFibGUtY2VsbDtcbiAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkICMwMDA7XG4gIHBhZGRpbmc6IC42NmVtIDEuMzNlbTsgfVxuXG50aCB7XG4gIGZvbnQtd2VpZ2h0OiAxMDA7XG4gIHRleHQtYWxpZ246IGxlZnQ7IH1cblxuLm1sYSwgLm1oYSwgLm14YSB7XG4gIG1hcmdpbi1sZWZ0OiBhdXRvOyB9XG5cbi5tcmEsIC5taGEsIC5teGEge1xuICBtYXJnaW4tcmlnaHQ6IGF1dG87IH1cblxuLm10YSwgLm12YSwgLm14YSB7XG4gIG1hcmdpbi10b3A6IGF1dG87IH1cblxuLm1iYSwgLm12YSwgLm14YSB7XG4gIG1hcmdpbi1ib3R0b206IGF1dG87IH1cblxuLm10MCwgLm12MCwgLm14MCB7XG4gIG1hcmdpbi10b3A6IDA7IH1cblxuLm1iMCwgLm12MCwgLm14MCB7XG4gIG1hcmdpbi1ib3R0b206IDA7IH1cblxuLm1sMCwgLm1oMCwgLm14MCB7XG4gIG1hcmdpbi1sZWZ0OiAwOyB9XG5cbi5tcjAsIC5taDAsIC5teDAge1xuICBtYXJnaW4tcmlnaHQ6IDA7IH1cblxuLnB0MCwgLnB2MCwgLnB4MCB7XG4gIHBhZGRpbmctdG9wOiAwOyB9XG5cbi5wYjAsIC5wdjAsIC5weDAge1xuICBwYWRkaW5nLWJvdHRvbTogMDsgfVxuXG4ucGwwLCAucGgwLCAucHgwIHtcbiAgcGFkZGluZy1sZWZ0OiAwOyB9XG5cbi5wcjAsIC5waDAsIC5weDAge1xuICBwYWRkaW5nLXJpZ2h0OiAwOyB9XG5cbi5tdDAyNSwgLm12MDI1LCAubXgwMjUge1xuICBtYXJnaW4tdG9wOiAwLjI1ZW07IH1cblxuLm1iMDI1LCAubXYwMjUsIC5teDAyNSB7XG4gIG1hcmdpbi1ib3R0b206IDAuMjVlbTsgfVxuXG4ubWwwMjUsIC5taDAyNSwgLm14MDI1IHtcbiAgbWFyZ2luLWxlZnQ6IDAuMjVlbTsgfVxuXG4ubXIwMjUsIC5taDAyNSwgLm14MDI1IHtcbiAgbWFyZ2luLXJpZ2h0OiAwLjI1ZW07IH1cblxuLm1objAyNSB7XG4gIG1hcmdpbi1sZWZ0OiAtMC4yNWVtO1xuICBtYXJnaW4tcmlnaHQ6IC0wLjI1ZW07IH1cblxuLnB0MDI1LCAucHYwMjUsIC5weDAyNSB7XG4gIHBhZGRpbmctdG9wOiAwLjI1ZW07IH1cblxuLnBiMDI1LCAucHYwMjUsIC5weDAyNSB7XG4gIHBhZGRpbmctYm90dG9tOiAwLjI1ZW07IH1cblxuLnBsMDI1LCAucGgwMjUsIC5weDAyNSB7XG4gIHBhZGRpbmctbGVmdDogMC4yNWVtOyB9XG5cbi5wcjAyNSwgLnBoMDI1LCAucHgwMjUge1xuICBwYWRkaW5nLXJpZ2h0OiAwLjI1ZW07IH1cblxuLm10MDUsIC5tdjA1LCAubXgwNSB7XG4gIG1hcmdpbi10b3A6IDAuNWVtOyB9XG5cbi5tYjA1LCAubXYwNSwgLm14MDUge1xuICBtYXJnaW4tYm90dG9tOiAwLjVlbTsgfVxuXG4ubWwwNSwgLm1oMDUsIC5teDA1IHtcbiAgbWFyZ2luLWxlZnQ6IDAuNWVtOyB9XG5cbi5tcjA1LCAubWgwNSwgLm14MDUge1xuICBtYXJnaW4tcmlnaHQ6IDAuNWVtOyB9XG5cbi5taG4wNSB7XG4gIG1hcmdpbi1sZWZ0OiAtMC41ZW07XG4gIG1hcmdpbi1yaWdodDogLTAuNWVtOyB9XG5cbi5wdDA1LCAucHYwNSwgLnB4MDUge1xuICBwYWRkaW5nLXRvcDogMC41ZW07IH1cblxuLnBiMDUsIC5wdjA1LCAucHgwNSB7XG4gIHBhZGRpbmctYm90dG9tOiAwLjVlbTsgfVxuXG4ucGwwNSwgLnBoMDUsIC5weDA1IHtcbiAgcGFkZGluZy1sZWZ0OiAwLjVlbTsgfVxuXG4ucHIwNSwgLnBoMDUsIC5weDA1IHtcbiAgcGFkZGluZy1yaWdodDogMC41ZW07IH1cblxuLm10MDc1LCAubXYwNzUsIC5teDA3NSB7XG4gIG1hcmdpbi10b3A6IDAuNzVlbTsgfVxuXG4ubWIwNzUsIC5tdjA3NSwgLm14MDc1IHtcbiAgbWFyZ2luLWJvdHRvbTogMC43NWVtOyB9XG5cbi5tbDA3NSwgLm1oMDc1LCAubXgwNzUge1xuICBtYXJnaW4tbGVmdDogMC43NWVtOyB9XG5cbi5tcjA3NSwgLm1oMDc1LCAubXgwNzUge1xuICBtYXJnaW4tcmlnaHQ6IDAuNzVlbTsgfVxuXG4ubWhuMDc1IHtcbiAgbWFyZ2luLWxlZnQ6IC0wLjc1ZW07XG4gIG1hcmdpbi1yaWdodDogLTAuNzVlbTsgfVxuXG4ucHQwNzUsIC5wdjA3NSwgLnB4MDc1IHtcbiAgcGFkZGluZy10b3A6IDAuNzVlbTsgfVxuXG4ucGIwNzUsIC5wdjA3NSwgLnB4MDc1IHtcbiAgcGFkZGluZy1ib3R0b206IDAuNzVlbTsgfVxuXG4ucGwwNzUsIC5waDA3NSwgLnB4MDc1IHtcbiAgcGFkZGluZy1sZWZ0OiAwLjc1ZW07IH1cblxuLnByMDc1LCAucGgwNzUsIC5weDA3NSB7XG4gIHBhZGRpbmctcmlnaHQ6IDAuNzVlbTsgfVxuXG4ubXQxLCAubXYxLCAubXgxIHtcbiAgbWFyZ2luLXRvcDogMWVtOyB9XG5cbi5tYjEsIC5tdjEsIC5teDEge1xuICBtYXJnaW4tYm90dG9tOiAxZW07IH1cblxuLm1sMSwgLm1oMSwgLm14MSB7XG4gIG1hcmdpbi1sZWZ0OiAxZW07IH1cblxuLm1yMSwgLm1oMSwgLm14MSB7XG4gIG1hcmdpbi1yaWdodDogMWVtOyB9XG5cbi5taG4xIHtcbiAgbWFyZ2luLWxlZnQ6IC0xZW07XG4gIG1hcmdpbi1yaWdodDogLTFlbTsgfVxuXG4ucHQxLCAucHYxLCAucHgxIHtcbiAgcGFkZGluZy10b3A6IDFlbTsgfVxuXG4ucGIxLCAucHYxLCAucHgxIHtcbiAgcGFkZGluZy1ib3R0b206IDFlbTsgfVxuXG4ucGwxLCAucGgxLCAucHgxIHtcbiAgcGFkZGluZy1sZWZ0OiAxZW07IH1cblxuLnByMSwgLnBoMSwgLnB4MSB7XG4gIHBhZGRpbmctcmlnaHQ6IDFlbTsgfVxuXG4ubXQyLCAubXYyLCAubXgyIHtcbiAgbWFyZ2luLXRvcDogMmVtOyB9XG5cbi5tYjIsIC5tdjIsIC5teDIge1xuICBtYXJnaW4tYm90dG9tOiAyZW07IH1cblxuLm1sMiwgLm1oMiwgLm14MiB7XG4gIG1hcmdpbi1sZWZ0OiAyZW07IH1cblxuLm1yMiwgLm1oMiwgLm14MiB7XG4gIG1hcmdpbi1yaWdodDogMmVtOyB9XG5cbi5taG4yIHtcbiAgbWFyZ2luLWxlZnQ6IC0yZW07XG4gIG1hcmdpbi1yaWdodDogLTJlbTsgfVxuXG4ucHQyLCAucHYyLCAucHgyIHtcbiAgcGFkZGluZy10b3A6IDJlbTsgfVxuXG4ucGIyLCAucHYyLCAucHgyIHtcbiAgcGFkZGluZy1ib3R0b206IDJlbTsgfVxuXG4ucGwyLCAucGgyLCAucHgyIHtcbiAgcGFkZGluZy1sZWZ0OiAyZW07IH1cblxuLnByMiwgLnBoMiwgLnB4MiB7XG4gIHBhZGRpbmctcmlnaHQ6IDJlbTsgfVxuXG5odG1sLCBib2R5IHtcbiAgbWFyZ2luOiAwO1xuICBwYWRkaW5nOiAwOyB9XG5cbi50aGVtZSB7XG4gIGNvbG9yOiAjMDBDOUZDOyB9XG5cbi5iZy10aGVtZSB7XG4gIGJhY2tncm91bmQ6ICMwMEM5RkM7IH1cblxuLndoaXRlIHtcbiAgY29sb3I6IHdoaXRlOyB9XG5cbi5yZWxhdGl2ZSB7XG4gIHBvc2l0aW9uOiByZWxhdGl2ZTsgfVxuXG4uYWJzb2x1dGUge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7IH1cblxuLmZpeGVkIHtcbiAgcG9zaXRpb246IGZpeGVkOyB9XG5cbi5maXQtdCwgLmZpdC14IHtcbiAgdG9wOiAwOyB9XG5cbi5maXQtYiwgLmZpdC14IHtcbiAgYm90dG9tOiAwOyB9XG5cbi5maXQtbCwgLmZpdC14IHtcbiAgbGVmdDogMDsgfVxuXG4uZml0LXIsIC5maXQteCB7XG4gIHJpZ2h0OiAwOyB9XG5cbi5maWxsLXYge1xuICBoZWlnaHQ6IDEwMHZoOyB9XG5cbi5maWxsLXYwNSB7XG4gIGhlaWdodDogNTB2aDsgfVxuXG4uZmlsbC1oIHtcbiAgd2lkdGg6IDEwMCU7IH1cblxuLmNvbnRhaW5lciB7XG4gIG1heC13aWR0aDogNTUwcHg7IH1cblxuOjotbW96LXNlbGVjdGlvbiB7XG4gIGJhY2tncm91bmQ6ICMwMEM5RkM7IH1cblxuOjpzZWxlY3Rpb24ge1xuICBiYWNrZ3JvdW5kOiAjMDBDOUZDOyB9XG5cbi5yb290IHAge1xuICBjb2xvcjogcmdiYSgwLCAwLCAwLCAwLjQpOyB9XG4gIC5yb290IHAuc2hhcmFibGUge1xuICAgIGNvbG9yOiBibGFjazsgfVxuXG4uc3NoYXJlIHtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICB2aXNpYmlsaXR5OiBoaWRkZW47XG4gIHRvcDogMDtcbiAgbGVmdDogMDtcbiAgb3BhY2l0eTogMDtcbiAgdHJhbnNpdGlvbi1wcm9wZXJ0eTogdHJhbnNmb3JtLCBvcGFjaXR5O1xuICB0cmFuc2l0aW9uLWR1cmF0aW9uOiAyMDBtcztcbiAgdHJhbnNpdGlvbi10aW1pbmctZnVuY3Rpb246IGN1YmljLWJlemllcigwLjI0LCAwLjgyLCAwLjM1LCAxKTsgfVxuXG4uc3NoYXJlOmZvY3VzIHtcbiAgb3V0bGluZTogMDsgfVxuXG4uc3NoYXJlLmlzLXRhY2tlZCB7XG4gIHZpc2liaWxpdHk6IHZpc2libGU7IH1cblxuLnNzaGFyZS5pcy1hY3RpdmUge1xuICBvcGFjaXR5OiAxOyB9XG5cbi5zc2hhcmUuaXMtaGlkaW5nIHtcbiAgb3BhY2l0eTogMDsgfVxuXG4uc3NoYXJlX19pbm5lciB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGJhY2tncm91bmQ6IHdoaXRlO1xuICBib3JkZXItcmFkaXVzOiAzcHg7XG4gIG92ZXJmbG93OiBoaWRkZW47XG4gIGJveC1zaGFkb3c6IDAgM3B4IDEycHggcmdiYSgwLCAwLCAwLCAwLjIpOyB9XG5cbi5zc2hhcmVfX2lubmVyOjpiZWZvcmUge1xuICBjb250ZW50OiAnJztcbiAgZGlzcGxheTogYmxvY2s7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgbGVmdDogMDtcbiAgcmlnaHQ6IDA7XG4gIGJvdHRvbTogMDtcbiAgbWFyZ2luOiBhdXRvO1xuICB3aWR0aDogMTBweDtcbiAgaGVpZ2h0OiAxMHB4O1xuICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVkoNDAlKSByb3RhdGUoNDVkZWcpO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiB3aGl0ZTsgfVxuXG4uc3NoYXJlX19pbm5lciBhIHtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICB3aWR0aDogMzVweDtcbiAgaGVpZ2h0OiAzNXB4O1xuICBsaW5lLWhlaWdodDogMzVweDtcbiAgY29sb3I6IGJsYWNrOyB9XG5cbi5zc2hhcmVfX2lubmVyIGE6aG92ZXIge1xuICBjb2xvcjogIzAwQzlGQzsgfVxuXG4uc3NoYXJlX19pbm5lciBhOmZvY3VzIHtcbiAgY29sb3I6ICMwMEM5RkM7XG4gIG91dGxpbmU6IDA7IH1cblxuLnNzaGFyZV9faW5uZXIgYSBzdmcge1xuICBkaXNwbGF5OiBibG9jaztcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICB0b3A6IDA7XG4gIGxlZnQ6IDA7XG4gIHJpZ2h0OiAwO1xuICBib3R0b206IDA7XG4gIG1hcmdpbjogYXV0bztcbiAgd2lkdGg6IDE0cHg7XG4gIGhlaWdodDogMTRweDsgfVxuIl19 */ -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "", 3 | "version": "", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "parallelshell 'npm run js:watch' 'npm run css:watch'", 8 | "js:build": "browserify index.js --debug -p [minifyify --map demo.js.map --output demo.js.map] > demo.js", 9 | "js:watch": "watchify index.js -v -d -o demo.js", 10 | "css:build": "node-sass styles/main.scss | postcss -u autoprefixer > main.css", 11 | "css:watch": "onchange 'styles/**/*.scss' -- npm run css:build" 12 | }, 13 | "browserify": { 14 | "debug": true, 15 | "cache": {}, 16 | "packageCache": {}, 17 | "extension": [ 18 | "js" 19 | ], 20 | "transform": [ 21 | "babelify" 22 | ] 23 | }, 24 | "browserify-shim": {}, 25 | "repository": { 26 | "type": "git", 27 | "url": "git+ssh://" 28 | }, 29 | "author": "estrattonbailey", 30 | "license": "MIT", 31 | "bugs": { 32 | "url": "" 33 | }, 34 | "homepage": "", 35 | "devDependencies": { 36 | "autoprefixer": "*", 37 | "babel-preset-es2015": "*", 38 | "babel-preset-react": "*", 39 | "babelify": "*", 40 | "browserify": "*", 41 | "exorcist": "*", 42 | "minifyify": "*", 43 | "node-sass": "*", 44 | "onchange": "*", 45 | "parallelshell": "*", 46 | "postcss-cli": "*", 47 | "watchify": "*" 48 | }, 49 | "dependencies": { 50 | "microstate": "0.0.3", 51 | "shallow-equal": "^1.0.0" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /example/src/Input.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { connect } from 'microstate' 3 | 4 | export default connect( 5 | { 6 | todos: [], 7 | activeInputValue: '' 8 | }, 9 | state => ({ 10 | val: state.activeInputValue 11 | }), 12 | (dispatch, state) => ({ 13 | update: val => dispatch({ 14 | activeInputValue: val 15 | }), 16 | add: todo => dispatch({ 17 | todos: [todo, ...state.todos], 18 | val: '', 19 | test: 'Hello world' 20 | }) 21 | }) 22 | )(({ val, update, add }) => { 23 | return ( 24 |
{ 25 | e.preventDefault() 26 | add(val) 27 | }}> 28 | update(e.target.value)}/> 29 |
30 | ) 31 | }) 32 | -------------------------------------------------------------------------------- /example/src/Todos.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { connect } from 'microstate' 3 | 4 | export default connect( 5 | null, 6 | state => ({ 7 | todos: state.todos 8 | }) 9 | )(props => { 10 | console.log(props.todos) 11 | return ( 12 |
13 |
    14 | {props.todos.map(todo => ( 15 |
  • {todo}
  • 16 | ))} 17 |
18 |
19 | ) 20 | }) 21 | -------------------------------------------------------------------------------- /example/styles/lib/align.scss: -------------------------------------------------------------------------------- 1 | 2 | .align-l { text-align: left } 3 | .align-c { text-align: center } 4 | .align-r { text-align: right } 5 | .align-j { text-align: justify } 6 | .align-m { vertical-align: middle } 7 | .align-t { vertical-align: top } 8 | .align-b { vertical-align: baseline } 9 | 10 | -------------------------------------------------------------------------------- /example/styles/lib/buttons.scss: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Buttons should be button.button or 4 | * .button[role="button"] for accessibility 5 | */ 6 | button.button, 7 | .button[role="button"], 8 | input.button[type="submit"] { 9 | border: 0; 10 | border-radius: 0; 11 | display: inline-block; 12 | background-color: #000; 13 | color: white; 14 | cursor: pointer; 15 | padding: 0.7em 2em; 16 | line-height: inherit; 17 | text-decoration: none; 18 | text-align: center; 19 | -webkit-appearance: none; 20 | } 21 | button[disabled], 22 | input[disabled] { 23 | cursor: default 24 | } 25 | 26 | -------------------------------------------------------------------------------- /example/styles/lib/display.scss: -------------------------------------------------------------------------------- 1 | 2 | .block { display: block } 3 | .inline { display: inline } 4 | .inline-block { display: inline-block } 5 | .hide { display: none } 6 | 7 | -------------------------------------------------------------------------------- /example/styles/lib/flexbox.scss: -------------------------------------------------------------------------------- 1 | 2 | .flex { display: flex } 3 | .flex-wrap { flex-wrap: wrap } 4 | .flex-items-start { align-items: flex-start } 5 | .flex-items-end { align-items: flex-end } 6 | .flex-items-center { align-items: center } 7 | .flex-items-baseline { align-items: baseline } 8 | .flex-items-stretch { align-items: stretch } 9 | .flex-justify-start { justify-content: flex-start } 10 | .flex-justify-end { justify-content: flex-end } 11 | .flex-justify-center { justify-content: center } 12 | .flex-justify-between { justify-content: space-between } 13 | .flex-justify-around { justify-content: space-around } 14 | .flex-auto { 15 | flex: 1 1 auto; 16 | min-width: 0; 17 | min-height: 0; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /example/styles/lib/floats.scss: -------------------------------------------------------------------------------- 1 | 2 | .float-l { float: left } 3 | .float-r { float: right } 4 | .clearfix { 5 | &::before, 6 | &::after { 7 | content:' '; 8 | display: table; 9 | } 10 | 11 | &::after { 12 | clear: both; 13 | } 14 | } 15 | 16 | -------------------------------------------------------------------------------- /example/styles/lib/forms.scss: -------------------------------------------------------------------------------- 1 | 2 | form { 3 | margin: 0; 4 | } 5 | input, 6 | label, 7 | select, 8 | textarea { 9 | outline: 0; 10 | border: 0; 11 | border-radius: 0; 12 | font-size: inherit; 13 | position: relative; 14 | background-color: transparent; 15 | } 16 | input, 17 | textarea, 18 | select { 19 | border: 1px solid #000; 20 | padding: .35em .65em; 21 | -webkit-appearance: none; 22 | } 23 | select::-ms-expand { 24 | display: none 25 | } 26 | textarea { 27 | max-width: 100%; 28 | overflow: auto; 29 | resize: vertical; 30 | } 31 | 32 | -------------------------------------------------------------------------------- /example/styles/lib/lists.scss: -------------------------------------------------------------------------------- 1 | 2 | ol, ul { 3 | list-style: none; 4 | } 5 | 6 | /* To achieve list styling, */ 7 | /* add the .list class */ 8 | /* i.e ol.list, ul.list */ 9 | .list ul, 10 | .list ol { 11 | margin: 0; 12 | padding-left: 2em; 13 | } 14 | .list ol { 15 | list-style: lower-alpha inside; 16 | } 17 | .list li { 18 | position: relative; 19 | margin: .33em 0; 20 | padding-left: 1.5em; 21 | } 22 | 23 | ol.list { 24 | counter-reset: num; 25 | } 26 | ol.list li::before { 27 | content: counter(num) '.'; 28 | counter-increment: num; 29 | display: block; 30 | position: absolute; 31 | left: 0; top: 0; 32 | } 33 | 34 | ul.list li::before { 35 | content: '•'; 36 | display: block; 37 | position: absolute; 38 | left: 0; top: 0; 39 | } 40 | 41 | -------------------------------------------------------------------------------- /example/styles/lib/positioning.scss: -------------------------------------------------------------------------------- 1 | 2 | .relative { position: relative } 3 | .absolute { position: absolute } 4 | .fixed { position: fixed } 5 | .fit-t, .fit-x { top: 0 } 6 | .fit-b, .fit-x { bottom: 0 } 7 | .fit-l, .fit-x { left: 0 } 8 | .fit-r, .fit-x { right: 0 } 9 | 10 | -------------------------------------------------------------------------------- /example/styles/lib/spacing.scss: -------------------------------------------------------------------------------- 1 | 2 | .mla, .mha, .mxa { margin-left: auto } 3 | .mra, .mha, .mxa { margin-right: auto } 4 | .mta, .mva, .mxa { margin-top: auto } 5 | .mba, .mva, .mxa { margin-bottom: auto; } 6 | 7 | .mt0, .mv0, .mx0 { margin-top: 0 } 8 | .mb0, .mv0, .mx0 { margin-bottom: 0 } 9 | .ml0, .mh0, .mx0 { margin-left: 0 } 10 | .mr0, .mh0, .mx0 { margin-right: 0 } 11 | .pt0, .pv0, .px0 { padding-top: 0 } 12 | .pb0, .pv0, .px0 { padding-bottom: 0 } 13 | .pl0, .ph0, .px0 { padding-left: 0 } 14 | .pr0, .ph0, .px0 { padding-right: 0 } 15 | 16 | .mt025, .mv025, .mx025 { margin-top: 0.25em } 17 | .mb025, .mv025, .mx025 { margin-bottom: 0.25em } 18 | .ml025, .mh025, .mx025 { margin-left: 0.25em } 19 | .mr025, .mh025, .mx025 { margin-right: 0.25em } 20 | .mhn025 { margin-left: -0.25em; margin-right: -0.25em; } 21 | .pt025, .pv025, .px025 { padding-top: 0.25em } 22 | .pb025, .pv025, .px025 { padding-bottom: 0.25em } 23 | .pl025, .ph025, .px025 { padding-left: 0.25em } 24 | .pr025, .ph025, .px025 { padding-right: 0.25em } 25 | 26 | .mt05, .mv05, .mx05 { margin-top: 0.5em } 27 | .mb05, .mv05, .mx05 { margin-bottom: 0.5em } 28 | .ml05, .mh05, .mx05 { margin-left: 0.5em } 29 | .mr05, .mh05, .mx05 { margin-right: 0.5em } 30 | .mhn05 { margin-left: -0.5em; margin-right: -0.5em; } 31 | .pt05, .pv05, .px05 { padding-top: 0.5em } 32 | .pb05, .pv05, .px05 { padding-bottom: 0.5em } 33 | .pl05, .ph05, .px05 { padding-left: 0.5em } 34 | .pr05, .ph05, .px05 { padding-right: 0.5em } 35 | 36 | .mt075, .mv075, .mx075 { margin-top: 0.75em } 37 | .mb075, .mv075, .mx075 { margin-bottom: 0.75em } 38 | .ml075, .mh075, .mx075 { margin-left: 0.75em } 39 | .mr075, .mh075, .mx075 { margin-right: 0.75em } 40 | .mhn075 { margin-left: -0.75em; margin-right: -0.75em; } 41 | .pt075, .pv075, .px075 { padding-top: 0.75em } 42 | .pb075, .pv075, .px075 { padding-bottom: 0.75em } 43 | .pl075, .ph075, .px075 { padding-left: 0.75em } 44 | .pr075, .ph075, .px075 { padding-right: 0.75em } 45 | 46 | .mt1, .mv1, .mx1 { margin-top: 1em } 47 | .mb1, .mv1, .mx1 { margin-bottom: 1em } 48 | .ml1, .mh1, .mx1 { margin-left: 1em } 49 | .mr1, .mh1, .mx1 { margin-right: 1em } 50 | .mhn1 { margin-left: -1em; margin-right: -1em; } 51 | .pt1, .pv1, .px1 { padding-top: 1em } 52 | .pb1, .pv1, .px1 { padding-bottom: 1em } 53 | .pl1, .ph1, .px1 { padding-left: 1em } 54 | .pr1, .ph1, .px1 { padding-right: 1em } 55 | 56 | .mt2, .mv2, .mx2 { margin-top: 2em } 57 | .mb2, .mv2, .mx2 { margin-bottom: 2em } 58 | .ml2, .mh2, .mx2 { margin-left: 2em } 59 | .mr2, .mh2, .mx2 { margin-right: 2em } 60 | .mhn2 { margin-left: -2em; margin-right: -2em; } 61 | .pt2, .pv2, .px2 { padding-top: 2em } 62 | .pb2, .pv2, .px2 { padding-bottom: 2em } 63 | .pl2, .ph2, .px2 { padding-left: 2em } 64 | .pr2, .ph2, .px2 { padding-right: 2em } 65 | -------------------------------------------------------------------------------- /example/styles/lib/tables.scss: -------------------------------------------------------------------------------- 1 | 2 | .table--fixed { table-layout: fixed } 3 | .table__row-header { display: table-header-group } 4 | .table__row-footer { display: table-footer-group } 5 | .table__row-group { display: table-row-group } 6 | .table__row { display: table-row } 7 | .table__cell { display: table-cell } 8 | 9 | table, 10 | .table { 11 | border-collapse: collapse; 12 | border-spacing: 0; 13 | display: table; 14 | width: 100%; 15 | } 16 | td, 17 | th { 18 | display: table-cell; 19 | border-bottom: 1px solid #000; 20 | padding: .66em 1.33em; 21 | } 22 | th { 23 | font-weight: 100; 24 | text-align: left; 25 | } 26 | 27 | -------------------------------------------------------------------------------- /example/styles/lib/typography.scss: -------------------------------------------------------------------------------- 1 | 2 | body { 3 | color: #000; 4 | font-family: Helvetica, Arial, sans-serif; 5 | font-size: 120%; 6 | line-height: 1.7; 7 | font-weight: 400; 8 | -webkit-font-smoothing: antialiased; 9 | } 10 | h1, h2, h3, h4, h5, h6 { 11 | margin: 1em 0 .6em; 12 | } 13 | .scale1, 14 | h1, .h1 { 15 | font-size: 4rem; 16 | } 17 | h1, .h1 { 18 | line-height: 1.1; 19 | } 20 | .scale2, 21 | h2, .h2 { 22 | font-size: 3rem; 23 | } 24 | h2, .h2 { 25 | line-height: 1.3; 26 | } 27 | .scale3, 28 | h3, .h3 { 29 | font-size: 2rem; 30 | } 31 | h3, .h3 { 32 | line-height: 1.5; 33 | } 34 | .scale4, 35 | h4, .h4 { 36 | font-size: 1.5rem; 37 | } 38 | h4, .h4 { 39 | line-height: 1.5; 40 | } 41 | .scale5, 42 | h5, .h5 { 43 | font-size: 1rem; 44 | } 45 | h5, .h5 { 46 | line-height: 1.6; 47 | } 48 | .scale6, 49 | h6, .h6 { 50 | font-size: 0.875rem; 51 | } 52 | h6, .h6 { 53 | line-height: 1.6; 54 | } 55 | .scale0, 56 | p, .p { 57 | font-size: 1rem; 58 | } 59 | p, .p { 60 | line-height: 1.7; 61 | } 62 | p { 63 | margin: 1.5em 0 64 | } 65 | a { 66 | color: inherit 67 | } 68 | blockquote { 69 | margin: 3rem 0; 70 | padding-left: 2rem; 71 | border-left: 4px solid #148ECC; 72 | } 73 | hr { 74 | display: block; 75 | margin: 0; 76 | border: 0; 77 | height: 1px; 78 | width: 100%; 79 | background-color: currentColor; 80 | color: inherit; 81 | } 82 | small { 83 | font-size: 0.8em; 84 | } 85 | strong { 86 | font-weight: bold; 87 | } 88 | .type--reset { 89 | margin: 0; 90 | line-height: 1; 91 | } 92 | .italic { 93 | font-style: italic; 94 | } 95 | .light { 96 | font-weight: 100; 97 | } 98 | .medium { 99 | font-weight: 500; 100 | } 101 | .bold { 102 | font-weight: 900; 103 | } 104 | .uppercase { 105 | text-transform: uppercase; 106 | } 107 | .underline { 108 | text-decoration: underline; 109 | } 110 | .decoration--none { 111 | text-decoration: none; 112 | } 113 | 114 | -------------------------------------------------------------------------------- /example/styles/lib/z-index.scss: -------------------------------------------------------------------------------- 1 | 2 | .z0 { z-index: 0 } 3 | .z1 { z-index: 100 } 4 | .z2 { z-index: 200 } 5 | .z3 { z-index: 300 } 6 | .z5 { z-index: 500 } 7 | .z6 { z-index: 600 } 8 | .z7 { z-index: 700 } 9 | .z8 { z-index: 800 } 10 | .z9 { z-index: 900 } 11 | .z10 { z-index: 1000 } 12 | 13 | -------------------------------------------------------------------------------- /example/styles/main.scss: -------------------------------------------------------------------------------- 1 | $theme: #00C9FC; 2 | 3 | @import 'lib/display'; 4 | @import 'lib/positioning'; 5 | @import 'lib/flexbox'; 6 | @import 'lib/align'; 7 | @import 'lib/floats'; 8 | @import 'lib/z-index'; 9 | @import 'lib/typography'; 10 | @import 'lib/buttons'; 11 | @import 'lib/forms'; 12 | @import 'lib/lists'; 13 | @import 'lib/tables'; 14 | @import 'lib/spacing'; 15 | 16 | html, body { 17 | margin: 0; 18 | padding: 0; 19 | } 20 | 21 | .theme { 22 | color: $theme; 23 | } 24 | .bg-theme { 25 | background: $theme; 26 | } 27 | .white { 28 | color: white; 29 | } 30 | 31 | .relative { position: relative } 32 | .absolute { position: absolute } 33 | .fixed { position: fixed } 34 | .fit-t, .fit-x { top: 0 } 35 | .fit-b, .fit-x { bottom: 0 } 36 | .fit-l, .fit-x { left: 0 } 37 | .fit-r, .fit-x { right: 0 } 38 | .fill-v { height: 100vh } 39 | .fill-v05 { height: 50vh } 40 | .fill-h { width: 100% } 41 | 42 | .container { 43 | max-width: 550px 44 | } 45 | 46 | ::-moz-selection { 47 | background: $theme 48 | } 49 | ::selection { 50 | background: $theme 51 | } 52 | 53 | .root { 54 | p { 55 | color: rgba(0,0,0,0.4); 56 | 57 | &.sharable { 58 | color: black; 59 | } 60 | } 61 | } 62 | 63 | .sshare { 64 | position: absolute; 65 | visibility: hidden; 66 | top: 0; 67 | left: 0; 68 | opacity: 0; 69 | transition-property: transform, opacity; 70 | transition-duration: 200ms; 71 | transition-timing-function: cubic-bezier(.24,.82,.35,1); 72 | } 73 | .sshare:focus { 74 | outline: 0; 75 | } 76 | .sshare.is-tacked { 77 | visibility: visible; 78 | } 79 | .sshare.is-active { 80 | opacity: 1; 81 | } 82 | .sshare.is-hiding { 83 | opacity: 0; 84 | } 85 | .sshare__inner { 86 | display: flex; 87 | background: white; 88 | 89 | border-radius: 3px; 90 | overflow: hidden; 91 | box-shadow: 0 3px 12px rgba(0,0,0,0.2); 92 | } 93 | .sshare__inner::before { 94 | content: ''; 95 | display: block; 96 | position: absolute; 97 | left: 0; right: 0; bottom: 0; 98 | margin: auto; 99 | width: 10px; 100 | height: 10px; 101 | transform: translateY(40%) rotate(45deg); 102 | background-color: white; 103 | } 104 | .sshare__inner a { 105 | position: relative; 106 | width: 35px; 107 | height: 35px; 108 | line-height: 35px; 109 | color: black; 110 | } 111 | .sshare__inner a:hover { 112 | color: $theme; 113 | } 114 | .sshare__inner a:focus { 115 | color: $theme; 116 | outline: 0; 117 | } 118 | .sshare__inner a svg { 119 | display: block; 120 | position: absolute; 121 | top: 0; left: 0; right: 0; bottom: 0; 122 | margin: auto; 123 | width: 14px; 124 | height: 14px; 125 | } 126 | -------------------------------------------------------------------------------- /package/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | "transform-object-rest-spread", 4 | "transform-class-properties" 5 | ], 6 | "presets": [ 7 | "es2015", 8 | "react" 9 | ] 10 | } 11 | 12 | -------------------------------------------------------------------------------- /package/.gitignore: -------------------------------------------------------------------------------- 1 | /dist 2 | -------------------------------------------------------------------------------- /package/.npmignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/estrattonbailey/microstate/7798800f386a293b3cfa24ddcc288428e23d40bc/package/.npmignore -------------------------------------------------------------------------------- /package/README.md: -------------------------------------------------------------------------------- 1 | # microstate 2 | Co-located, functional state management for React. `seState` syntatic sugar. 3 | 4 | [![js-standard-style](https://cdn.rawgit.com/feross/standard/master/badge.svg)](http://standardjs.com) 5 | 6 | ## Usage 7 | Wrap your application with the `Provider`. 8 | ```javascript 9 | import { Provider } from 'microstate' 10 | 11 | const App = props => ( 12 | 13 |

My App

14 |
15 | ) 16 | 17 | render(, root) 18 | ``` 19 | 20 | Connect your component to the provider state using `connect`. The function signature for connect looks like this: 21 | ``` 22 | connect(mapStateToProps[, mapDispatchToProps, initialState])(MyComp) 23 | ``` 24 | 25 | ```javascript 26 | import { connect } from 'microstate' 27 | 28 | const initialState = { 29 | count: 0 30 | } 31 | 32 | const mapStateToProps = state => ({ 33 | count: state.count 34 | }) 35 | 36 | const mapDispatchToProps = dispatch => ({ 37 | inc: () => dispatch(state => { 38 | count: state.count + 1 39 | }) 40 | }) 41 | 42 | const Component = ({ inc, count }) => ( 43 |
44 | 45 | {count} 46 |
47 | ) 48 | 49 | export default connect( 50 | mapStateToProps, 51 | mapDispatchToProps, 52 | initialState 53 | )(Component) 54 | ``` 55 | 56 | Then render your component within the Provider context. 57 | ```javascript 58 | import { Provider } from 'microstate' 59 | import Component from './Component.js' 60 | 61 | const App = props => ( 62 | 63 | 64 | 65 | ) 66 | 67 | render(, root) 68 | ``` 69 | 70 | Note: the state is availabe at a component level and below during first render. However, since an initial render is required to evaluate the `connect` function, state will only be availabe at the application level *after* that first render. 71 | 72 | ## Subscribing to state 73 | Subscribing to another component's state is easy. Let's pretend the below is a different component than the counter above. 74 | ```javascript 75 | // Output.js 76 | export default connect( 77 | state => ({ 78 | count: state.count, 79 | text: state.text 80 | }, 81 | null, 82 | { 83 | text: 'The count is' 84 | } 85 | )(({ count, text }) => ( 86 |
{text + ' ' + count}
87 | )) 88 | ``` 89 | 90 | Then add it to the rendered `App` from above. 91 | ```javascript 92 | import { Provider } from 'microstate' 93 | import Component from './Component.js' 94 | import Output from './Output.js' 95 | 96 | export default props => ( 97 | 98 | 99 | 100 | 101 | ) 102 | 103 | render(, root) 104 | ``` 105 | 106 | MIT License 107 | -------------------------------------------------------------------------------- /package/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import PropTypes from 'prop-types' 3 | 4 | class LocalProvider extends React.Component { 5 | static displayName = 'LocalProvider' 6 | 7 | static contextTypes = { 8 | setGlobalState: PropTypes.func, 9 | getGlobalState: PropTypes.func, 10 | getInitialGlobalState: PropTypes.func, 11 | setInitialGlobalState: PropTypes.func, 12 | removeGlobalState: PropTypes.func 13 | } 14 | 15 | constructor (props, context) { 16 | super(props, context) 17 | 18 | if (!context.setGlobalState) throw new Error( 19 | `connect(${this.props.children.displayName}) component has been rendered outside Provider context.` 20 | ) 21 | } 22 | 23 | componentWillMount () { 24 | this.context.setInitialGlobalState(this.props.initialState || {}) 25 | } 26 | 27 | componentWillUnmount () { 28 | this.context.removeGlobalState(this.props.initialState || {}) 29 | } 30 | 31 | render() { 32 | const { initialState, mapStateToProps, mapDispatchToProps, children } = this.props 33 | const { getGlobalState, setGlobalState, getInitialGlobalState } = this.context 34 | 35 | const _state = getGlobalState() 36 | const state = mapStateToProps ? mapStateToProps(_state) : _state 37 | const dispatch = mapDispatchToProps ? mapDispatchToProps(setGlobalState, _state || {}, getInitialGlobalState()) : {} 38 | 39 | const props = { 40 | ...children.props, 41 | ...state, 42 | ...dispatch 43 | } 44 | 45 | return typeof children === 'function' ? ( 46 | children(props) 47 | ) : ( 48 | React.cloneElement(children, props) 49 | ) 50 | } 51 | } 52 | 53 | export class Provider extends React.Component { 54 | static displayName = 'Provider' 55 | 56 | static childContextTypes = { 57 | setGlobalState: PropTypes.func, 58 | getGlobalState: PropTypes.func, 59 | getInitialGlobalState: PropTypes.func, 60 | setInitialGlobalState: PropTypes.func, 61 | removeGlobalState: PropTypes.func 62 | } 63 | 64 | constructor (props) { 65 | super(props) 66 | 67 | this.state = {} 68 | 69 | this.ready = false 70 | this.initial = {} 71 | } 72 | 73 | getChildContext () { 74 | const _ = this 75 | 76 | return { 77 | setInitialGlobalState (state) { 78 | _.initial = Object.assign(_.state, state) 79 | }, 80 | setGlobalState (state, cb) { 81 | _.setState(state, () => { 82 | _.ready = true 83 | 84 | cb && cb() 85 | }) 86 | }, 87 | getGlobalState () { 88 | return _.state 89 | }, 90 | getInitialGlobalState () { 91 | return _.initial 92 | }, 93 | removeGlobalState (state) { 94 | const keys = Object.keys(state).forEach(key => { 95 | delete _.state[key] 96 | }) 97 | 98 | _.setState(_.state) 99 | } 100 | } 101 | } 102 | 103 | render () { 104 | return React.Children.only(this.props.children) 105 | } 106 | } 107 | 108 | export const connect = (mapStateToProps, mapDispatchToProps, initialState) => Comp => props => ( 109 | 113 | 114 | 115 | ) 116 | -------------------------------------------------------------------------------- /package/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "microstate", 3 | "version": "0.4.2", 4 | "description": "Co-located and composable state management for React and React-like libraries.", 5 | "main": "dist/index.js", 6 | "scripts": { 7 | "lint": "standard 'src/*.js'", 8 | "prebuild": "npm run lint", 9 | "build": "babel index.js -d dist/", 10 | "watch": "babel -w index.js -d dist/", 11 | "copy": "rm README.md ; cp ../README.md ./" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+ssh://git@github.com/estrattonbailey/microstate.git" 16 | }, 17 | "author": "estrattonbailey", 18 | "license": "MIT", 19 | "bugs": { 20 | "url": "https://github.com/estrattonbailey/microstate/issues" 21 | }, 22 | "homepage": "https://github.com/estrattonbailey/microstate#readme", 23 | "devDependencies": { 24 | "babel-cli": "^6.24.0", 25 | "babel-core": "^6.22.1", 26 | "babel-plugin-transform-class-properties": "^6.24.1", 27 | "babel-plugin-transform-object-rest-spread": "^6.23.0", 28 | "babel-preset-babili": "0.0.10", 29 | "babel-preset-es2015": "^6.22.0", 30 | "babel-preset-react": "^6.22.0", 31 | "parallelshell": "^2.0.0", 32 | "standard": "^8.6.0" 33 | }, 34 | "dependencies": { 35 | "prop-types": "*" 36 | }, 37 | "peerDependencies": { 38 | "react": "^15.5.4", 39 | "react-dom": "^15.5.4" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /static/basic.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/estrattonbailey/microstate/7798800f386a293b3cfa24ddcc288428e23d40bc/static/basic.gif --------------------------------------------------------------------------------