@quenty/snackbar 11.21.2 → 11.21.3

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/CHANGELOG.md CHANGED
@@ -3,6 +3,14 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [11.21.3](https://github.com/Quenty/NevermoreEngine/compare/@quenty/snackbar@11.21.2...@quenty/snackbar@11.21.3) (2025-04-10)
7
+
8
+ **Note:** Version bump only for package @quenty/snackbar
9
+
10
+
11
+
12
+
13
+
6
14
  ## [11.21.2](https://github.com/Quenty/NevermoreEngine/compare/@quenty/snackbar@11.21.0...@quenty/snackbar@11.21.2) (2025-04-07)
7
15
 
8
16
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quenty/snackbar",
3
- "version": "11.21.2",
3
+ "version": "11.21.3",
4
4
  "description": "Snackbars provide lightweight feedback on an operation at the base of the screen. They automatically disappear after a timeout or user interaction. There can only be one on the screen at a time.",
5
5
  "keywords": [
6
6
  "Roblox",
@@ -25,33 +25,33 @@
25
25
  "Quenty"
26
26
  ],
27
27
  "dependencies": {
28
- "@quenty/baseobject": "^10.8.2",
29
- "@quenty/basicpane": "^13.17.2",
30
- "@quenty/blend": "^12.18.2",
31
- "@quenty/buttondragmodel": "^1.15.2",
32
- "@quenty/buttonhighlightmodel": "^14.18.2",
33
- "@quenty/ducktype": "^5.8.3",
34
- "@quenty/genericscreenguiprovider": "^13.20.2",
35
- "@quenty/inputobjectutils": "^4.18.2",
36
- "@quenty/lipsum": "^14.18.2",
37
- "@quenty/loader": "^10.8.2",
38
- "@quenty/maid": "^3.4.2",
28
+ "@quenty/baseobject": "^10.8.3",
29
+ "@quenty/basicpane": "^13.17.3",
30
+ "@quenty/blend": "^12.18.3",
31
+ "@quenty/buttondragmodel": "^1.15.3",
32
+ "@quenty/buttonhighlightmodel": "^14.18.3",
33
+ "@quenty/ducktype": "^5.8.4",
34
+ "@quenty/genericscreenguiprovider": "^13.20.3",
35
+ "@quenty/inputobjectutils": "^4.18.3",
36
+ "@quenty/lipsum": "^14.18.3",
37
+ "@quenty/loader": "^10.8.3",
38
+ "@quenty/maid": "^3.4.3",
39
39
  "@quenty/math": "^2.7.3",
40
- "@quenty/promise": "^10.10.3",
41
- "@quenty/promisemaid": "^5.10.3",
42
- "@quenty/promptqueue": "^1.18.2",
43
- "@quenty/qgui": "^2.3.3",
44
- "@quenty/rx": "^13.17.2",
45
- "@quenty/servicebag": "^11.11.3",
46
- "@quenty/table": "^3.7.3",
47
- "@quenty/textserviceutils": "^13.18.2",
48
- "@quenty/transitionmodel": "^7.19.2",
40
+ "@quenty/promise": "^10.10.4",
41
+ "@quenty/promisemaid": "^5.10.4",
42
+ "@quenty/promptqueue": "^1.18.3",
43
+ "@quenty/qgui": "^2.3.4",
44
+ "@quenty/rx": "^13.17.3",
45
+ "@quenty/servicebag": "^11.11.4",
46
+ "@quenty/table": "^3.7.4",
47
+ "@quenty/textserviceutils": "^13.18.3",
48
+ "@quenty/transitionmodel": "^7.19.3",
49
49
  "@quenty/utf8": "^2.3.3",
50
- "@quenty/valueobject": "^13.17.2",
50
+ "@quenty/valueobject": "^13.17.3",
51
51
  "@quentystudios/t": "^3.0.0"
52
52
  },
53
53
  "publishConfig": {
54
54
  "access": "public"
55
55
  },
56
- "gitHead": "64def70499ec067077ee39f279936b620b217847"
56
+ "gitHead": "b06c070ae91d5dab7bd8de6e290ad2caabb15d8f"
57
57
  }
@@ -1,3 +1,4 @@
1
+ --!strict
1
2
  --[=[
2
3
  Snackbars provide lightweight feedback on an operation
3
4
  at the base of the screen. They automatically disappear
@@ -24,6 +25,7 @@ local ValueObject = require("ValueObject")
24
25
  local SpringObject = require("SpringObject")
25
26
  local Table = require("Table")
26
27
  local _Promise = require("Promise")
28
+ local _Observable = require("Observable")
27
29
 
28
30
  local SHADOW_RADIUS = 2
29
31
  local CORNER_RADIUS = 2
@@ -47,13 +49,29 @@ local Snackbar = setmetatable({}, TransitionModel)
47
49
  Snackbar.ClassName = "Snackbar"
48
50
  Snackbar.__index = Snackbar
49
51
 
50
- export type Snackbar = typeof(setmetatable({} :: {}, Snackbar)) & TransitionModel.TransitionModel
52
+ export type Snackbar = typeof(setmetatable(
53
+ {} :: {
54
+ Gui: GuiObject,
55
+
56
+ _text: ValueObject.ValueObject<string>,
57
+ _backgroundColor: ValueObject.ValueObject<Color3>,
58
+ _percentVisibleModel: SpringTransitionModel.SpringTransitionModel<number>,
59
+ _dragSpring: SpringObject.SpringObject<Vector2>,
60
+ _positionSpringModel: SpringTransitionModel.SpringTransitionModel<UDim2>,
61
+ _dragModel: ButtonDragModel.ButtonDragModel,
62
+ _computedTransparency: _Observable.Observable<number>,
63
+ _mainButton: GuiButton?,
64
+ _callToActionContainer: GuiObject?,
65
+ _textLabel: TextLabel?,
66
+ },
67
+ {} :: typeof({ __index = Snackbar })
68
+ )) & TransitionModel.TransitionModel
51
69
 
52
70
  function Snackbar.new(text: string, options: SnackbarOptionUtils.SnackbarOptions?): Snackbar
53
71
  assert(SnackbarOptionUtils.isSnackbarOptions(options) or options == nil, "Bad options")
54
72
  options = options or SnackbarOptionUtils.createSnackbarOptions({})
55
73
 
56
- local self = setmetatable(TransitionModel.new(), Snackbar)
74
+ local self: Snackbar = setmetatable(TransitionModel.new() :: any, Snackbar)
57
75
 
58
76
  self._text = self._maid:Add(ValueObject.new(text, "string"))
59
77
  self._backgroundColor = self._maid:Add(ValueObject.new(Color3.new(0.196, 0.196, 0.196), "Color3"))
@@ -98,7 +116,7 @@ function Snackbar.isSnackbar(value: any): boolean
98
116
  return DuckTypeUtils.isImplementation(Snackbar, value)
99
117
  end
100
118
 
101
- function Snackbar:PromiseSustain(): _Promise.Promise<()>
119
+ function Snackbar.PromiseSustain(self: Snackbar): _Promise.Promise<()>
102
120
  local promise = PromiseUtils.delayed(DURATION)
103
121
 
104
122
  PromiseMaidUtils.whilePromise(promise, function(maid)
@@ -112,7 +130,7 @@ function Snackbar:PromiseSustain(): _Promise.Promise<()>
112
130
  return promise
113
131
  end
114
132
 
115
- function Snackbar:_setupDragging()
133
+ function Snackbar._setupDragging(self: Snackbar)
116
134
  self._maid:GiveTask(self._dragSpring:ObserveTarget():Subscribe(function()
117
135
  self:_updateHideFromDragTarget()
118
136
  end))
@@ -134,27 +152,27 @@ function Snackbar:_setupDragging()
134
152
  return
135
153
  end
136
154
 
137
- if delta.magnitude == 0 then
155
+ if delta.Magnitude == 0 then
138
156
  return
139
157
  end
140
158
 
141
159
  if dragDirection == SnackbarDragDirections.VERTICAL then
142
- self._dragSpring:SetTarget(Vector2.new(0, delta.y), true)
160
+ self._dragSpring:SetTarget(Vector2.new(0, delta.Y), true)
143
161
  elseif dragDirection == SnackbarDragDirections.HORIZONTAL then
144
- self._dragSpring:SetTarget(Vector2.new(delta.x, 0), true)
162
+ self._dragSpring:SetTarget(Vector2.new(delta.X, 0), true)
145
163
  else
146
- if math.abs(delta.x) > math.abs(delta.y) then
164
+ if math.abs(delta.X) > math.abs(delta.Y) then
147
165
  dragDirection = SnackbarDragDirections.HORIZONTAL
148
- self._dragSpring:SetTarget(Vector2.new(delta.x, 0), true)
166
+ self._dragSpring:SetTarget(Vector2.new(delta.X, 0), true)
149
167
  else
150
168
  dragDirection = SnackbarDragDirections.VERTICAL
151
- self._dragSpring:SetTarget(Vector2.new(0, delta.y), true)
169
+ self._dragSpring:SetTarget(Vector2.new(0, delta.Y), true)
152
170
  end
153
171
  end
154
172
  end))
155
173
 
156
174
  maid:GiveTask(function()
157
- if self._dragSpring.Target.magnitude > 0.5*DRAG_DISTANCE_TO_HIDE then
175
+ if self._dragSpring.Target.Magnitude > 0.5 * DRAG_DISTANCE_TO_HIDE then
158
176
  self:Hide()
159
177
  else
160
178
  self._dragSpring:SetTarget(Vector2.zero)
@@ -165,19 +183,19 @@ function Snackbar:_setupDragging()
165
183
  self:_updateHideFromDragTarget()
166
184
  end
167
185
 
168
- function Snackbar:_updateHideFromDragTarget(doNotAnimate)
186
+ function Snackbar._updateHideFromDragTarget(self: Snackbar, doNotAnimate: boolean?)
169
187
  local target = self._dragSpring.Target
170
188
  local guiSize = self.Gui.AbsoluteSize
171
189
  local hideTarget
172
- if target.y > 0 then
190
+ if target.Y > 0 then
173
191
  -- Down
174
192
  hideTarget = SHOW_POSITION + UDim2.new(0, 0, 0, guiSize.Y)
175
- elseif target.y < 0 then
193
+ elseif target.Y < 0 then
176
194
  -- Up
177
195
  hideTarget = SHOW_POSITION + UDim2.new(0, 0, 0, -guiSize.Y)
178
- elseif target.x < 0 then
196
+ elseif target.X < 0 then
179
197
  hideTarget = SHOW_POSITION + UDim2.new(0, -guiSize.X, 0, 0)
180
- elseif target.x > 0 then
198
+ elseif target.X > 0 then
181
199
  hideTarget = SHOW_POSITION + UDim2.new(0, guiSize.X, 0, 0)
182
200
  else
183
201
  hideTarget = SHOW_POSITION + UDim2.new(0, 0, 0, guiSize.Y)
@@ -186,144 +204,149 @@ function Snackbar:_updateHideFromDragTarget(doNotAnimate)
186
204
  self._positionSpringModel:SetHideTarget(hideTarget, doNotAnimate)
187
205
  end
188
206
 
189
-
190
- function Snackbar:_render()
207
+ function Snackbar._render(self: Snackbar)
191
208
  local percentDragHidden = Blend.Computed(self._dragSpring:Observe(), function(value)
192
209
  return math.clamp(Math.map(value.magnitude, 0, DRAG_DISTANCE_TO_HIDE, 0, 1), 0, 1)
193
210
  end)
194
- self._computedTransparency = Blend.Computed(self._percentVisibleModel:Observe(), percentDragHidden, function(visible, dragHidden)
195
- return Math.map(visible, 0, 1, 1, dragHidden)
196
- end)
197
-
198
- return Blend.New "Frame" {
199
- ZIndex = 1;
200
- Name = "Snackbar";
201
- Size = UDim2.new(0, 0, 0, 0);
202
- AutomaticSize = Enum.AutomaticSize.XY;
203
- Position = Blend.Computed(self._positionSpringModel:Observe(), self._dragSpring:Observe(), function(position, dragPosition)
204
- return position + UDim2.fromOffset(dragPosition.x, dragPosition.y)
205
- end);
206
- AnchorPoint = Vector2.new(1, 1);
207
- BackgroundTransparency = 1;
208
-
209
- Blend.New "UIPadding" {
210
- PaddingTop = UDim.new(0, PADDING_FROM_BOTTOM);
211
- PaddingBottom = UDim.new(0, PADDING_FROM_BOTTOM);
212
- PaddingLeft = UDim.new(0, PADDING_FROM_BOTTOM);
213
- PaddingRight = UDim.new(0, PADDING_FROM_BOTTOM);
214
- };
215
-
216
- Blend.New "UIListLayout" {
217
- FillDirection = Enum.FillDirection.Horizontal;
218
- };
219
-
220
- Blend.New "ImageButton" {
221
- Size = UDim2.new(0, 0, 0, 0);
222
- AnchorPoint = Vector2.new(1, 1);
223
- AutomaticSize = Enum.AutomaticSize.XY;
224
- BackgroundTransparency = 1;
225
- AutoButtonColor = false;
226
-
227
- [Blend.Instance] = function(gui)
211
+ self._computedTransparency = Blend.Computed(
212
+ self._percentVisibleModel:Observe(),
213
+ percentDragHidden,
214
+ function(visible, dragHidden)
215
+ return Math.map(visible, 0, 1, 1, dragHidden)
216
+ end
217
+ )
218
+
219
+ return Blend.New("Frame")({
220
+ ZIndex = 1,
221
+ Name = "Snackbar",
222
+ Size = UDim2.new(0, 0, 0, 0),
223
+ AutomaticSize = Enum.AutomaticSize.XY,
224
+ Position = Blend.Computed(
225
+ self._positionSpringModel:Observe(),
226
+ self._dragSpring:Observe(),
227
+ function(position: UDim2, dragPosition: Vector2)
228
+ return position + UDim2.fromOffset(dragPosition.X, dragPosition.Y)
229
+ end
230
+ ),
231
+ AnchorPoint = Vector2.new(1, 1),
232
+ BackgroundTransparency = 1,
233
+
234
+ Blend.New("UIPadding")({
235
+ PaddingTop = UDim.new(0, PADDING_FROM_BOTTOM),
236
+ PaddingBottom = UDim.new(0, PADDING_FROM_BOTTOM),
237
+ PaddingLeft = UDim.new(0, PADDING_FROM_BOTTOM),
238
+ PaddingRight = UDim.new(0, PADDING_FROM_BOTTOM),
239
+ }),
240
+
241
+ Blend.New("UIListLayout")({
242
+ FillDirection = Enum.FillDirection.Horizontal,
243
+ }),
244
+
245
+ Blend.New("ImageButton")({
246
+ Size = UDim2.new(0, 0, 0, 0),
247
+ AnchorPoint = Vector2.new(1, 1),
248
+ AutomaticSize = Enum.AutomaticSize.XY,
249
+ BackgroundTransparency = 1,
250
+ AutoButtonColor = false,
251
+
252
+ [Blend.Instance :: any] = function(gui: GuiButton)
228
253
  self._mainButton = gui
229
254
  self._dragModel:SetButton(gui)
230
- end;
231
-
232
- Blend.New "UICorner" {
233
- CornerRadius = UDim.new(0, CORNER_RADIUS);
234
- };
235
-
236
- Blend.New "UIListLayout" {
237
- FillDirection = Enum.FillDirection.Horizontal;
238
- };
239
-
240
-
241
- Blend.New "Folder" {
242
- Name = "BackingFolder";
243
-
244
- Blend.New "ImageLabel" {
245
- Name = "Shadow";
246
- ZIndex = 1;
247
- Image = "rbxassetid://191838004";
248
- AnchorPoint = Vector2.new(0.5, 0.5);
249
- Position = UDim2.fromScale(0.5, 0.5);
250
- ImageRectSize = Vector2.new(150, 150);
251
- ScaleType = Enum.ScaleType.Slice;
252
- SliceCenter = Rect.new(50, 50, 100, 100);
253
- SliceScale = (2*SHADOW_RADIUS + CORNER_RADIUS)/50;
254
- BackgroundTransparency = 1;
255
- Size = UDim2.new(1, 2*SHADOW_RADIUS, 1, 2*SHADOW_RADIUS);
255
+ end,
256
+
257
+ Blend.New("UICorner")({
258
+ CornerRadius = UDim.new(0, CORNER_RADIUS),
259
+ }),
260
+
261
+ Blend.New("UIListLayout")({
262
+ FillDirection = Enum.FillDirection.Horizontal,
263
+ }),
264
+
265
+ Blend.New("Folder")({
266
+ Name = "BackingFolder",
267
+
268
+ Blend.New("ImageLabel")({
269
+ Name = "Shadow",
270
+ ZIndex = 1,
271
+ Image = "rbxassetid://191838004",
272
+ AnchorPoint = Vector2.new(0.5, 0.5),
273
+ Position = UDim2.fromScale(0.5, 0.5),
274
+ ImageRectSize = Vector2.new(150, 150),
275
+ ScaleType = Enum.ScaleType.Slice,
276
+ SliceCenter = Rect.new(50, 50, 100, 100),
277
+ SliceScale = (2 * SHADOW_RADIUS + CORNER_RADIUS) / 50,
278
+ BackgroundTransparency = 1,
279
+ Size = UDim2.new(1, 2 * SHADOW_RADIUS, 1, 2 * SHADOW_RADIUS),
256
280
  ImageTransparency = Blend.Computed(self._computedTransparency, function(value)
257
281
  return Math.map(value, 0, 1, 0.75, 1)
258
- end);
259
- };
260
- };
261
-
262
- Blend.New "Frame" {
263
- Name = "InnerSnackbarContainer";
264
- AutomaticSize = Enum.AutomaticSize.XY;
265
- Size = UDim2.new(0, 0, 0, 0);
266
- ZIndex = 2;
267
- BackgroundColor3 = self._backgroundColor:Observe();
268
- BackgroundTransparency = self._computedTransparency;
269
-
270
- Blend.New "UISizeConstraint" {
271
- MaxSize = Vector2.new(700, 48*2);
272
- MinSize = Vector2.new(100, 0);
273
- };
274
-
275
- [Blend.Instance] = function(gui)
282
+ end),
283
+ }),
284
+ }),
285
+
286
+ Blend.New("Frame")({
287
+ Name = "InnerSnackbarContainer",
288
+ AutomaticSize = Enum.AutomaticSize.XY,
289
+ Size = UDim2.new(0, 0, 0, 0),
290
+ ZIndex = 2,
291
+ BackgroundColor3 = self._backgroundColor:Observe(),
292
+ BackgroundTransparency = self._computedTransparency,
293
+
294
+ Blend.New("UISizeConstraint")({
295
+ MaxSize = Vector2.new(700, 48 * 2),
296
+ MinSize = Vector2.new(100, 0),
297
+ }),
298
+
299
+ [Blend.Instance :: any] = function(gui)
276
300
  self._callToActionContainer = gui
277
- end;
278
-
279
- Blend.New "UICorner" {
280
- CornerRadius = UDim.new(0, CORNER_RADIUS);
281
- };
282
-
283
- Blend.New "UIListLayout" {
284
- FillDirection = Enum.FillDirection.Horizontal;
285
- HorizontalAlignment = Enum.HorizontalAlignment.Left;
286
- VerticalAlignment = Enum.VerticalAlignment.Center;
287
- Padding = UDim.new(0, PADDING_X);
288
- };
289
-
290
- Blend.New "UIPadding" {
291
- PaddingTop = UDim.new(0, 15);
292
- PaddingBottom = UDim.new(0, 15);
293
- PaddingLeft = UDim.new(0, PADDING_X);
294
- PaddingRight = UDim.new(0, PADDING_X);
295
- };
296
-
297
-
298
- Blend.New "TextLabel" {
299
- Name = "SnackbarLabel";
300
- LayoutOrder = 1;
301
- BackgroundTransparency = 1;
302
- AutomaticSize = Enum.AutomaticSize.XY;
303
- TextColor3 = Color3.new(1, 1, 1);
304
- Size = UDim2.new(0, 0, 0, 0);
305
- Position = UDim2.new(0, 0, 0, 18);
306
- TextXAlignment = Enum.TextXAlignment.Left;
307
- TextYAlignment = Enum.TextYAlignment.Center;
308
- BorderSizePixel = 0;
309
- Font = Enum.Font.SourceSans;
310
- Text = self._text:Observe();
311
- TextWrapped = false;
301
+ end,
302
+
303
+ Blend.New("UICorner")({
304
+ CornerRadius = UDim.new(0, CORNER_RADIUS),
305
+ }),
306
+
307
+ Blend.New("UIListLayout")({
308
+ FillDirection = Enum.FillDirection.Horizontal,
309
+ HorizontalAlignment = Enum.HorizontalAlignment.Left,
310
+ VerticalAlignment = Enum.VerticalAlignment.Center,
311
+ Padding = UDim.new(0, PADDING_X),
312
+ }),
313
+
314
+ Blend.New("UIPadding")({
315
+ PaddingTop = UDim.new(0, 15),
316
+ PaddingBottom = UDim.new(0, 15),
317
+ PaddingLeft = UDim.new(0, PADDING_X),
318
+ PaddingRight = UDim.new(0, PADDING_X),
319
+ }),
320
+
321
+ Blend.New("TextLabel")({
322
+ Name = "SnackbarLabel",
323
+ LayoutOrder = 1,
324
+ BackgroundTransparency = 1,
325
+ AutomaticSize = Enum.AutomaticSize.XY,
326
+ TextColor3 = Color3.new(1, 1, 1),
327
+ Size = UDim2.new(0, 0, 0, 0),
328
+ Position = UDim2.new(0, 0, 0, 18),
329
+ TextXAlignment = Enum.TextXAlignment.Left,
330
+ TextYAlignment = Enum.TextYAlignment.Center,
331
+ BorderSizePixel = 0,
332
+ Font = Enum.Font.SourceSans,
333
+ Text = self._text:Observe(),
334
+ TextWrapped = false,
312
335
  TextTransparency = Blend.Computed(self._computedTransparency, function(value)
313
336
  return Math.map(value, 0, 1, 0.13, 1)
314
- end);
315
- TextSize = 18;
337
+ end),
338
+ TextSize = 18,
316
339
 
317
- [Blend.Instance] = function(gui)
340
+ [Blend.Instance] = function(gui: TextLabel)
318
341
  self._textLabel = gui
319
- end;
320
- };
321
- };
322
- }
323
- }
342
+ end,
343
+ }),
344
+ }),
345
+ }),
346
+ })
324
347
  end
325
348
 
326
- function Snackbar:_renderCallToAction(callToAction)
349
+ function Snackbar._renderCallToAction(self: Snackbar, callToAction)
327
350
  local callToActionText = ""
328
351
  local onClick = nil
329
352
  if type(callToAction) == "string" then
@@ -345,7 +368,7 @@ function Snackbar:_renderCallToAction(callToAction)
345
368
  Size = UDim2.new(0, 0, 0, 18);
346
369
  Text = UTF8.upper(callToActionText);
347
370
  Font = Enum.Font.SourceSans;
348
- FontSize = self._textLabel.FontSize;
371
+ TextSize = assert(self._textLabel, "Must have textLabel").TextSize;
349
372
  TextXAlignment = Enum.TextXAlignment.Right;
350
373
  TextColor3 = Blend.Computed(buttonModel:ObservePercentHighlighted(), function(percent)
351
374
  local scale = Math.map(percent, 0, 1, 0, 0.2)
@@ -9,11 +9,13 @@ local t = require("t")
9
9
 
10
10
  local SnackbarOptionUtils = {}
11
11
 
12
+ export type CallToActionOptions = {
13
+ Text: string,
14
+ OnClick: ((any) -> any) | nil,
15
+ }
16
+
12
17
  export type SnackbarOptions = {
13
- CallToAction: string | {
14
- Text: string,
15
- OnClick: ((any) -> any) | nil,
16
- } | nil,
18
+ CallToAction: string | CallToActionOptions?,
17
19
  }
18
20
 
19
21
  function SnackbarOptionUtils.createSnackbarOptions(options: SnackbarOptions): SnackbarOptions