{"id":3106,"date":"2022-06-07T13:22:34","date_gmt":"2022-06-07T13:22:34","guid":{"rendered":"https:\/\/rengga.dev\/blog\/?p=3106"},"modified":"2023-06-12T14:30:38","modified_gmt":"2023-06-12T14:30:38","slug":"js-tutorial-usestateincustomproperties","status":"publish","type":"post","link":"https:\/\/rengga.dev\/blog\/js-tutorial-usestateincustomproperties\/","title":{"rendered":"JS Tutorial &#8211; useStateInCustomProperties"},"content":{"rendered":"<p><span style=\"color: #ef3207;\"><a style=\"color: #ef3207;\" href=\"https:\/\/rengga.dev\/\" target=\"_blank\" rel=\"noopener\"><strong>Rengga Dev<\/strong><\/a> <\/span>&#8211; In my recent\u00a0\u201cCustom Properties as\u00a0State\u201d\u00a0post, one of the things I mentioned was that theoretically, UI libraries, like React and Vue, could automatically map the state they manage over to CSS Custom Properties so we could use that state right there if we wanted.<\/p>\n<blockquote class=\"wp-block-quote is-style-default\"><p>Someone should make a\u00a0<code>useStateWithCustomProperties<\/code>\u00a0hook or something to do that.\u00a0<strong>#freeidea<\/strong><\/p><\/blockquote>\n<p>Andrew Bloyce\u00a0<a href=\"https:\/\/www.npmjs.com\/package\/use-state-in-custom-properties\" rel=\"noopener\">took me up on that idea<\/a>.<\/p>\n<p>It works just like I had hoped. The hook returns a component that is the Custom Property \u201cboundary\u201d and any state you pass it is mapped to those custom properties. Basic demo:<\/p>\n<p><iframe style=\"width: 100%;\" title=\"JS Tutorial - useStateInCustomProperties\" src=\"https:\/\/codepen.io\/renggagumilar\/embed\/rNdPrer?default-tab=result&amp;theme-id=dark\" height=\"300\" frameborder=\"no\" scrolling=\"no\" allowfullscreen=\"allowfullscreen\"><br \/>\nSee the Pen <a href=\"https:\/\/codepen.io\/renggagumilar\/pen\/rNdPrer\"><br \/>\nJS Tutorial &#8211; useStateInCustomProperties<\/a> by Rengga Gumilar (<a href=\"https:\/\/codepen.io\/renggagumilar\">@renggagumilar<\/a>)<br \/>\non <a href=\"https:\/\/codepen.io\">CodePen<\/a>.<br \/>\n<\/iframe><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"html\">&lt;div id=\"root\"&gt;&lt;\/div&gt;<\/pre>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"css\">body {\r\n  height: 100vh;\r\n  margin: 0;\r\n  display: grid;\r\n  place-items: center;\r\n}\r\n.box {\r\n  max-width: 400px;\r\n  color: white;\r\n  background-color: var(\r\n    --activeColor\r\n  ); \/* comes from useStateInCustomProperties *\/\r\n}<\/pre>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">import React, { useState } from \"https:\/\/cdn.skypack.dev\/react\";\r\nimport ReactDOM from \"https:\/\/cdn.skypack.dev\/react-dom\";\r\nimport useStateInCustomProperties from \"https:\/\/cdn.skypack.dev\/use-state-in-custom-properties\";\r\n\r\nconst App = () =&gt; {\r\n  const [activeColor, setActiveColor] = useState(\"red\");\r\n  const CustomPropertiesWrapper = useStateInCustomProperties(\"box\", {\r\n    activeColor\r\n  });\r\n  return (\r\n    &lt;CustomPropertiesWrapper&gt;\r\n      &lt;h1 class=\"is-size-4\"&gt;Active Color: {activeColor}&lt;\/h1&gt;\r\n      &lt;button onClick={() =&gt; setActiveColor(\"red\")}&gt;Change to red&lt;\/button&gt;{\" \"}\r\n      &lt;button onClick={() =&gt; setActiveColor(\"blue\")}&gt;Change to blue&lt;\/button&gt;\r\n    &lt;\/CustomPropertiesWrapper&gt;\r\n  );\r\n};\r\n\r\nReactDOM.render(&lt;App \/&gt;, document.getElementById(\"root\"));<\/pre>\n<p>This is clever and useful already, but I\u2019m tellin\u2019 ya, this will be\u00a0<em>extremely<\/em>\u00a0useful should the concept of\u00a0<a href=\"https:\/\/www.bram.us\/2020\/12\/30\/the-future-of-css-higher-level-custom-properties-to-control-multiple-declarations\/\" rel=\"noopener\">higher level custom properties<\/a>\u00a0land. The idea is that you could flip one custom property and have a whole block of styling change, which is is what we already enjoy with media queries and you know how useful those are.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Rengga Dev &#8211; In my recent\u00a0\u201cCustom Properties as\u00a0State\u201d\u00a0post, one of the things <a class=\"read-more\" href=\"https:\/\/rengga.dev\/blog\/js-tutorial-usestateincustomproperties\/\" title=\"JS Tutorial &#8211; useStateInCustomProperties\" itemprop=\"url\"><\/a><\/p>\n","protected":false},"author":1,"featured_media":3741,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[20,12],"tags":[263,293,103,227],"newstopic":[],"class_list":{"0":"post-3106","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-javascript","8":"category-web-development","9":"tag-js-tutorial","10":"tag-usestateincustomproperties","11":"tag-web-design","12":"tag-web-designer"},"_links":{"self":[{"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/posts\/3106","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/comments?post=3106"}],"version-history":[{"count":1,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/posts\/3106\/revisions"}],"predecessor-version":[{"id":3108,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/posts\/3106\/revisions\/3108"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/media\/3741"}],"wp:attachment":[{"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/media?parent=3106"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/categories?post=3106"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/tags?post=3106"},{"taxonomy":"newstopic","embeddable":true,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/newstopic?post=3106"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}