Remove html api, update docs

This commit is contained in:
Insality
2025-03-20 00:26:29 +02:00
parent f786b20951
commit 10556ba31a
69 changed files with 294 additions and 17870 deletions

View File

@@ -2,13 +2,21 @@ local event = require("event.event")
local const = require("druid.const")
local component = require("druid.component")
---The component that handles the back handler action, like backspace or android back button
---Component to handle back button. It handles Android back button and Backspace key.
---
---### Setup
---Create back handler component with druid: `druid:new_back_handler(callback)`
---
---### Notes
---- Key triggers in `input.binding` should be setup for correct working
---- It uses a key_back and key_backspace action ids
---@class druid.back_handler: druid.component
---@field on_back event Trigger on back handler action, fun(self, params)
---@field params any|nil Custom args to pass in the callback
local M = component.create("back_handler")
---The Back Handler constructor
---@param callback function|nil The callback to call when the back handler is triggered
---@param params any? Custom args to pass in the callback
function M:init(callback, params)

View File

@@ -1,12 +1,22 @@
local const = require("druid.const")
local component = require("druid.component")
---Druid component for block input. Use it to block input in special zone.
---
---### Setup
---Create blocker component with druid: `druid:new_blocker(node_name)`
---
---### Notes
---- Blocker can be used to create safe zones, where you have big buttons
---- Blocker will capture all input events that hit the node, preventing them from reaching other components
---- Blocker works placed as usual component in stack, so any other component can be placed on top of it and will work as usual
---@class druid.blocker: druid.component
---@field node node
---@field private _is_enabled boolean
---@field node node The node that will block input
---@field private _is_enabled boolean Whether blocker is enabled
local M = component.create("blocker")
---The Blocker constructor
---@param node node|string The node to use as a blocker
function M:init(node)
self.node = self:get_node(node)

View File

@@ -15,14 +15,29 @@ local component = require("druid.component")
---@field on_mouse_hover fun(self, node, hover_state)|nil
---@field on_set_enabled fun(self, node, enabled_state)|nil
---Druid component to make clickable node with various interaction callbacks
---Basic Druid input component. Handle input on node and provide different callbacks on touch events.
---
---### Setup
---Create button with druid: `button = druid:new_button(node_name, callback, [params], [animation_node])`
---Where node_name is name of node from GUI scene. You can use `node_name` as input trigger zone and point another node for animation via `animation_node`
---
---### Notes
---- Button callback have next params: (self, params, button_instance)
---- - **self** - Druid self context
---- - **params** - Additional params, specified on button creating
---- - **button_instance** - button itself
---- You can set _params_ on button callback on button creating: `druid:new_button("node_name", callback, params)`.
---- Button have several events like on_click, on_repeated_click, on_long_click, on_hold_click, on_double_click
---- Click event will not trigger if between pressed and released state cursor was outside of node zone
---- Button can have key trigger to use them by key: `button:set_key_trigger`
----
---@class druid.button: druid.component
---@field on_click event function(self, custom_args, button_instance)
---@field on_pressed event function(self, custom_args, button_instance)
---@field on_repeated_click event function(self, custom_args, button_instance, click_count)
---@field on_long_click event function(self, custom_args, button_instance, hold_time)
---@field on_double_click event function(self, custom_args, button_instance, click_amount)
---@field on_hold_callback event function(self, custom_args, button_instance, press_time)
---@field on_repeated_click event function(self, custom_args, button_instance, click_count) Repeated click callback, while holding the button
---@field on_long_click event function(self, custom_args, button_instance, hold_time) Callback on long button tap
---@field on_double_click event function(self, custom_args, button_instance, click_amount) Different callback, if tap button 2+ in row
---@field on_hold_callback event function(self, custom_args, button_instance, press_time) Hold callback, before long_click trigger
---@field on_click_outside event function(self, custom_args, button_instance)
---@field node node Clickable node
---@field node_id hash Node id
@@ -41,8 +56,8 @@ local M = component.create("button")
---The constructor for the button component
---@param node_or_node_id node|string Node name or GUI Node itself
---@param callback fun()|nil Callback on button click
---@param custom_args any|nil Custom args for any Button event
---@param anim_node node|string|nil Node to animate instead of trigger node
---@param custom_args any|nil Custom args for any Button event, will be passed to callbacks
---@param anim_node node|string|nil Node to animate instead of trigger node, useful for animating small icons on big panels
function M:init(node_or_node_id, callback, custom_args, anim_node)
self.druid = self:get_druid()
self.node = self:get_node(node_or_node_id)

View File

@@ -18,12 +18,29 @@ local component = require("druid.component")
---@field WHEEL_SCROLL_INVERTED boolean|nil If true, invert direction for touchpad and mouse wheel scroll. Default: false
---@field WHEEL_SCROLL_BY_INERTION boolean|nil If true, wheel will add inertion to scroll. Direct set position otherwise.. Default: false
---Basic Druid scroll component. Handles all scrolling behavior in Druid GUI.
---
---### Setup
---Create scroll component with druid: `druid:new_scroll(view_node, content_node)`
---
---### Notes
---- View_node is the static part that captures user input and recognizes scrolling touches
---- Content_node is the dynamic part that will change position according to the scroll system
---- Initial scroll size will be equal to content_node size
---- The initial view box will be equal to view_node size
---- Scroll by default style has inertia and extra size for stretching effect
---- You can setup "points of interest" to make scroll always center on closest point
---- Scroll events:
---- - on_scroll(self, position): On scroll move callback
---- - on_scroll_to(self, position, is_instant): On scroll_to function callback
---- - on_point_scroll(self, item_index, position): On scroll_to_index function callback
---- Multitouch is required for scroll. Scroll correctly handles touch_id swap while dragging
---@class druid.scroll: druid.component
---@field node node The root node
---@field click_zone node|nil Optional click zone to restrict scroll area
---@field on_scroll event Triggered on scroll move with (self, position)
---@field on_scroll_to event Triggered on scroll_to with (self, target, is_instant)
---@field on_point_scroll event Triggered on scroll_to_index with (self, index, point)
---@field on_scroll event Triggered on scroll move with fun(self, position)
---@field on_scroll_to event Triggered on scroll_to with fun(self, target, is_instant)
---@field on_point_scroll event Triggered on scroll_to_index with fun(self, index, point)
---@field view_node node The scroll view node (static part)
---@field view_border vector4 The scroll view borders
---@field content_node node The scroll content node (moving part)
@@ -47,8 +64,9 @@ local M = component.create("scroll")
---The Scroll constructor
---@param view_node string|node GUI view scroll node
---@param content_node string|node GUI content scroll node
---@param view_node string|node GUI view scroll node - the static part that captures user input
---@param content_node string|node GUI content scroll node - the dynamic part that will change position
---@return druid.scroll
function M:init(view_node, content_node)
self.druid = self:get_druid()

View File

@@ -11,12 +11,31 @@ local utf8 = utf8 or utf8_lua --[[@as utf8]]
---@field ADJUST_STEPS number|nil Amount of iterations for text adjust by height. Default: 20
---@field ADJUST_SCALE_DELTA number|nil Scale step on each height adjust step. Default: 0.02
---The component to handle text behaviour over a GUI Text node, mainly used to automatically adjust text size to fit the text area
---@alias druid.text.adjust_type "downscale"|"trim"|"no_adjust"|"downscale_limited"|"scroll"|"scale_then_scroll"|"trim_left"|"scale_then_trim"|"scale_then_trim_left"
---Basic Druid text component. Text components by default have the text size adjusting.
---
---### Setup
---Create text node with druid: `text = druid:new_text(node_name, [initial_value], [text_adjust_type])`
---
---### Notes
---- Text component by default have auto adjust text sizing. Text never will be bigger, than text node size, which you can setup in GUI scene.
---- Text pivot can be changed with `text:set_pivot`, and text will save their position inside their text size box
---- There are several text adjust types:
---- - **"downscale"** - Change text's scale to fit in the text node size (default)
---- - **"trim"** - Trim the text with postfix (default - "...") to fit in the text node size
---- - **"no_adjust"** - No any adjust, like default Defold text node
---- - **"downscale_limited"** - Change text's scale like downscale, but there is limit for text's scale
---- - **"scroll"** - Change text's pivot to imitate scrolling in the text box. Use with stencil node for better effect.
---- - **"scale_then_scroll"** - Combine two modes: first limited downscale, then scroll
---- - **"trim_left"** - Trim the text with postfix (default - "...") to fit in the text node size
---- - **"scale_then_trim"** - Combine two modes: first limited downscale, then trim
---- - **"scale_then_trim_left"** - Combine two modes: first limited downscale, then trim left
---@class druid.text: druid.component
---@field node node The text node
---@field on_set_text event The event triggered when the text is set, fun(self, text)
---@field on_update_text_scale event The event triggered when the text scale is updated, fun(self, scale, metrics)
---@field on_set_pivot event The event triggered when the text pivot is set, fun(self, pivot)
---@field on_set_text event fun(self, text) The event triggered when the text is set
---@field on_update_text_scale event fun(self, scale, metrics) The event triggered when the text scale is updated
---@field on_set_pivot event fun(self, pivot) The event triggered when the text pivot is set
---@field style druid.text.style The style of the text
---@field private start_pivot userdata The start pivot of the text
---@field private start_scale vector3 The start scale of the text
@@ -27,7 +46,7 @@ local M = component.create("text")
---The Text constructor
---@param node string|node Node name or GUI Text Node itself
---@param value string|nil Initial text. Default value is node text from GUI scene. Default: nil
---@param adjust_type string|nil Adjust type for text. By default is DOWNSCALE. Look const.TEXT_ADJUST for reference. Default: DOWNSCALE
---@param adjust_type druid.text.adjust_type|nil Adjust type for text. By default is "downscale". Options: "downscale", "trim", "no_adjust", "downscale_limited", "scroll", "scale_then_scroll", "trim_left", "scale_then_trim", "scale_then_trim_left"
function M:init(node, value, adjust_type)
self.node = self:get_node(node)
self.pos = gui.get_position(self.node)

View File

@@ -112,22 +112,30 @@ end
---Set text for Rich Text
--- -- Color
--- rich_text:set_text("color=redFoobar/color")
--- rich_text:set_text("color=1.0,0,0,1.0Foobar/color")
--- rich_text:set_text("color=#ff0000Foobar/color")
--- rich_text:set_text("color=#ff0000ffFoobar/color")
--- -- Shadow
--- rich_text:set_text("shadow=redFoobar/shadow")
--- rich_text:set_text("shadow=1.0,0,0,1.0Foobar/shadow")
--- rich_text:set_text("shadow=#ff0000Foobar/shadow")
--- rich_text:set_text("shadow=#ff0000ffFoobar/shadow")
--- -- Outline
--- rich_text:set_text("outline=redFoobar/outline")
--- rich_text:set_text("outline=1.0,0,0,1.0Foobar/outline")
--- rich_text:set_text("outline=#ff0000Foobar/outline")
--- rich_text:set_text("outline=#ff0000ffFoobar/outline")
--- -- Font
--- rich_text:set_text("font=MyCoolFontFoobar/font")
--- -- Size
--- rich_text:set_text("size=2Twice as large/size")
--- -- Line break
--- rich_text:set_text("br/Insert a line break")
--- -- No break
--- rich_text:set_text("nobrPrevent the text from breaking")
--- -- Image
--- rich_text:set_text("img=texture:imageDisplay image")
--- rich_text:set_text("img=texture:image,sizeDisplay image with size")
--- rich_text:set_text("img=texture:image,width,heightDisplay image with width and height")

View File

@@ -30,7 +30,19 @@ local CORNER_PIVOTS = {
---@field DRAGGABLE_CORNER_SIZE vector3 Size of box node for debug draggable corners
---@field DRAGGABLE_CORNER_COLOR vector4 Color of debug draggable corners
---The component used for managing the size and positions with other containers relations to create a adaptable layouts
---Druid component to manage the size and positions with other containers relations to create a adaptable layouts.
---
---### Setup
---Create container component with druid: `container = druid:new_container(node, mode, callback)`
---
---### Notes
---- Container can be used to create adaptable layouts that respond to window size changes
---- Container supports different layout modes: FIT, STRETCH, STRETCH_X, STRETCH_Y
---- Container can be nested inside other containers
---- Container supports fixed margins and percentage-based sizing
---- Container can be positioned using pivot points
---- Container supports minimum size constraints
---- Container can be fitted into window or custom size
---@class druid.container: druid.component
---@field node node The gui node
---@field druid druid.instance The druid instance
@@ -52,6 +64,7 @@ local CORNER_PIVOTS = {
local M = component.create("container")
---The Container constructor
---@param node node Gui node
---@param mode string Layout mode
---@param callback fun(self: druid.container, size: vector3)|nil Callback on size changed
@@ -245,7 +258,7 @@ function M:on_window_resized()
end
---@param node_or_container node|string|druid.container|table
---@param node_or_container node|string|druid.container|table The node or container to add
---@param mode string|nil stretch, fit, stretch_x, stretch_y. Default: Pick from node, "fit" or "stretch"
---@param on_resize_callback fun(self: userdata, size: vector3)|nil
---@return druid.container Container New created layout instance

View File

@@ -3,7 +3,18 @@ local helper = require("druid.helper")
local component = require("druid.component")
local event = require("event.event")
---The component used for managing a list of data with a scrollable view, used to manage huge list data and render only visible elements
---Druid component to manage a list of data with a scrollable view, used to manage huge list data and render only visible elements.
---
---### Setup
---Create data list component with druid: `data_list = druid:new_data_list(scroll, grid, create_function)`
---
---### Notes
---- Data List uses a scroll component for scrolling and a grid component for layout
---- Data List only renders visible elements for better performance
---- Data List supports caching of elements for better performance
---- Data List supports adding, removing and updating elements
---- Data List supports scrolling to specific elements
---- Data List supports custom element creation and cleanup
---@class druid.data_list: druid.component
---@field scroll druid.scroll The scroll instance for Data List component
---@field grid druid.grid The StaticGrid or DynamicGrid instance for Data List component
@@ -21,6 +32,7 @@ local event = require("event.event")
local M = component.create("data_list")
---The DataList constructor
---@param scroll druid.scroll The Scroll instance for Data List component
---@param grid druid.grid The StaticGrid instance for Data List component
---@param create_function function The create function callback(self, data, index, data_list). Function should return (node, [component])

View File

@@ -5,7 +5,18 @@ local component = require("druid.component")
---@class druid.hotkey.style
---@field MODIFICATORS string[]|hash[] The list of action_id as hotkey modificators
---The component used for managing hotkeys and trigger callbacks when hotkeys are pressed
---Druid component to manage hotkeys and trigger callbacks when hotkeys are pressed.
---
---### Setup
---Create hotkey component with druid: `hotkey = druid:new_hotkey(keys, callback, callback_argument)`
---
---### Notes
---- Hotkey can be triggered by pressing a single key or a combination of keys
---- Hotkey supports modificator keys (e.g. Ctrl, Shift, Alt)
---- Hotkey can be triggered on key press, release or repeat
---- Hotkey can be added or removed at runtime
---- Hotkey can be enabled or disabled
---- Hotkey can be set to repeat on key hold
---@class druid.hotkey: druid.component
---@field on_hotkey_pressed event fun(self, context, callback_argument) The event triggered when a hotkey is pressed
---@field on_hotkey_released event fun(self, context, callback_argument) The event triggered when a hotkey is released

View File

@@ -13,7 +13,18 @@ local utf8 = utf8 or utf8_lua
---@field on_unselect fun(self: druid.input, button_node: node) Callback on input field unselecting
---@field on_input_wrong fun(self: druid.input, button_node: node) Callback on wrong user input
---The component used for managing input fields in basic way
---Basic Druid text input component. Handles user text input via component with button and text.
---
---### Setup
---Create input component with druid: `input = druid:new_input(button_node_name, text_node_name, keyboard_type)`
---
---### Notes
---- Input component handles user text input. Input contains button and text components
---- Button needed for selecting/unselecting input field
---- Click outside of button to unselect input field
---- On focus lost (game minimized) input field will be unselected
---- You can setup max length of the text
---- You can setup allowed characters. On add not allowed characters `on_input_wrong` will be called
---@class druid.input: druid.component
---@field on_input_select event fun(self: druid.input, input: druid.input) The event triggered when the input field is selected
---@field on_input_unselect event fun(self: druid.input, text: string, input: druid.input) The event triggered when the input field is unselected

View File

@@ -2,7 +2,16 @@ local event = require("event.event")
local component = require("druid.component")
local settings = require("druid.system.settings")
---The component used for displaying localized text, can automatically update text when locale is changed
---The component used for displaying localized text, can automatically update text when locale is changed.
---It wraps the Text component to handle localization using druid's get_text_function to set text by its id.
---
---### Setup
---Create lang text component with druid: `text = druid:new_lang_text(node_name, locale_id)`
---
---### Notes
---- Component automatically updates text when locale is changed
---- Uses druid's get_text_function to get localized text by id
---- Supports string formatting with additional parameters
---@class druid.lang_text: druid.component
---@field text druid.text The text component
---@field node node The node of the text component
@@ -13,7 +22,7 @@ local M = component.create("lang_text")
---@param node string|node The node_id or gui.get_node(node_id)
---@param locale_id string|nil Default locale id or text from node as default
---@param locale_id string|nil Default locale id or text from node as default. If not provided, will use text from the node
---@param adjust_type string|nil Adjust type for text. By default is DOWNSCALE. Look const.TEXT_ADJUST for reference
function M:init(node, locale_id, adjust_type)
self.druid = self:get_druid()
@@ -38,7 +47,7 @@ function M:on_language_change()
end
---Setup raw text to lang_text component
---Setup raw text to lang_text component. This will clear any locale settings.
---@param text string Text for text node
---@return druid.lang_text self Current instance
function M:set_to(text)
@@ -50,7 +59,7 @@ function M:set_to(text)
end
---Setup raw text to lang_text component
---Setup raw text to lang_text component. This will clear any locale settings.
---@param text string Text for text node
---@return druid.lang_text self Current instance
function M:set_text(text)
@@ -58,8 +67,8 @@ function M:set_text(text)
end
---Translate the text by locale_id
---@param locale_id string Locale id
---Translate the text by locale_id. The text will be automatically updated when locale changes.
---@param locale_id string Locale id to get text from
---@param ... string Optional params for string.format
---@return druid.lang_text self Current instance
function M:translate(locale_id, ...)
@@ -71,7 +80,7 @@ function M:translate(locale_id, ...)
end
---Format string with new text params on localized text
---Format string with new text params on localized text. Keeps the current locale but updates the format parameters.
---@param ... string Optional params for string.format
---@return druid.lang_text self Current instance
function M:format(...)

View File

@@ -2,7 +2,7 @@ local event = require("event.event")
local helper = require("druid.helper")
local component = require("druid.component")
---@alias druid.layout.mode "horizontal"|"vertical"|"horizontal_wrap"
---@alias druid.layout.type "horizontal"|"vertical"|"horizontal_wrap"
---@class event.on_size_changed: event
---@field subscribe fun(_, callback: fun(new_size: vector3), context: any|nil)
@@ -19,11 +19,22 @@ local component = require("druid.component")
---@field nodes_height table<node, number>
---@field rows druid.layout.row_data[]>
---The component used for managing the layout of nodes, placing them inside the node size with respect to the size and pivot of each node
---Druid component to manage the layout of nodes, placing them inside the node size with respect to the size and pivot of each node.
---
---### Setup
---Create layout component with druid: `layout = druid:new_layout(node, layout_type)`
---
---### Notes
---- Layout can be horizontal, vertical or horizontal with wrapping
---- Layout can resize parent node to fit content
---- Layout can justify content
---- Layout supports margins and padding
---- Layout automatically updates when nodes are added or removed
---- Layout can be manually updated by calling set_dirty()
---@class druid.layout: druid.component
---@field node node The node to manage the layout of
---@field rows_data druid.layout.rows_data Last calculated rows data
---@field is_dirty boolean
---@field is_dirty boolean True if layout needs to be updated
---@field entities node[] The entities to manage the layout of
---@field margin {x: number, y: number} The margin of the layout
---@field padding vector4 The padding of the layout
@@ -35,8 +46,8 @@ local component = require("druid.component")
local M = component.create("layout")
---@param node_or_node_id node|string
---@param layout_type druid.layout.mode
---@param node_or_node_id node|string The node to manage the layout of
---@param layout_type druid.layout.type The type of layout (horizontal, vertical, horizontal_wrap)
function M:init(node_or_node_id, layout_type)
self.node = self:get_node(node_or_node_id)
@@ -138,10 +149,10 @@ function M:set_justify(is_justify)
end
---@param type string The layout type: "horizontal", "vertical", "horizontal_wrap"
---@param layout_type druid.layout.type
---@return druid.layout self Current layout instance
function M:set_type(type)
self.type = type
function M:set_type(layout_type)
self.type = layout_type
self.is_dirty = true
return self

View File

@@ -6,19 +6,29 @@ local component = require("druid.component")
---@field SPEED number|nil Progress bas fill rate. More -> faster. Default: 5
---@field MIN_DELTA number|nil Minimum step to fill progress bar. Default: 0.005
---The component used to manage a node as a progress bar, changing the size and scale of the node
---Basic Druid progress bar component. Changes the size or scale of a node to represent progress.
---
---### Setup
---Create progress bar component with druid: `progress = druid:new_progress(node_name, key, init_value)`
---
---### Notes
---- Node should have maximum node size in GUI scene, it's represent the progress bar maximum size
---- Key is value from druid const: "x" or "y"
---- Progress works correctly with 9slice nodes, it tries to set size by _set_size_ first, until minimum size is reached, then it sizing via _set_scale_
---- Progress bar can fill only by vertical or horizontal size. For diagonal progress bar, just rotate node in GUI scene
---- If you have glitchy or dark texture bugs with progress bar, try to disable mipmaps in your texture profiles
---@class druid.progress: druid.component
---@field node node
---@field on_change event
---@field style druid.progress.style
---@field key string
---@field prop hash
---@field node node The progress bar node
---@field on_change event Event triggered when progress value changes
---@field style druid.progress.style Component style parameters
---@field key string Progress bar direction: "x" or "y"
---@field prop hash Property for scaling the progress bar
local M = component.create("progress")
---@param node string|node Node name or GUI Node itself.
---@param key string Progress bar direction: "x" or "y"
---@param init_value number|nil Initial value of progress bar. Default: 1
---@param init_value number|nil Initial value of progress bar (0 to 1). Default: 1
function M:init(node, key, init_value)
assert(key == "x" or key == "y", "Progress bar key should be 'x' or 'y'")

View File

@@ -3,7 +3,17 @@ local helper = require("druid.helper")
local const = require("druid.const")
local component = require("druid.component")
---The component to make a draggable node over a line with a progress report
---Basic Druid slider component. Creates a draggable node over a line with progress reporting.
---
---### Setup
---Create slider component with druid: `slider = druid:new_slider(node_name, end_pos, callback)`
---
---### Notes
---- Pin node should be placed in initial position at zero progress
---- It will be available to move Pin node between start pos and end pos
---- You can setup points of interests on slider via `slider:set_steps`. If steps exist, slider values will be only from these steps (notched slider)
---- Start pos and end pos should be on vertical or horizontal line (their x or y value should be equal)
---- To catch input across all slider, you can setup input node via `slider:set_input_node`
---@class druid.slider: druid.component
---@field node node The node to manage the slider
---@field on_change_value event The event triggered when the slider value changes

View File

@@ -2,7 +2,15 @@ local event = require("event.event")
local helper = require("druid.helper")
local component = require("druid.component")
---The component that handles a text to display a seconds timer
---Druid component to handle timer work on gui text node. Displays time in a formatted way.
---
---### Setup
---Create timer component with druid: `timer = druid:new_timer(text_node, from_seconds, to_seconds, callback)`
---
---### Notes
---- Timer fires callback when timer value equals to _to_seconds_
---- Timer will set text node with current timer value
---- Timer uses update function to handle time
---@class druid.timer: druid.component
---@field on_tick event fun(context, value) The event triggered when the timer ticks
---@field on_set_enabled event fun(context, is_on) The event triggered when the timer is enabled
@@ -18,7 +26,7 @@ local M = component.create("timer")
---@param node node Gui text node
---@param seconds_from number|nil Start timer value in seconds
---@param seconds_to number|nil End timer value in seconds
---@param callback function|nil Function on timer end
---@param callback function|nil Function that triggers when timer value equals to seconds_to
function M:init(node, seconds_from, seconds_to, callback)
self.node = self:get_node(node)
seconds_to = math.max(seconds_to or 0, 0)

View File

@@ -667,7 +667,7 @@ end
local progress = require("druid.extended.progress")
---Create Progress component
---@param node string|node Progress bar fill node or node name
---@param key string Progress bar direction: const.SIDE.X or const.SIDE.Y
---@param key string Progress bar direction: "x" or "y"
---@param init_value number|nil Initial value of progress bar. Default: 1
---@return druid.progress progress The new progress component
function M:new_progress(node, key, init_value)