local Children = require(script.Parent.PropMarkers.Children) local ElementKind = require(script.Parent.ElementKind) local Logging = require(script.Parent.Logging) local Type = require(script.Parent.Type) local config = require(script.Parent.GlobalConfig).get() local multipleChildrenMessage = [[ The prop `Roact.Children` was defined but was overriden by the third parameter to createElement! This can happen when a component passes props through to a child element but also uses the `children` argument: Roact.createElement("Frame", passedProps, { child = ... }) Instead, consider using a utility function to merge tables of children together: local children = mergeTables(passedProps[Roact.Children], { child = ... }) local fullProps = mergeTables(passedProps, { [Roact.Children] = children }) Roact.createElement("Frame", fullProps)]] --[[ Creates a new element representing the given component. Elements are lightweight representations of what a component instance should look like. Children is a shorthand for specifying `Roact.Children` as a key inside props. If specified, the passed `props` table is mutated! ]] local function createElement(component, props, children) if config.typeChecks then assert(component ~= nil, "`component` is required") assert(typeof(props) == "table" or props == nil, "`props` must be a table or nil") assert(typeof(children) == "table" or children == nil, "`children` must be a table or nil") end if props == nil then props = {} end if children ~= nil then if props[Children] ~= nil then Logging.warnOnce(multipleChildrenMessage) end props[Children] = children end local elementKind = ElementKind.fromComponent(component) local element = { [Type] = Type.Element, [ElementKind] = elementKind, component = component, props = props, } if config.elementTracing then -- We trim out the leading newline since there's no way to specify the -- trace level without also specifying a message. element.source = debug.traceback("", 2):sub(2) end return element end return createElement