@ultraviolet/plus 0.4.10 → 0.5.1

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.
Files changed (24) hide show
  1. package/dist/index.d.ts +261 -1
  2. package/dist/src/components/ContentCard/index.js +1 -1
  3. package/dist/src/components/ContentCardGroup/Card.js +41 -11
  4. package/dist/src/components/EstimateCost/Components/CustomUnitInput.js +48 -0
  5. package/dist/src/components/EstimateCost/Components/Item.js +327 -0
  6. package/dist/src/components/EstimateCost/Components/LineThrough.js +15 -0
  7. package/dist/src/components/EstimateCost/Components/NumberInput.js +41 -0
  8. package/dist/src/components/EstimateCost/Components/Region.js +50 -0
  9. package/dist/src/components/EstimateCost/Components/Regular.js +44 -0
  10. package/dist/src/components/EstimateCost/Components/Strong.js +37 -0
  11. package/dist/src/components/EstimateCost/Components/Unit.js +61 -0
  12. package/dist/src/components/EstimateCost/Components/UnitInput.js +122 -0
  13. package/dist/src/components/EstimateCost/Components/Zone.js +50 -0
  14. package/dist/src/components/EstimateCost/EstimateCost.js +126 -0
  15. package/dist/src/components/EstimateCost/EstimateCostContent.js +299 -0
  16. package/dist/src/components/EstimateCost/EstimateCostProvider.js +39 -0
  17. package/dist/src/components/EstimateCost/OverlayComponent.js +139 -0
  18. package/dist/src/components/EstimateCost/OverlayContext.js +19 -0
  19. package/dist/src/components/EstimateCost/componentStyle.js +196 -0
  20. package/dist/src/components/EstimateCost/constants.js +31 -0
  21. package/dist/src/components/EstimateCost/helper.js +23 -0
  22. package/dist/src/components/EstimateCost/locales/en.js +23 -0
  23. package/dist/src/index.js +1 -0
  24. package/package.json +9 -2
@@ -0,0 +1,50 @@
1
+ import _styled from '@emotion/styled/base';
2
+ import { useEstimateCost } from '../EstimateCostProvider.js';
3
+ import { Item } from './Item.js';
4
+ import { Strong } from './Strong.js';
5
+ import { jsx, jsxs } from '@emotion/react/jsx-runtime';
6
+
7
+ const StyledImage = /*#__PURE__*/_styled("img", {
8
+ target: "e24b3x10"
9
+ })("width:15px;margin-right:", _ref => {
10
+ let {
11
+ theme
12
+ } = _ref;
13
+ return theme.space['1'];
14
+ }, ";");
15
+ const Zone = _ref2 => {
16
+ let {
17
+ label,
18
+ image,
19
+ shouldBeHidden = false,
20
+ priceText,
21
+ animated = false,
22
+ isFirstElement,
23
+ isLastElement,
24
+ productsCallback,
25
+ iteration,
26
+ discount
27
+ } = _ref2;
28
+ const {
29
+ locales
30
+ } = useEstimateCost();
31
+ return jsx(Item, {
32
+ label: locales['estimate.cost.az.label'],
33
+ shouldBeHidden: shouldBeHidden,
34
+ priceText: priceText,
35
+ animated: animated,
36
+ isFirstElement: isFirstElement,
37
+ isLastElement: isLastElement,
38
+ productsCallback: productsCallback,
39
+ iteration: iteration,
40
+ discount: discount,
41
+ children: jsxs(Strong, {
42
+ children: [jsx(StyledImage, {
43
+ alt: label,
44
+ src: image
45
+ }), label]
46
+ })
47
+ });
48
+ };
49
+
50
+ export { Zone };
@@ -0,0 +1,126 @@
1
+ import _styled from '@emotion/styled/base';
2
+ import { Text } from '@ultraviolet/ui';
3
+ import { Children } from 'react';
4
+ import { Item } from './Components/Item.js';
5
+ import { LineThrough } from './Components/LineThrough.js';
6
+ import { NumberInput } from './Components/NumberInput.js';
7
+ import { Region } from './Components/Region.js';
8
+ import { Regular } from './Components/Regular.js';
9
+ import { Strong } from './Components/Strong.js';
10
+ import { Unit } from './Components/Unit.js';
11
+ import { Zone } from './Components/Zone.js';
12
+ import { EstimateCostContent } from './EstimateCostContent.js';
13
+ import { EstimateCostProvider } from './EstimateCostProvider.js';
14
+ import { useOverlay } from './OverlayContext.js';
15
+ import EstimateCostLocales from './locales/en.js';
16
+ import { jsx } from '@emotion/react/jsx-runtime';
17
+
18
+ const MaxWidthText = /*#__PURE__*/_styled(Text, {
19
+ target: "e13v5qur1"
20
+ })("max-width:", _ref => {
21
+ let {
22
+ maxWidth
23
+ } = _ref;
24
+ return maxWidth;
25
+ }, "px;");
26
+ const DEFAULT_UNIT_LIST = ['hours', 'days', 'months'];
27
+ const EstimateCost = _ref2 => {
28
+ let {
29
+ description,
30
+ alert,
31
+ alertVariant = 'warning',
32
+ defaultTimeUnit = 'hours',
33
+ timeUnits = DEFAULT_UNIT_LIST,
34
+ hideOverlay = false,
35
+ disableOverlayLeft = false,
36
+ disableOverlayRight = false,
37
+ hideTimeUnit = false,
38
+ hideTotal = false,
39
+ discount = 0,
40
+ OverlayRight,
41
+ OverlayLeft,
42
+ isBeta = false,
43
+ commitmentFees,
44
+ commitmentFeesContent,
45
+ monthlyFees,
46
+ monthlyFeesLabel,
47
+ monthlyFeesContent,
48
+ overlayUnit = 'hours',
49
+ children = null,
50
+ locales = EstimateCostLocales,
51
+ numberLocales = 'en-EN',
52
+ currency = 'EUR'
53
+ } = _ref2;
54
+ return jsx(EstimateCostProvider, {
55
+ locales: locales,
56
+ currency: currency,
57
+ numberLocales: numberLocales,
58
+ children: jsx(EstimateCostContent, {
59
+ description: description,
60
+ alert: alert,
61
+ alertVariant: alertVariant,
62
+ defaultTimeUnit: defaultTimeUnit,
63
+ timeUnits: timeUnits,
64
+ hideOverlay: hideOverlay,
65
+ disableOverlayLeft: disableOverlayLeft,
66
+ disableOverlayRight: disableOverlayRight,
67
+ hideTimeUnit: hideTimeUnit,
68
+ hideTotal: hideTotal,
69
+ discount: discount,
70
+ OverlayRight: OverlayRight,
71
+ OverlayLeft: OverlayLeft,
72
+ isBeta: isBeta,
73
+ commitmentFees: commitmentFees,
74
+ commitmentFeesContent: commitmentFeesContent,
75
+ monthlyFees: monthlyFees,
76
+ monthlyFeesLabel: monthlyFeesLabel,
77
+ monthlyFeesContent: monthlyFeesContent,
78
+ overlayUnit: overlayUnit,
79
+ locales: locales,
80
+ children: children
81
+ })
82
+ });
83
+ };
84
+ EstimateCost.LineThrough = LineThrough;
85
+ EstimateCost.Item = Item;
86
+ EstimateCost.NumberInput = NumberInput;
87
+ EstimateCost.Unit = Unit;
88
+ EstimateCost.Strong = Strong;
89
+ EstimateCost.Regular = Regular;
90
+ EstimateCost.Image = /*#__PURE__*/_styled("img", {
91
+ target: "e13v5qur0"
92
+ })("width:15px;margin-right:", _ref3 => {
93
+ let {
94
+ theme
95
+ } = _ref3;
96
+ return theme.space['1'];
97
+ }, ";");
98
+ EstimateCost.Region = Region;
99
+ EstimateCost.Zone = Zone;
100
+ const Ellipsis = _ref4 => {
101
+ let {
102
+ children,
103
+ maxWidth = 350,
104
+ 'data-testid': dataTestId
105
+ } = _ref4;
106
+ const {
107
+ isOverlay
108
+ } = useOverlay();
109
+ const text = Children.toArray(children).join('').toString();
110
+ return jsx("div", {
111
+ style: {
112
+ display: !isOverlay ? 'inline-flex' : undefined
113
+ },
114
+ "data-testid": dataTestId,
115
+ children: jsx(MaxWidthText, {
116
+ as: "p",
117
+ oneLine: true,
118
+ variant: "bodyStrong",
119
+ maxWidth: isOverlay ? 200 : maxWidth,
120
+ children: text
121
+ })
122
+ });
123
+ };
124
+ EstimateCost.Ellipsis = Ellipsis;
125
+
126
+ export { EstimateCost };
@@ -0,0 +1,299 @@
1
+ import _styled from '@emotion/styled/base';
2
+ import { Text, Stack, Alert, Icon } from '@ultraviolet/ui';
3
+ import { useState, useMemo, useEffect, Children, cloneElement } from 'react';
4
+ import flattenChildren from 'react-flatten-children';
5
+ import { useInView } from 'react-intersection-observer';
6
+ import { CustomUnitInput } from './Components/CustomUnitInput.js';
7
+ import { Item } from './Components/Item.js';
8
+ import { LineThrough } from './Components/LineThrough.js';
9
+ import { useEstimateCost } from './EstimateCostProvider.js';
10
+ import { OverlayComponent } from './OverlayComponent.js';
11
+ import { OverlayContextProvider } from './OverlayContext.js';
12
+ import { StyledTable, PriceCol, Title, TimeCell, EmptyTable, EmptyCell, TotalPriceCell, BadgeBeta, StyledFeesTable, Cell, PriceCell } from './componentStyle.js';
13
+ import { maximumFractionDigitsLong, maximumFractionDigits } from './constants.js';
14
+ import { calculatePrice } from './helper.js';
15
+ import EstimateCostLocales from './locales/en.js';
16
+ import { jsxs, jsx, Fragment } from '@emotion/react/jsx-runtime';
17
+
18
+ function _EMOTION_STRINGIFIED_CSS_ERROR__() { return "You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."; }
19
+ const FeesText = /*#__PURE__*/_styled(Text, {
20
+ target: "excc3v74"
21
+ })("margin-top:", _ref => {
22
+ let {
23
+ theme
24
+ } = _ref;
25
+ return theme.space['3'];
26
+ }, ";");
27
+ const StyledText = /*#__PURE__*/_styled(Text, {
28
+ target: "excc3v73"
29
+ })("text-align:right;", _ref2 => {
30
+ let {
31
+ isBeta,
32
+ theme
33
+ } = _ref2;
34
+ return isBeta ? `margin-left: ${theme.space['2']};` : null;
35
+ }, ";");
36
+ const RightAlignedText = /*#__PURE__*/_styled(Text, {
37
+ target: "excc3v72"
38
+ })(process.env.NODE_ENV === "production" ? {
39
+ name: "2qga7i",
40
+ styles: "text-align:right"
41
+ } : {
42
+ name: "2qga7i",
43
+ styles: "text-align:right",
44
+ toString: _EMOTION_STRINGIFIED_CSS_ERROR__
45
+ });
46
+ const StyledIcon = /*#__PURE__*/_styled(Icon, {
47
+ target: "excc3v71"
48
+ })("margin-right:", _ref3 => {
49
+ let {
50
+ theme
51
+ } = _ref3;
52
+ return theme.space['1'];
53
+ }, ";");
54
+ const StyledPriceCell = /*#__PURE__*/_styled(Cell.withComponent('th', {
55
+ target: "excc3v75"
56
+ }), {
57
+ target: "excc3v70"
58
+ })(_ref4 => {
59
+ let {
60
+ theme
61
+ } = _ref4;
62
+ return PriceCell(theme);
63
+ }, ";");
64
+ const DEFAULT_UNIT_LIST = ['hours', 'days', 'months'];
65
+ const EstimateCostContent = _ref5 => {
66
+ let {
67
+ description,
68
+ alert,
69
+ alertVariant = 'warning',
70
+ defaultTimeUnit = 'hours',
71
+ timeUnits = DEFAULT_UNIT_LIST,
72
+ hideOverlay = false,
73
+ disableOverlayLeft = false,
74
+ disableOverlayRight = false,
75
+ hideTimeUnit = false,
76
+ hideTotal = false,
77
+ discount = 0,
78
+ OverlayRight,
79
+ OverlayLeft,
80
+ isBeta = false,
81
+ commitmentFees,
82
+ commitmentFeesContent,
83
+ monthlyFees,
84
+ monthlyFeesLabel,
85
+ monthlyFeesContent,
86
+ overlayUnit = 'hours',
87
+ children = null,
88
+ locales = EstimateCostLocales
89
+ } = _ref5;
90
+ const {
91
+ formatNumber
92
+ } = useEstimateCost();
93
+ const [ref, inView] = useInView();
94
+ const [products, setProducts] = useState([]); // product is used to store each items with their price and amount
95
+ const [totalPrice, setTotalPrice] = useState({
96
+ overlayHourly: 0,
97
+ maxOverlayHourly: 0,
98
+ hourly: 0,
99
+ maxHourly: 0,
100
+ total: 0,
101
+ maxTotal: 0
102
+ });
103
+ const [iteration, setIteration] = useState({
104
+ value: 1,
105
+ unit: defaultTimeUnit ?? 'hours'
106
+ });
107
+ const [isLongFractionDigits, setIsLongFractionDigits] = useState(false);
108
+ const providerValue = useMemo(() => ({
109
+ isOverlay: false
110
+ }), []);
111
+ const list = flattenChildren(children);
112
+ const productsCallback = useMemo(() => ({
113
+ add: newProduct => {
114
+ setProducts(total => {
115
+ if (total.find(product => product.id === newProduct.id)) {
116
+ return total.map(product => product.id === newProduct.id ? newProduct : product);
117
+ }
118
+ return [...total, newProduct];
119
+ });
120
+ },
121
+ remove: _ref6 => {
122
+ let {
123
+ id
124
+ } = _ref6;
125
+ setProducts(total => total.filter(product => product.id !== id));
126
+ }
127
+ }), [setProducts]);
128
+ useEffect(() => {
129
+ // this variable check if there is a maxAmount in each product
130
+ // if not we do not need to calculate maxTotal, maxHourly, maxOverlayHourly
131
+ const isMaxAmountInProducts = products.find(product => product.maxAmount);
132
+ setIsLongFractionDigits(!!products.find(product => product.longFractionDigits));
133
+ setTotalPrice({
134
+ total: !hideTotal ? products.reduce((acc, product) => acc + calculatePrice({
135
+ price: product.price,
136
+ amount: product.amount,
137
+ amountFree: product.amountFree,
138
+ timeUnit: product.noIteration ? 'hours' : iteration.unit,
139
+ timeAmount: product.noIteration ? 1 : iteration.value,
140
+ discount: product.discount
141
+ }), 0) : 0,
142
+ maxTotal: isMaxAmountInProducts ? products.reduce((acc, product) => acc + calculatePrice({
143
+ price: product.price,
144
+ amount: product.maxAmount || product.amount,
145
+ // Not all products have maxAmount, so we need to check both
146
+ amountFree: product.amountFree,
147
+ timeUnit: product.noIteration ? 'hours' : iteration.unit,
148
+ timeAmount: product.noIteration ? 1 : iteration.value,
149
+ discount: product.discount
150
+ }), 0) : 0,
151
+ hourly: products.reduce((acc, product) => acc + (product.noIteration ? 0 : (product.price - product.price * product.discount) * Math.max(product.amount - product.amountFree, 0)), 0),
152
+ maxHourly: isMaxAmountInProducts ? products.reduce((acc, product) => acc && product.noIteration ? 0 : (product.price - product.price * product.discount) * Math.max(product.maxAmount - product.amountFree, 0), 0) : 0,
153
+ overlayHourly: products.reduce((acc, product) => acc + (product.noIteration ? 0 : (product.price - product.price * product.discount) * Math.max(product.amount - product.amountFree, 0)), 0),
154
+ maxOverlayHourly: isMaxAmountInProducts ? products.reduce((acc, product) => acc + (product.noIteration ? 0 : (product.price - product.price * product.discount) * Math.max(product.maxAmount - product.amountFree, 0)), 0) : 0
155
+ });
156
+ }, [hideTotal, products, iteration, setTotalPrice]);
157
+ useEffect(() => {
158
+ if (hideTimeUnit && (iteration.value > 1 || iteration.unit !== (defaultTimeUnit ?? 'hours'))) {
159
+ setIteration({
160
+ unit: defaultTimeUnit ?? 'hours',
161
+ value: 1
162
+ });
163
+ }
164
+ }, [hideTimeUnit, iteration, defaultTimeUnit]);
165
+ return jsxs(Stack, {
166
+ gap: 2,
167
+ children: [!hideOverlay ? jsx(OverlayComponent, {
168
+ inView: inView,
169
+ totalPrice: totalPrice,
170
+ disableOverlayLeft: disableOverlayLeft,
171
+ disableOverlayRight: disableOverlayRight,
172
+ OverlayLeft: OverlayLeft,
173
+ OverlayRight: OverlayRight,
174
+ isBeta: isBeta,
175
+ discount: discount,
176
+ unit: overlayUnit ?? 'hours',
177
+ children: children
178
+ }) : null, typeof description === 'string' || !description ? jsx(Text, {
179
+ as: "span",
180
+ variant: "body",
181
+ children: description || locales['estimate.cost.description']
182
+ }) : description, alert ? jsx(Alert, {
183
+ sentiment: alertVariant,
184
+ children: alert
185
+ }) : null, jsx(OverlayContextProvider, {
186
+ value: providerValue,
187
+ children: jsxs("div", {
188
+ children: [children ? jsxs(StyledTable, {
189
+ cellPadding: "0",
190
+ cellSpacing: "0",
191
+ ref: ref,
192
+ "data-testid": "summary",
193
+ noTotal: hideTotal,
194
+ children: [jsxs("colgroup", {
195
+ children: [jsx("col", {}), jsx(PriceCol, {})]
196
+ }), !hideTimeUnit ? jsx("thead", {
197
+ children: jsxs("tr", {
198
+ children: [jsx("th", {
199
+ children: jsxs(Title, {
200
+ children: [jsx(StyledIcon, {
201
+ name: "calculator",
202
+ color: "primary",
203
+ size: 20
204
+ }), locales['estimate.cost.label']]
205
+ })
206
+ }), jsx(StyledPriceCell, {
207
+ children: jsx(TimeCell, {
208
+ children: jsx(CustomUnitInput, {
209
+ defaultTimeUnit: defaultTimeUnit,
210
+ setIteration: setIteration,
211
+ iteration: iteration,
212
+ timeUnits: timeUnits
213
+ })
214
+ })
215
+ })]
216
+ })
217
+ }) : null, jsx("tbody", {
218
+ children: Children.map(list, (child, index) =>
219
+
220
+ /* @ts-expect-error I'm too dumb to understand this sorcery */
221
+ cloneElement(child, {
222
+ isLastElement: index === list.length - 1,
223
+ productsCallback,
224
+ iteration,
225
+ discount: discount && !child.props.discount ? discount : child.props.discount
226
+ }))
227
+ })]
228
+ }) : null, !hideTotal ? jsxs(EmptyTable, {
229
+ cellPadding: "0",
230
+ cellSpacing: "0",
231
+ children: [jsxs("colgroup", {
232
+ children: [jsx("col", {}), jsx(PriceCol, {})]
233
+ }), jsx("tbody", {
234
+ children: jsxs("tr", {
235
+ children: [jsx(EmptyCell, {
236
+ "aria-label": "control"
237
+ }), jsxs(TotalPriceCell, {
238
+ hasBorder: false,
239
+ children: [isBeta ? jsx(BadgeBeta, {
240
+ prominence: "strong",
241
+ long: locales[`estimate.cost.beta.${discount > 0 ? 'discount' : 'free'}`].length > 25,
242
+ sentiment: "warning",
243
+ children: `${discount * 100}
244
+ ${locales[`estimate.cost.beta.${discount > 0 ? 'discount' : 'free'}`]}`
245
+ }) : null, jsx(StyledText, {
246
+ as: "h3",
247
+ variant: "heading",
248
+ color: "primary",
249
+ isBeta: isBeta,
250
+ children: jsxs(LineThrough, {
251
+ isActive: isBeta && (discount === 0 || discount >= 1),
252
+ children: [formatNumber(totalPrice.total, {
253
+ maximumFractionDigits: isLongFractionDigits ? maximumFractionDigitsLong[iteration.unit] : maximumFractionDigits[iteration.unit]
254
+ }), totalPrice.maxTotal > 0 ? ` - ${formatNumber(totalPrice.maxTotal, {
255
+ maximumFractionDigits: isLongFractionDigits ? maximumFractionDigitsLong[iteration.unit] : maximumFractionDigits[iteration.unit]
256
+ })}` : null]
257
+ })
258
+ }), totalPrice.hourly > 0 && totalPrice.hourly !== totalPrice.total && totalPrice.total > 0 ? jsx(RightAlignedText, {
259
+ as: "p",
260
+ variant: "body",
261
+ children: jsxs(LineThrough, {
262
+ isActive: isBeta && (discount === 0 || discount >= 1),
263
+ children: [formatNumber(totalPrice.hourly, {
264
+ maximumFractionDigits: isLongFractionDigits ? maximumFractionDigitsLong.hours : maximumFractionDigits.hours
265
+ }), totalPrice.maxHourly > 0 ? ` - ${formatNumber(totalPrice.maxHourly, {
266
+ maximumFractionDigits: isLongFractionDigits ? maximumFractionDigitsLong.hours : maximumFractionDigits.hours
267
+ })}` : null, "/", locales[`estimate.cost.units.hours.label`].toLowerCase()]
268
+ })
269
+ }) : null]
270
+ })]
271
+ })
272
+ })]
273
+ }) : null, commitmentFees !== undefined || monthlyFees !== undefined ? jsxs(Fragment, {
274
+ children: [jsx(FeesText, {
275
+ as: "h3",
276
+ variant: "headingSmall",
277
+ children: locales[`estimate.cost.fees.${commitmentFees ? 'oneTime' : 'monthly'}.title`]
278
+ }), jsx(StyledFeesTable, {
279
+ children: jsx("tbody", {
280
+ children: jsx(Item, {
281
+ label: commitmentFees ? locales['estimate.cost.fees.commitment'] : monthlyFeesLabel,
282
+ noIteration: true,
283
+ isLastElement: true,
284
+ price: commitmentFees || monthlyFees,
285
+ productsCallback: {
286
+ add: () => {},
287
+ remove: () => {}
288
+ },
289
+ children: commitmentFees ? commitmentFeesContent : monthlyFeesContent
290
+ })
291
+ })
292
+ })]
293
+ }) : null]
294
+ })
295
+ })]
296
+ });
297
+ };
298
+
299
+ export { EstimateCostContent };
@@ -0,0 +1,39 @@
1
+ import { useMemo, useCallback, createContext, useContext } from 'react';
2
+ import EstimateCostLocales from './locales/en.js';
3
+ import { jsx } from '@emotion/react/jsx-runtime';
4
+
5
+ const EstimateCostContext = /*#__PURE__*/createContext({
6
+ locales: EstimateCostLocales,
7
+ formatNumber: () => ''
8
+ });
9
+ const useEstimateCost = () => useContext(EstimateCostContext);
10
+ const EstimateCostProvider = _ref => {
11
+ let {
12
+ children,
13
+ locales,
14
+ currency,
15
+ numberLocales
16
+ } = _ref;
17
+ const newLocales = useMemo(() => locales ? {
18
+ ...EstimateCostLocales,
19
+ ...locales
20
+ } : EstimateCostLocales, [locales]);
21
+ const formatNumber = useCallback((number, options) => {
22
+ const numberFormat = new Intl.NumberFormat(numberLocales, {
23
+ style: 'currency',
24
+ currency,
25
+ ...options
26
+ });
27
+ return numberFormat.format(number);
28
+ }, [currency, numberLocales]);
29
+ const value = useMemo(() => ({
30
+ locales: newLocales,
31
+ formatNumber
32
+ }), [formatNumber, newLocales]);
33
+ return jsx(EstimateCostContext.Provider, {
34
+ value: value,
35
+ children: children
36
+ });
37
+ };
38
+
39
+ export { EstimateCostProvider, useEstimateCost };
@@ -0,0 +1,139 @@
1
+ import _styled from '@emotion/styled/base';
2
+ import { Stack, Icon } from '@ultraviolet/ui';
3
+ import { useMemo, Children, isValidElement, cloneElement } from 'react';
4
+ import flattenChildren from 'react-flatten-children';
5
+ import { LineThrough } from './Components/LineThrough.js';
6
+ import { Strong } from './Components/Strong.js';
7
+ import { useEstimateCost } from './EstimateCostProvider.js';
8
+ import { OverlayContextProvider } from './OverlayContext.js';
9
+ import { OverlayRow, ItemResourceName, StyledBadge } from './componentStyle.js';
10
+ import { multiplier, maximumFractionDigits } from './constants.js';
11
+ import { jsx, jsxs } from '@emotion/react/jsx-runtime';
12
+
13
+ function _EMOTION_STRINGIFIED_CSS_ERROR__() { return "You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."; }
14
+ const OverlayContainer = /*#__PURE__*/_styled("div", {
15
+ target: "e1p62vjs2"
16
+ })("position:fixed;z-index:999;left:0;right:0;bottom:", _ref => {
17
+ let {
18
+ inView
19
+ } = _ref;
20
+ return inView ? -120 : 0;
21
+ }, "px;height:120px;background-color:", _ref2 => {
22
+ let {
23
+ theme
24
+ } = _ref2;
25
+ return theme.colors.neutral.background;
26
+ }, ";margin:0 0 0 200px;display:flex;justify-content:center;box-shadow:", _ref3 => {
27
+ let {
28
+ inView,
29
+ theme
30
+ } = _ref3;
31
+ return inView ? '0' : theme.shadows.defaultShadow;
32
+ }, ";transition:bottom 0.3s,box-shadow 0.3s;");
33
+ const List = /*#__PURE__*/_styled("ul", {
34
+ target: "e1p62vjs1"
35
+ })("display:flex;flex-direction:row;justify-content:center;list-style:none;margin:0;padding:", _ref4 => {
36
+ let {
37
+ theme
38
+ } = _ref4;
39
+ return theme.space['3'];
40
+ }, " 0;");
41
+ const SideItem = /*#__PURE__*/_styled("li", {
42
+ target: "e1p62vjs0"
43
+ })(process.env.NODE_ENV === "production" ? {
44
+ name: "wpiop9",
45
+ styles: "display:flex;padding:12px 0;min-width:158px"
46
+ } : {
47
+ name: "wpiop9",
48
+ styles: "display:flex;padding:12px 0;min-width:158px",
49
+ toString: _EMOTION_STRINGIFIED_CSS_ERROR__
50
+ });
51
+ const OverlayComponent = _ref5 => {
52
+ let {
53
+ children,
54
+ inView = false,
55
+ discount = 1,
56
+ OverlayRight,
57
+ disableOverlayRight = false,
58
+ OverlayLeft,
59
+ disableOverlayLeft = false,
60
+ totalPrice,
61
+ unit = 'hours',
62
+ isBeta = false
63
+ } = _ref5;
64
+ const {
65
+ locales,
66
+ formatNumber
67
+ } = useEstimateCost();
68
+ const value = useMemo(() => ({
69
+ isOverlay: true
70
+ }), []);
71
+ const list = flattenChildren(children);
72
+ const totalOverlayPrice = {
73
+ days: totalPrice.maxOverlayHourly * multiplier.days,
74
+ hours: totalPrice.maxOverlayHourly,
75
+ minutes: totalPrice.maxOverlayHourly * multiplier.minutes,
76
+ seconds: totalPrice.maxOverlayHourly * multiplier.seconds,
77
+ months: totalPrice.maxOverlayHourly * multiplier.months
78
+ }[unit];
79
+ const overlayPrice = {
80
+ days: totalPrice.overlayHourly * multiplier.days,
81
+ hours: totalPrice.overlayHourly,
82
+ minutes: totalPrice.overlayHourly * multiplier.minutes,
83
+ seconds: totalPrice.overlayHourly * multiplier.seconds,
84
+ months: totalPrice.overlayHourly * multiplier.months
85
+ }[unit];
86
+ return jsx(OverlayContextProvider, {
87
+ value: value,
88
+ children: jsx(OverlayContainer, {
89
+ inView: inView,
90
+ "data-testid": "summary-overlay",
91
+ children: jsxs(List, {
92
+ children: [OverlayLeft ? jsx(SideItem, {
93
+ children: jsx(OverlayLeft, {
94
+ disabled: disableOverlayLeft,
95
+ children: locales['estimate.cost.submit.label']
96
+ })
97
+ }) : null, Children.map(list, (child, index) => /*#__PURE__*/isValidElement(child) ? /*#__PURE__*/cloneElement(child, {
98
+ isFirstElement: index === 0,
99
+ isLastElement: index === list.length - 1
100
+ }) : null), jsxs(OverlayRow, {
101
+ children: [jsxs(Stack, {
102
+ direction: "row",
103
+ alignItems: "center",
104
+ gap: 1,
105
+ children: [jsx(Icon, {
106
+ name: "calculator",
107
+ color: "primary",
108
+ size: 20
109
+ }), locales['estimate.cost.label']]
110
+ }), jsxs(ItemResourceName, {
111
+ animated: false,
112
+ children: [jsx(Strong, {
113
+ variant: "big",
114
+ children: jsxs(LineThrough, {
115
+ isActive: isBeta && discount === 0,
116
+ children: [formatNumber(overlayPrice, {
117
+ maximumFractionDigits: maximumFractionDigits[unit]
118
+ }), totalOverlayPrice > 0 ? ` - ${formatNumber(totalOverlayPrice, {
119
+ maximumFractionDigits: maximumFractionDigits[unit]
120
+ })}` : null, "/", locales[`estimate.cost.units.${unit}.label`]]
121
+ })
122
+ }), isBeta ? jsx(StyledBadge, {
123
+ prominence: "strong",
124
+ sentiment: "warning",
125
+ children: locales[`estimate.cost.beta.${discount > 0 ? 'discount' : 'free'}`]
126
+ }) : null]
127
+ })]
128
+ }), OverlayRight ? jsx(SideItem, {
129
+ children: jsx(OverlayRight, {
130
+ disabled: disableOverlayRight,
131
+ children: locales['estimate.cost.submit.label']
132
+ })
133
+ }) : null]
134
+ })
135
+ })
136
+ });
137
+ };
138
+
139
+ export { OverlayComponent };
@@ -0,0 +1,19 @@
1
+ import { useContext, createContext } from 'react';
2
+ import { jsx } from '@emotion/react/jsx-runtime';
3
+
4
+ const OverlayContext = /*#__PURE__*/createContext({
5
+ isOverlay: false
6
+ });
7
+ const useOverlay = () => useContext(OverlayContext);
8
+ const OverlayContextProvider = _ref => {
9
+ let {
10
+ children,
11
+ value
12
+ } = _ref;
13
+ return jsx(OverlayContext.Provider, {
14
+ value: value,
15
+ children: children
16
+ });
17
+ };
18
+
19
+ export { OverlayContextProvider, useOverlay };