{"id":"sap0bombado/quill-rblx-components","name":"quill-rblx-components","scope":"sap0bombado","platform":"roblox","description":"A simple components system for Quill","version":"0.1.0-alpha.2","latest":"0.1.0-alpha.2","versions":["0.1.0-alpha.2"],"license":"MIT","licenseRating":"safe","licenseCaveats":[],"licenseVerified":true,"dependencies":{"sap0bombado/quill-core":{"version":"^0.1.0-alpha.2","alias":"core"}},"integrity":"2d5366666e14e007af976014f4e321610773bc06e910154c55d3c2aa0fe0f99b","likes":0,"downloads":0,"install":"forest install sap0bombado/quill-rblx-components","url":"https://forest.dev/p/roblox/sap0bombado/quill-rblx-components","files":"https://api.forest.dev/ai/package/roblox/sap0bombado/quill-rblx-components/files","readme":"# Components\r\n\r\nComponents are a powerful way to work with Roblox CollectionService tags to make behaviour for instances.<br>\r\nThanks to an abhorrent amount of used type functions, everything is completely typesafe.\r\n\r\n## Usage\r\n\r\n```luau\r\nlocal components = require(\"@pkg/quill_rblx_components\")\r\n\r\nlocal Door = {}\r\nlocal door_mt = { __index = Door }\r\n\r\ntype DoorProperties = {\r\n    is_open: boolean,\r\n    turn_rotation: vector,\r\n    toggle_prompt: ProximityPrompt,\r\n    instance: BasePart,\r\n    connections: { RBXScriptConnection },\r\n}\r\nexport type Door = setmetatable<DoorProperties, typeof(door_mt)>\r\n\r\nfunction Door.init(self: Door)\r\n    table.insert(\r\n        self.connections,\r\n        self.toggle_prompt.Triggered:Connect(function()\r\n            self:toggle()\r\n        end)\r\n    )\r\nend\r\n\r\nfunction Door.toggle(self: Door)\r\n    local sign = if self.is_open then -1 else 1\r\n    local target_angles = self.turn_rotation * vector.create(sign, sign, sign)\r\n    self.instance.CFrame *= CFrame.Angles(\r\n        target_angles.x,\r\n        target_angles.y,\r\n        target_angles.z\r\n    )\r\n    self.is_open = not self.is_open\r\nend\r\n\r\nfunction Door.destroy(self: Door)\r\n    for _, connection in self.connections do\r\n        connection:Disconnect()\r\n    end\r\nend\r\n\r\nlocal DoorComponent = {}\r\nDoorComponent.info = components.info {\r\n    attributes = {\r\n        default_state = components.attribute(\"boolean\", false), -- Boolean attribute with default value of `false`\r\n        turn_rotation = components.attribute(\"vector\"), -- Vector attribute with no default value, therefore it must exist, otherwise the constructor doesn't get called\r\n    },\r\n    children = {\r\n        toggle_prompt = components.child(\"ProximityPrompt\"), -- Child called `toggle_prompt` on the tagged instance that's a ProximityPrompt\r\n    },\r\n    is = components.singleton(\"BasePart\"), -- Any instance tagged with `Door` must be a `Part` to be initialized\r\n    tag = components.singleton(\"Door\"),\r\n}\r\ntype DoorData = components.CreationData<typeof(DoorComponent.info)>\r\n\r\nfunction DoorComponent.new(self: self, data: DoorData): Door\r\n    local door = {\r\n        is_open = data.attributes.default_state,\r\n        turn_rotation = data.attributes.turn_rotation,\r\n        toggle_prompt = data.children.toggle_prompt,\r\n        instance = data.instance,\r\n        connections = {},\r\n    }\r\n    return setmetatable(door, door_mt)\r\nend\r\n\r\nexport type self = typeof(DoorComponent)\r\nreturn DoorComponent\r\n```\r\n\r\nEach part tagged with `Door` must:\r\n- Have an attribute `default_state` of type boolean with the default value of `false`\r\n- Have an attribute `turn_rotation` of type vector with no default value; if it doesn't exist, the component isn't constructed for it\r\n- Have a child `toggle_prompt` of kind ProximityPrompt; if it doesn't exist, the component isn't constructed for it\r\n\r\nAfter a fitting door comes into the datamodel, the component will be:\r\n1. Created with `DoorComponent:new()`\r\n2. Initialized with `Door:init()`\r\n3. Destroyed with `Door:destroy()` if the tag gets removed or the instance is destroyed\r\n\r\n## Reference\r\n\r\nAll supported attribute types at the type of writing are also supported by this crate:\r\n- `string`\r\n- `number`\r\n- `boolean`\r\n- `vector`, interchangeable with `Vector3`, exists due to horrendous Roblox types for them\r\n- `Vector3`, interchangeable with `vector`, exists due to horrendous Roblox types for them\r\n- `Vector2`\r\n- `UDim`\r\n- `UDim2`\r\n- `BrickColor`\r\n- `Color3`\r\n- `CFrame`\r\n- `NumberSequence`\r\n- `ColorSequence`\r\n- `NumberRange`\r\n- `Rect`\r\n- `Font`\r\n\r\nAll instances, past, current and future, are supported by this crate.<br>\r\nOnly a select few get end to end typechecking support (see rblx_components/lib/rblx_types.luau -> type Instances), as there currently isn't to the extent of my knowledge a way to do it spare for typing out every single instance class in Roblox.\r\n","readmeTruncated":false}