[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-6071":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":17,"stars7d":18,"stars30d":19,"stars90d":16,"forks30d":16,"starsTrendScore":20,"compositeScore":21,"rankGlobal":10,"rankLanguage":10,"license":22,"archived":23,"fork":23,"defaultBranch":24,"hasWiki":23,"hasPages":23,"topics":25,"createdAt":10,"pushedAt":10,"updatedAt":28,"readmeContent":29,"aiSummary":30,"trendingCount":16,"starSnapshotCount":16,"syncStatus":31,"lastSyncTime":32,"discoverSource":33},6071,"clay","nicbarker\u002Fclay","nicbarker","High performance UI layout library in C.","https:\u002F\u002Fnicbarker.com\u002Fclay",null,"C",17423,685,99,178,0,6,46,225,30,110.51,"zlib License",false,"main",[26,27],"layout","ui","2026-06-12 04:00:27","# Clay, A UI Layout Library\n**_Clay_** (short for **C Layout**) is a high performance 2D UI layout library.\n\n### Major Features\n- Microsecond layout performance\n- Flex-box like layout model for complex, responsive layouts including text wrapping, scrolling containers and aspect ratio scaling\n- Transition API for easy layout animations\n- Single 4.8k LOC **clay.h** file with **zero** dependencies (including no standard library linking)\n- Wasm support: compile with clang to a 15kb uncompressed **.wasm** file for use in the browser\n- Static arena based memory use with no malloc \u002F free, and low total memory overhead (e.g. ~3.5mb for 8192 layout elements).\n- React-like nested declarative syntax\n- Renderer agnostic: outputs a sorted list of rendering primitives that can be easily composited in any 3D engine, and even compiled to HTML (examples provided)\n\nTake a look at the [clay website](https:\u002F\u002Fnicbarker.com\u002Fclay) for an example of clay compiled to wasm and running in the browser, or others in the [examples directory](https:\u002F\u002Fgithub.com\u002Fnicbarker\u002Fclay\u002Ftree\u002Fmain\u002Fexamples).\n\nYou can also watch the [introduction video](https:\u002F\u002Fyoutu.be\u002FDYWTw19_8r4) for an overview of the motivation behind Clay's development and a short demo of its usage.\n\n\u003Cimg width=\"1394\" alt=\"A screenshot of a code IDE with lots of visual and textual elements\" src=\"https:\u002F\u002Fgithub.com\u002Fuser-attachments\u002Fassets\u002F9986149a-ee0f-449a-a83e-64a392267e3d\">\n\n_An example GUI application built with clay_\n\n## Quick Start\n\nDownload or clone clay.h and include it after defining `CLAY_IMPLEMENTATION` in one file.\n\n```C\n\u002F\u002F Must be defined in one file, _before_ #include \"clay.h\"\n#define CLAY_IMPLEMENTATION\n#include \"..\u002F..\u002Fclay.h\"\n\nconst Clay_Color COLOR_LIGHT = (Clay_Color) {224, 215, 210, 255};\nconst Clay_Color COLOR_RED = (Clay_Color) {168, 66, 28, 255};\nconst Clay_Color COLOR_ORANGE = (Clay_Color) {225, 138, 50, 255};\n\nvoid HandleClayErrors(Clay_ErrorData errorData) {\n    \u002F\u002F See the Clay_ErrorData struct for more information\n    printf(\"%s\", errorData.errorText.chars);\n    switch(errorData.errorType) {\n        \u002F\u002F etc\n    }\n}\n\n\u002F\u002F Example measure text function\nstatic inline Clay_Dimensions MeasureText(Clay_StringSlice text, Clay_TextElementConfig *config, uintptr_t userData) {\n    \u002F\u002F Clay_TextElementConfig contains members such as fontId, fontSize, letterSpacing etc\n    \u002F\u002F Note: Clay_String->chars is not guaranteed to be null terminated\n    return (Clay_Dimensions) {\n            .width = text.length * config->fontSize, \u002F\u002F \u003C- this will only work for monospace fonts, see the renderers\u002F directory for more advanced text measurement\n            .height = config->fontSize\n    };\n}\n\n\u002F\u002F Layout config is just a struct that can be declared statically, or inline\nClay_ElementDeclaration sidebarItemConfig = (Clay_ElementDeclaration) {\n    .layout = {\n        .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(50) }\n    },\n    .backgroundColor = COLOR_ORANGE\n};\n\n\u002F\u002F Re-useable components are just normal functions\nvoid SidebarItemComponent() {\n    CLAY(id, sidebarItemConfig) {\n        \u002F\u002F children go here...\n    }\n}\n\nint main() {\n    \u002F\u002F Note: malloc is only used here as an example, any allocator that provides\n    \u002F\u002F a pointer to addressable memory of at least totalMemorySize will work\n    uint64_t totalMemorySize = Clay_MinMemorySize();\n    Clay_Arena arena = Clay_CreateArenaWithCapacityAndMemory(totalMemorySize, malloc(totalMemorySize));\n\n    \u002F\u002F Note: screenWidth and screenHeight will need to come from your environment, Clay doesn't handle window related tasks\n    Clay_Initialize(arena, (Clay_Dimensions) { screenWidth, screenHeight }, (Clay_ErrorHandler) { HandleClayErrors });\n\n    while(renderLoop()) { \u002F\u002F Will be different for each renderer \u002F environment\n        \u002F\u002F Optional: Update internal layout dimensions to support resizing\n        Clay_SetLayoutDimensions((Clay_Dimensions) { screenWidth, screenHeight });\n        \u002F\u002F Optional: Update internal pointer position for handling mouseover \u002F click \u002F touch events - needed for scrolling & debug tools\n        Clay_SetPointerState((Clay_Vector2) { mousePositionX, mousePositionY }, isMouseDown);\n        \u002F\u002F Optional: Update internal pointer position for handling mouseover \u002F click \u002F touch events - needed for scrolling and debug tools\n        Clay_UpdateScrollContainers(true, (Clay_Vector2) { mouseWheelX, mouseWheelY }, deltaTime);\n\n        \u002F\u002F All clay layouts are declared between Clay_BeginLayout and Clay_EndLayout\n        Clay_BeginLayout();\n\n        \u002F\u002F An example of laying out a UI with a fixed width sidebar and flexible width main content\n        CLAY(CLAY_ID(\"OuterContainer\"), { .layout = { .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)}, .padding = CLAY_PADDING_ALL(16), .childGap = 16 }, .backgroundColor = {250,250,255,255} }) {\n            CLAY(CLAY_ID(\"SideBar\"), {\n                .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_FIXED(300), .height = CLAY_SIZING_GROW(0) }, .padding = CLAY_PADDING_ALL(16), .childGap = 16 },\n                .backgroundColor = COLOR_LIGHT\n            }) {\n                CLAY(CLAY_ID(\"ProfilePictureOuter\"), { .layout = { .sizing = { .width = CLAY_SIZING_GROW(0) }, .padding = CLAY_PADDING_ALL(16), .childGap = 16, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER } }, .backgroundColor = COLOR_RED }) {\n                    CLAY(CLAY_ID(\"ProfilePicture\"), { .layout = { .sizing = { .width = CLAY_SIZING_FIXED(60), .height = CLAY_SIZING_FIXED(60) }}, .image = { .imageData = &profilePicture } }) {}\n                    CLAY_TEXT(CLAY_STRING(\"Clay - UI Library\"), { .fontSize = 24, .textColor = {255, 255, 255, 255} });\n                }\n\n                \u002F\u002F Standard C code like loops etc work inside components\n                for (int i = 0; i \u003C 5; i++) {\n                    SidebarItemComponent();\n                }\n\n                CLAY(CLAY_ID(\"MainContent\"), { .layout = { .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0) } }, .backgroundColor = COLOR_LIGHT }) {}\n            }\n        }\n\n        \u002F\u002F All clay layouts are declared between Clay_BeginLayout and Clay_EndLayout\n        Clay_RenderCommandArray renderCommands = Clay_EndLayout(deltaTime); \u002F\u002F deltaTime is the time since the last frame, and is used for transitions\n\n        \u002F\u002F More comprehensive rendering examples can be found in the renderers\u002F directory\n        for (int i = 0; i \u003C renderCommands.length; i++) {\n            Clay_RenderCommand *renderCommand = &renderCommands.internalArray[i];\n\n            switch (renderCommand->commandType) {\n                case CLAY_RENDER_COMMAND_TYPE_RECTANGLE: {\n                    DrawRectangle(renderCommand->boundingBox, renderCommand->renderData.rectangle.backgroundColor);\n                }\n                \u002F\u002F ... Implement handling of other command types\n            }\n        }\n    }\n}\n```\n    \nThe above example, rendered correctly will look something like the following:\n\n![Clay Example](https:\u002F\u002Fgithub.com\u002Fuser-attachments\u002Fassets\u002F1928c6d4-ada9-4a4c-a3d1-44fe9b23b3bd)\n\nIn summary, the general order of steps is:\n\n1. [Clay_SetLayoutDimensions(dimensions)](#clay_setlayoutdimensions)\t\n2. [Clay_SetPointerState(pointerPosition, isPointerDown)](#clay_setpointerstate)\n3. [Clay_UpdateScrollContainers(enableDragScrolling, scrollDelta, deltaTime)](#clay_updatescrollcontainers)\n4. [Clay_BeginLayout()](#clay_beginlayout)\n5. Declare your layout with the provided [Element Macros](#element-macros)\n6. [Clay_EndLayout()](#clay_endlayout)\n7. Render the results using the outputted [Clay_RenderCommandArray](#clay_rendercommandarray)\n\nFor help starting out or to discuss clay, considering joining [the discord server.](https:\u002F\u002Fdiscord.gg\u002Fb4FTWkxdvT)\n\n## Summary\n\n\u003C!-- TOC -->\n* [High Level Documentation](#high-level-documentation)\n  * [Building UI Hierarchies](#building-ui-hierarchies)\n  * [Configuring Layout and Styling UI Elements](#configuring-layout-and-styling-ui-elements)\n  * [Element IDs](#element-ids)\n  * [Mouse, Touch and Pointer Interactions](#mouse-touch-and-pointer-interactions)\n  * [Scrolling Elements](#scrolling-elements)\n  * [Floating Elements (\"Absolute\" Positioning)](#floating-elements-absolute-positioning)\n  * [Laying Out Your Own Custom Elements](#laying-out-your-own-custom-elements)\n  * [Transitions](#transitions)\n  * [Retained Mode Rendering](#retained-mode-rendering)\n  * [Visibility Culling](#visibility-culling)\n  * [Preprocessor Directives](#preprocessor-directives)\n  * [Bindings for non C](#bindings-for-non-c)\n  * [Other implementations](#other-implementations)\n  * [Debug Tools](#debug-tools)\n  * [Running more than one Clay instance](#running-more-than-one-clay-instance)\n* [API](#api)\n    * [Naming Conventions](#naming-conventions)\n  * [Public Functions](#public-functions)\n    * [Lifecycle for public functions](#lifecycle-for-public-functions)\n    * [Clay_MinMemorySize](#clay_minmemorysize)\n    * [Clay_CreateArenaWithCapacityAndMemory](#clay_createarenawithcapacityandmemory)\n    * [Clay_SetMeasureTextFunction](#clay_setmeasuretextfunction)\n    * [Clay_ResetMeasureTextCache](#clay_resetmeasuretextcache)\n    * [Clay_SetMaxElementCount](#clay_setmaxelementcount)\n    * [Clay_SetMaxMeasureTextCacheWordCount](#clay_setmaxmeasuretextcachewordcount)\n    * [Clay_Initialize](#clay_initialize)\n    * [Clay_SetCurrentContext](#clay_setcurrentcontext)\n    * [Clay_GetCurrentContext](#clay_getcurrentcontext)\n    * [Clay_SetLayoutDimensions](#clay_setlayoutdimensions)\n    * [Clay_SetPointerState](#clay_setpointerstate)\n    * [Clay_UpdateScrollContainers](#clay_updatescrollcontainers)\n    * [Clay_GetScrollOffset](#clay_getscrolloffset)\n    * [Clay_BeginLayout](#clay_beginlayout)\n    * [Clay_EndLayout](#clay_endlayout)\n    * [Clay_Hovered](#clay_hovered)\n    * [Clay_OnHover](#clay_onhover)\n    * [Clay_PointerOver](#clay_pointerover)\n    * [Clay_GetOpenElementId](#clay_getopenelementid)\n    * [Clay_GetScrollContainerData](#clay_getscrollcontainerdata)\n    * [Clay_GetElementData](#clay_getelementdata)\n    * [Clay_GetElementId](#clay_getelementid)\n  * [Element Macros](#element-macros)\n    * [CLAY()](#clay)\n    * [CLAY_AUTO_ID()](#clay_auto_id)\n    * [CLAY_TEXT()](#clay_text)\n    * [CLAY_ID()](#clay_id)\n    * [CLAY_SID()](#clay_sid)\n    * [CLAY_IDI()](#clay_idi)\n    * [CLAY_SIDI()](#clay_sidi)\n    * [CLAY_ID_LOCAL()](#clay_id_local)\n    * [CLAY_SID_LOCAL()](#clay_sid_local)\n    * [CLAY_IDI_LOCAL()](#clay_idi_local)\n    * [CLAY_SIDI_LOCAL()](#clay_sidi_local)\n  * [Data Structures & Definitions](#data-structures--definitions)\n    * [Clay_ElementDeclaration](#clay_elementdeclaration)\n    * [Clay_LayoutConfig](#clay_layoutconfig)\n    * [Clay_ImageElementConfig](#clay_imageelementconfig)\n    * [Clay_AspectRatioElementConfig](#clay_aspectratioelementconfig)\n    * [Clay_ImageElementConfig](#clay_imageelementconfig-1)\n    * [Clay_ClipElementConfig](#clay_clipelementconfig)\n    * [Clay_BorderElementConfig](#clay_borderelementconfig)\n    * [Clay_FloatingElementConfig](#clay_floatingelementconfig)\n    * [Clay_CustomElementConfig](#clay_customelementconfig)\n    * [Clay_TransitionElementConfig](#clay_transitionelementconfig)\n    * [Clay_Color](#clay_color)\n    * [Clay_String](#clay_string)\n    * [Clay_ElementId](#clay_elementid)\n    * [Clay_RenderCommandArray](#clay_rendercommandarray)\n    * [Clay_RenderCommand](#clay_rendercommand)\n    * [Clay_ScrollContainerData](#clay_scrollcontainerdata)\n    * [Clay_ElementData](#clay_elementdata)\n    * [Clay_PointerData](#clay_pointerdata)\n    * [Clay_ErrorHandler](#clay_errorhandler)\n    * [Clay_ErrorData](#clay_errordata)\n\u003C!-- TOC -->\n\n## High Level Documentation\n\n### Building UI Hierarchies\nClay UIs are built using the C macro `CLAY(id, { configuration })`. This macro creates a new empty element in the UI hierarchy, and supports modular customisation of layout, styling and functionality. The `CLAY()` macro can also be _nested_, similar to other declarative UI systems like HTML.\n\nChild elements are added by opening a block: `{}` after calling the `CLAY()` macro (exactly like you would with an `if` statement or `for` loop), and declaring child components inside the braces.\n```C\n\u002F\u002F Parent element with 8px of padding\nCLAY(CLAY_ID(\"parent\"), { .layout = { .padding = CLAY_PADDING_ALL(8) } }) {\n    \u002F\u002F Child element 1\n    CLAY_TEXT(CLAY_STRING(\"Hello World\"), { .fontSize = 16 });\n    \u002F\u002F Child element 2 with red background\n    CLAY((CLAY_ID(\"child\"), { .backgroundColor = COLOR_RED }) {\n        \u002F\u002F etc\n    }\n}\n```\n\nHowever, unlike HTML and other declarative DSLs, this macro is just C. As a result, you can use arbitrary C code such as loops, functions and conditions inside your layout declaration code:\n```C\n\u002F\u002F Re-usable \"components\" are just functions that declare more UI\nvoid ButtonComponent(Clay_String buttonText) {\n    \u002F\u002F Red box button with 8px of padding\n    CLAY_AUTO_ID({ .layout = { .padding = CLAY_PADDING_ALL(8) }, .backgroundColor = COLOR_RED }) {\n        CLAY_TEXT(buttonText, textConfig);\n    }\n}\n\n\u002F\u002F Parent element\nCLAY(CLAY_ID(\"parent\"), { .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM } }) {\n    \u002F\u002F Render a bunch of text elements\n    for (int i = 0; i \u003C textArray.length; i++) {\n        CLAY_TEXT(textArray.elements[i], textConfig);\n    }\n    \u002F\u002F Only render this element if we're on a mobile screen\n    if (isMobileScreen) {\n        CLAY(0) {\n            \u002F\u002F etc\n        }\n    }\n    \u002F\u002F Re-usable components\n    ButtonComponent(CLAY_STRING(\"Click me!\"));\n    ButtonComponent(CLAY_STRING(\"No, click me!\"));\n});\n```\n\n### Configuring Layout and Styling UI Elements\nThe layout and style of clay elements is configured with the [Clay_ElementDeclaration](#clay_elementdeclaration) struct passed to the `CLAY()` macro. \n```C\nCLAY(CLAY_ID(\"box\"), { .layout = { .padding = { 8, 8, 8, 8 }, .layoutDirection = CLAY_TOP_TO_BOTTOM } }) {\n    \u002F\u002F Children are 8px inset into parent, and laid out top to bottom\n}\n```\nThis macro isn't magic - all it's doing is wrapping the standard designated initializer syntax. e.g. `(Clay_ElementDeclaration) { .layout = { .padding = { .left = 8, .right = 8 } ...`.\n\nSee the [Clay_ElementDeclaration](#clay_elementdeclaration) API for the full list of options.\n\nA `Clay_ElementDeclaration` struct can be defined in file scope or elsewhere, and reused.\n```C\n\u002F\u002F Define a style in the global \u002F file scope\nClay_ElementDeclaration reuseableStyle = (Clay_ElementDeclaration) {\n    .layout = { .padding = { .left = 12 } },\n    .backgroundColor = { 120, 120, 120, 255 },\n    .cornerRadius = { 12, 12, 12, 12 }\n};\n\nCLAY(CLAY_ID(\"box\"), reuseableStyle) {\n    \u002F\u002F ...\n}\n```\n\n### Element IDs\n\nThe Clay macro by default accepts an ID as its first argument, which is usually provided by the [CLAY_ID()](#clay_id) convenience macro. Elements can also be created with auto generated IDs, by using the [CLAY_AUTO_ID()](#clay-auto-id) macro.\n\n```C\n\u002F\u002F Will always produce the same ID from the same input string\nCLAY(CLAY_ID(\"OuterContainer\"), { ...configuration }) {}\n\n\u002F\u002F Generates a unique ID that may not be the same between two layout calls\nCLAY_AUTO_ID({ ...configuration }) {}\n```\n\nElement IDs have two main use cases. Firstly, tagging an element with an ID allows you to query information about the element later, such as its [mouseover state](#clay_pointerover) or dimensions.\n\nSecondly, IDs are visually useful when attempting to read and modify UI code, as well as when using the built-in [debug tools](#debug-tools).\n\nTo avoid having to construct dynamic strings at runtime to differentiate ids in loops, clay provides the [CLAY_IDI(string, index)](#clay_idi) macro to generate different ids from a single input string. Think of IDI as \"**ID** + **I**ndex\"\n```C\n\u002F\u002F This is the equivalent of calling CLAY_ID(\"Item0\"), CLAY_ID(\"Item1\") etc\nfor (int index = 0; index \u003C items.length; index++) {\n    CLAY(CLAY_IDI(\"Item\", index), { ..configuration }) {}\n}\n```\n\nThis ID will be forwarded to the final `Clay_RenderCommandArray` for use in retained mode UIs. Using duplicate IDs may cause some functionality to misbehave (i.e. if you're trying to attach a floating container to a specific element with ID that is duplicated, it may not attach to the one you expect)\n\n### Mouse, Touch and Pointer Interactions\n\nClay provides several functions for handling mouse and pointer interactions.\n\nAll pointer interactions depend on the function `void Clay_SetPointerState(Clay_Vector2 position, bool isPointerDown)` being called after each mouse position update and before any other clay functions.\n\n**During UI declaration**\n\nThe function `bool Clay_Hovered()` can be called during element construction or in the body of an element, and returns `true` if the mouse \u002F pointer is over the currently open element.\n\n```C\n\u002F\u002F An orange button that turns blue when hovered\nCLAY(CLAY_ID(\"Button\"), { .backgroundColor = Clay_Hovered() ? COLOR_BLUE : COLOR_ORANGE }) {\n    bool buttonHovered = Clay_Hovered();\n    CLAY_TEXT(buttonHovered ? CLAY_STRING(\"Hovered\") : CLAY_STRING(\"Hover me!\"), headerTextConfig);\n}\n```\n\nThe function `void Clay_OnHover()` allows you to attach a function pointer to the currently open element, which will be called if the mouse \u002F pointer is over the element.\n\n```C\nvoid HandleButtonInteraction(Clay_ElementId elementId, Clay_PointerData pointerInfo, void *userData) {\n    ButtonData *buttonData = (ButtonData *)userData;\n    \u002F\u002F Pointer state allows you to detect mouse down \u002F hold \u002F release\n    if (pointerInfo.state == CLAY_POINTER_DATA_PRESSED_THIS_FRAME) {\n        \u002F\u002F Do some click handling\n        NavigateTo(buttonData->link);\n    }\n}\n\nButtonData linkButton = (ButtonData) { .link = \"https:\u002F\u002Fgithub.com\u002Fnicbarker\u002Fclay\" };\n\n\u002F\u002F HandleButtonInteraction will be called for each frame the mouse \u002F pointer \u002F touch is inside the button boundaries\nCLAY(CLAY_ID(\"Button\"), { .layout = { .padding = CLAY_PADDING_ALL(8) } }) {\n    Clay_OnHover(HandleButtonInteraction, &linkButton);\n    CLAY_TEXT(CLAY_STRING(\"Button\"), &headerTextConfig);\n}\n```\n\n**Before \u002F After UI declaration**\n\nIf you want to query mouse \u002F pointer overlaps outside layout declarations, you can use the function `bool Clay_PointerOver(Clay_ElementId id)`, which takes an [element id](#element-ids) and returns a bool representing whether the current pointer position is within its bounding box. \n```C\n\u002F\u002F Reminder: Clay_SetPointerState must be called before functions that rely on pointer position otherwise it will have no effect\nClay_Vector2 mousePosition = { x, y };\nClay_SetPointerState(mousePosition, mouseButtonDown(0));\n\u002F\u002F ...\n\u002F\u002F If profile picture was clicked\nif (mouseButtonDown(0) && Clay_PointerOver(Clay_GetElementId(\"ProfilePicture\"))) {\n    \u002F\u002F Handle profile picture clicked\n}\n```\n\nNote that the bounding box queried by `Clay_PointerOver` is from the last frame. This generally shouldn't make a difference except in the case of animations that move at high speed.\nIf this is an issue for you, performing layout twice per frame with the same data will give you the correct interaction the second time.\n\n### Scrolling Elements\n\nElements are configured as scrollable with the `.clip` configuration. Clipping instructs the renderer to not draw any pixels outside the clipped element's boundaries, and by specifying the `.childOffset` field, the clipped element's contents can be shifted around to provide \"scrolling\" behaviour.\n\nYou can either calculate scrolling yourself and simply provide the current offset each frame to `.childOffset`, or alternatively, Clay provides a built in mechanism for tracking and updating scroll container offsets, detailed below.\n\nTo make scroll containers respond to mouse wheel and scroll events, two functions need to be called before `BeginLayout()`:\n```C\nClay_Vector2 mousePosition = { x, y };\n\u002F\u002F Reminder: Clay_SetPointerState must be called before Clay_UpdateScrollContainers otherwise it will have no effect\nClay_SetPointerState(mousePosition);\n\u002F\u002F Clay_UpdateScrollContainers needs to be called before Clay_BeginLayout for the position to avoid a 1 frame delay\nClay_UpdateScrollContainers(\n    true, \u002F\u002F Enable drag scrolling\n    scrollDelta, \u002F\u002F Clay_Vector2 scrollwheel \u002F trackpad scroll x and y delta this frame\n    float deltaTime, \u002F\u002F Time since last frame in seconds as a float e.g. 8ms is 0.008f\n);\n\u002F\u002F ...\n\u002F\u002F Clay internally tracks the scroll containers offset, and Clay_GetScrollOffset returns the x,y offset of the currently open element\nCLAY(CLAY_ID(\"ScrollContainer\"), { .clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() } }) {\n    \u002F\u002F Scrolling contents\n}\n\u002F\u002F .childOffset can be provided directly if you would prefer to manage scrolling outside of clay\nCLAY(CLAY_ID(\"ScrollContainer\"), { .clip = { .vertical = true, .childOffset = myData.scrollContainer.offset } }) {\n    \u002F\u002F Scrolling contents\n}\n```\n\nMore specific details can be found in the docs for [Clay_UpdateScrollContainers](#clay_updatescrollcontainers), [Clay_SetPointerState](#clay_setpointerstate), [Clay_ClipElementConfig](#clay_clipelementconfig) and [Clay_GetScrollOffset](#clay_getscrolloffset).\n\n### Floating Elements (\"Absolute\" Positioning)\n\nAll standard elements in clay are laid out on top of, and _within_ their parent, positioned according to their parent's layout rules, and affect the positioning and sizing of siblings.\n\n**\"Floating\"** is configured with the `CLAY_FLOATING()` macro. Floating elements don't affect the parent they are defined in, or the position of their siblings.\nThey also have a **z-index**, and as a result can intersect and render over the top of other elements.\n\nA classic example use case for floating elements is tooltips and modals.\n\n```C\n\u002F\u002F The two text elements will be laid out top to bottom, and the floating container\n\u002F\u002F will be attached to \"Outer\"\nCLAY(CLAY_ID(\"Outer\"), { .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM } }) {\n    CLAY_TEXT(text, &headerTextConfig);\n    CLAY(CLAY_ID(\"Tooltip\"), { .floating = { .attachTo = CLAY_ATTACH_TO_PARENT } }) {}\n    CLAY_TEXT(text, &headerTextConfig);\n}\n```\n\nMore specific details can be found in the full [Floating API](#clay_floatingelementconfig).\n\n### Laying Out Your Own Custom Elements\n\nClay only supports a simple set of UI element primitives, such as rectangles, text and images. Clay provides a singular API for layout out custom elements:\n```C\n#include \"clay.h\"\n\ntypedef enum {\n    CUSTOM_ELEMENT_TYPE_MODEL,\n    CUSTOM_ELEMENT_TYPE_VIDEO\n} CustomElementType;\n\n\u002F\u002F A rough example of how you could handle laying out 3d models in your UI\ntypedef struct {\n    CustomElementType type;\n    union {\n        Model model;\n        Video video;\n        \u002F\u002F ...\n    };\n} CustomElementData;\n\nModel myModel = Load3DModel(filePath);\nCustomElement modelElement = (CustomElement) { .type = CUSTOM_ELEMENT_TYPE_MODEL, .model = myModel }\n\ntypedef struct {\n    void* memory;\n    uintptr_t offset;\n} Arena;\n\n\u002F\u002F During init\nArena frameArena = (Arena) { .memory = malloc(1024) };\n\n\u002F\u002F Custom elements only take a single pointer, so we need to store the data somewhere\nCustomElementData *modelData = (CustomElementData *)(frameArena.memory + frameArena.offset);\n*modelData = (CustomElementData) { .type = CUSTOM_ELEMENT_TYPE_MODEL, .model = myModel };\nframeArena.offset += sizeof(CustomElementData);\nCLAY(CLAY_ID(\"3DModelViewer\"), { .custom = { .customData = modelData } }) {}\n\n\u002F\u002F Later during your rendering\nswitch (renderCommand->commandType) {\n    \u002F\u002F ...\n    case CLAY_RENDER_COMMAND_TYPE_CUSTOM: {\n        \u002F\u002F Your extended struct is passed through\n        CustomElementData *customElement = renderCommand->config.customElementConfig->customData;\n        if (!customElement) continue;\n        switch (customElement->type) {\n            case CUSTOM_ELEMENT_TYPE_MODEL: {\n                \u002F\u002F Render your 3d model here\n                break;\n            }\n            case CUSTOM_ELEMENT_TYPE_VIDEO: {\n                \u002F\u002F Render your video here\n                break;\n            }\n            \u002F\u002F ...\n        }\n        break;\n    }\n}\n```\n\nMore specific details can be found in the full [Custom Element API](#clay_customelementconfig).\n\n### Transitions\nClay includes a \"Transition\" API, which allows you to smoothly animate \u002F tween from one state to another.\nBoth layout-affecting properties such as `width` and `height`, as well as non-layout properties such as `backgroundColor` are supported.\nSee the [transition documentation]() for more info.\n\n```C\n\u002F\u002F Note: for transitions to work, elements need a stable ID from one frame to the next - using loop indexes or CLAY_AUTO_ID will not work.\nCLAY(CLAY_IDI(\"box\", colors[index].id), {\n    .layout.sizing = { CLAY_SIZING_GROW(), CLAY_SIZING_GROW() },\n    .layout.childAlignment = { CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER },\n    .backgroundColor = boxColor,\n    .overlayColor = Clay_Hovered() ? (Clay_Color) { 140, 140, 140, 80 } : (Clay_Color) { 255, 255, 255, 0 },\n    \u002F\u002F Transitions will activate once a handler function is defined.\n    .transition = {\n        .handler = Clay_EaseOut,\n        .duration = 0.5f,\n        \u002F\u002F A \"flag\" enum is used to specify which properties to transition, use a bitwise OR (|) to construct the flags.\n        .properties = CLAY_TRANSITION_PROPERTY_WIDTH | CLAY_TRANSITION_PROPERTY_POSITION | CLAY_TRANSITION_PROPERTY_OVERLAY_COLOR | CLAY_TRANSITION_PROPERTY_BACKGROUND_COLOR,\n        .enter = { .setInitialState = EnterExitSlideUp },\n        .exit = { .setFinalState = EnterExitSlideUp },\n    }\n}) {\n    Clay_OnHover(HandleCellButtonInteraction, (void*)(uint64_t)index);\n    CLAY_TEXT(((Clay_String) { .length = 2, .chars = colors[index].stringId, .isStaticallyAllocated = true }), {\n        .fontSize = 32,\n        .textColor = colors[index].id > 29 ? (Clay_Color) {255, 255, 255, 255} : (Clay_Color) {154, 123, 184, 255 }\n    });\n}\n```\n\n\u003Cvideo src=\"https:\u002F\u002Fgithub.com\u002Fuser-attachments\u002Fassets\u002Fa8e5cd88-f0da-4fad-acd0-81f253436bc7\" controls>\u003C\u002Fvideo>\n\n_An example of the transition API action can be found at examples\u002Fraylib-transitions_\n\n### Retained Mode Rendering\nClay was originally designed for [Immediate Mode](https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=Z1qyvQsjK5Y) rendering - where the entire UI is redrawn every frame. This may not be possible with your platform, renderer design or performance constraints.\n\nThere are some general techniques that can be used to integrate clay into a retained mode rendering system:\n\n- `Clay_RenderCommand` includes the `uint32_t id` that was used to declare the element. If unique ids are used, these can be mapped to persistent graphics objects across multiple frames \u002F layouts.\n- Render commands are culled automatically to only currently visible elements, and `Clay_RenderCommand` is a small enough struct that you can simply compare the memory of two render commands with matching IDs to determine if the element is \"dirty\" and needs to be re-rendered or updated.\n\nFor a worked example, see the provided [HTML renderer](https:\u002F\u002Fgithub.com\u002Fnicbarker\u002Fclay\u002Fblob\u002Fmain\u002Frenderers\u002Fweb\u002Fhtml\u002Fclay-html-renderer.html). This renderer converts clay layouts into persistent HTML documents with minimal changes per frame.  \n\n### Visibility Culling\nClay provides a built-in visibility-culling mechanism that is **enabled by default**. It will only output render commands for elements that are visible - that is, **at least one pixel of their bounding box is inside the viewport.**\n\nThis culling mechanism can be disabled via the use of the `#define CLAY_DISABLE_CULLING` directive. See [Preprocessor Directives](#preprocessor-directives) for more information.\n\n### Preprocessor Directives\nClay supports C preprocessor directives to modulate functionality at compile time. These can be set either in code using `#define CLAY_DISABLE_CULLING` or on the command line when compiling using the appropriate compiler specific arguments, e.g. `clang -DCLAY_DISABLE_CULLING main.c ...`\n\nThe supported directives are:\n\n- `CLAY_WASM` - Required when targeting Web Assembly.\n- `CLAY_DLL` - Required when creating a .Dll file.\n\n### Bindings for non C\n\nClay is usable out of the box as a `.h` include in both C99 and C++20 with designated initializer support.\nThere are also supported bindings for other languages, including:\n\n- [Odin Bindings](https:\u002F\u002Fgithub.com\u002Fnicbarker\u002Fclay\u002Ftree\u002Fmain\u002Fbindings\u002Fodin)\n- [Rust Bindings](https:\u002F\u002Fgithub.com\u002Fclay-ui-rs\u002Fclay)\n\n### Other implementations\nClay has also been implemented in other languages:\n\n- [`glay`](https:\u002F\u002Fgithub.com\u002Fsoypat\u002Fglay) - Go line-by-line rewrite with readability as main goal.\n- [`totallygamerjet\u002Fclay`](https:\u002F\u002Fgithub.com\u002Ftotallygamerjet\u002Fclay) - Port using `cxgo`, a C to Go transpiler.\n- [`goclay`](https:\u002F\u002Fgithub.com\u002Figadmg\u002Fgoclay) - Go line-by-line rewrite closely matching the reference.\n\n### Debug Tools\n\nClay includes built-in UI debugging tools, similar to the \"inspector\" in browsers such as Chrome or Firefox. These tools are included in `clay.h`, and work by injecting additional render commands into the output [Clay_RenderCommandArray](#clay_rendercommandarray).\n\nAs long as the renderer that you're using works correctly, no additional setup or configuration is required to use the debug tools.\n\nTo enable the debug tools, use the function `Clay_SetDebugModeEnabled(bool enabled)`. This boolean is persistent and does not need to be set every frame.\n\nThe debug tooling by default will render as a panel to the right side of the screen, compressing your layout by its width. The default width is 400 and is currently configurable via the direct mutation of the internal variable `Clay__debugViewWidth`, however this is an internal API and is potentially subject to change.\n\n\u003Cimg width=\"1506\" alt=\"Screenshot 2024-09-12 at 12 54 03 PM\" src=\"https:\u002F\u002Fgithub.com\u002Fuser-attachments\u002Fassets\u002F2d122658-3305-4e27-88d6-44f08c0cb4e6\">\n\n_The official Clay website with debug tooling visible_\n\n### Running more than one Clay instance\n\nClay allows you to run more than one instance in a program. To do this, [Clay_Initialize](#clay_initialize) returns a [Clay_Context*](#clay_context) reference. You can activate a specific instance using [Clay_SetCurrentContext](#clay_setcurrentcontext). If [Clay_SetCurrentContext](#clay_setcurrentcontext) is not called, then Clay will default to using the context from the most recently called [Clay_Initialize](#clay_initialize).\n\n**⚠ Important: Do not render instances across different threads simultaneously, as Clay does not currently support proper multi-threading.**\n\n```c++\n\u002F\u002F Define separate arenas for the instances.\nClay_Arena arena1, arena2;\n\u002F\u002F ... allocate arenas\n\n\u002F\u002F Initialize both instances, storing the context for each one.\nClay_Context* instance1 = Clay_Initialize(arena1, layoutDimensions, errorHandler);\nClay_Context* instance2 = Clay_Initialize(arena2, layoutDimensions, errorHandler);\n\n\u002F\u002F In the program's render function, activate each instance before executing clay commands and macros.\nClay_SetCurrentContext(instance1);\nClay_BeginLayout();\n\u002F\u002F ... declare layout for instance1\nClay_RenderCommandArray renderCommands1 = Clay_EndLayout(deltaTime);\nrender(renderCommands1);\n\n\u002F\u002F Switch to the second instance\nClay_SetCurrentContext(instance2);\nClay_BeginLayout();\n\u002F\u002F ... declare layout for instance2\nClay_RenderCommandArray renderCommands2 = Clay_EndLayout(deltaTime);\nrender(renderCommands2);\n```\n\n# API\n\n### Naming Conventions\n\n- \"**CAPITAL_LETTERS()**\" are used for macros.\n- \"**Clay__**\" (\"Clay\" followed by **double** underscore) is used for internal functions that are not intended for use and are subject to change.\n- \"**Clay_**\" (\"Clay\" followed by **single** underscore) is used for external functions that can be called by the user.\n\n## Public Functions\n\n### Lifecycle for public functions\n\n**At startup \u002F initialization time, run once**\n`Clay_MinMemorySize` -> `Clay_CreateArenaWithCapacityAndMemory` -> `Clay_Initialize` -> `Clay_SetMeasureTextFunction`\n\n**Each Frame**\n`Clay_SetLayoutDimensions` -> `Clay_SetPointerState` -> `Clay_UpdateScrollContainers` -> `Clay_BeginLayout` -> `CLAY() etc...` -> `Clay_EndLayout`\n\n---\n\n### Clay_MinMemorySize\n\n`uint32_t Clay_MinMemorySize()`\n\nReturns the minimum amount of memory **in bytes** that clay needs to accommodate the current [CLAY_MAX_ELEMENT_COUNT](#preprocessor-directives).\n\n---\n\n### Clay_CreateArenaWithCapacityAndMemory\n\n`Clay_Arena Clay_CreateArenaWithCapacityAndMemory(size_t capacity, void *memory)`\n\nCreates a `Clay_Arena` struct with the given capacity and base memory pointer, which can be passed to [Clay_Initialize](#clay_initialize).\n\n---\n\n### Clay_SetMeasureTextFunction\n\n`void Clay_SetMeasureTextFunction(Clay_Dimensions (*measureTextFunction)(Clay_StringSlice text, Clay_TextElementConfig *config, void* userData), void* userData)`\n\nTakes a pointer to a function that can be used to measure the `width, height` dimensions of a string. Used by clay during layout to determine [CLAY_TEXT](#clay_text) element sizing and wrapping.\n\n**Note 1: This string is not guaranteed to be null terminated.** Clay saves significant performance overhead by using slices when wrapping text instead of having to clone new null terminated strings. If your renderer does not support **ptr, length** style strings (e.g. Raylib), you will need to clone this to a new C string before rendering.\n\n**Note 2: It is essential that this function is as fast as possible.** For text heavy use-cases this function is called many times, and despite the fact that clay caches text measurements internally, it can easily become the dominant overall layout cost if the provided function is slow. **This is on the hot path!**\n\n---\n\n### Clay_ResetMeasureTextCache\n\n`void Clay_ResetMeasureTextCache(void)`\n\nClay caches measurements from the provided MeasureTextFunction, and this will be sufficient for the majority of use-cases. However, if the measurements can depend on external factors that clay does not know about, like DPI changes, then the cached values may be incorrect. When one of these external factors changes, Clay_ResetMeasureTextCache can be called to force clay to recalculate all string measurements in the next frame.\n\n---\n\n### Clay_SetMaxElementCount\n\n`void Clay_SetMaxElementCount(int32_t maxElementCount)`\n\nSets the internal maximum element count that will be used in subsequent [Clay_Initialize()](#clay_initialize) and [Clay_MinMemorySize()](#clay_minmemorysize) calls, allowing clay to allocate larger UI hierarchies.\n\n**Note: You will need to reinitialize clay, after calling [Clay_MinMemorySize()](#clay_minmemorysize) to calculate updated memory requirements.**\n\n---\n\n### Clay_SetMaxMeasureTextCacheWordCount\n\n`void Clay_SetMaxMeasureTextCacheWordCount(int32_t maxMeasureTextCacheWordCount)`\n\nSets the internal text measurement cache size that will be used in subsequent [Clay_Initialize()](#clay_initialize) and [Clay_MinMemorySize()](#clay_minmemorysize) calls, allowing clay to allocate more text. The value represents how many separate words can be stored in the text measurement cache.\n\n**Note: You will need to reinitialize clay, after calling [Clay_MinMemorySize()](#clay_minmemorysize) to calculate updated memory requirements.**\n\n---\n\n### Clay_Initialize\n\n`Clay_Context* Clay_Initialize(Clay_Arena arena, Clay_Dimensions layoutDimensions, Clay_ErrorHandler errorHandler)`\n\nInitializes the internal memory mapping, sets the internal dimensions for layout, and binds an error handler for clay to use when something goes wrong. Returns a [Clay_Context*](#clay_context) that can optionally be given to [Clay_SetCurrentContext](#clay_setcurrentcontext) to allow running multiple instances of clay in the same program, and sets it as the current context. See [Running more than one Clay instance](#running-more-than-one-clay-instance).\n\nReference: [Clay_Arena](#clay_createarenawithcapacityandmemory), [Clay_ErrorHandler](#clay_errorhandler), [Clay_SetCurrentContext](#clay_setcurrentcontext)\n\n---\n\n### Clay_SetCurrentContext\n\n`void Clay_SetCurrentContext(Clay_Context* context)`\n\nSets the context that subsequent clay commands will operate on. You can get this reference from [Clay_Initialize](#clay_initialize) or [Clay_GetCurrentContext](#clay_getcurrentcontext). See [Running more than one Clay instance](#running-more-than-one-clay-instance).\n\n---\n\n### Clay_GetCurrentContext\n\n`Clay_Context* Clay_GetCurrentContext()`\n\nReturns the context that clay commands are currently operating on, or null if no context has been set. See [Running more than one Clay instance](#running-more-than-one-clay-instance).\n\n---\n\n### Clay_SetLayoutDimensions\n\n`void Clay_SetLayoutDimensions(Clay_Dimensions dimensions)`\n\nSets the internal layout dimensions. Cheap enough to be called every frame with your screen dimensions to automatically respond to window resizing, etc.\n\n---\n\n### Clay_SetPointerState\n\n`void Clay_SetPointerState(Clay_Vector2 position, bool isPointerDown)`\n\nSets the internal pointer position and state (i.e. current mouse \u002F touch position) and recalculates overlap info, which is used for mouseover \u002F click calculation (via [Clay_PointerOver](#clay_pointerover) and updating scroll containers with [Clay_UpdateScrollContainers](#clay_updatescrollcontainers). **isPointerDown should represent the current state this frame, e.g. it should be `true` for the entire duration the left mouse button is held down.** Clay has internal handling for detecting click \u002F touch start & end.\n\n---\n\n### Clay_UpdateScrollContainers\n\n`void Clay_UpdateScrollContainers(bool enableDragScrolling, Clay_Vector2 scrollDelta, float deltaTime)`\n\nThis function handles scrolling of containers. It responds to both `scrollDelta`, which represents mouse wheel or trackpad scrolling this frame, as well as \"touch scrolling\" on mobile devices, or \"drag scrolling\" with a mouse or similar device.\n\nTouch \u002F drag scrolling only occurs if the `enableDragScrolling` parameter is `true`, **and** [Clay_SetPointerState](#clay_setpointerstate) has been called this frame. As a result, you can simply always call it with `false` as the first argument if you want to disable touch scrolling.\n\n`deltaTime` is the time **in seconds** since the last frame (e.g. 0.016 is **16 milliseconds**), and is used to normalize & smooth scrolling across different refresh rates.\n\n---\n\n### Clay_GetScrollOffset\n\n`Clay_Vector2 Clay_GetScrollOffset()`\n\nReturns the internally stored scroll offset for the currently open element.\n\nGenerally intended for use with [clip elements](#clay_clipelementconfig) and the `.childOffset` field to create scrolling containers.\n\nSee [Scrolling Elements](#scrolling-elements) for more details.\n\n```C\n\u002F\u002F Create a horizontally scrolling container\nCLAY(CLAY_ID(\"ScrollContainer\"), {\n    .clip = { .horizontal = true, .childOffset = Clay_GetScrollOffset() }\n})\n```\n\n---\n\n### Clay_BeginLayout\n\n`void Clay_BeginLayout()`\n\nPrepares clay to calculate a new layout. Called each frame \u002F layout **before** any of the [Element Macros](#element-macros).\n\n---\n\n### Clay_EndLayout\n\n`Clay_RenderCommandArray Clay_EndLayout()`\n\nEnds declaration of element macros and calculates the results of the current layout. Renders a [Clay_RenderCommandArray](#clay_rendercommandarray) containing the results of the layout calculation.\n\n---\n\n### Clay_Hovered\n\n`bool Clay_Hovered()`\n\nCalled **during** layout declaration, and returns `true` if the pointer position previously set with `Clay_SetPointerState` is inside the bounding box of the currently open element. Note: this is based on the element's position from the **last** frame.\n\n---\n\n### Clay_OnHover\n\n`void Clay_OnHover(void (*onHoverFunction)(Clay_ElementId elementId, Clay_PointerData pointerData, void *userData), void *userData)`\n\nCalled **during** layout declaration, this function allows you to attach a function pointer to the currently open element that will be called once per layout if the pointer position previously set with `Clay_SetPointerState` is inside the bounding box of the currently open element. See [Clay_PointerData](#clay_pointerdata) for more information on the `pointerData` argument.\n\n```C\nvoid HandleButtonInteraction(Clay_ElementId elementId, Clay_PointerData pointerData, void *userData) {\n    ButtonData *buttonData = (ButtonData *)userData;\n    \u002F\u002F Pointer state allows you to detect mouse down \u002F hold \u002F release\n    if (pointerData.state == CLAY_POINTER_DATA_PRESSED_THIS_FRAME) {\n        \u002F\u002F Do some click handling\n        NavigateTo(buttonData->link);\n    }\n}\n\nButtonData linkButton = (ButtonData) { .link = \"https:\u002F\u002Fgithub.com\u002Fnicbarker\u002Fclay\" };\n\n\u002F\u002F HandleButtonInteraction will be called for each frame the mouse \u002F pointer \u002F touch is inside the button boundaries\nCLAY(CLAY_ID(\"Button\"), { .layout = { .padding = CLAY_PADDING_ALL(8) } }) {\n    Clay_OnHover(HandleButtonInteraction, &buttonData);\n    CLAY_TEXT(CLAY_STRING(\"Click me!\"), &headerTextConfig);\n}\n```\n\n---\n\n### Clay_PointerOver\n\n`bool Clay_PointerOver(Clay_ElementId id)`\n\nReturns `true` if the pointer position previously set with `Clay_SetPointerState` is inside the bounding box of the layout element with the provided `id`. Note: this is based on the element's position from the **last** frame. If frame-accurate pointer overlap detection is required, perhaps in the case of significant change in UI layout between frames, you can simply run your layout code twice that frame. The second call to `Clay_PointerOver` will be frame-accurate.\n\n---\n\n### Clay_GetOpenElementId\n\n`Clay_ElementId Clay_GetOpenElementId()`\n\nReturns the [Clay_ElementId](#clay_elementid) of the currently open element. Useful for getting the ID of elements opened with [CLAY_AUTO_ID](#clay_auto_id).\n\n---\n\n\n### Clay_GetScrollContainerData\n\n`Clay_ScrollContainerData Clay_GetScrollContainerData(Clay_ElementId id)`\n\nReturns [Clay_ScrollContainerData](#clay_scrollcontainerdata) for the scroll container matching the provided ID. This function allows imperative manipulation of scroll position, allowing you to build things such as scroll bars, buttons that \"jump\" to somewhere in a scroll container, etc.\n\n---\n\n### Clay_GetElementData\n\n`Clay_ElementData Clay_GetElementData(Clay_ElementId id)`\n\nReturns [Clay_ElementData](#clay_elementdata) for the element matching the provided ID.\nUsed to retrieve information about elements such as their final calculated bounding box.\n\n---\n\n### Clay_GetElementId\n\n`Clay_ElementId Clay_GetElementId(Clay_String idString)`\n\nReturns a [Clay_ElementId](#clay_elementid) for the provided id string, used for querying element info such as mouseover state, scroll container data, etc.\n\n## Element Macros\n\n### CLAY()\n**Usage**\n\n`CLAY(...configuration) { ...children }`\n\n**Lifecycle**\n\n`Clay_BeginLayout()` -> `CLAY()` -> `Clay_EndLayout()` \n\n**Notes**\n\n**CLAY** opens a generic empty container, that is configurable and supports nested children.\n**CLAY** requires a parameter, so if you want to create an element without any configuration, use `CLAY(0)`.\n\n**Examples**\n```C\n\u002F\u002F Define an element with 16px of x and y padding\nCLAY(CLAY_ID(\"Outer\"), { .layout = { .padding = CLAY_PADDING_ALL(16) } }) {\n    \u002F\u002F A nested child element\n    CLAY(CLAY_ID(\"SideBar\"), { .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 16 } }) {\n        \u002F\u002F Children laid out top to bottom with a 16 px gap between them\n    }\n    \u002F\u002F A vertical scrolling container with a colored background\n    CLAY(CLAY_ID(\"ScrollContainer\"), {\n        .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 16 },\n        .backgroundColor = { 200, 200, 100, 255 },\n        .cornerRadius = CLAY_CORNER_RADIUS(10),\n        .clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() }\n    }) {\n        \u002F\u002F child elements\n    }\n}\n```\n\n---\n\n### CLAY_AUTO_ID()\n\nA version of the core [CLAY()](#clay) element creation macro that generates an ID automatically instead of requiring it as the first argument.\n\nNote that under the hood this ID is generated in the same way as [CLAY_ID_LOCAL()](#clay_id_local), which is based on the element's position in the hierarchy, and may chance between layout calls if elements are added \u002F removed from the hierarchy before the element is defined. As a result, for transitions & retained mode backends to work correctly, IDs should be specified.\n\n```C\n\u002F\u002F Note that CLAY_AUTO_ID only takes one argument: the configuration\nCLAY_AUTO_ID({ .layout = { .padding = CLAY_PADDING_ALL(16) } }) {\n    \u002F\u002F A nested child element\n    CLAY_AUTO_ID({ .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 16 } }) {\n        \u002F\u002F Children laid out top to bottom with a 16 px gap between them\n    }\n    \u002F\u002F A vertical scrolling container with a colored background\n    CLAY_AUTO_ID({\n        .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 16 },\n        .backgroundColor = { 200, 200, 100, 255 },\n        .cornerRadius = CLAY_CORNER_RADIUS(10),\n        .clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() }\n    }) {\n        \u002F\u002F child elements\n    }\n}\n```\n\n---\n\n### CLAY_TEXT()\n**Usage**\n\n`CLAY_TEXT(Clay_String textContents, Clay_TextElementConfig *textConfig);`\n\n**Lifecycle**\n\n`Clay_BeginLayout()` -> `CLAY_TEXT()` -> `Clay_EndLayout()`\n\n**Notes**\n\n**TEXT** is a measured, auto-wrapped text element. It uses `Clay_TextElementConfig` to configure text specific options.\n\nNote that `Clay_TextElementConfig` uses `uint32_t fontId`. Font ID to font asset mapping is managed in user code and passed to render commands.\n\n**Struct API (Pseudocode)**\n\n```C\n\u002F\u002F CLAY_TEXT(text, { .member = value }) supports these options\nClay_TextElementConfig {\n    Clay_Color textColor {\n        float r; float g; float b; float a;\n    };\n    uint16_t fontId;\n    uint16_t fontSize;\n    uint16_t letterSpacing;\n    uint16_t lineHeight;\n    Clay_TextElementConfigWrapMode wrapMode {\n        CLAY_TEXT_WRAP_WORDS (default),\n        CLAY_TEXT_WRAP_NEWLINES,\n        CLAY_TEXT_WRAP_NONE,\n    };\n    Clay_TextAlignment textAlignment {\n        CLAY_TEXT_ALIGN_LEFT (default),\n        CLAY_TEXT_ALIGN_CENTER,\n        CLAY_TEXT_ALIGN_RIGHT,\n    };\n    void *userData;\n};\n```\n\n**Fields**\n\n**`.textColor`**\n\n`CLAY_TEXT(text, { .textColor = {120, 120, 120, 255} })`\n\nUses [Clay_Color](#clay_color). Conventionally accepts `rgba` float values between 0 and 255, but interpretation is left up to the renderer and does not affect layout.\n\n---\n\n**`.fontId`**\n\n`CLAY_TEXT(text, { .fontId = FONT_ID_LATO })`\n\nIt's up to the user to load fonts and create a mapping from `fontId` to a font that can be measured and rendered.\n\n---\n\n**`.fontSize`**\n\n`CLAY_TEXT(text, { .fontSize = 16 })`\n\nFont size is generally thought of as `x pixels tall`, but interpretation is left up to the user & renderer.\n\n---\n\n**`.letterSpacing`**\n\n`CLAY_TEXT(text, { .letterSpacing = 1 })`\n\n`.letterSpacing` results in **horizontal** white space between individual rendered characters.\n\n---\n\n**`.lineHeight`**\n\n`CLAY_TEXT(text, { .lineHeight = 20 })`\n\n`.lineHeight` - when non zero - forcibly sets the `height` of each wrapped line of text to `.lineheight` pixels tall. Will affect the layout of both parents and siblings. A value of `0` will use the measured height of the font.\n\n---\n\n**`.wrapMode`**\n\n`CLAY_TEXT(text, { .wrapMode = CLAY_TEXT_WRAP_NONE })`\n\n`.wrapMode` specifies under what conditions text should [wrap](https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FLine_wrap_and_word_wrap).\n\nAvailable options are:\n\n- `CLAY_TEXT_WRAP_WORDS` (default) - Text will wrap on whitespace characters as container width shrinks, preserving whole words.\n- `CLAY_TEXT_WRAP_NEWLINES` -  will only wrap when encountering newline characters.\n- `CLAY_TEXT_WRAP_NONE` - Text will never wrap even if its container is compressed beyond the text measured width.\n\n---\n\n**`.textAlignment`**\n\n`CLAY_TEXT(text, { .textAlignment = CLAY_TEXT_ALIGN_CENTER })`\n\n`.textAlignment` controls how **wrapping** text lines are aligned. If you want to control the alignment of single lines of text, instead use the `childAlignment` property of the **parent** layout element.\n\nAvailable options are:\n\n- `CLAY_TEXT_ALIGN_LEFT` (default)\n- `CLAY_TEXT_ALIGN_CENTER`\n- `CLAY_TEXT_ALIGN_RIGHT`\n\n---\n\n**Examples**\n\n```C\n\u002F\u002F Define a font somewhere in your code\nconst uint32_t FONT_ID_LATO = 3;\n\u002F\u002F ..\nCLAY_TEXT(CLAY_STRING(\"John Smith\"), { .fontId = FONT_ID_LATO, .fontSize = 24, .textColor = {255, 0, 0, 255} });\n\u002F\u002F Rendering example\nFont fontToUse = LoadedFonts[renderCommand->renderData.text.fontId];\n```\n\n**Rendering**\n\nElement is subject to [culling](#visibility-culling). Otherwise, multiple `Clay_RenderCommand`s with `commandType = CLAY_RENDER_COMMAND_TYPE_TEXT` may be created, one for each wrapped line of text.\n\n`Clay_RenderCommand.textContent` will be populated with a `Clay_String` _slice_ of the original string passed in (i.e. wrapping doesn't reallocate, it just returns a `Clay_String` pointing to the start of the new line with a `length`)\n\n---\n\n### CLAY_ID()\n\n`Clay_ElementId CLAY_ID(STRING_LITERAL idString)`\n\n**CLAY_ID()** is used to generate and attach a [Clay_ElementId](#clay_elementid) to a layout element during declaration.\n\nNote this macro only works with String literals and won't compile if used with a `char*` variable. To use a heap allocated `char*` string as an ID, use [CLAY_SID](#clay_sid). \n\nTo regenerate the same ID outside of layout declaration when using utility functions such as [Clay_PointerOver](#clay_pointerover), use the [Clay_GetElementId](#clay_getelementid) function.\n\n**Examples**\n\n```C\n\u002F\u002F Tag a button with the Id \"Button\"\nCLAY(CLAY_ID(\"Button\"), {\n    .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_GROW(0) }, .padding = CLAY_PADDING_ALL(16), .childGap = 16 }\n}) {\n    \u002F\u002F ...children\n}\n\n\u002F\u002F Later on outside of layout code\nbool buttonIsHovered = Clay_PointerOver(Clay_GetElementId(\"Button\"));\nif (buttonIsHovered && leftMouseButtonPressed) {\n    \u002F\u002F ... do some click handling\n}\n```\n\n---\n\n### CLAY_SID()\n\n`Clay_ElementId CLAY_SID(Clay_String idString)`\n\nA version of [CLAY_ID](#clay_id) that can be used with heap allocated `char *` data. The underlying `char` data will not be copied internally and should live until at least the next frame.\n\n---\n\n### CLAY_IDI()\n\n`Clay_ElementId CLAY_IDI(STRING_LITERAL idString, int32_t index)`\n\nAn offset version of [CLAY_ID](#clay_id). Generates a [Clay_ElementId](#clay_elementid) string id from the provided `char *label`, combined with the `int index`.\n\nUsed for generating ids for sequential elements (such as in a `for` loop) without having to construct dynamic strings at runtime.\n\nNote this macro only works with String literals and won't compile if used with a `char*` variable. To use a heap allocated `char*` string as an ID, use [CLAY_SIDI](#clay_sidi).\n\n---\n\n### CLAY_SIDI()\n\n`Clay_ElementId CLAY_SIDI(Clay_String idString, int32_t index)`\n\nA version of [CLAY_IDI](#clay_idi) that can be used with heap allocated `char *` data. The underlying `char` data will not be copied internally and should live until at least the next frame.\n\n---\n\n### CLAY_ID_LOCAL()\n\n**Usage**\n\n`Clay_ElementId CLAY_ID_LOCAL(STRING_LITERAL idString)`\n\n**Lifecycle**\n\n`Clay_BeginLayout()` -> `CLAY(` -> `CLAY_ID_LOCAL()` -> `)` -> `Clay_EndLayout()`\n\n**Notes**\n\n**CLAY_ID_LOCAL()** is used to generate and attach a [Clay_ElementId](#clay_elementid) to a layout element during declaration.\n\nUnlike [CLAY_ID](#clay_id) which needs to be globally unique, a local ID is based on the ID of it's parent and only needs to be unique among its siblings.\n\nAs a result, local id is suitable for use in reusable components and loops.\n\nNote this macro only works with String literals and won't compile if used with a `char*` variable. To use a heap allocated `char*` string as an ID, use [CLAY_SID_LOCAL](#clay_sid_local).\n\n**Examples**\n\n```C\nvoid RenderHeaderButton(ButtonData button) {\n    CLAY({\n        .id = CLAY_ID_LOCAL(\"HeaderButton\"),\n        .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_GROW(0) }, .padding = CLAY_PADDING_ALL(16), .childGap = 16 }\n    }) {\n        \u002F\u002F ...children\n    }\n}\n\nfor (int i = 0; i \u003C headerButtons.length; i++) {\n    RenderHeaderButton(headerButtons.items[i]);\n}\n```\n\n---\n\n### CLAY_SID_LOCAL()\n\n`Clay_ElementId CLAY_SID_LOCAL(Clay_String idString)`\n\nA version of [CLAY_ID_LOCAL](#clay_id_local) that can be used with heap allocated `char *` data. The underlying `char` data will not be copied internally and should live until at least the next frame.\n\n---\n\n### CLAY_IDI_LOCAL()\n\n`Clay_ElementId CLAY_IDI_LOCAL(STRING_LITERAL idString, int32_t index)`\n\nAn offset version of [CLAY_ID_LOCAL](#clay_local_id). Generates a [Clay_ElementId](#clay_elementid) string id from the provided `char *label`, combined with the `int index`.\n\nUsed for generating ids for sequential elements (such as in a `for` loop) without having to construct dynamic strings at runtime.\n\nNote this macro only works with String literals and won't compile if used with a `char*` variable. To use a heap allocated `char*` string as an ID, use [CLAY_SIDI_LOCAL](#clay_sidi_local).\n\n---\n\n### CLAY_SIDI_LOCAL()\n\n`Clay_ElementId CLAY_SIDI_LOCAL(Clay_String idString, int32_t index)`\n\nA version of [CLAY_IDI_LOCAL](#clay_idi_local) that can be used with heap allocated `char *` data. The underlying `char` data will not be copied internally and should live until at least the next frame.\n\n---\n\n## Data Structures & Definitions\n\n### Clay_ElementDeclaration\nThe **Clay_ElementDeclaration** struct is the only argument to the `CLAY()` macro and provides configuration options for layout elements.\n\n```C\ntypedef struct {\n    Clay_LayoutConfig layout;\n    Clay_Color backgroundColor;\n    Clay_CornerRadius cornerRadius;\n    Clay_AspectRatioElementConfig aspectRatio;\n    Clay_ImageElementConfig image;\n    Clay_FloatingElementConfig floating;\n    Clay_CustomElementConfig custom;\n    Clay_ClipElementConfig clip;\n    Clay_BorderElementConfig border;\n    void *userData;\n} Clay_ElementDeclaration;\n```\n\n**Fields**\n\n**`.layout`** - `Clay_LayoutConfig`\n\n`CLAY(CLAY_ID(\"Element\"), { .layout = { .padding = { 16, 16, 12, 12 }, .layoutDirection = CLAY_TOP_TO_BOTTOM } })`\n\nUses [Clay_LayoutConfig](#clay_layoutconfig). Controls various settings related to _layout_, which can be thought of as \"the size and position of this element and its children\".\n\n---\n\n**`.backgroundColor`** - `Clay_Color`\n\n`CLAY(CLAY_ID(\"Element\"), { .backgroundColor = { 120, 120, 120, 255 } } })`\n\nUses [Clay_Color](#clay_color). Conventionally accepts `rgba` float values between 0 and 255, but interpretation is left up to the renderer and does not affect layout.\n\n---\n\n**`.overlayColor`** - `Clay_Color`\n\n`CLAY(CLAY_ID(\"Element\"), { .overlayColor = { 255, 120, 120, 255 } } })`\n\nUses [Clay_Color](#clay_color). Conventionally accepts `rgba` float values between 0 and 255, but interpretation is left up to the renderer and does not affect layout.\n\nSpecifying `.overlayColor` will cause two new render commands to be emitted: `OVERLAY_COLOR_BEGIN` immediately, and `OVERLAY_COLOR_END` after this elements subtree has been emitted.\n\nThis instructs the renderer to begin applying a color overlay to this element, and all child elements. The color overlay effect is similar to glsl's `mix(source, target, alpha)`. As a result, the strength of the color overlay is controlled by the `.a` channel of `.overlayColor`.\nZero alpha means \"all child colors remain the same\", full alpha means \"all child colours are replaced by the RGB overlayColor\", and values in between mean \"lerp from the child color to the overlay color by the alpha\".\n\nThis can be used as a cheap replacement for alpha \u002F opacity to \"fade in \u002F out\", by applying (and potentially transitioning) an overlay color to the same color as the background with full alpha.\n\n---\n\n**`.cornerRadius`** - `Clay_CornerRadius`\n\n`CLAY(CLAY_ID(\"Element\"), { .cornerRadius = { .topLeft = 16, .topRight = 16, .bottomLeft = 16, .bottomRight = 16 } })`\n\nDefines the radius in pixels for the arc of rectangle corners (`0` is square, `rectangle.width \u002F 2` is circular).\n\nNote that the `CLAY_CORNER_RADIUS(radius)` function-like macro is available to provide short hand for setting all four corner radii to the same value. e.g. `CLAY_BORDER({ .cornerRadius = CLAY_CORNER_RADIUS(10) })`\n\n---\n\n**`.aspectRatio`** - `Clay_AspectRatioElementConfig`\n\n`CLAY(CLAY_ID(\"Element\"), { .aspectRatio = 1 })`\n\nUses [Clay_AspectRatioElementConfig](#clay_aspectratioelementconfig). Configures the element as an aspect ratio scaling element. Especially useful for rendering images, but can also be used to enforce a fixed width \u002F height ratio of other elements.\n\n---\n\n**`.image`** - `Clay_ImageElementConfig`\n\n`CLAY(CLAY_ID(\"Element\"), { .image = { .imageData = &myImage } })`\n\nUses [Clay_ImageElementConfig](#clay_imageelementconfig). Configures the element as an image element. Causes a render command with type `IMAGE` to be emitted.\n\n---\n\n**`.floating`** - `Clay_FloatingElementConfig`\n\n`CLAY(CLAY_ID(\"Element\"), { .floating = { .attachTo = CLAY_ATTACH_TO_PARENT } })`\n\nUses [Clay_FloatingElementConfig](#clay_floatingelementconfig). Configures the element as an floating element, which allows it to stack \"in front\" and \"on top\" of other elements without affecting sibling or parent size or position. \n\n---\n\n**`.custom`** - `Clay_CustomElementConfig`\n\n`CLAY(CLAY_ID(\"Element\"), { .custom = { .customData = &my3DModel } })`\n\nUses [Clay_CustomElementConfig](#clay_customelementconfig). Configures the element as a custom element, which allows you to pass custom data through to the renderer. Causes a render command with type `CUSTOM` to be emitted.\n\n---\n\n**`.clip`** - `Clay_ClipElementConfig`\n\n`CLAY(CLAY_ID(\"Element\"), { .clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() } })`\n\nUses [Clay_ClipElementConfig](#clay_cliplelementconfig). Configures the element as a clip element, which causes child elements to be clipped \u002F masked if they overflow, and together with the functions listed in [Scrolling Elements](#scrolling-elements) enables scrolling of child contents.\n\n\u003Cimg width=\"580\" alt=\"An image demonstrating the concept of clipping which prevents rendering of a child elements pixels if they fall outside the bounds of the parent element.\" src=\"https:\u002F\u002Fgithub.com\u002Fuser-attachments\u002Fassets\u002F2eb83ff9-e186-4ea4-8a87-d90cbc0838b5\">\n\n---\n\n**`.border`** - `Clay_BorderElementConfig`\n\n`CLAY(CLAY_ID(\"Element\"), { .border = { .width = { .left = 5 }, .color = COLOR_BLUE } })`\n\nUses [Clay_BorderElementConfig](#clay_borderelementconfig). Configures the element as a border element, which instructs the renderer to draw coloured border lines along the perimeter of this element's bounding box. Causes a render command with type `BORDER` to be emitted.\n\n---\n\n**`.userData`** - `void *`\n\n`CLAY(CLAY_ID(\"Element\"), { .userData = &extraData })`\n\nTransparently passes a pointer through to the corresponding [Clay_RenderCommands](#clay_rendercommand)s generated by this element.\n\n---\n\n**Examples**\n\n```C\n\u002F\u002F Declare a reusable rectangle config, with a purple color and 10px rounded corners\nClay_RectangleElementConfig rectangleConfig = (Clay_RectangleElementConfig) { .color = { 200, 200, 100, 255 }, .cornerRadius = CLAY_CORNER_RADIUS(10) };\n\u002F\u002F Declare a rectangle element using a reusable config\nCLAY(CLAY_ID(\"Box\"), rectangleConfig) {}\n\u002F\u002F Declare a retangle element using an inline config\nCLAY(CLAY_ID(\"BoxInline\"), { .color = { 200, 200, 100, 255 }, .cornerRadius = CLAY_CORNER_RADIUS(10) })) {\n    \u002F\u002F child elements\n}\n\u002F\u002F Declare a scrolling container with a colored background\nCLAY(CLAY_ID(\"ScrollingContainer\"), { \n    .backgroundColor = { 200, 200, 100, 255 }, \n    .cornerRadius = CLAY_CORNER_RADIUS(10)\n    .clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() }\n) {\n    \u002F\u002F child elements\n}\n```\n\nElement is subject to [culling](#visibility-culling). Otherwise, a single `Clay_RenderCommand`s with `commandType = CLAY_RENDER_COMMAND_TYPE_RECTANGLE` will be created, with `renderCommand->renderData.rectangle` containing a pointer to the element's Clay_RectangleElementConfig.\n\n### Clay_LayoutConfig\n\n**Clay_LayoutConfig** is used for configuring _layout_ options (i.e. options that affect the final position and size of an element, its parents, siblings, and children)\n\n**Struct API (Pseudocode)**\n\n```C\n\u002F\u002F CLAY({ .layout = { ...fields } }) supports these options\nClay_LayoutConfig {\n    Clay_LayoutDirection layoutDirection = CLAY_LEFT_TO_RIGHT (default) | CLAY_TOP_TO_BOTTOM;\n    Clay_Padding padding {\n        u16 left; u16 right; u16 top; u16 bottom; \n    };\n    uint16_t childGap;\n    Clay_ChildAlignment childAlignment {\n        .x = CLAY_ALIGN_X_LEFT (default) | CLAY_ALIGN_X_CENTER | CLAY_ALIGN_X_RIGHT;\n        .y = CLAY_ALIGN_Y_TOP (default) | CLAY_ALIGN_Y_CENTER | CLAY_ALIGN_Y_BOTTOM;\n    };\n    Clay_Sizing sizing { \u002F\u002F Recommended to use the provided macros here - see #sizing for more in depth explanation\n        .width = CLAY_SIZING_FIT(float min, float max) (default) | CLAY_SIZING_GROW(float min, float max) | CLAY_SIZING_FIXED(float width) | CLAY_SIZING_PERCENT(float percent)\n        .height = CLAY_SIZING_FIT(float min, float max) (default) | CLAY_SIZING_GROW(float min, float max) | CLAY_SIZING_FIXED(float height) | CLAY_SIZING_PERCENT(float percent)\n    }; \u002F\u002F See CLAY_SIZING_GROW() etc for more details\n};\n```\n\n**Fields**\n\n**`.layoutDirection`** - `Clay_LayoutDirection`\n\n`CLAY(CLAY_ID(\"Element\"), { .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM } })`\n\nControls the axis \u002F direction in which child elements are laid out. Available options are `CLAY_LEFT_TO_RIGHT` (default) and `CLAY_TOP_TO_BOTTOM`.\n\n_Did you know that \"left to right\" and \"top to bottom\" both have 13 letters?_\n\n\u003Cimg width=\"580\" alt=\"Screenshot 2024-08-22 at 11 10 27 AM\" src=\"https:\u002F\u002Fgithub.com\u002Fuser-attachments\u002Fassets\u002F7008aa47-8826-4338-9257-8bc83f7813ce\">\n\n---\n\n**`.padding`** - `Clay_Padding`\n\n`CLAY(CLAY_ID(\"Element\"), { .layout = { .padding = { .left = 16, .right = 16, .top = 8, .bottom = 8 } } })`\n\nControls white-space \"padding\" around the **outside** of child elements.\n\n\u003Cimg width=\"486\" alt=\"Screenshot 2024-08-22 at 10 50 49 AM\" src=\"https:\u002F\u002Fgithub.com\u002Fuser-attachments\u002Fassets\u002Fb454fa36-92d5-4b1d-bf8b-e4c25428e9de\">\n\n---\n\n**`.childGap`** - `uint16_t`\n\n`CLAY(CLAY_ID(\"Element\"), { .layout = { .childGap = 16 } })`\n\nControls the white-space **between** child elements as they are laid out. When `.layoutDirection` is `CLAY_LEFT_TO_RIGHT` (default), this will be horizontal space, whereas for `CLAY_TOP_TO_BOTTOM` it will be vertical space.\n\n\u003Cimg width=\"600\" alt=\"Screenshot 2024-08-22 at 11 05 15 AM\" src=\"https:\u002F\u002Fgithub.com\u002Fuser-attachments\u002Fassets\u002Ffa0dae1f-1936-47f6-a299-634bd7d40d58\">\n\n---\n\n**`.childAlignment`** - `Clay_ChildAlignment`\n\n`CLAY(CLAY_ID(\"Element\"), { .layout = { .childAlignment = { .x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_CENTER } } })`\n\nControls the alignment of children relative to the height and width of the parent container. Available options are:\n```C\n.x = CLAY_ALIGN_X_LEFT (default) | CLAY_ALIGN_X_CENTER | CLAY_ALIGN_X_RIGHT;\n.y = CLAY_ALIGN_Y_TOP (default) | CLAY_ALIGN_Y_CENTER | CLAY_ALIGN_Y_BOTTOM;\n```\n\n\u003Cimg width=\"1030\" alt=\"Screenshot 2024-08-22 at 11 25 16 AM\" src=\"https:\u002F\u002Fgithub.com\u002Fuser-attachments\u002Fassets\u002Fbe61b4a7-db4f-447c-b6d6-b2d4a91fc664\">\n\n---\n\n**`.sizing`** - `Clay_Sizing`\n\n`CLAY(CLAY_ID(\"Element\"), { .layout = { .sizing = { .width = CLAY_SIZING_FIXED(300), .height = CLAY_SIZING_PERCENT(0.5) } } })`\n\nControls how final width and height of element are calculated. The same configurations are available for both the `.width` and `.height` axis. There are several options:\n\n- `CLAY_SIZING_FIT(float min, float max) (default)` - The element will be sized to fit its children (plus padding and gaps), up to `max`. If `max` is left unspecified, it will default to `FLOAT_MAX`. When elements are compressed to fit into a smaller parent, this element will not shrink below `min`.\n\n- `CLAY_SIZING_GROW(float min, float max)` - The element will grow to fill available space in its parent, up to `max`. If `max` is left unspecified, it will default to `FLOAT_MAX`. When elements are compressed to fit into a smaller parent, this element will not shrink below `min`.\n\n- `CLAY_SIZING_FIXED(float fixed)` - The final size will always be exactly the provided `fixed` value. Shorthand for `CLAY_SIZING_FIT(fixed, fixed)`\n\n- `CLAY_SIZING_PERCENT(float percent)` - Final size will be a percentage of parent size, minus padding and child gaps. `percent` is assumed to be a float between `0` and `1`.\n\n\u003Cimg width=\"1056\" alt=\"Screenshot 2024-08-22 at 2 10 33 PM\" src=\"https:\u002F\u002Fgithub.com\u002Fuser-attachments\u002Fassets\u002F1236efb1-77dc-44cd-a207-7944e0f5e500\">\n\n\u003Cimg width=\"1141\" alt=\"Screenshot 2024-08-22 at 2 19 04 PM\" src=\"https:\u002F\u002Fgithub.com\u002Fuser-attachments\u002Fassets\u002Fa26074ff-f155-4d35-9ca4-9278a64aac00\">\n\n\n**Example Usage**\n\n```C\nCLAY(CLAY_ID(\"Button\"), { .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_GROW(0) }, .padding = CLAY_PADDING_ALL(16, .childGap = 16) } }) {\n    \u002F\u002F Children will be laid out vertically with 16px of padding around and between\n}\n```\n\n---\n\n### Clay_ImageElementConfig\n**Usage**\n\n`CLAY(CLAY_ID(\"Element\"), { .image = { ...image config } }) {}`\n\n**Clay_ImageElementConfig** configures a clay element to render an image as its background.\n\n**Struct API (Pseudocode)**\n\n```C\nClay_ImageElementConfig {\n    void * imageData;\n};\n```\n\n**Fields**\n\n**`.imageData`** - `void *`\n\n`CLAY(CLAY_ID(\"Image\"), { .image = { .imageData = &myImage } }) {}`\n\n`.imageData` is a generic void pointer that can be used to pass through image data to the renderer.\n\n```C\n\u002F\u002F Load an image somewhere in your code\nYourImage profilePicture = LoadYourImage(\"profilePicture.png\");\n\u002F\u002F Note that when rendering, .imageData w","Clay 是一个用 C 语言编写的高性能 2D UI 布局库。它提供了微秒级的布局性能、类似 Flexbox 的布局模型以支持复杂的响应式布局（包括文本换行、滚动容器和宽高比缩放），以及易于使用的过渡 API 来实现布局动画。Clay 仅依赖于一个 4.8k 行的头文件，无任何外部依赖（甚至不链接标准库），并且支持 WebAssembly 编译，在浏览器中运行。此外，Clay 使用静态内存管理，避免了动态内存分配，具有低内存占用的特点。该库还提供了一个类似 React 的嵌套声明式语法，并且是渲染器无关的，可以轻松集成到各种 3D 引擎或转换为 HTML。Clay 适用于需要高性能且资源受限环境下的图形用户界面开发场景。",2,"2026-06-11 03:05:36","top_language"]