Now what I've done in the scene is I've added to the floor a new script component collision test And if you go look at that script, it has three methods on collision enter on collision stay and on collision exit And these special methods are called in physics updates when a collision is detected on a collider of that same game object So in this case it's attached to the floor. So when a collision occurs with this floor We're gonna get a so-called collision event that triggers these methods on collision enter is called in just that first update Where there's the collision with that other collider on collision stay is also called at the same time But it's called for every subsequent physics update where those two colliders are still intersecting And then on collision exit is called in that first physics update where the two colliders are no longer touching and Notice all these methods have a parameter of type collision that has information about the collision including which other collider we're colliding with And so what I'm doing here in on collision enter is I'm printing out enter and then the name of the collider and on collision exit I'm printing out exit and then the name of the collider To see all these methods in action on the cube. I removed all the code that was manipulating this velocity and all that So now it's just simply going to be under the force of gravity and fall straight onto the floor But then to see the on collision exit We need it to then stop touching the floor and so I added some code where when I hit space It's gonna have a force apply then jump a little bit. So if I now play the game Fall so the floor we see enter cube and I'm gonna hit space jumps and we see the exit cube and then hits again It's enter cube again Now if I come back in here and Uncommon with this line and save then when on collision stay when a stay event happens We'll see print out stay plus the collider name come back play And we get the enter cube and then stay cube stay cube stay cube stay cube that keeps triggering But it doesn't keep going on forever. We don't get just a definite number of stay cubes As long as these two things are touching because what's happened is our red cube It's rigid body has gone to sleep and once that happens. It's no longer triggering collision events Something would have to happen to wake this object up some other rigid body would have to come along with the collider and hit it Or force would have to be applied to this thing directly Something would have to wake it up before we'd get collision events again So in fact now if I hit space the cube will jump and then it'll do some more events But eventually quite shortly. It'll then go back to sleep once it's that rest Now a collision of course is always happening between two colliders and those colliders are components of game objects and Both of those game objects can have any number of script components And if any one of those script components has on collision methods Each of those on collision methods are called So if say a single game object has multiple script components each with on collision methods Then all of those collision methods get called when there's a collision for that game object And when the game objects of both colliders in a collision have On collision methods in scripts attached to the game objects, then all of those methods get called In those calls this collision parameter the other collider the collider we're colliding with That depends on which object we're attached to so in this case because the script is Attached to the floor when we have a collision with the cube The other collider is the cube if we had a similar script attached to the cube In its on collision events the other object the other collider would be the floor collider And in fact we can see this in action if I simply on the cube attach a Script collision test component and now hit play And we get our collision events. Well We get collisions on both the floor and the cube It's a little confusing because this is the call inside the script attached to the cube It's printing out the name of the other collider the thing we're colliding with and so it says enter floor And vice versa when it says enter cube, that's the floor script saying what we're colliding with on the enter event And then for all subsequent on collision stay events, they're happening in both the cube and the floor So we see printed both stay floor and stay cube And just to make this even more clear we can give the same game object multiple Scripts of the same type. So I'll give the floor here another collision test script. And now when I play And we get the collision notice we get enter cube twice Because for every collision event on the floor, it's actually calling those methods twice One for each of the two instances of the script In addition to collision events, we also have trigger events And these are very similar. They occur when two colliders are intersecting But they occur when one or both of those colliders is marked as a trigger If we look at a collider like the floor here, there's this checkbox is trigger, which is off by default It's false by default but I'm going to make it true And now this floor collider is a trigger collider rather than just a regular collider And so when the cube collides with the floor that causes trigger events not collision events And that has two significances number one It means that these methods are not going to get called when we have a trigger event They only happen when we have a collision event Instead these methods will be called And these methods don't have a collision parameter. They have a collider parameter So they get less information the collision not just tells you what you're colliding with It also tells you what the points of intersection are and a few other things So it's less information that we get in the trigger but usually for triggers we don't care about those details And then the other significance is that rigid bodies don't care about trigger events. They only care about collisions And so when this cube hits the floor The rigid body doesn't hear about it and it doesn't update its velocity accordingly And so the cube will just fall straight through the floor So now here before hitting play understand that on the floor I removed one of the copies of collision tests We just have the one component and I removed the collision test component of the cube So we just have the one collision test component on the floor Come here hit play And our cube just falls straight through the floor And in our log we have trigger enter cube gets called once then stay cube say cube say cube And then down at the end we get an exit because it fell through and stopped the collision So if you want your collider to be hit by rigid bodies like a solid object You can't make it a trigger Rigid bodies will simply just pass through triggers So what triggers are meant to be used for is that we place trigger colliders in our world and then hook up to their methods here and do some sort of logical operation in response till they say like The player entering the trigger. So typically in one of these methods you'll like test Well, what is the other collider? Is it the player's collider? If so, then this other door should open or unlock or something like that Just be clear though that as soon as one or both of the colliders as a trigger, you're not going to get collision events So actually here, let's make the floor. Let's make it a non trigger again and make the cube this time a trigger We should see the same behavior. We're not going to have the box hit the floor. It's going to fall right through So we can do this and in this setup the behavior is the same But it almost never makes sense really to make your colliders with rigid bodies Make them triggers because if you do so, then they're not going to send collision events to their rigid bodies So this would be an odd thing to do Now finally, let's look at using these colliders and rigid bodies in a fairly realistic application Here we have our environment geometry the floors and obstacles. These are all static colliders They don't have rigid bodies and then we have our player object, which is just this cube But it's a rigid body and we've set up logic in the script attached to this cube Such that our input is translated into force on the cube When I push left and right or a and d on the keyboard when I do horizontal input That's translated into force going left and right on the cube and when I hit space That's a jump force. It's an impulse force upwards. So let's see this in action. I hit play Our box falls under gravity, but I can move it left and right by hitting a and d on my keyboard And I can space to jump And as you can see we can't penetrate into these Obstacles. So let's pause and look at the logic First be clear that the cube object itself is where the script is attached And so we come into here into the code and we have a rigid body private field Which is being initialized and start to be the rigid body of the component Again, this is implicitly this dot get component where this is the script component And it knows well if you try and get a component on the script component You're really asking for the component on the game object. It's attached to so that gets us the rigid body Of the same game object assign it to rb and then We in our update Well, we get the input from the so-called virtual axis called horizontal Which by default again is is bound to the keys a and d and left and right on the keyboard And this is going to be a value between negative one and one Where negative means left and positive values mean right And so we're going to take that value and add force to the rigid body to our cube And we do so there's an overload of ad force We didn't mention where instead of passing a vector three you just pass x y z values separately And so this is the x value of the of the force and then zero for y and z And we're multiplying by four here just to amplify the amounts of force In fact, I can make that even bigger because it's kind of slow as it is So this will then effectively apply force every frame And by default again ad force uses the force mode called force Which takes into account both elapsed time and mass So if we came in here and we increased the mass of our rigid body That would effectively diminish how much Acceleration we're applying when we move left and right Anyway, so that's the horizontal movement and then for the jumping code Well, we test whether the user hits the space key in that frame We don't want them to jump Additionally as they hold down the key just when they initially press the key so it's get key down not get key But we don't want to let the player jump when they're not actually touching the ground Well in some games you do some games you want to let them just like double jump or infinitely jump But in our game, assume we don't So the logic for this actually done properly would get quite complicated But we do a simple little hack here Uh, we keep track of this in value touching what starts out at zero It's just a count of how many other colliders our player cube is touching And so every on collision enter event we increment it and every on collision exit We decrement it and so when touching is greater than zero that means our cube is touching something And so we'll allow it to jump that does though mean that we get some kind of not quite correct behavior where like here Right now I can jump even though I'm not on the ground But because I'm touching that collider right there, it's allowing me to jump So we're doing a quick hack. It's not really proper logic, but for our purposes, it's close enough We also have some other problems with the logic as we've currently implemented it We did like the simplest possible thing But like right now it's Well, because we have I increased the force and so now we have enough force to get up the slope But before when I had the lower force value No matter how much you pushed right you couldn't get up the slope Whereas I assume over here this slope is too great. I mean, yeah, we can't go up at all I can have it sit there. In fact, if I let go left It'll slide down the slope So I mean we could overcome that just by increasing the force, but the point is that Actually properly counting for all the possible scenarios the player could end up with and making the controls feel good for all scenarios and and seem responsive That would take a lot more work But as you can see using the built-in physics system, we can get some basic functionality going with very little code The question though is do we want our player controlled character to necessarily be governed by Physical simulation It's perhaps not the case that you even want to use the built-in physics system for your character movement If you go back and look at older side scrollers like classic platformers in the 8 bit and 16 era None of them had physics of this style They didn't really think in terms of forces and mass and velocity Well, they didn't have velocity to take that back But the way they handle collisions is very different and the way they handle player movement is also very different So if you want that classic platforming feel you really wouldn't use the built-in physics system At least for controlling the motion of your character Maybe some things would be physically simulated with the physics system But then the movement of your character itself would be custom logic largely handwritten Because while you can Play around with the physics system and add in special case logic of like how the forces get applied and all that You're kind of in the end. You're still just fighting with the physics system to get exactly the kind of movement you want Which may not necessarily be a realistic feel. You may want like a cartoony physics feel, right? So in those cases, you probably don't want to use the built-in physics system For certain kinds of controls like say for vehicle controls Maybe you do want a physicsy feel a realistic physicsy feel and so maybe in those cases you do use the built-in physics system But particularly for like classic style platformers you probably don't Also one more detail here. I didn't mention You may have noticed like wait this box is I'm like shoving it up against these slopes and everything But it's never rotating no matter what the forces are like you would expect With me shoving up against this slope the the box should start tumbling But what I've done is I've constrained on the rigid body. I've constrained its movements So first off here, you notice that we have the z-axis constrained. We probably don't really need that because Given the forces applied Nothing should move the box in the z Direction at all either positive or negative So that really shouldn't be necessary given the forces we're applying But just to be safe, I've constrained its movement in the z-axis and now no matter what the velocity It'll never move along its z-axis But then also we don't want the box to rotate at all. So I've constrained rotations of x y and z if I disable these Let's see What axis are they rotating around? I have to think we're right rotating around the x-axis. No the z-axis So let me uncheck z and we'll start seeing some strange behavior here in a second. I think wait me Yep, there. Yep. Now we're tilted Maybe that's actually what we want. It's kind of fun, but I don't think we'd see rotations in other axes. I'll Get rid of those Yeah, given the forces and the collisions involved here I don't think we'd ever see collision on the other axes Regardless of whether they're frozen or not, but just to be safe. I'm going to freeze them As I was saying just a moment ago quite often in games We don't necessarily want a realistic physics feel for the player controlled character or other player controlled things and other things in the scene Like for example, perhaps you want your character when there's user input to move You just want them to instantly start going at full speed Rather than accelerate and and so forth and you don't want to apply force or take into mass or anything. You just want to have Directly controlled movements from the logic of the code And so in such cases it generally doesn't really make sense to use a rigid body because you'd just be fighting with the Rigid body physics when you did that So then what you might do in unity is you would just have a game object that is rendered But then you mainly are keeping track of its position and updating its position According to your own collision logic that doesn't use colliders or rigid bodies at all You can do that It would be nice though if we could just use colliders and all their built-in collusion detection logic that we can take advantage of But not have necessarily an associated rigid body The problem with that though is that like say if we gave our player controlled cube here A collider, but no rigid body is that as I mentioned every time you move a static collider collider with no rigid body That triggers an expensive recomputation, which we don't want to pay the cost of So what can we do? We want to have a collider that isn't really simulated under physics, but we can still move it Well, what you do is a little weird you add a rigid body to it, but you mark that rigid body as kinematic So here on this cube, we do have a rigid body, but it's marked as kinematic And a kinematic rigid body is a body with no concept of velocity The properties are still there and you can access them, but generally they're just going to be zero So effectively the velocities are just ignored the directional angular velocities are simply ignored And so these are rigid bodies that when the physics update is performed, they're not automatically moved These are things that only move when you explicitly and directly set in your code their position and rotation The reason we want these things to still be rigid bodies is because they have to have a concept of mass Because we may want these things to still collide with other non kinematic rigid bodies The primary use case here is you have some player controlled character Which is a kinematic rigid body, but then it runs into say like boxes and debris on the ground And those are non kinematic rigid bodies that respond to the collisions The kinematic rigid body for those collisions doesn't actually receive the the collision event and it doesn't respond to them It doesn't update its velocity and its velocity is ignored regardless So the collision doesn't affect the kinematic rigid body itself, but it affects the other rigid body if it's not kinematic So in fact, there's a special rule for collision events If one of the colliders has a rigid body that's kinematic You only get a collision event if the other collider has a rigid body that is non kinematic If the other collider doesn't have a rigid body at all if it's a static collider Or if it's another kinematic there's no collision event And so you can't automatically detect when kinematics hit other kinematics or when kinematics hit statics But again, you still get a collision between a kinematic and a non kinematic And so those non kinematics can respond to the collisions Even though the kinematic itself doesn't automatically respond to those collisions So let me repeat that again to be clear when a collider with a kinematic rigid body hits a collider with a non kinematic rigid body There's a collision event the kinematic doesn't respond to that collision, but the non kinematic does In effect collisions between kinematics and non kinematics affect only the non kinematics So now putting this into action. We have this kinematic rigid body, which is our player controlled cube It does have gravity checked But that doesn't matter actually because now as soon as this kinematic the gravity is just being ignored It's just another force being applied Same with drag drag doesn't affect kinematics all the force stuff is just totally ignored The only thing that moves our kinematic is when in code we explicitly change its position and rotation So now let's go look at the code Which is significantly more complicated because now we're responsible for all the movements of the box And also detecting when it hits the static colliders There's no automatic detection of when this thing is intersecting with a static collider So we have to check for itself and move the box accordingly So first off the part that's the same is we're just getting the rigid body assigned to this field up here And then we have to explicitly keep track of its velocity because the rigid body's velocity Even if we explicitly set it, it'll still just be zero. It'll just be ignored So we need to keep track of velocity for our cube We do so as a vector two rather than a vector three because we we don't care about Velocity in the z direction We're not moving along the z-axis and then we have a field representing the rate of gravity Which this is just to be constant. I could just make this constant. I guess Same deal, which is negative 9.8. That's about earth gravity And then in the update we're getting input from the horizontal axis This value then is used to modify the x of our velocity and we're we're multiplying by 10 Just to amplify it because by default it's in the range of negative one to one So we just want to amplify it to make it more Consequential But we do want to still factor in time. So we multiply by delta time And we want to constrain how fast the player can move horizontally So we have a max horizontal velocity and we clamp velocity x within that range And then next we're manually simulating drag. So in the case where our velocity is greater than x We diminish it by the horizontal drag value, which we just initialized to one But the amount we're diminishing x by should be proportional to the time elapsed so we factor in delta time But then wait, what if we've diminished it too much and now we've reduced the velocity from positive to negative? That's not how drag's supposed to work. It's supposed to stop at zero So we do this final check. Oh wait, are we less than zero then we set it to zero And then we have to handle separately the opposite case of where velocity was negative going leftwards So in that case to get closer to zero we add in horizontal drag But then if we go too far if we added too much now our value went from negative to positive So it really should just be zero. So that's what all this logic is. It's just about drag And then here we check if the user hits space and if we want to allow them to jump Then well, they're just going to set the upward velocity to 10 But we want to make sure that the box is on top of something rather than just in midair And to do so the pause that's the the vector representing the center of the box and extents That's the well, it's actually the half extents. It's the dimensions of the box along x y z The the half the length width and and height And so we're doing a checkbox But we're being sure to do so with a position that's not where the center of the box is Is actually something just a little bit below that so we're effectively checking for collision Not with the box itself, but with a box that's slightly lower than wherever the box currently is Because we want to know here if there's anything just below the box So that's what this check is all about. Hey, is there something just a little bit below the box? And if so, then we're allowed to jump but when we do this check, we don't want to get back true If it overlaps with the box itself The logic of this test is ruined if it collides with the cube itself So we want this test to only return true if we got a collision with something other than the player So we use a layer mask layers in unity every game objects can be added to a layer And what I've done is there are these eight default layers that come stock with any new project But you can define your own layers and I define this layer called player And then I added the cube to that player layer And this layer mask it's it's a bit field mask, which I won't explain them right now if you're not familiar But in short, it's an integer where the individual bits represent a yes no value So it's it's an int value here But in this case we want all the bits to be one except for the bit that represents layer eight or player layer So this gets us back this call here layer mask dot get mask with the name player gets us back A bit mask where only the bit representing the player layer Is one and all the other bits are zero But then we do the bitwise not operation and that flips all the bits So we get a layer effectively where everything but the player layer is enabled And so we pass it into checkbox here and it's doing a test checking for collisions with all layers except the player layer the the one that includes the cube Anyway, so if this test is true, then we're going to jump we'll set the velocity to positive 10 And then we want to factor in gravity, which is just being applied every frame But proportional to the amount of actual lapse time delta time So we factor that into velocity dot y So now we have our movement vector, which is our current velocity With time factored in multiplied by delta time The problem though is that what if where we want to move for that frame? What if there's another collider in the way? What if we're going to hit the floor or a wall? We don't want to move our cube so that it's overlapping the floor or the walls or anything So what we're going to do is use the method sweep test of rigid body Which is analogous to raycast a raycast is an individual ray That tests for collisions along the ray sweep test takes all the colliders to which this rigid body is attached And moves them along a specified vector and tells us if we hit anything So here we're sweeping all of the colliders of a rigid body along this velocity vector Could have been movement vector would have been the same deals just they point in the same direction They just have different magnitudes and then we're saying how far we want to to sweep them We want to sweep them the magnitude of movement And if there's a hit that is then stored in this out hit parameter, which is a raycast hit And the method itself will return true if there was a hit and so if there's a hit That effectively means that if we were to move our cube By this movement we would then be intersecting with other colliders and we don't want that So what we're going to do is we want to move in the same direction But we want to stop before we actually hit anything And it turns out that the raycast hit we get back Tells us exactly what that distance is along that Along that vector And so now what we want the movement to be is we want to take the movement and and clamp it So that it's the same vector pointing in the same direction But its length has been clamped to the hit distance And here actually it shouldn't matter if it's velocity or movement because they're both vectors pointing in the same direction Velocity has greater magnitude, but they're both longer than hit distance which we're clamping to so It really shouldn't matter. In fact, let me do that And in fact, I think I have a bug here. I don't think I should be multiplying by delta time. That doesn't make any sense We've already factored in time for the movement here. So yeah, I'm pretty sure I've made a mistake there. Let's see now. I'm going to save Just for debug purposes, I'm printing out that movement how much we're moving and then Setting the new velocity to zero because well, we've hit something and when we hit something we should stop moving This is not exactly correct because what if we just like hit a wall? Well, we don't want to constrain our movement in all directions. We still want to fall down As you'll see this logic is not exactly what we want But uh, we'll live with it for now Anyway, so having computed what the movement should be We then update the position of the rigid body By movement and rb position is always a vector three So we have to convert from a vector two to a vector three. That's why we have the cast here This conversion simply just takes the vector two and creates a vector three where the z value is zero as you would expect So let's see this in action and I can tell you ahead of time. I know it doesn't work properly We got collision with the ground there. That's good But then now I can't actually move left and right because we didn't account for sliding along surfaces Because what's happening is gravity is being applied every frame and if I hit left to right here Well, now I have a vector of motion that's actually going like diagonally down into the ground Either left or right and that then would collide and in the code We have it set upon collision with any collider set the movement back to zero to nothing So we're not actually moving then and similarly if I jump against here and I hold left as long as I'm holding left Moving into this wall. We're just going to be stuck there. So we've accidentally implemented wall grab But if I let go now, okay now gravity kicks in fall back down But then we also have worse over here on these colliders. This one in particular. Yeah, I always fall into that one and this has to do with imprecisions of floating point What's happening here is that when we land there's a collision you can see it detects the collision. It stops momentarily um And the velocity is set to zero But then because of floating point imprecisions when we actually then move the rigid body We move it to a place where it's actually slightly intersecting with the thing. It's sitting on top of And the sweep test method Doesn't consider it a hit if the starting position of your colliders is already intersecting with something Those collisions don't count as far as the sweep test is concerned So next time around It's not colliding with the thing. It's sitting on top of and so gravity kicks in and applies force And it starts flying under gravity Yeah, so now it's resting on this thing because it just happens that the y value for this collider It's top edge The calculations just work out that When collision is detected and motion stopped it's positioned in the cube. So it's above the collider not intersecting That's just a a happy accident It just happened that the the numbers worked out that time and this thing got positioned sitting on top rather than partly intersected They're actually our cases get based on uh, how fast or velocity design. I think I can get this to fall through No, I did last time Anyway, there are cases where I've jumped from here to here and it ended up positioned in a place where it did fall through Again, these are just imprecisions of the floating pointer with the tick So our logic clearly is insufficient and what can we do about it? Well, that's not something we'll approach here Yeah, same behavior on that that edge. Yeah, so all sorts of bad things are happening because of these collisions um, it's just Now we we really only up there I fell through the floor Okay, so enough of that. So clearly our logic isn't adequate. We're using the right tools sweep tests collision checks That's the starting place but then actually getting this behavior correctly And then accounting for all the possibilities of making sure that if we land on a slope that never one We don't fall through it, but we can also like walk up and down it accounting for friction things like that We have to account for all this manually and it's difficult It's a tricky thing to do But it ultimately is really what you want If you want a more classic video gamey platformer feel in particular And we won't work through all that right now, but it's something I'll come back to We'll we'll go through a full proper solution for actual platformer physics


The study aimed to understand the factors that facilitate or hinder the use of mental health apps among community college students, finding that perceived stress, perceived need for help, past use of professional services, social influence and privacy concerns were associated with app use, while stigma, age and gender did not have a significant effect.


The most important message to the 8th sector is that we need to move from a risk-averse position to proactive action. We need to bring results and we need to be effective in protecting vulnerable persons. Too many cases have occurred. We need to act collectively. We need to take action. We can no longer accept that criminals infiltrate the 8th sector to cause harm to vulnerable communities.


So yeah, so as mentioned, my name's David Wells. I'm a full stack JavaScript developer based out of San Francisco. We're at a company called Serverless, which, if you guys were here on Tuesday, you might have seen our CEO, Austin, talking about what Serverless is. But previously, before I worked at Serverless, I worked at a company called MuleSoft on the UX UI team. And I want to take a quick second to thank Full Stack Fest for inviting me to talk here. It's awesome to be in Barcelona. It's always great to travel. And the slides for my presentation can be found right there at that tiny link. But cool, so I'm going to start off with a story. The story is about a quest, a quest for the perfect platform user interface. What would be the ideal setup for a larger project? This is something that I feel like a lot of us strive to reach. And it seems like an unattainable goal as things are always changing. And more specifically, when I talk about Platform UI, when you're working with a larger team or you're perhaps working across multiple departments in your organization, how do you build out UI that transcends those boundaries? And this is the number of JavaScript frameworks that were released this previous week, 1,972. There's no shortage of ways to do things. And each one comes with its upsides and downsides. But I'm here to tell the tale basically what I've learned over the past two years building Platform UI and some mistakes to avoid and some best practices to take back into your own companies. So first, imagine in your minds what the perfect setup would be for your UI. Just think about it for a second. What's the perfect back end? What's the perfect front end? What kind of CSS setup would you want? Start imagining that. And I'll tell you mine. So first and foremost, imagine a scenario where your UI is running out of a single code base that's shared across multiple areas of your company, shared across like the marketing site is using it, your blog is using it, your web applications are using it, your mobile apps are using it, and even you're using it inside of legacy applications. And this setup is shared across teams and across platforms. Like I mentioned, mobile desktop web, you name it. So that's like an ideal setup for me. I want it to work everywhere and have one code base to maintain and use. So the other thing would be organized. So it'd be super organized. What if every single layout, icon, font, building block, component, button, link, whatever you use is in one centralized location for all developers to use. And one place where people can find things and freely contribute to that. The other kind of core tenant that I would strive for is like keeping things in sync. So if we have this one single code base to rule them all, like a platform UI, as it were, what if your latest style change could propagate across all of your applications all at once? That would be pretty compelling and a huge problem that companies with more than one application and a larger team face on a pretty regular basis. So just imagine having that kind of platform leverage where deploying code and updates across apps is easy. And even better than that, just imagine a consistent brand experience for your end user.  And then everything, the ideal setup would be like it's also self-contained. So imagine a world where your CSS is completely self-contained and is guaranteed not to cause conflicts with other applications, other third-party CSS libraries. You name it. It's isolated. That sounds pretty compelling to me. And then the last thing is like, how do we actually have a scalable solution that achieves all of these things and that work across the company? So scalable from both a people perspective of, is this code actually maintainable? And from a tech perspective as well, like, does it work everywhere? Will it handle all of our needs? Is it performant, et cetera? And that's basically what we're going to be chatting about today. Basically, Platform UI, building a component-based architecture. And a component-based architecture basically enables all of the things that I told you guys to imagine are possible today with this kind of setup that I'm going to run through. And more specifically today, we're going to be talking about a React component-based architecture, but there's no reason why these kind of ideas and methodologies can't apply to your framework of choice. So let's go ahead and explore this. So it all starts with a design system. So a design system is basically a place where you formalize your user interface, all the different kind of layouts. You have the tonality of how your application is going to work, your brand. A lot of people call them style guides. There's tons of examples out there on the web, but it just makes things easier for both internal and external people to consume and build things with. So there's a couple of different examples. So this is a really good one out of Salesforce called the Lightning Design System. I highly recommend checking that out. They did a really, really good job basically baking in all the different rules for how to do different layouts for settings pages, for list pages, for feed pages, et cetera, how all the different variations of buttons are managed, and stuff like that. It's basically how to do everything with their UI framework. It's super handy, I would imagine, for everyone inside of Salesforce and outside building apps for the Salesforce platform. But what we're going to be talking about today is the component library that I built at MuleSoft, and you can see it at ux.mulesoft.com. And basically, it's, again, the one-stop shop where you can go and see all the different components that are consumable, all the documentation, all the different icons, all the different colors, all the variables and mix-ins available to developers, and some actual layout demos, and kind of standards around that. So I'm gonna skip the live demo till the end. But yeah, so what lives in this style guide? So documentation, like I mentioned, so this is both documentation that's written by the team, but also documentation that lives directly in your code. So when you're building React components, if you're using PropTypes, you can basically automatically generate the documentation for your component library so you don't have to maintain text in a different place whenever you make a change in your code. That's automatically reflected in basically your living style guide. The other thing that I put in here is a live code playground where basically you can interact with the components, change the props, see how they act, and mix and match them together, and we'll see that in the live demo. And then also, what's extremely important is usage examples. So how do you actually use this component with some dummy data? So you're basically, you're almost writing the code for your team so they can kind of get off building their specific use case quickly. And then also platform guidelines, like I mentioned, like how to show warning text, when to use certain types of buttons, et cetera. So you have a very consistent feel. So when your user is moving around to maybe different applications, the experience feels the same. And just a little bit of context around this, MuleSoft has around eight different products that were kind of all built in silos over the past couple of years. And the experience wasn't as cohesive as we wanted it to be. So that's kind of the idea behind why we wanted to do this. Yeah, cool, but how? So this is all like pie in the sky, like yeah, this sounds good, but how do we actually go about doing this? And it's pretty straightforward. We're gonna run through these five things. We might not run through profit maybe later, I don't know, we'll see. But yeah, so basically, we need to break things down. We need to figure out how we're gonna actually handle like our CSS, like I mentioned, how we're gonna handle all the global assets to be easily consumable, and then how to actually package them and distribute them out to different teams, or to the public if you decide to maybe open source your component library and profit. So cool, so this is an example of like UI, this is a demo on the ux.mulestop.com, but basically start by breaking down a particular view of your application and start thinking about things as components. Everything on this screen is a component. So every single tiny little piece, like the radio buttons, the chart, the icons, the labels, the drop downs, et cetera, like each tiny piece can be broken out into a separate component and reused across multiple areas of your application. So basically you start thinking about your UI in such a way where it's like, how can I build this design that the designer has given me into something with the maximum amount of code reuse? And that's really what like React, the kind of core philosophy around React is like, how can you componentize things and make the code easily easy to reuse? And then after that you basically have like, once you have all the little tiny pieces, the individual components, how do you compose those together to create maybe more complex components? And here we have an example of like, so the nav bar is a component, the detail pane is a component, the menus a component and like the table, is they're all made up of smaller pieces but for the consuming developer, they're just pulling in that one larger piece. And this kind of riffs off of a concept called atomic design by a guy named Brad Frost.  This inspired me to kind of follow this pattern. We don't follow it exactly like that but very similarly. So here's an example.  And basically you can compose those together now to create a, let's say a search box or a form input or a modal or let's say it's a marketing copy with a button thingy on the blog or whatever. So there's a lot of different ways that you can use these three components and compose them together to create basically composed components to use throughout your application.  Okay, that's the moral of the story. Cool, so what does it actually look like? What does like a component look like in code? This is the anatomy in which we build components. We're basically like all of our components live in a components repository. Every component gets its own folder. Every component has like a component name.js so like button.js, that's where the actual source code of the component lives. The styles live in there. The tests live in there in that same folder and then we have an index file for easy importing and exporting and then we also have examples. So uses examples, so that examples folder is actually what automatically generates the documentation and live code examples on the site that I'm gonna show you. Cool, so our approach at serverals is slightly different take on atomic design where we have the low level components. Those compose into what I'm calling fragments right now I'm trying to find a good name. That's what I came up with. Those fragments compose into layouts and those layouts compose into pages. So this is serverless.com. It's built with our component library. So this is our front end marketing site. It's a statically built website completely with React and then we push that up to a CDN and yeah. So we can use the components that we're actually using in our applications that we're building and in our marketing site and on our blog, et cetera. So if we did ever make a change to let's say that the button design that would reflect throughout the platform, not just in our app and then we would have to go update, let's say like WordPress or whatever we're actually, if we had that as our marketing site. And under the hood, the tool it's using is called Phenomic which is a static site generator that uses React. Super awesome, there's a link here in the slide to check it out. Yeah, so cool. So here's the obligatory Peter Griffin CSS slide that by law you must put in every presentation where you mentioned CSS. And we're gonna talk about handling styles in your component library. So, yeah. So basically there's some challenges with CSS, right? So we've all faced it like how do you handle class name collisions? How do you handle if you're using like a third party CSS library like Bootstrap? How do like if we wanna use these components inside of a legacy application, how do we make sure the styles don't conflict? Like what we had to do at MuleSoft is there were some green field projects that just were built with the components but there were also a lot of legacy applications that were built in Angular 1 with Bootstrap and a whole bunch of other stuff where we had to make the components basically live inside of that application. So we needed to make sure that we're not messing with their stuff and they're not messing with our stuff which is quite a challenge, but it is actually pretty easily doable. Cool. And this is a real quote from our favorite presidential nominee.  If you really want your components to be standalone, we need to solve that. So how do we do that? So basically we use a technology called Post-CSS and CSS modules and this works with Webpack if you're familiar with Webpack. I have an entire like hour long presentation on exactly how to do CSS with React. The links are right there and it goes through like all the different variations of how you can do styling. I'm just focusing right now on like my favorite and the one that works best in this platform UI situation which is Post-CSS and CSS modules. But what Post-CSS is is you can think about it like it's babble for CSS. It'll turn your CSS into an abstract syntax tree and then you can manipulate that. It's exactly the same as well not exactly but very similar to SAS and less except just a little bit I think more powerful in my opinion and you can do everything that you can do with SAS and less with Post-CSS. Cool. So what does it look like? So this is a React component. At the top I'm importing the styles from the CSS file and it's just normal CSS. But what's happening here is that styles that's being imported is actually so it's being turned into an object with keys on it and those keys are basically localized class names. Now your CSS names that you're writing normal CSS so wrapper and like the class of button get turned into this localized class when it actually renders to the page and that's either if you're rendering on runtime or if you're rendering on the server this is what it looks like. So and that is customizable by the way. This is that's a long like name. You can just for production you would customize that to just be the hash at the end. So if you look at like Gmail source code or anything like that you'll notice like they have crazy class names that are hash numbers. This is how you achieve something like that. The other thing that you'd want to do is with post CSS there is a plugin called I believe it's called post CSS initial where basically it turns on a future CSS for spec for you which basically is all colon initial and what that'll do is it will reset all inherited properties. All CSS properties that can be inherited from a parent and reset them to the browser defaults. So when you add that to your CSS just all colon initial when post CSS transpiles your CSS it will like basically polyfill that for the browser so it'll reset that. So now you have like a completely isolated component based off this unique class name which is awesome and something that we couldn't really do before very easily. The other thing that you could do with like post CSS and CSS modules is like use the CSS for spec today. You can do like A11y linting for accessibility. Yeah and you can polyfill flexbox back to IE8 if that's something you have to support. And I feel sorry for you if you do. But yeah so yeah so many many many many other things you can do with post CSS and CSS modules not gonna go through all of this. See the go check out the other talk that I did at the React Meetup in San Francisco. Cool so do you really need this? If you answer yes to any of these questions then yeah if you're working on a team like you could implement BIM style writing your CSS classes but we're humans and humans make mistakes. This makes it so like you cannot make mistakes. The class name is localized for you by a machine based off like a random hash based off the file name so it's completely unique won't run into collisions. Are you including any third party CSS so like do you have to use Foundation or Bootstrap or any other library that conflict with your stuff? Yeah this will kind of make your life a lot easier. Are you running in a third party environment? The answer to this for everyone is yes because the browser is a third party environment meaning anybody could install any kind of browser extension and theme your app however they want. If you wanna stop that you can do this. And then yeah so and do you want your styles to look right no matter what? The answer to that should be yes. Cool so that is kind of post CSS in a nutshell. Really really like transforms how you can write your CSS normal regular CSS and then automatically transpile that into something that will get rid of global namespaces and fix the main problems with CSS. It also allows you like some there are some use cases where you do need global CSS and it gives you an escape hatch to do that. Like an example would be for like let's say a modal pops open and you wanna add a class to the body that does something like you can do stuff like that with it. Cool so how do you handle global assets? So global assets meaning variables, mixins and icons. So variables and mixins. No longer do you need to write your variables and mixins in CSS. You can just do it in JavaScript why not? JavaScript is eating the world and it's far more powerful than writing like let's say a mix in function. You're writing if you're writing a mix in function in SAS you're kind of using this weird syntax that's not really supposed to do this thing. But if you write it in JavaScript you're just writing a JavaScript function that returns something. You have the full access to the NPM ecosystem to do whatever you want. This is how you enable this with post CSS. This is basically you require two plugins. So it's very similar to Babel. You would include what you actually want to do in the transpilation step. But here I'm just saying, okay, grab my mixins file and grab my variables file and then make that globally available to all of my CSS. And what that looks like, this might be a little hard to see. So this is the variables.js file just as an example where I'm just, it's just an object. So I'm defining my various break points. I'm defining platform-wide Z indexes to use everywhere, my colors, et cetera. And then on the right-hand side there we have our mixins, which a mixin is pretty much just like multiple values at once. And interestingly down at the bottom it's a function which you can pass in any value you want or use an NPM package to like calculate a different color or something. Like you can do whatever you want. And the usage in the CSS is just like at, so I'm using a mixin at denpro, use that font, and then a variable there. So very similar to lesson sass, but yeah. And then what's cool about this, because it's written in JavaScript, is I can also use this inside of my components. So now if I have, let's say, state-based, like I wanna add a red text to a button because something bad happened, I can import my brand color red from my variables file because it's just a JavaScript object and use that where I want to. So cool, running short on time so I'm gonna speed it up a little bit. So icons, so if you're doing icons, font icons are kind of going the way of the dinosaur. They're not as flexible as SVG icons. SVGs are also typically lighter weight and more flexible than font icons. For example, SVGs, I mean, it's markup that you can style individual lines and strokes, whereas font icons are just a single color that you can apply different colors to. But here you can see we have a ton of different SVG icons that are multicolored and we can change those individual colors with CSS whenever we want or do cool animations and yada, yada, yada. But the way that that works is designers make the SVGs. There's a build script that runs through all the SVGs, runs it through Webpack, bundles it with a Webpack plugin called Webpack SVG Store. It will optimize everything and create a sprite. And then you have an icon sprite of an SVG icon sprite that gets injected into the DOM. And then again, you can profit. And the way that that works is with the SVG use tag. So if you have a SVG sprite on the page, it's hidden, nobody can see it. But anywhere you use SVG and then the use tag and the ID of the corresponding icon in the sprite, it'll just render your icon right there, which is super handy. Cool. And so how can I build this? This is all super cool. How can I build this stuff? So at MuleSoft, it was a custom solution that I built. But we're using some open source things and maybe one day the library will be actually open sourced. I think they're working on that. But here are some other resources for you guys. So there's a project called Car Blanche where basically it will kind of build out that component library for you. You give it a path, it's a webpack plugin, and you give it a path to where your components live. It will then generate this kind of UI for you. And it'll also do some cool stuff, like build out your examples and really stress tests. Like, oh, what happens when all these weird properties are passed into this component? There's also a React Storybook, which is very similar to this, where it's kind of like writing tests though, where you're writing examples for your components. React Doctrine from the React core team, super handy. You could basically pass a directory of React components, as long as those React components have prop types and comments above the prop types.  That's actually what we're using under the hood with our solution. Or you could roll your own. Again, with React Doctrine, it's a command line tool, but you can basically give it a path. It'll spit back all the data about that component, and then you can just render out whatever you want so you can get creative there. Our Component Library uses these two links at the bottom here, the React Component Illustrator, and its corresponding Webpack plugin. This does the same thing as React Doctrine, it's using it under the hood, but it also will grab those example files that I showed in that Component Anatomy, and it will take that example source code and also make that available to me in the user interface for the Component Library. So people can see that code and interact with it. So if you're interested in that, check out those two links. Cool. This is a last minute, really awful diagram that I put in here. Or basically, this is kind of the idea.  And then when you make an update, you can basically propagate that out throughout your applications. It's important to use semantic versioning. So if there are breaking changes, you want to make sure that those don't actually get passed through your CI-CD system. But yeah, cool.  Many of them have this kind of like living style guide, which you could fork and kind of do whatever with. But you don't need to start from scratch if you're working with React. There's tons of stuff to leverage or just to see how specific components are built. Cool. So let's talk about distribution. So how do I actually get this out to my team? How can they actually consume it? And that's just very simply with Webpack and with MPM. There's a couple important things to note though with this.  You don't want to build this massive index file or this output to this lib file because then if, let's say a consuming application is only using two components or three components or maybe four, they would, in their bundle, they would have everything. And it's going to be rather large until tree shaking is like relatively used everywhere. It's going to be a problem and the bundle size is going to grow tremendously. So what you want to do is build each individual component separately and give it its own entry point basically, where then the consumer would just import button from at your Component Library and then the built output. And what this looks like, because you're building each thing into like a flat directory structure, what that means is like now you can externalize all of the components that each component is using. And like basically, so let's, for this example, the button component, it also uses the icon component. It also uses the tooltip component. And if you weren't building these separately and externalizing, which is a webpack feature, externalizing those, button would have the entire source code for icon and it would have the entire source code for tooltip and it's like built output. And then the consumer app could also be using other things that use tooltip and there's basically code duplication that you want to avoid. What we also did to keep the bundle sizes down is we also externalized the CSS. So this requires that the consumer also uses post-CSS but it's for our team at MuleSoft so that's fine and everyone can do that. And this also means that when the CSS, when the actual application is built, it'll only use the CSS that the application is using it won't use other stuff. And you can also pipe that down to the browser in a CSS file rather than in the JavaScript bundle. And browsers can request multiple files concurrently so this is kind of a performance optimization. Cool so and then the other kind of like core piece of this especially if a lot of people are consuming your components is like how do you actually know that? Like what components are being used where? Like it's very hard to keep track of that stuff manually so this code you could actually probably just grab and tweak a little bit but basically this will, every time webpack builds it will parse through. Webpack gives you the entire file structure of your application, all the things that are being imported so you can basically just check and see, okay what components is this consuming application actually using and then report that back? So we set this up at MuleSoft to actually ping a Lambda function with a serverless framework, shameless plug to store that so I actually know what version of the application it was, what components that they're consuming and that basically helps inform the team of okay we're making this change to component XYZ who's actually consuming it? Okay I can see that there's these three applications consuming it, cool when we make this change let's double check those three applications that we didn't do something bad so it's important to have that kind of visibility in there. Cool and then some lessons learned. So you want to be like very vigilant with your component APIs, it's super, super easy to say like okay let's add all the properties you need to do this, you have a use case for this, you have a use case for this, your props start to grow out of control and it's really, really hard to deprecate props. Yeah so basically you want to be vigilant and make sure that use higher order components basically wrapping the component in another component if there's like some one off use cases that you need don't just add more and more props. Yeah don't add things so you have use cases for them this was a conversation all the time of like hey what about this future use case that we don't have yet that we may never have? We yeah you want to avoid stuff like that. Name things well and agree on a standard so I have a blog post prop type naming conventions so we try to mirror the DOM as close as possible we don't want to reinvent API like things if it's really just mapping down to a DOM primitive use like really good naming conventions for props like for example if it's a Boolean property use is filled or is open or has value instead of just value or whatever or filled. Yeah and avoid unnecessary abstractions.  Test server side render ability early and often this is something that we didn't do in the beginning and I had to go back and like retrofit a lot of code if you are gonna be rendering on the server or if you want a static website like I showed you wanna make sure that you basically aren't doing any document or window calls in your components but yeah cool. So yeah so let me actually I'm gonna show you guys the component library and then I'll wrap up with some final thoughts. So this is the MuleSoft component library. We have basically all this stuff automatically generated from the source code. There we go. So this is it. Okay no this is gonna be hard to demo now. Okay so basically these are all like working components. You can actually see the usage here of like okay here is my component. Here's all the props that I'm giving it. This documentation the prop types and the comments are automatically generated from the code. This is a live code editor so I can change this to danger let's say and you could see this is now a danger button. But yeah so it's basically like this is exactly how you use this component in your application. I wrote the code for you so you don't have to. And what this like allows is for like really really really quick prototyping and really really fast basically iterations on products. Likewise we have some demos. So this is kind of what I showed before. And also I can't go back. So we also have our typography all the colors which is being automatically generated from that JavaScript file and just looping over that printing amount and all of our icons. And these are all like basically SVG use tags. Let me show you guys what that looks like. So here's our SVG and here is the use tag that's just referencing the sprite that's down in the bottom of the page. So this means like you don't want to inline like icons everywhere especially if you're using icons in a table or whatever it's going to make your DOM super heavy. So you want to keep those things kind of down to a minimum. But yeah, so that is the live demo. Well, so some final thoughts. So with this setup you can basically like achieve like a faster development velocity. If everyone's consuming the same things and contributing back to the same code base you can do things a lot faster. That's not to say that everything needs to like every component needs to live in the component library. We did have some use cases where like project XYZ had some custom things that it needed. So those components just lived in their repository. And then sometimes they actually were like, oh, we actually need that in other things. Let's move that into the component library and use it elsewhere. But yeah, individuals can work on these like isolated components without worrying about breaking things. The main thing for me is like having a multi-platform component library. So again, targeting mobile browser and desktop. And having it like basically on all of our assets. So I don't have to maintain three different sets of CSS. I just maintain my component library. I can use that again on my marketing site, on my blog, on any demo apps inside of the application and you name it. Yeah. And you can render this stuff statically. So server-side rendering for better user experience and indexability. And yeah, and if you choose the static path, so this is again using something like Phenomic, you can render your, basically it's doing server-side rendering like in your CI system. And then it's deploying that out through a CDN. So you basically have like raw scale like out of the box if your application isn't that dynamic, which is what we're doing a lot of. So like no matter how much traffic goes to like our site or whatever, it's on a CDN. So it doesn't really matter. We're not rendering that over and over again, only once that build. Yeah, so that in my opinion is like the future stack. And I hope that was informative. And yeah, let me know if you guys have any questions on Twitter. I'm at David Wells. Yeah, and these are my favorite pieces of technology right now. Cool. Thank you.


So it is important that we don't judge people through our own lens But that we try to understand the person's experience through their eyes their history their situation And it is not a sign of weakness I think it's I like to call it more a sign of Processing sometimes people are trying to process the new information that is coming into their lives the new sense of threat That is coming into a life. They're trying to process the fear response and how to Work that through in their lives Trauma can stay with you for a long time But it can also stay with you for a very short time And if you do if you take certain steps and allow that process of transformation to take place I mean, how do I get some balance and harmony in my life and how can I share that balance and harmony with others? because any Identity that is fully formed will move from a narcissistic approach to a more Altruistic approach in every single case because as we become older more mature We also become more able to see in different layers So this is impacting in this area of life But where else is it impacting and how can I be of service in other areas? That doesn't mean you become a superhero. We can't be everything to everyone We're not Superman, but it does mean that as we good as we grow as we grow older We do Expand to help other people and this could not be achieved by the way without this existential inquiry that makes us sometimes feel threatened and it pushes some of us into trauma and Also, almost everyone pushes almost everyone into grief and loss even if we experience it differently I'm sure that a lot of people We have cried many times Over what's going on in the world right now, right? It may be not just because we covered maybe we have cried because Because of how the world is being polluted and we don't want to see it that way We have cried because of how many animals are disappearing or being extinct Who knows there's so many things that we could focus on but it is an existential inquiry It is a call to action. How are you going to show up for the world from today on? Yeah, it's it's hard. I realize it's hard because we we've said social animals I'm way and it's all about emotion sometimes when we interact with people how we make them feel how they make us feel But it is important if we're gonna help people and I know some of you are interested in what do I do? How do I help people that are experiencing this and try to be as neutral as possible for their sake? While still remaining human So with that it brings me to point eight. Don't ask you what is going to be helpful rule number one rule number one of anyone that wants to help is Ask three letter word ASK What do you need to feel safe? Are you feeling a safe? How do you feel should be the first one? How do you feel? I'm fine. Okay, if you can believe it if it's unlike and I'm fine, but maybe you don't believe it You know, you're not sounding like you're fine So but make sure that you do that in a kind way not in a push away Not in a in a sticky big way not like in a in a way that you want to Leave them naked, you know, some people just need to know that you're there. They don't need you to be a counselor You shouldn't be a counselor anyway, if you want to help people in a workplace for example It might be simple things like how is that there's position in the office and I've seen a lot of people that get relaxed with very different things It's amazing in English countries how many people get get back into Relax mode with a cup of tea or a cup of coffee, you know It's wonderful and that's all they need However, however that is their experience. It doesn't mean that because I like a cup of tea or like a coffee That makes me relax. That's gonna relax them. So find out ask help the process for them When you're asking you shouldn't be You're asking because you want to know you should be more a helpful questioning that helps them Work out things because it's not about us. Is it it's about them. So the question should be Such a way that they get helps them well Hi, I'm Amy Golding director of psychology for the Workplace Mental Health Institute We hope you liked the video if you did make sure to give it a thumbs up We have more and more videos being released each week So when you subscribe you'll get a notification letting you know when a new one's just been published so make sure to hit that subscribe button and Don't miss out on this vital information for yourself your colleagues and your loved ones