@nrbx/topbar-components 1.0.11 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2023 wad4444
3
+ Copyright (c) 2023 ninjaninja140 (forked from wad4444)
4
4
  Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  of this software and associated documentation files (the "Software"), to deal
6
6
  in the Software without restriction, including without limitation the rights
package/README.md CHANGED
@@ -15,7 +15,7 @@
15
15
 
16
16
  **Topbar Components** is a react component package that mimics [*topbar-plus*](https://devforum.roblox.com/t/v3-topbarplus-v300-construct-intuitive-topbar-icons-customise-them-with-themes-dropdowns-captions-labels-and-much-more/1017485) for [Roblox-TS](https://roblox-ts.com), with JSX markup support.
17
17
 
18
- ## 📦 Installation
18
+ ## Installation
19
19
 
20
20
  **@nrbx/topbar-components** is available on NPM and can be installed with the following commands:
21
21
 
@@ -45,7 +45,7 @@ And this to your `tsconfig.json`
45
45
  "typeRoots": ["node_modules/@rbxts", "node_modules/@nrbx"],
46
46
  ```
47
47
 
48
- ### Quick Start
48
+ ### Quick Start
49
49
 
50
50
  Instantiate `<TopbarProvider />` to be a root of your topbar component tree.
51
51
 
@@ -55,7 +55,7 @@ Instantiate `<TopbarProvider />` to be a root of your topbar component tree.
55
55
  </TopbarProvider>
56
56
  ```
57
57
 
58
- #### 📍 Positioning icons with dock containers
58
+ #### Positioning icons with dock containers
59
59
 
60
60
  Icons placed directly inside `<TopbarProvider>` default to the left side. Use the dock container components to position icons at the center or right of the bar:
61
61
 
@@ -76,16 +76,16 @@ Icons placed directly inside `<TopbarProvider>` default to the left side. Use th
76
76
 
77
77
  | Container | Anchor | Purpose |
78
78
  |---|---|---|
79
- | `<LeftDock>` | left edge | Default icons flow left-to-right from the left |
79
+ | `<LeftDock>` | left edge | Default - icons flow left-to-right from the left |
80
80
  | `<CenterDock>` | center (50%) | Centers icons in the bar |
81
81
  | `<RightDock>` | right edge | Right-aligns icons |
82
82
 
83
83
  Each dock container renders its own horizontal list with the configured `iconSpacing` and vertical centering. Center and right docks automatically apply `iconGroupSpacing` for visual separation.
84
84
 
85
- #### 🏷️ Icon props: `static` and `disabled`
85
+ #### Icon props: `static` and `disabled`
86
86
 
87
- - **`static`** turns the icon into a non-interactive label (no clicks, no hovers, no state toggling, no sounds)
88
- - **`disabled`** dims the icon with a configurable semi-transparent overlay
87
+ - **`static`** - turns the icon into a non-interactive label (no clicks, no hovers, no state toggling, no sounds)
88
+ - **`disabled`** - dims the icon with a configurable semi-transparent overlay
89
89
 
90
90
  ```tsx
91
91
  <Icon text="Read Only" static /> {/* label, not clickable */}
@@ -95,7 +95,7 @@ Each dock container renders its own horizontal list with the configured `iconSpa
95
95
 
96
96
  The disabled overlay transparency and color are configurable via the stylesheet `sizing` section.
97
97
 
98
- #### 🔽 Dropdowns
98
+ #### Dropdowns
99
99
 
100
100
  You can add a dropdown to an icon by mounting `<Dropdown />` component as it's child.
101
101
  Dropdowns & TopbarProvider have a property called `selectionMode`, which lets you specify how many icons can be selected at once.
@@ -111,7 +111,107 @@ Dropdowns & TopbarProvider have a property called `selectionMode`, which lets yo
111
111
 
112
112
  Dropdowns **can be nested.**
113
113
 
114
- ### 🎨 Stylesheets
114
+ #### Hover animations
115
+
116
+ Icons can lift upward on hover for a subtle interactive feel. Enable or disable it globally via the stylesheet:
117
+
118
+ ```tsx
119
+ <Stylesheet stylesheet={{
120
+ animation: {
121
+ hoverEnabled: true, // turn hover lift on/off
122
+ hoverLift: 4, // pixels to lift
123
+ },
124
+ }}>
125
+ <TopbarProvider>
126
+ <Icon text="Hover Me" />
127
+ </TopbarProvider>
128
+ </Stylesheet>
129
+ ```
130
+
131
+ Hover lift uses the same spring configuration as state transitions (`animation.stateSpring`).
132
+
133
+ #### Notification badges
134
+
135
+ Add a red notification badge to any icon with the `notificationCount` prop. Counts over 99 display as `99+`. The badge hides automatically when the count is 0.
136
+
137
+ ```tsx
138
+ <Icon text="Inbox" notificationCount={3} />
139
+ <Icon text="Mail" notificationCount={150} /> {/* shows "99+" */}
140
+ <Icon text="Clear" notificationCount={0} /> {/* badge hidden */}
141
+ ```
142
+
143
+ Badge styling (colors, position, corner radius, border) is controlled via `stylesheet.notification`.
144
+
145
+ #### Toggle keys
146
+
147
+ Bind a keyboard key to toggle an icon on/off with the `toggleKey` prop:
148
+
149
+ ```tsx
150
+ <Icon text="Menu" toggleKey={Enum.KeyCode.M} toggleStateOnClick />
151
+ ```
152
+
153
+ Any `Enum.KeyCode` value works. The key binding only activates while the icon is mounted.
154
+
155
+ #### Tooltips
156
+
157
+ Wrap any element in a `<Tooltip>` to show a hover tooltip after a configurable delay:
158
+
159
+ ```tsx
160
+ <Tooltip content="Go home" side="bottom" delayMs={500}>
161
+ <Icon imageId="rbxassetid://..." />
162
+ </Tooltip>
163
+ ```
164
+
165
+ | Prop | Type | Default | Description |
166
+ |---|---|---|---|
167
+ | `content` | `string` | required | Text displayed inside the tooltip |
168
+ | `side` | `"top"` \| `"bottom"` \| `"left"` \| `"right"` | `"top"` | Which side of the child to appear on |
169
+ | `delayMs` | `number` | stylesheet value | Milliseconds before the tooltip appears |
170
+
171
+ Tooltip appearance (colors, font, padding, border) is controlled via `stylesheet.tooltip`.
172
+
173
+ #### Custom Dropdowns
174
+
175
+ Use `<CustomDropdown>` when you need to show rich, arbitrary content in a dropdown panel - not just child `<Icon>` elements:
176
+
177
+ ```tsx
178
+ <Icon text="Info" toggleStateOnClick>
179
+ <CustomDropdown width={250} maxHeight={180}>
180
+ <textlabel Text="Custom content here!" />
181
+ <textbutton Text="A button" />
182
+ </CustomDropdown>
183
+ </Icon>
184
+ ```
185
+
186
+ | Prop | Type | Default | Description |
187
+ |---|---|---|---|
188
+ | `visible` | `boolean` | - | Whether the dropdown is open (usually driven by icon state) |
189
+ | `width` | `number` | `200` | Width in pixels |
190
+ | `maxHeight` | `number` | `200` | Max height before scrolling |
191
+ | `position` | `UDim2` | stylesheet value | Position relative to the parent icon |
192
+
193
+ Appearance is controlled via `stylesheet.customDropdown`.
194
+
195
+ #### Overflow handler
196
+
197
+ When you have many icons in a dock, wrap them in `<Overflow>` to automatically collapse extras into a "more" (⋯) dropdown:
198
+
199
+ ```tsx
200
+ <LeftDock>
201
+ <Overflow>
202
+ <Icon text="Home" />
203
+ <Icon text="Settings" />
204
+ <Icon text="Profile" />
205
+ <Icon text="Messages" />
206
+ <Icon text="Help" />
207
+ {/* ... many more ... */}
208
+ </Overflow>
209
+ </LeftDock>
210
+ ```
211
+
212
+ Based on TopbarPlus v3's overflow handler.
213
+
214
+ ### Stylesheets
115
215
 
116
216
  You can use stylesheets to override default properties of all components within.
117
217
  Stylesheets are partial, and work like patches to already established default properties within the package:
@@ -144,7 +244,7 @@ The stylesheet exposes the following sections for full control:
144
244
 
145
245
  ```tsx
146
246
  <Stylesheet stylesheet={{
147
- // ── Icon defaults (all IconProps) ──
247
+ // Icon defaults (all IconProps)
148
248
  icon: {
149
249
  textSize: 20,
150
250
  textColor: { selected: Color3.fromRGB(57, 60, 65), deselected: Color3.fromRGB(255, 255, 255) },
@@ -157,7 +257,7 @@ The stylesheet exposes the following sections for full control:
157
257
  // ... all other IconProps
158
258
  },
159
259
 
160
- // ── Dropdown defaults (all DropdownProps) ──
260
+ // Dropdown defaults (all DropdownProps)
161
261
  dropdown: {
162
262
  maxWidth: 300,
163
263
  minWidth: 200,
@@ -168,7 +268,7 @@ The stylesheet exposes the following sections for full control:
168
268
  // ... all other DropdownProps
169
269
  },
170
270
 
171
- // ── Provider frame ──
271
+ // Provider frame
172
272
  provider: {
173
273
  paddingLeft: 8, paddingRight: 12,
174
274
  paddingTop: 11, paddingBottom: 0,
@@ -181,12 +281,15 @@ The stylesheet exposes the following sections for full control:
181
281
  forceFrameHeight: undefined, // override auto height (e.g. 55)
182
282
  },
183
283
 
184
- // ── Icon internal sizing ──
284
+ // Icon internal sizing
185
285
  sizing: {
186
- iconHeight: undefined, // explicit override
286
+ iconHeight: undefined, // explicit override
287
+ iconWidth: undefined, // explicit override (auto-fits when undefined/0)
187
288
  imagePadding: 6,
188
289
  labelPadding: 6,
189
290
  imageToTextSpacing: 6,
291
+ contentPaddingX: 6, // horizontal pad from button edge to content
292
+ contentPaddingY: 6, // vertical pad from button edge to content
190
293
  textMeasurementWidth: 99999,
191
294
  minLabelWidthPadding: 12,
192
295
  buttonLabelHeightFraction: 0.8,
@@ -194,7 +297,7 @@ The stylesheet exposes the following sections for full control:
194
297
  disabledOverlayColor: new Color3(0, 0, 0),
195
298
  },
196
299
 
197
- // ── Dropdown surface theme ──
300
+ // Dropdown surface theme
198
301
  dropdownTheme: {
199
302
  backgroundColor: new Color3(1, 1, 1),
200
303
  backgroundTransparency: 0,
@@ -204,17 +307,60 @@ The stylesheet exposes the following sections for full control:
204
307
  position: UDim2.fromScale(0, 1),
205
308
  },
206
309
 
207
- // ── Animation ──
310
+ // Animation
208
311
  animation: {
209
312
  dropdownTransitionSpeed: 10,
210
313
  stateSpring: { tension: 400 },
314
+ hoverEnabled: true, // whether icons lift on hover
315
+ hoverLift: 4, // pixels to lift
316
+ },
317
+
318
+ // Notification badge
319
+ notification: {
320
+ backgroundColor: Color3.fromRGB(255, 59, 48),
321
+ backgroundTransparency: 0,
322
+ textColor: new Color3(1, 1, 1),
323
+ textSize: 12,
324
+ fontFace: new Font("rbxasset://fonts/families/GothamSSm.json", Enum.FontWeight.Bold),
325
+ position: new UDim2(0.5, 4, 0, -4),
326
+ size: new UDim2(0, 18, 0, 18),
327
+ cornerRadius: new UDim(1, 0),
328
+ borderColor: new Color3(1, 1, 1),
329
+ borderTransparency: 0,
330
+ },
331
+
332
+ // Tooltip
333
+ tooltip: {
334
+ backgroundColor: new Color3(0.1, 0.1, 0.1),
335
+ backgroundTransparency: 0.2,
336
+ textColor: new Color3(1, 1, 1),
337
+ textSize: 14,
338
+ fontFace: new Font("rbxasset://fonts/families/GothamSSm.json", Enum.FontWeight.Medium),
339
+ cornerRadius: new UDim(0, 4),
340
+ borderColor: new Color3(0.4, 0.4, 0.4),
341
+ borderTransparency: 0,
342
+ borderSize: 1,
343
+ paddingX: 8,
344
+ paddingY: 4,
345
+ delayMs: 500,
346
+ },
347
+
348
+ // Custom dropdown
349
+ customDropdown: {
350
+ backgroundColor: new Color3(1, 1, 1),
351
+ backgroundTransparency: 0,
352
+ cornerRadius: new UDim(0, 6),
353
+ borderSize: 0,
354
+ borderColor: new Color3(0, 0, 0),
355
+ borderTransparency: 1,
356
+ position: UDim2.fromScale(0, 1),
211
357
  },
212
358
  }}>
213
359
  {/* children */}
214
360
  </Stylesheet>
215
361
  ```
216
362
 
217
- ### 📝 License
363
+ ### License
218
364
 
219
365
  Package is licensed under the MIT License.
220
366
 
@@ -0,0 +1,19 @@
1
+ import React from '@rbxts/react';
2
+ interface CustomDropdownProps extends React.PropsWithChildren {
3
+ /** Whether the dropdown is visible. Typically driven by parent icon state. */
4
+ visible: boolean;
5
+ /** Width of the dropdown in pixels. */
6
+ width?: number;
7
+ /** Maximum height before scrolling. */
8
+ maxHeight?: number;
9
+ /** Position relative to the parent icon. */
10
+ position?: UDim2;
11
+ }
12
+ /**
13
+ * A dropdown panel for arbitrary custom content (not just child icons).
14
+ *
15
+ * Use this when you need rich UI inside a dropdown — forms, text, images —
16
+ * rather than a list of `<Icon>` children. Animated open/closed with a spring.
17
+ */
18
+ export declare function CustomDropdown({ visible, width, maxHeight, position, children }: CustomDropdownProps): React.JSX.Element;
19
+ export {};
@@ -0,0 +1,86 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ local TS = _G[script]
3
+ local _pretty_react_hooks = TS.import(script, TS.getModule(script, "@rbxts", "pretty-react-hooks").out)
4
+ local mapBinding = _pretty_react_hooks.mapBinding
5
+ local useMotion = _pretty_react_hooks.useMotion
6
+ local useMountEffect = _pretty_react_hooks.useMountEffect
7
+ local _react = TS.import(script, TS.getModule(script, "@rbxts", "react"))
8
+ local React = _react
9
+ local useBinding = _react.useBinding
10
+ local useRef = _react.useRef
11
+ local useStylesheet = TS.import(script, script.Parent.Parent, "context").useStylesheet
12
+ --[[
13
+ *
14
+ * A dropdown panel for arbitrary custom content (not just child icons).
15
+ *
16
+ * Use this when you need rich UI inside a dropdown — forms, text, images —
17
+ * rather than a list of `<Icon>` children. Animated open/closed with a spring.
18
+
19
+ ]]
20
+ local function CustomDropdown(_param)
21
+ local visible = _param.visible
22
+ local width = _param.width
23
+ if width == nil then
24
+ width = 200
25
+ end
26
+ local maxHeight = _param.maxHeight
27
+ if maxHeight == nil then
28
+ maxHeight = 200
29
+ end
30
+ local position = _param.position
31
+ local children = _param.children
32
+ local stylesheet = useStylesheet()
33
+ local theme = stylesheet.customDropdown
34
+ local animation = stylesheet.animation
35
+ local transition, transitionMotion = useMotion(if visible then 1 else 0)
36
+ local contentSize, setContentSize = useBinding(Vector2.zero)
37
+ local frameRef = useRef()
38
+ React.useEffect(function()
39
+ transitionMotion:spring(if visible then 1 else 0, {
40
+ tension = animation.dropdownTransitionSpeed * 15,
41
+ friction = 26,
42
+ })
43
+ end, { visible })
44
+ useMountEffect(function()
45
+ local frame = frameRef.current
46
+ if not frame then
47
+ return nil
48
+ end
49
+ setContentSize(frame.AbsoluteCanvasSize)
50
+ local conn = frame:GetPropertyChangedSignal("AbsoluteCanvasSize"):Connect(function()
51
+ setContentSize(frame.AbsoluteCanvasSize)
52
+ end)
53
+ return function()
54
+ return conn:Disconnect()
55
+ end
56
+ end)
57
+ local pos = position or theme.position
58
+ return React.createElement("scrollingframe", {
59
+ ref = frameRef,
60
+ ClipsDescendants = true,
61
+ Size = mapBinding(transition, function(t)
62
+ return UDim2.fromOffset(width, t * math.min(contentSize:getValue().Y, maxHeight))
63
+ end),
64
+ BorderSizePixel = theme.borderSize,
65
+ BorderColor3 = theme.borderColor,
66
+ BackgroundColor3 = theme.backgroundColor,
67
+ BackgroundTransparency = theme.backgroundTransparency,
68
+ Position = pos,
69
+ CanvasSize = UDim2.fromOffset(0, contentSize:getValue().Y),
70
+ AutomaticCanvasSize = Enum.AutomaticSize.Y,
71
+ ScrollBarThickness = 5,
72
+ ScrollBarImageColor3 = Color3.new(1, 1, 1),
73
+ ScrollBarImageTransparency = 0.8,
74
+ ScrollingEnabled = false,
75
+ ZIndex = 30,
76
+ }, React.createElement("uicorner", {
77
+ CornerRadius = theme.cornerRadius,
78
+ }), React.createElement("uistroke", {
79
+ Color = theme.borderColor,
80
+ Transparency = theme.borderTransparency,
81
+ Thickness = theme.borderSize,
82
+ }), children)
83
+ end
84
+ return {
85
+ CustomDropdown = CustomDropdown,
86
+ }
@@ -1,18 +1,38 @@
1
1
  import React from '@rbxts/react';
2
2
  import type { SelectionMode } from './provider';
3
+ /** Properties accepted by {@link Dropdown}. */
3
4
  export interface DropdownProps extends React.PropsWithChildren {
5
+ /** Minimum width of the dropdown in pixels. */
4
6
  minWidth?: number;
7
+ /** Maximum height before the dropdown becomes scrollable. */
5
8
  maxHeight?: number;
9
+ /** Maximum width of the dropdown in pixels. */
6
10
  maxWidth?: number;
11
+ /** Vertical padding between child icons. */
7
12
  padding?: UDim;
13
+ /** Fixed height applied to child icons inside this dropdown. */
8
14
  forceHeight?: number;
15
+ /** Corner radius applied to child icons inside this dropdown. */
9
16
  iconCornerRadius?: UDim;
17
+ /** Scroll bar thickness in pixels. */
10
18
  scrollBarThickness?: number;
19
+ /** Scroll bar transparency (0 = opaque, 1 = invisible). */
11
20
  scrollBarTransparency?: number;
21
+ /** Image for the scroll bar top cap. */
12
22
  topImage?: string;
23
+ /** Image for the scroll bar bottom cap. */
13
24
  bottomImage?: string;
25
+ /** Image for the scroll bar middle segment. */
14
26
  midImage?: string;
27
+ /** Color applied to the scroll bar images. */
15
28
  scrollBarImageColor?: Color3;
29
+ /** Selection mode: `Single` deselects others, `Multiple` allows many. */
16
30
  selectionMode?: SelectionMode;
17
31
  }
32
+ /**
33
+ * A dropdown menu that appears below its parent icon.
34
+ *
35
+ * Child `<Icon>` components placed inside automatically register and size
36
+ * themselves. The dropdown animates open/closed with a spring transition.
37
+ */
18
38
  export declare function Dropdown(componentProps: DropdownProps): React.JSX.Element;
@@ -13,6 +13,15 @@ local _context = TS.import(script, script.Parent.Parent, "context")
13
13
  local LocationContext = _context.LocationContext
14
14
  local useLocation = _context.useLocation
15
15
  local useStylesheet = _context.useStylesheet
16
+ --* Properties accepted by {@link Dropdown}.
17
+ --[[
18
+ *
19
+ * A dropdown menu that appears below its parent icon.
20
+ *
21
+ * Child `<Icon>` components placed inside automatically register and size
22
+ * themselves. The dropdown animates open/closed with a spring transition.
23
+
24
+ ]]
16
25
  local function Dropdown(componentProps)
17
26
  local location = useLocation()
18
27
  local fullStylesheet = useStylesheet()
@@ -43,8 +52,9 @@ local function Dropdown(componentProps)
43
52
  end, { contents, maxWidth, minWidth, stylesheet.padding.Offset })
44
53
  useEffect(function()
45
54
  location.setAnimationState(true)
46
- transitionMotion:linear(if location.isVisible then 1 else 0, {
47
- speed = fullStylesheet.animation.dropdownTransitionSpeed,
55
+ transitionMotion:spring(if location.isVisible then 1 else 0, {
56
+ tension = fullStylesheet.animation.dropdownTransitionSpeed * 15,
57
+ friction = 26,
48
58
  })
49
59
  end, { location.isVisible })
50
60
  useMountEffect(function()
@@ -170,20 +180,15 @@ local function Dropdown(componentProps)
170
180
  MidImage = props.midImage,
171
181
  TopImage = props.topImage,
172
182
  BottomImage = props.bottomImage,
173
- key = "Dropdown",
174
183
  }, React.createElement("uicorner", {
175
- key = "DropdownCorner",
176
184
  CornerRadius = fullStylesheet.dropdownTheme.cornerRadius,
177
185
  }), React.createElement("uistroke", {
178
- key = "DropdownStroke",
179
186
  Thickness = fullStylesheet.dropdownTheme.borderSize,
180
187
  Color = fullStylesheet.dropdownTheme.borderColor,
181
188
  Transparency = fullStylesheet.dropdownTheme.borderTransparency,
182
189
  }), props.children, isNested and React.createElement("uipadding", {
183
- key = "UIPadding",
184
190
  PaddingTop = stylesheet.padding,
185
191
  }), React.createElement("uilistlayout", {
186
- key = "UIListLayout",
187
192
  SortOrder = Enum.SortOrder.LayoutOrder,
188
193
  Padding = stylesheet.padding,
189
194
  })))
@@ -1,47 +1,112 @@
1
1
  import React from '@rbxts/react';
2
2
  import { type Stylesheet } from '../style';
3
+ /**
4
+ * Properties accepted by {@link Icon}.
5
+ *
6
+ * Most visual props accept a `StateDependent<T>` — either a single value for
7
+ * both states, or `{ deselected: T; selected: T }` to animate between them.
8
+ */
3
9
  export interface IconProps extends React.PropsWithChildren {
10
+ /** Background transparency of the button. Animated on state change. */
4
11
  backgroundTransparency?: StateDependent<number>;
12
+ /** Background color of the button. Animated on state change. */
5
13
  backgroundColor?: StateDependent<Color3>;
14
+ /** Asset ID or full asset string for the icon image. */
6
15
  imageId?: StateDependent<string>;
16
+ /** Color applied to the icon image. Animated on state change. */
7
17
  imageColor?: StateDependent<Color3>;
18
+ /** Color applied to the label text. */
8
19
  textColor?: StateDependent<Color3>;
20
+ /** Transparency of the icon image. Animated on state change. */
9
21
  imageTransparency?: StateDependent<number>;
22
+ /** Layout order used for horizontal sorting in docks. */
10
23
  layoutOrder?: StateDependent<number>;
24
+ /** Text displayed next to or instead of the image. */
11
25
  text?: StateDependent<string>;
26
+ /** Font size of the label text. */
12
27
  textSize?: StateDependent<number>;
28
+ /** Pixel offset added to the computed image size. Negative values shrink the image. */
13
29
  imageSizeOffset?: StateDependent<number>;
30
+ /** Offset into the source image to crop from. */
14
31
  imageRectOffset?: StateDependent<Vector2>;
32
+ /** Size of the crop region from the source image. */
15
33
  imageRectSize?: StateDependent<Vector2>;
34
+ /** Initial state when the icon first mounts. */
16
35
  defaultState?: IconState;
36
+ /** Font face used for the label text. */
17
37
  fontFace?: StateDependent<Font>;
38
+ /** Override that locks the icon to a specific state. */
18
39
  forcedState?: IconState;
40
+ /** Sound played on left click (asset ID or empty for none). */
19
41
  leftClickSound?: StateDependent<string>;
42
+ /** Sound played on right click (asset ID or empty for none). */
20
43
  rightClickSound?: StateDependent<string>;
44
+ /** Corner radius of the button. */
21
45
  cornerRadius?: StateDependent<UDim>;
46
+ /** Stroke transparency of the label text. */
22
47
  strokeTransparency?: StateDependent<number>;
48
+ /** Stroke color of the label text. */
23
49
  strokeColor?: StateDependent<Color3>;
50
+ /** Stroke thickness of the label text. */
24
51
  strokeThickness?: StateDependent<number>;
52
+ /** Horizontal text alignment within the label. */
25
53
  textAlignment?: StateDependent<Enum.TextXAlignment>;
54
+ /** Whether the label supports rich text markup. */
26
55
  richText?: StateDependent<boolean>;
56
+ /** When `true`, clicking the icon toggles between selected and deselected. */
27
57
  toggleStateOnClick?: boolean;
28
- /** When true, renders as a non-interactive label (no clicks, no hovers, no state changes) */
58
+ /** When `true`, the icon ignores all clicks, hover, and state changes. */
29
59
  static?: boolean;
30
- /** When true, dulls the text and icon with a dimming overlay */
60
+ /** When `true`, the icon is dimmed and non-interactive. */
31
61
  disabled?: boolean;
32
- /** Per-icon stylesheet overrides merged above the global stylesheet but below explicit props */
62
+ /** Inline overrides for icon props and sizing values. */
33
63
  style?: Partial<IconProps & Stylesheet['sizing']>;
64
+ /** Explicit icon width in pixels. When undefined or `0`, auto-fits to content. */
65
+ iconWidth?: number;
66
+ /** Horizontal padding between the button edge and its content. */
67
+ contentPaddingX?: number;
68
+ /** Vertical padding between the button edge and its content. */
69
+ contentPaddingY?: number;
70
+ /** Gap between the image and the text label. */
71
+ imageToTextSpacing?: number;
72
+ /** KeyCode that toggles the icon when pressed. */
73
+ toggleKey?: Enum.KeyCode;
74
+ /** Shows a red notification badge with this count. Hides when `0` or `undefined`. */
75
+ notificationCount?: number;
76
+ /** Callback fired when the icon becomes selected. */
34
77
  selected?: () => void;
78
+ /** Callback fired when the icon becomes deselected. */
35
79
  deselected?: () => void;
80
+ /** Callback fired on mouse enter. */
36
81
  hover?: () => void;
82
+ /** Callback fired on mouse leave. */
37
83
  unhover?: () => void;
84
+ /** Callback fired whenever the state changes (receives the new state). */
38
85
  stateChanged?: (state: IconState) => void;
86
+ /** Callback fired on left click (in addition to the built-in toggle). */
39
87
  onClick?: () => void;
88
+ /** Callback fired on right click. */
40
89
  onRightClick?: () => void;
90
+ /** Function used to play click sounds. Receives the sound asset ID. */
41
91
  playSound?: (id: string) => void;
42
92
  }
93
+ /** Icon select/deselect state. */
43
94
  export type IconState = 'selected' | 'deselected';
95
+ /**
96
+ * A value that can change with icon state.
97
+ * Pass a single value for both states, or `{ deselected, selected }` for
98
+ * separate values that animate on state transitions.
99
+ */
44
100
  export type StateDependent<T> = Record<IconState, T> | T;
101
+ /** Extracts the inner type from a `StateDependent`. */
45
102
  export type FromStateDependent<T> = T extends StateDependent<infer U> ? U : T;
103
+ /** Unique numeric identifier for an icon instance. */
46
104
  export type IconId = number;
105
+ /**
106
+ * A single icon in the topbar.
107
+ *
108
+ * Supports an image, a text label, state-dependent styling, animated state
109
+ * transitions, hover lift, notification badges, toggle keys, and nested
110
+ * dropdown content.
111
+ */
47
112
  export declare function Icon(componentProps: IconProps): React.JSX.Element;