- 💻 Sizzy - A browser for designers and developers, focused on responsive design
- 🏫 React Academy - Interactive React and GraphQL workshops
- 🔮 Glink - Changelogs, Roadmap, User Requests
- 🐶 Benji - Ultimate wellness and productivity platform
✉️️ Landing page for Twizzle, a desktop app for Twitter DM & composing tweets
It's CRA 2
with customize-cra
and react-app-rewired
.
The config file is adding/changing the following:
- Add
babel-plugin-styled-components
- Add
inline-react-svg
to inline svg files (I know CRA has this functionality but you import every file in a specific way) - Disable ESlint 🤷♂️️
The magic happens in components/App/index.js
All of the hooks are in utils/hooks.js
useCanHover
- detect if the device supports hover, if it doesn't, useonClick
for the "tweeting" buttonuseToggleBodyClass
- toggle a body class based on a boolean. Used to triggerdark/light
andscroll/no-scroll
classes on thebody
tag.useGoogleAnalytics
- inserts a google analytics script, but only when the app is readyuseMousePosition
- track the mouse position. It's used to detect if the user is over the menu bar, otherwise the tweet composer gets glitchy.useLoadScript
- appends a script tag to the head of the page (used to load the Paddle script after the page is loaded)
- I extracted all the logic for the background in a Background component
- For the background I'm using 2 different svg images of a desert, a light one and a dark one.
- I tried using them as background images, but they get all weird for some reason
- They are switched using the DayNightToggle.
- I'm using a
desertLoaded
boolean to detect when the dark image is completely loaded, and fade it in (otherwise it would look ugly on slow connections) - I'm waiting until the app is ready to start loading the light image, otherwise it's just slowing down the other requests for no reason
- All the animation logic is extracted in this custom hook
- It's using react-pose for the animations
- It's using sequence which is a function that I wrote for scheduling state changes. I also used it for the intro animation of ok-google.io. It goes through the arguments and if it finds a function it calls it, and if it finds a number it's gonna wait with
setTimeout
for the amount of ms. There is more info in this article. - It's always enabled in production, but it can be turned off in development using a boolean
It's really nothing fancy, just couple of styled divs. I feel a bit guilty because it's completely inaccessible by keyboard users.
So, z-index has been driving me crazy for a long time, so I decided to simplify the logic by ordering all elements in an order
array and then using ...zIndexFor(ELEMENTS.COMPOSE)
in the styles for the component that needs z-index. Smooth.
-
The app has a dark and a light mode, and all the logic for them is in styles/themes.js.
-
Other components can use the themes either by destructuring the
theme
prop, or with the following mixins: -
whenTheme
- It applies style only when the certain theme name is active. Example:whenTheme('dark', {backgroundColor: 'black})
-
applyTheme
- It applies certain theme styles to the element. Example:applyTheme('windowBar')
will get thetheme.windowBar
styles from the current theme -
getThemeColor
- It reads a certain color from the current theme. Example:getThemeColor('icon')
will return the icon color for the current theme.
Just open an issue if you're interested about anything else in the app, and I'll add it in the readme.