{"id":1548,"date":"2023-06-10T22:36:49","date_gmt":"2023-06-10T19:36:49","guid":{"rendered":"https:\/\/notes.profidev.online\/?p=1548"},"modified":"2023-06-10T22:36:51","modified_gmt":"2023-06-10T19:36:51","slug":"calculator-reactjs","status":"publish","type":"post","link":"https:\/\/notes.profidev.online\/ru\/reactjs\/1548\/","title":{"rendered":"\u041a\u0430\u043b\u044c\u043a\u0443\u043b\u044f\u0442\u043e\u0440 ReactJS"},"content":{"rendered":"\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe title=\"Calculator ReactJS\" width=\"640\" height=\"360\" src=\"https:\/\/www.youtube.com\/embed\/LS421DYImwY?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;htmlmixed&quot;,&quot;mime&quot;:&quot;text\/html&quot;,&quot;theme&quot;:&quot;cobalt&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:true,&quot;lineWrapping&quot;:true,&quot;readOnly&quot;:false,&quot;fileName&quot;:&quot;&quot;,&quot;TrpContentRestriction&quot;:{&quot;restriction_type&quot;:&quot;exclude&quot;,&quot;selected_languages&quot;:[],&quot;panel_open&quot;:true},&quot;language&quot;:&quot;HTML&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;html&quot;}\">&lt;div id=&quot;root&quot;&gt;&lt;\/div&gt;<\/pre><\/div>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;css&quot;,&quot;mime&quot;:&quot;text\/css&quot;,&quot;theme&quot;:&quot;cobalt&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:true,&quot;lineWrapping&quot;:true,&quot;readOnly&quot;:false,&quot;fileName&quot;:&quot;&quot;,&quot;TrpContentRestriction&quot;:{&quot;restriction_type&quot;:&quot;exclude&quot;,&quot;selected_languages&quot;:[],&quot;panel_open&quot;:true},&quot;language&quot;:&quot;CSS&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;css&quot;}\">:root {\n  --white: #efefef;\n  --white-alpha: rgba(239, 239, 239, .64);\n  --grey: #d6d6d6;\n  --gray: var(--grey);\n  --black: #292f36;\n  --pure-black: #131313;\n  --pure-black-alpha: rgba(19, 19, 19, .64);\n  --pure-black-alpha-light: rgba(19, 19, 19, .24);\n  --pure-black-alpha-transparent: rgba(19, 19, 19, .12);\n  \n  --primary: #d63c6b;\n  --primary-dk: #c41c4f;\n  --accent: #5cc8ff;\n  --accent-dk: #00a3f5;\n  \n  --transition: 300ms;\n  --easing: cubic-bezier(1, 1, 1, 1);\n  --easing-bounce-in: cubic-bezier(0, 0, .43, 1.3);\n  --easing-bounce-out: cubic-bezier(.43, 1.3, 0, 0);\n  font-size: 100%;\n  font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;\n}\n\n*,\n*:before,\n*:after {\n  box-sizing: border-box;\n}\n\nhtml,\nbody {\n  position: relative;\n  \n  width: 100%;\n  height: 100%;\n  background-image: linear-gradient(to bottom right, var(--accent) 0%, var(--primary) 100%);\n  background-repeat: no-repeat;\n  background-attachment: fixed;\n}\n\nbody {\n  padding-top: 20px;\n  user-select: none;\n}\n\nbutton {\n  outline: none;\n  border: 0;\n  padding: 1rem;\n  background-color: var(--black);\n  \n  font-size: 1.25rem;\n  line-height: 1;\n  color: var(--accent);\n\n  transition: all var(--transition) var(--easing);\n}\n\nbutton:hover {\n    color: var(--accent-dk);\n  }\n\nbutton.block {\n    width: 100%;\n  }\n\nbutton.transparent {\n    background-color: transparent;\n  }\n\nbutton.no-padding {\n    padding: 0;\n  }\n\nbutton.long-text { font-size: 1rem; }\n\n.react-calculator {\n  position: relative;\n  margin: 0 auto;\n  width: 320px;\n  \n  box-shadow: 0 19px 38px var(--pure-black-alpha-light),\n    0 15px 12px var(--pure-black-alpha-transparent);\n}\n\nbody::-webkit-scrollbar, .editable-field::-webkit-scrollbar, .memory-bank::-webkit-scrollbar { width: .5rem; }\n\nbody::-webkit-scrollbar:horizontal, .editable-field::-webkit-scrollbar:horizontal, .memory-bank::-webkit-scrollbar:horizontal { height: .5rem; }\n\nbody::-webkit-scrollbar-track,\n  body::-webkit-scrollbar:horizontal,\n  .editable-field::-webkit-scrollbar-track,\n  .editable-field::-webkit-scrollbar:horizontal,\n  .memory-bank::-webkit-scrollbar-track,\n  .memory-bank::-webkit-scrollbar:horizontal {\n    background-color: var(--pure-black);\n  }\n\nbody::-webkit-scrollbar-thumb,\n  body::-webkit-scrollbar:horizontal,\n  .editable-field::-webkit-scrollbar-thumb,\n  .editable-field::-webkit-scrollbar:horizontal,\n  .memory-bank::-webkit-scrollbar-thumb,\n  .memory-bank::-webkit-scrollbar:horizontal {\n    background-color: var(--primary);\n  }\n\ns\n  body:hover::-webkit-scrollbar-thumb,\n    s\n  body:hover::-webkit-scrollbar:horizontal,\n    s\n  .editable-field:hover::-webkit-scrollbar-thumb,\n    s\n  .editable-field:hover::-webkit-scrollbar:horizontal,\n    s\n  .memory-bank:hover::-webkit-scrollbar-thumb,\n    s\n  .memory-bank:hover::-webkit-scrollbar:horizontal {\n      background-color: var(--primary-dk);\n    }\n\n.editable-field {\n  position: relative;\n  width: 320px;\n  height: 80px;\n  z-index: 10;\n  \n  outline: none;\n  box-shadow: 0 4px 2px -2px var(--pure-black-alpha);\n  padding: .5rem;\n  overflow-y: hidden;\n  overflow-x: scroll;\n  \n  background-color: var(--pure-black-alpha);\n\n  font-size: 2rem;\n  line-height: 2;\n  color: var(--primary);\n  text-align: right;\n  direction: rtl;\n  white-space: nowrap;\n}\n\n.memory-bank {\n  position: absolute;\n  top: 80px;\n  left: 0;\n  z-index: 10;\n  \n  width: 100%;\n  height: 0;\n  overflow: hidden;\n  padding: 0;\n  \n  background-color: var(--pure-black-alpha);\n  color: var(--accent-dk);\n  \n  transition: height 150ms var(--easing),\n    overflow 1ms var(--easing) 200ms,\n    padding 1ms var(--easing) 200ms;\n}\n\n.memory-bank .toggle-close {\n    position: absolute;\n    top: 5px;\n    right: 5px;\n    padding: 2px 5px;\n  }\n\n.memory-bank .toggle-close .title {\n      display: inline-block;\n      transform: rotate(45deg);\n    }\n\n.memory-bank.visible {\n    height: calc(100% - 80px);\n    padding: 10px;\n    overflow-y: auto;\n    \n    transition: height 200ms var(--easing),\n      padding 1ms var(--easing);\n  }\n\n.button-set--functions,\n  .button-set--equations {\n    background-color: var(--black);\n  }\n\n.button-set--functions button, .button-set--equations button {\n      display: inline-block;\n      width: 80px;\n      height: 80px;\n      \n      vertical-align: top;\n      text-transform: uppercase;\n      font-variant: small-caps;\n      color: var(--primary);\n    }\n\n.button-set--functions button:hover, .button-set--equations button:hover {\n        color: var(--primary-dk);\n      }\n\n.button-set--numbers {\n    width: 240px;\n    float: left;\n    background-color: var(--black);\n  }\n\n.button-set--numbers button {\n      display: block;\n      position: relative;\n      \n      width: 80px;\n      height: 80px;\n      float: left;\n      \n      background-color: var(--black);\n      \n      transition: box-shadow var(--transition) var(--easing);\n    }\n\n.button-set--numbers button:last-child {        \n        width: 100%;\n      }\n\n.button-set--functions {\n    clear: left;\n    float: left;\n    width: 240px;\n  }<\/pre><\/div>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;javascript&quot;,&quot;mime&quot;:&quot;text\/javascript&quot;,&quot;theme&quot;:&quot;cobalt&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:true,&quot;lineWrapping&quot;:true,&quot;readOnly&quot;:false,&quot;fileName&quot;:&quot;&quot;,&quot;TrpContentRestriction&quot;:{&quot;restriction_type&quot;:&quot;exclude&quot;,&quot;selected_languages&quot;:[],&quot;panel_open&quot;:true},&quot;language&quot;:&quot;JavaScript&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;js&quot;}\">const ee = new EventEmitter();\nconst App = React.createClass({ displayName: &quot;App&quot;,\n  render() {\n    return \/*#__PURE__*\/(\n      React.createElement(&quot;main&quot;, { className: &quot;react-calculator&quot; }, \/*#__PURE__*\/\n      React.createElement(InputField, null), \/*#__PURE__*\/\n      React.createElement(TotalRecall, null), \/*#__PURE__*\/\n      React.createElement(ButtonSetNumbers, null), \/*#__PURE__*\/\n      React.createElement(ButtonSetFunctions, null), \/*#__PURE__*\/\n      React.createElement(ButtonSetEquations, null)));\n\n\n  } });\n\nconst Button = React.createClass({ displayName: &quot;Button&quot;,\n  _handleClick() {\n    let text = this.props.text,\n    cb = this.props.clickHandler;\n\n    if (cb) {\n      cb.call(null, text);\n    }\n  },\n\n  render() {\n    return \/*#__PURE__*\/(\n      React.createElement(&quot;button&quot;, { className: this.props.klass, onClick: this._handleClick }, \/*#__PURE__*\/\n      React.createElement(&quot;span&quot;, { className: &quot;title&quot; }, this.props.text)));\n\n\n  } });\n\nconst ContentEditable = React.createClass({ displayName: &quot;ContentEditable&quot;,\n  _handleClick() {\n    const cb = this.props.clickHandler;\n\n    if (cb) {\n      cb.call(this);\n    }\n  },\n\n  render() {\n    return \/*#__PURE__*\/(\n      React.createElement(&quot;div&quot;, { className: &quot;editable-field&quot;, contentEditable: this.props.initEdit, spellcheck: this.props.spellCheck, onClick: this._handleClick },\n      this.props.text));\n\n\n  } });\n\n\nconst InputField = React.createClass({ displayName: &quot;InputField&quot;,\n  _updateField(newStr) {\n    newStr = newStr.split ? newStr.split(' ').reverse().join(' ') : newStr;\n    return this.setState({ text: newStr });\n  },\n\n  getInitialState() {\n    this.props.text = this.props.text || '0';\n\n    return { text: this.props.text };\n  },\n\n  componentWillMount() {\n    ee.addListener('numberCruncher', this._updateField);\n  },\n\n  render() {\n    return \/*#__PURE__*\/React.createElement(ContentEditable, { text: this.state.text, initEdit: &quot;false&quot;, spellcheck: &quot;false&quot;, clickHandler: this._clickBait });\n  } });\n\nconst TotalRecall = React.createClass({ displayName: &quot;TotalRecall&quot;,\n  _toggleMemories() {\n    this.setState({ show: !this.state.show });\n  },\n\n  _recallMemory(memory) {\n    store.newInput = memory;\n    ee.emitEvent('toggle-memories');\n  },\n\n  getInitialState() {\n    return { show: false };\n  },\n\n  componentWillMount() {\n    ee.addListener('toggle-memories', this._toggleMemories);\n  },\n\n  render() {\n    let classNames = `memory-bank ${this.state.show ? 'visible' : ''}`;\n\n    return \/*#__PURE__*\/(\n      React.createElement(&quot;section&quot;, { className: classNames }, \/*#__PURE__*\/\n      React.createElement(Button, { text: &quot;+&quot;, clickHandler: this._toggleMemories, klass: &quot;toggle-close&quot; }),\n      store.curMemories.map(mem =&gt; {\n        return \/*#__PURE__*\/(\n          React.createElement(Button, { klass: &quot;block memory transparent&quot;, text: mem, clickHandler: this._recallMemory }));\n\n      })));\n\n\n  } });\n\nconst ButtonSetFunctions = React.createClass({ displayName: &quot;ButtonSetFunctions&quot;,\n  _showMemoryBank() {\n    ee.emitEvent('toggle-memories');\n  },\n\n  _clear() {\n    store.newInput = 0;\n  },\n\n  _contentClear() {\n    let curInput = String(store.curInput),\n    lessOne = curInput.substring(0, curInput.length - 1);\n\n    return store.newInput = lessOne === '' ? 0 : lessOne;\n  },\n\n  render() {\n    return \/*#__PURE__*\/(\n      React.createElement(&quot;section&quot;, { className: &quot;button-set--functions&quot; }, \/*#__PURE__*\/\n      React.createElement(Button, { klass: &quot;long-text&quot;, text: &quot;recall&quot;, clickHandler: this._showMemoryBank }), \/*#__PURE__*\/\n      React.createElement(Button, { klass: &quot;long-text&quot;, text: &quot;clear&quot;, clickHandler: this._clear }), \/*#__PURE__*\/\n      React.createElement(Button, { text: &quot;\\u2190&quot;, clickHandler: this._contentClear })));\n\n\n  } });\n\nconst ButtonSetEquations = React.createClass({ displayName: &quot;ButtonSetEquations&quot;,\n  _eq(type) {\n    store.newInput = `${store.curInput} ${type} `;\n  },\n\n  _equate() {\n    store.newInput = eval(store.curInput);\n  },\n\n  render() {\n    return \/*#__PURE__*\/(\n      React.createElement(&quot;section&quot;, { className: &quot;button-set--equations&quot; }, \/*#__PURE__*\/\n      React.createElement(Button, { text: &quot;+&quot;, clickHandler: this._eq }), \/*#__PURE__*\/\n      React.createElement(Button, { text: &quot;-&quot;, clickHandler: this._eq }), \/*#__PURE__*\/\n      React.createElement(Button, { text: &quot;*&quot;, clickHandler: this._eq }), \/*#__PURE__*\/\n      React.createElement(Button, { text: &quot;\/&quot;, clickHandler: this._eq }), \/*#__PURE__*\/\n      React.createElement(Button, { text: &quot;=&quot;, clickHandler: this._equate })));\n\n\n  } });\n\nconst ButtonSetNumbers = React.createClass({ displayName: &quot;ButtonSetNumbers&quot;,\n  _number(num) {\n    if (!store.curInput) {\n      return store.newInput = num;\n    }\n\n    return store.newInput = `${store.curInput}${num}`;\n  },\n\n  render() {\n    return \/*#__PURE__*\/(\n      React.createElement(&quot;section&quot;, { className: &quot;button-set--numbers&quot; }, \/*#__PURE__*\/\n      React.createElement(Button, { text: &quot;1&quot;, clickHandler: this._number }), \/*#__PURE__*\/\n      React.createElement(Button, { text: &quot;2&quot;, clickHandler: this._number }), \/*#__PURE__*\/\n      React.createElement(Button, { text: &quot;3&quot;, clickHandler: this._number }), \/*#__PURE__*\/\n      React.createElement(Button, { text: &quot;4&quot;, clickHandler: this._number }), \/*#__PURE__*\/\n      React.createElement(Button, { text: &quot;5&quot;, clickHandler: this._number }), \/*#__PURE__*\/\n      React.createElement(Button, { text: &quot;6&quot;, clickHandler: this._number }), \/*#__PURE__*\/\n      React.createElement(Button, { text: &quot;7&quot;, clickHandler: this._number }), \/*#__PURE__*\/\n      React.createElement(Button, { text: &quot;8&quot;, clickHandler: this._number }), \/*#__PURE__*\/\n      React.createElement(Button, { text: &quot;9&quot;, clickHandler: this._number }), \/*#__PURE__*\/\n      React.createElement(Button, { text: &quot;0&quot;, clickHandler: this._number })));\n\n\n  } });\n\n\nlet store = {\n  input: 0,\n  memory: [],\n  get curInput() {\n    return this.input;\n  },\n\n  get curMemories() {\n    return this.memory.filter(m =&gt; m !== undefined);\n  },\n\n  set commitMemory(input) {\n    this.memory.push(input);\n  },\n\n  set newInput(str) {\n    let curInput = str,\n    oldInput = this.curInput;\n\n    if (this.curMemories.indexOf(oldInput) === -1) {\n      this.commitMemory = oldInput;\n    }\n\n    this.input = curInput;\n    ee.emitEvent('numberCruncher', [this.curInput]);\n  } };\n\n\nReact.render( \/*#__PURE__*\/\nReact.createElement(App, null),\ndocument.querySelector('body'));<\/pre><\/div>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":1549,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[67,66],"tags":[64],"class_list":["post-1548","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-other","category-reactjs","tag-reactjs"],"_links":{"self":[{"href":"https:\/\/notes.profidev.online\/ru\/wp-json\/wp\/v2\/posts\/1548","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/notes.profidev.online\/ru\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/notes.profidev.online\/ru\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/notes.profidev.online\/ru\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/notes.profidev.online\/ru\/wp-json\/wp\/v2\/comments?post=1548"}],"version-history":[{"count":1,"href":"https:\/\/notes.profidev.online\/ru\/wp-json\/wp\/v2\/posts\/1548\/revisions"}],"predecessor-version":[{"id":1550,"href":"https:\/\/notes.profidev.online\/ru\/wp-json\/wp\/v2\/posts\/1548\/revisions\/1550"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/notes.profidev.online\/ru\/wp-json\/wp\/v2\/media\/1549"}],"wp:attachment":[{"href":"https:\/\/notes.profidev.online\/ru\/wp-json\/wp\/v2\/media?parent=1548"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/notes.profidev.online\/ru\/wp-json\/wp\/v2\/categories?post=1548"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/notes.profidev.online\/ru\/wp-json\/wp\/v2\/tags?post=1548"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}