{"id":292329,"date":"2019-07-03T07:36:24","date_gmt":"2019-07-03T14:36:24","guid":{"rendered":"https:\/\/css-tricks.com\/?p=292329"},"modified":"2019-07-03T07:36:24","modified_gmt":"2019-07-03T14:36:24","slug":"haunted-hooks-for-web-components","status":"publish","type":"post","link":"https:\/\/css-tricks.com\/haunted-hooks-for-web-components\/","title":{"rendered":"Haunted: Hooks for Web Components"},"content":{"rendered":"

I was just chatting with Dave<\/a> and he told me about Haunted<\/a>. It’s hooks, but for native web components<\/a>! Pretty cool. I think the existence of stuff like this makes using web components more and more palatable — particularly in that totally-native no-build-step-needed-at-all kinda way. <\/p>\n

<\/p>\n

I get that there are all sorts of issues with web components<\/a>, but the things that typically turn me away from them are a lack of nice templating and rerendering<\/strong> and no state management<\/strong>. <\/p>\n

But we can knock those two out right quick these days…<\/p>\n

First, making a component like <my-app><\/code> is perfectly comfortable<\/a>:<\/p>\n

import { html } from \"https:\/\/unpkg.com\/lit-html\/lit-html.js\";\r\nimport { component } from \"https:\/\/unpkg.com\/haunted\/haunted.js\";\r\n\r\nfunction App() {\r\n  return html`\r\n    <div class=\"module\">\r\n      Hello, World!\r\n    <\/div>\r\n  `;\r\n}\r\n\r\ncustomElements.define(\"my-app\", component(App));<\/code><\/pre>\n

Then we could add some state<\/a> with hooks:<\/p>\n

import { html } from \"https:\/\/unpkg.com\/lit-html\/lit-html.js\";\r\nimport { component, useState} from \"https:\/\/unpkg.com\/haunted\/haunted.js\";\r\n\r\nfunction App() {\r\n  const [name, setName] = useState(\"Chris\");\r\n  return html`\r\n    <div class=\"module\">\r\n      Hello, ${name}!\r\n    <\/div>\r\n  `;\r\n}\r\n\r\ncustomElements.define(\"my-app\", component(App));<\/code><\/pre>\n

The CodePen Challenge this week<\/a> is using the Star Wars API<\/abbr>, so let’s make a fetch request and use that to fill state. That’s a great use case for useEffect<\/a>. <\/p>\n

import { html } from \"https:\/\/unpkg.com\/lit-html\/lit-html.js\";\r\nimport { component, useState, useEffect } from \"https:\/\/unpkg.com\/haunted\/haunted.js\";\r\n\r\nfunction App() {\r\n  \r\n  const [planets, setPlanets] = useState([]);\r\n  useEffect(() => {\r\n    fetch('https:\/\/swapi.co\/api\/planets\/?page=2')\r\n      .then(response => {\r\n        return response.json();\r\n      })\r\n      .then(data => {\r\n        let planets = data.results;\r\n        \/\/ remove ones with no diameters\r\n        planets = planets.filter(planet => planet.diameter !== \"0\");\r\n        setPlanets(planets);\r\n      });\r\n  }, []);\r\n\r\n  return html`\r\n    <style>\r\n      \/* Shadow DOM styles *\/\r\n    <\/style>\r\n    <div class=\"all-planets\">\r\n      ${planets.map(planet => html`\r\n        <div class=\"planet\" style=\"--dia: ${planet.diameter}px\">\r\n           <span class=\"planet-name\">\r\n              ${planet.name}\r\n           <\/span>\r\n        <\/div>\r\n      `)}\r\n    <\/div>\r\n  `;\r\n}\r\n\r\ncustomElements.define(\"my-app\", component(App));<\/code><\/pre>\n

That’s a proper little web component! <\/p>\n

\n See the Pen
\n Star Wars API with Haunted.js<\/a> by Chris Coyier (
@chriscoyier<\/a>)
\n on
CodePen<\/a>.<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"

I was just chatting with Dave and he told me about Haunted. It’s hooks, but for native web components! Pretty cool. I think the existence of stuff like this makes using web components more and more palatable — particularly in that totally-native no-build-step-needed-at-all kinda way.<\/p>\n","protected":false},"author":3,"featured_media":292359,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"sig_custom_text":"","sig_image_type":"featured-image","sig_custom_image":0,"sig_is_disabled":false,"inline_featured_image":false,"c2c_always_allow_admin_comments":false,"footnotes":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":[]},"categories":[4],"tags":[],"jetpack_publicize_connections":[],"acf":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2019\/07\/lots-of-bubbles.png?fit=1200%2C600&ssl=1","jetpack-related-posts":[{"id":340901,"url":"https:\/\/css-tricks.com\/links-on-web-components\/","url_meta":{"origin":292329,"position":0},"title":"Links on Web Components","date":"May 26, 2021","format":false,"excerpt":"How we use Web Components at GitHub \u2014 Kristj\u00e1n Oddsson talks about how GitHub is using web components. I remember they were very early adopters, and it says here they released a component in 2014! Now they've got a whole bunch of open source components. So easy to use!\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2020\/10\/web-component-thumb.jpg?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":284489,"url":"https:\/\/css-tricks.com\/advanced-tooling-for-web-components\/","url_meta":{"origin":292329,"position":1},"title":"Advanced Tooling for Web Components","date":"March 22, 2019","format":false,"excerpt":"Over the course of the last four articles in this five-part series, we\u2019ve taken a broad look at the technologies that make up the Web Components standards. First, we looked at how to create HTML templates that could be consumed at a later time. Second, we dove into creating our\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":339759,"url":"https:\/\/css-tricks.com\/awesome-standalone-web-components\/","url_meta":{"origin":292329,"position":2},"title":"Awesome Standalone (Web Components)","date":"May 26, 2021","format":false,"excerpt":"In his last An Event Apart talk, Dave made a point that it's really only just about right now that Web Components are becoming a practical choice for production web development. For example, it has only been about a year since Edge went Chromium. Before that, Edge didn't support any\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2020\/10\/web-component-thumb.jpg?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":345756,"url":"https:\/\/css-tricks.com\/css-modules-the-native-ones\/","url_meta":{"origin":292329,"position":3},"title":"CSS Modules (The Native Ones)","date":"August 2, 2021","format":false,"excerpt":"They are actually called \"CSS Module Scripts\" and are a native browser feature, as opposed to the popular open-source project that essentially does scoped styles by creating unique class name identifiers in both HTML and CSS. Native CSS Modules are a part of ES Modules (a lot like JSON modules\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2021\/08\/css-modules-connections.jpg?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":302288,"url":"https:\/\/css-tricks.com\/web-component-for-a-code-block\/","url_meta":{"origin":292329,"position":4},"title":"Web Component for a Code Block","date":"February 18, 2020","format":false,"excerpt":"We'll get to that, but first, a long-winded introduction. I'm still not in a confident place knowing a good time to use native web components. The templating isn't particularly robust, so that doesn't draw me in. There is no state management, and I like having standard ways of handling that.\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2020\/01\/code-block-screenshot.png?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":317870,"url":"https:\/\/css-tricks.com\/a-bit-on-web-component-libraries\/","url_meta":{"origin":292329,"position":5},"title":"A Bit on Web Component Libraries","date":"July 28, 2020","format":false,"excerpt":"A run of Web Components news crossed my desk recently so I thought I'd group it up here. To my mind, one of the best use cases for Web Components is pattern libraries. Instead of doing, say,