@janbox/storefront-ui 4.0.6 → 4.0.8

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 (84) hide show
  1. package/dist/components/scroll-view.d.ts +3 -2
  2. package/dist/components/scroll-view.js +5 -3
  3. package/dist/components/virtualized-list.d.ts +3 -3
  4. package/dist/lib/accordion/accordion-content/accordion-content.js +1 -1
  5. package/dist/lib/button/button.js +2 -2
  6. package/dist/lib/cascader/cascader-floating-content.d.ts +1 -1
  7. package/dist/lib/cascader/cascader-floating-content.js +52 -73
  8. package/dist/lib/cascader/cascader.d.ts +1 -1
  9. package/dist/lib/cascader/cascader.js +10 -12
  10. package/dist/lib/collapse/collapse.d.ts +1 -1
  11. package/dist/lib/collapse/collapse.js +12 -4
  12. package/dist/lib/collapse/types.d.ts +3 -3
  13. package/dist/lib/count-up/README.md +22 -0
  14. package/dist/lib/count-up/count-up.d.ts +1 -1
  15. package/dist/lib/count-up/count-up.js +22 -5
  16. package/dist/lib/count-up/types.d.ts +9 -3
  17. package/dist/lib/date-picker/date-picker.js +25 -10
  18. package/dist/lib/dialog/dialog/dialog.d.ts +1 -1
  19. package/dist/lib/dialog/dialog/dialog.js +25 -28
  20. package/dist/lib/dialog/dialog-body/dialog-body.d.ts +1 -1
  21. package/dist/lib/dialog/dialog-body/dialog-body.js +10 -11
  22. package/dist/lib/dialog/dialog-body/types.d.ts +2 -3
  23. package/dist/lib/dialog/dialog-close/dialog-close.d.ts +1 -1
  24. package/dist/lib/dialog/dialog-footer/dialog-footer.js +2 -3
  25. package/dist/lib/dialog/dialog-header/dialog-header.d.ts +1 -1
  26. package/dist/lib/dialog/dialog-header/dialog-header.js +24 -27
  27. package/dist/lib/drawer/drawer/drawer.d.ts +1 -1
  28. package/dist/lib/drawer/drawer/drawer.js +39 -26
  29. package/dist/lib/drawer/drawer-close/drawer-close.d.ts +1 -1
  30. package/dist/lib/filter-panel/checkbox-filter-panel.d.ts +1 -1
  31. package/dist/lib/filter-panel/checkbox-filter-panel.js +2 -2
  32. package/dist/lib/filter-panel/filter-panel.d.ts +1 -1
  33. package/dist/lib/filter-panel/filter-panel.js +30 -15
  34. package/dist/lib/filter-panel/radio-filter-panel.d.ts +1 -1
  35. package/dist/lib/filter-panel/radio-filter-panel.js +3 -3
  36. package/dist/lib/floating/floating-close/floating-close.d.ts +1 -1
  37. package/dist/lib/floating/floating-close/floating-close.js +3 -2
  38. package/dist/lib/floating/floating-content/floating-content.d.ts +1 -1
  39. package/dist/lib/floating/floating-content/floating-content.js +8 -6
  40. package/dist/lib/form-label/form-label.d.ts +4 -3
  41. package/dist/lib/form-label/form-label.js +10 -8
  42. package/dist/lib/highlight-words/highlight-words.d.ts +1 -1
  43. package/dist/lib/highlight-words/highlight-words.js +3 -2
  44. package/dist/lib/input/input.js +1 -3
  45. package/dist/lib/lightbox/lightbox.d.ts +1 -1
  46. package/dist/lib/lightbox/lightbox.js +44 -32
  47. package/dist/lib/linear-progress/linear-progress.d.ts +1 -1
  48. package/dist/lib/linear-progress/linear-progress.js +50 -51
  49. package/dist/lib/loading/image-skeleton/image-skeleton.d.ts +1 -1
  50. package/dist/lib/loading/image-skeleton/image-skeleton.js +9 -4
  51. package/dist/lib/loading/loading-overlay/loading-overlay.d.ts +1 -1
  52. package/dist/lib/loading/loading-overlay/loading-overlay.js +2 -2
  53. package/dist/lib/menu/menu-item/menu-item.d.ts +1 -1
  54. package/dist/lib/menu/menu-item/menu-item.js +2 -2
  55. package/dist/lib/multiple-select/multiple-select.d.ts +1 -1
  56. package/dist/lib/multiple-select/multiple-select.js +38 -39
  57. package/dist/lib/notifications/notifications.d.ts +1 -1
  58. package/dist/lib/notifications/notifications.js +7 -7
  59. package/dist/lib/otp-input/otp-input.d.ts +1 -1
  60. package/dist/lib/otp-input/otp-input.js +43 -30
  61. package/dist/lib/pagination/pagination.d.ts +1 -1
  62. package/dist/lib/pagination/pagination.js +60 -54
  63. package/dist/lib/phone-input/phone-input.js +12 -11
  64. package/dist/lib/popover/popover-close/popover-close.d.ts +1 -1
  65. package/dist/lib/progress/progress.d.ts +1 -1
  66. package/dist/lib/progress/progress.js +26 -29
  67. package/dist/lib/progress/types.d.ts +5 -4
  68. package/dist/lib/select/select.js +15 -11
  69. package/dist/lib/star-rating/README.md +11 -3
  70. package/dist/lib/star-rating/star-rating.d.ts +1 -1
  71. package/dist/lib/star-rating/star-rating.js +40 -28
  72. package/dist/lib/star-rating/types.d.ts +3 -4
  73. package/dist/lib/stepper/step.js +8 -6
  74. package/dist/lib/stepper/stepper.d.ts +1 -1
  75. package/dist/lib/stepper/stepper.js +10 -9
  76. package/dist/lib/stepper/types.d.ts +2 -1
  77. package/dist/lib/swiper/swiper/swiper.js +3 -3
  78. package/dist/lib/swiper/swiper-dots-paging/swiper-dots-paging.d.ts +1 -1
  79. package/dist/lib/swiper/swiper-dots-paging/swiper-dots-paging.js +8 -7
  80. package/dist/lib/tabs/tab-indicator/tab-indicator.js +1 -1
  81. package/dist/lib/tabs/tabs/tabs.d.ts +1 -1
  82. package/dist/lib/tabs/tabs/tabs.js +1 -1
  83. package/dist/lib/time-picker/time-picker.js +16 -22
  84. package/package.json +1 -1
@@ -1,4 +1,5 @@
1
+ import { PropsWithSx } from '../types';
1
2
  import { OverlayScrollbarsComponentProps, OverlayScrollbarsComponentRef } from 'overlayscrollbars-react';
2
- export type ScrollViewProps = OverlayScrollbarsComponentProps;
3
+ export type ScrollViewProps = PropsWithSx<OverlayScrollbarsComponentProps>;
3
4
  export type ScrollViewRef = OverlayScrollbarsComponentRef;
4
- export declare const ScrollView: ({ children, options, ...props }: ScrollViewProps) => import("react/jsx-runtime").JSX.Element;
5
+ export declare const ScrollView: ({ children, options, sx, ...props }: ScrollViewProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,7 +1,8 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { OverlayScrollbarsComponent } from "overlayscrollbars-react";
3
- const ScrollView = ({ children, options, ...props }) => {
4
- return /* @__PURE__ */ jsx(
3
+ import { Stylesheet } from "../lib/stylesheet/stylesheet.js";
4
+ const ScrollView = ({ children, options, sx, ...props }) => {
5
+ return /* @__PURE__ */ jsx(Stylesheet, { children: ({ cx, css }) => /* @__PURE__ */ jsx(
5
6
  OverlayScrollbarsComponent,
6
7
  {
7
8
  options: options ?? {
@@ -10,9 +11,10 @@ const ScrollView = ({ children, options, ...props }) => {
10
11
  }
11
12
  },
12
13
  ...props,
14
+ className: cx(css(sx), props.className),
13
15
  children
14
16
  }
15
- );
17
+ ) });
16
18
  };
17
19
  export {
18
20
  ScrollView
@@ -1,14 +1,14 @@
1
1
  import { JSX, Ref } from 'react';
2
2
  import { useVirtualizer, VirtualItem } from '@tanstack/react-virtual';
3
3
  import { ScrollViewRef } from './scroll-view';
4
- import { ShallowMerge } from '../types';
4
+ import { PropsWithSx, ShallowMerge } from '../types';
5
5
  type VirtualizedListOptions = Omit<Parameters<typeof useVirtualizer<HTMLDivElement, HTMLDivElement>>[0], 'getScrollElement'>;
6
- type VirtualizedListProps = ShallowMerge<JSX.IntrinsicElements['div'], {
6
+ type VirtualizedListProps = PropsWithSx<ShallowMerge<JSX.IntrinsicElements['div'], {
7
7
  RowComponent: React.ComponentType<{
8
8
  row: VirtualItem;
9
9
  }>;
10
10
  options: VirtualizedListOptions;
11
11
  ref?: Ref<ScrollViewRef>;
12
- }>;
12
+ }>>;
13
13
  export type { VirtualItem, VirtualizedListProps, VirtualizedListOptions };
14
14
  export declare const VirtualizedList: ({ RowComponent, options, ref, ...props }: VirtualizedListProps) => import("react/jsx-runtime").JSX.Element;
@@ -3,8 +3,8 @@ import { useRef } from "react";
3
3
  import { motion } from "motion/react";
4
4
  import { getAccordionContentProps } from "./helpers.js";
5
5
  import { useAccordionContext } from "../accordion/helpers.js";
6
- import { Stylesheet } from "../../stylesheet/stylesheet.js";
7
6
  import { useAccordionGroupContext } from "../accordion-group/helpers.js";
7
+ import { Stylesheet } from "../../stylesheet/stylesheet.js";
8
8
  import { Primitive } from "../../primitive/primitive.js";
9
9
  const AccordionContent = ({ children, ref, ..._props }) => {
10
10
  const { accordionContentProps: accordionContentPropsByGroup = {} } = useAccordionGroupContext();
@@ -163,7 +163,7 @@ const Button = ({ children, ref, ..._props }) => {
163
163
  }
164
164
  }
165
165
  ),
166
- /* @__PURE__ */ jsx(Fragment, { children: isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { dangerouslySetInnerHTML, css: truncateStyle, children }) }),
166
+ /* @__PURE__ */ jsx(Fragment, { children: isValidElement(children) ? children : /* @__PURE__ */ jsx(Primitive, { as: "span", dangerouslySetInnerHTML, sx: truncateStyle, children }) }),
167
167
  !!endIcon && /* @__PURE__ */ jsx(
168
168
  Icon,
169
169
  {
@@ -200,7 +200,7 @@ const Button = ({ children, ref, ..._props }) => {
200
200
  justifyContent: "center"
201
201
  },
202
202
  as: "span",
203
- children: /* @__PURE__ */ jsx(Icon, { css: animateSpinStyle, source: LoadingIcon })
203
+ children: /* @__PURE__ */ jsx(Icon, { sx: animateSpinStyle, source: LoadingIcon })
204
204
  }
205
205
  ),
206
206
  /* @__PURE__ */ jsx(RippleEffect, {})
@@ -15,5 +15,5 @@ type CascaderFloatingContentProps = {
15
15
  } & ToResponsiveProps<{
16
16
  size?: SizeVariant;
17
17
  }>;
18
- export declare const CascaderFloatingContent: ({ searchable, selectedPath, options, loadOptions, onChange, inputProps, listProps, separator, lazy, size, sm, md, lg, }: CascaderFloatingContentProps) => import("@emotion/react/jsx-runtime").JSX.Element;
18
+ export declare const CascaderFloatingContent: ({ searchable, selectedPath, options, loadOptions, onChange, inputProps, listProps, separator, lazy, size, sm, md, lg, }: CascaderFloatingContentProps) => import("react/jsx-runtime").JSX.Element;
19
19
  export {};
@@ -1,4 +1,4 @@
1
- import { jsxs, jsx, Fragment } from "@emotion/react/jsx-runtime";
1
+ import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
2
  import { useRef, useId, useState, useEffect, useMemo, useCallback } from "react";
3
3
  import { isString, isNil, trimStart } from "lodash-es";
4
4
  import { findOptionPath, isExpandable, hasChildren } from "./helpers.js";
@@ -14,6 +14,7 @@ import { getColorVar } from "../../theme/palette.js";
14
14
  import { getTypographyVar } from "../../theme/typography.js";
15
15
  import { useFloatingContext } from "../floating/floating/helpers.js";
16
16
  import { ensureArray, matchSearch } from "../../utils/common.js";
17
+ import { Primitive } from "../primitive/primitive.js";
17
18
  import { Input } from "../input/input.js";
18
19
  import { TextSkeleton } from "../loading/text-skeleton/text-skeleton.js";
19
20
  const DEFAULT_DISPLAY_ROW_COUNT = 5;
@@ -189,28 +190,27 @@ const CascaderFloatingContent = ({
189
190
  const renderBreadcrumbs = () => {
190
191
  if (expandedPath.length === 0) return null;
191
192
  return /* @__PURE__ */ jsxs(
192
- "div",
193
+ Primitive,
193
194
  {
194
- css: {
195
+ sx: {
195
196
  paddingLeft: inputPaddingX,
196
197
  paddingRight: inputPaddingX,
197
198
  minHeight: rowMinHeight,
198
199
  borderTop: `1px solid ${getColorVar("neutral.200")}`,
199
200
  display: "flex",
200
201
  alignItems: "center",
201
- gap: "0.25rem",
202
+ gap: 4,
202
203
  flexWrap: "wrap",
203
- paddingTop: "0.25rem",
204
- paddingBottom: "0.25rem"
204
+ paddingBlock: 4
205
205
  },
206
206
  children: [
207
207
  /* @__PURE__ */ jsx(
208
- "button",
208
+ Primitive,
209
209
  {
210
210
  "data-index": -1,
211
- type: "button",
211
+ role: "button",
212
212
  onClick: handleBreadcrumbClick,
213
- css: {
213
+ sx: {
214
214
  color: getColorVar("neutral.500"),
215
215
  transition: "color 150ms",
216
216
  ":hover": { color: getColorVar("primary.600") }
@@ -218,31 +218,24 @@ const CascaderFloatingContent = ({
218
218
  children: "All"
219
219
  }
220
220
  ),
221
- expandedOptions.map((opt, idx) => /* @__PURE__ */ jsxs(
222
- "div",
223
- {
224
- css: { display: "flex", alignItems: "center", gap: "0.25rem" },
225
- children: [
226
- /* @__PURE__ */ jsx("span", { css: { color: getColorVar("neutral.400") }, children: separator }),
227
- /* @__PURE__ */ jsx(
228
- "button",
229
- {
230
- "data-index": idx,
231
- type: "button",
232
- onClick: handleBreadcrumbClick,
233
- css: {
234
- color: idx === expandedOptions.length - 1 ? getColorVar("primary.600") : getColorVar("neutral.600"),
235
- fontWeight: idx === expandedOptions.length - 1 ? 500 : void 0,
236
- transition: "color 150ms",
237
- ":hover": { color: getColorVar("primary.600") }
238
- },
239
- children: opt.breadcrumbLabel ?? opt.label
240
- }
241
- )
242
- ]
243
- },
244
- `${uniqueId}-breadcrumb-${opt.value}`
245
- ))
221
+ expandedOptions.map((opt, idx) => /* @__PURE__ */ jsxs(Primitive, { sx: { display: "flex", alignItems: "center", gap: 4 }, children: [
222
+ /* @__PURE__ */ jsx(Primitive, { as: "span", sx: { color: getColorVar("neutral.400") }, children: separator }),
223
+ /* @__PURE__ */ jsx(
224
+ Primitive,
225
+ {
226
+ "data-index": idx,
227
+ role: "button",
228
+ onClick: handleBreadcrumbClick,
229
+ sx: {
230
+ color: idx === expandedOptions.length - 1 ? getColorVar("primary.600") : getColorVar("neutral.600"),
231
+ fontWeight: idx === expandedOptions.length - 1 ? 500 : void 0,
232
+ transition: "color 150ms",
233
+ ":hover": { color: getColorVar("primary.600") }
234
+ },
235
+ children: opt.breadcrumbLabel ?? opt.label
236
+ }
237
+ )
238
+ ] }, `${uniqueId}-breadcrumb-${opt.value}`))
246
239
  ]
247
240
  }
248
241
  );
@@ -292,21 +285,20 @@ const CascaderFloatingContent = ({
292
285
  });
293
286
  };
294
287
  return /* @__PURE__ */ jsx(
295
- "div",
288
+ Primitive,
296
289
  {
297
290
  "aria-hidden": true,
298
291
  role: "button",
299
292
  onClick: handleSelect,
300
- css: {
293
+ sx: {
301
294
  minHeight: rowMinHeight,
302
295
  paddingLeft: inputPaddingX,
303
296
  paddingRight: inputPaddingX,
304
- paddingTop: "0.25rem",
305
- paddingBottom: "0.25rem",
297
+ paddingBlock: 4,
306
298
  display: "flex",
307
299
  alignItems: "center",
308
- gap: "0.5rem",
309
- borderRadius: "0.5rem",
300
+ gap: 8,
301
+ borderRadius: 8,
310
302
  transition: "background-color 150ms, color 150ms",
311
303
  "&:hover": { backgroundColor: getColorVar("neutral.100") },
312
304
  ...isSelected && !isExpandable(rowData) ? {
@@ -316,59 +308,46 @@ const CascaderFloatingContent = ({
316
308
  ...rowData.disabled ? { opacity: 0.5, cursor: "not-allowed" } : {}
317
309
  },
318
310
  children: isLoading ? /* @__PURE__ */ jsx(TextSkeleton, {}) : /* @__PURE__ */ jsxs(Fragment, { children: [
319
- /* @__PURE__ */ jsx("div", { css: { flex: 1, ...truncateStyle }, children: rowData.label }),
320
- isExpandable(rowData) ? /* @__PURE__ */ jsx(SvgLoader, { source: ArrowRightIcon, width: 20, height: 20, css: { color: getColorVar("neutral.400") } }) : isSelected && /* @__PURE__ */ jsx(SvgLoader, { source: CheckIcon, width: 20, height: 20, css: { color: getColorVar("primary.600") } })
311
+ /* @__PURE__ */ jsx(Primitive, { sx: { flex: 1, ...truncateStyle }, children: rowData.label }),
312
+ isExpandable(rowData) ? /* @__PURE__ */ jsx(SvgLoader, { source: ArrowRightIcon, width: 20, height: 20, sx: { color: getColorVar("neutral.400") } }) : isSelected && /* @__PURE__ */ jsx(SvgLoader, { source: CheckIcon, width: 20, height: 20, sx: { color: getColorVar("primary.600") } })
321
313
  ] })
322
314
  },
323
315
  `${uniqueId}-option-${rowData.value}`
324
316
  );
325
317
  };
326
318
  return /* @__PURE__ */ jsxs(
327
- "div",
319
+ Primitive,
328
320
  {
329
- css: {
330
- paddingTop: "0.5rem",
331
- paddingBottom: "0.5rem",
321
+ sx: {
322
+ paddingBlock: 8,
332
323
  border: `1px solid ${getColorVar("border.default")}`,
333
- borderRadius: "0.5rem",
324
+ borderRadius: 8,
334
325
  boxShadow: "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",
335
326
  fontSize: getTypographyVar("sm").fontSize,
336
327
  lineHeight: getTypographyVar("sm").lineHeight,
337
328
  backgroundColor: getColorVar("surface.default")
338
329
  },
339
330
  children: [
340
- !searchable && /* @__PURE__ */ jsx(
341
- "div",
331
+ !searchable && /* @__PURE__ */ jsx(Primitive, { sx: { padding: 8 }, children: /* @__PURE__ */ jsx(
332
+ Input,
342
333
  {
343
- css: {
344
- paddingLeft: "0.5rem",
345
- paddingRight: "0.5rem",
346
- paddingTop: "0.5rem",
347
- paddingBottom: "0.5rem"
348
- },
349
- children: /* @__PURE__ */ jsx(
350
- Input,
351
- {
352
- size,
353
- sm: { size: sm == null ? void 0 : sm.size },
354
- md: { size: md == null ? void 0 : md.size },
355
- lg: { size: lg == null ? void 0 : lg.size },
356
- value: inputValue,
357
- placeholder: "Search...",
358
- ...inputProps,
359
- onChange: onInputChange,
360
- ref: searchInputRef
361
- }
362
- )
334
+ size,
335
+ sm: { size: sm == null ? void 0 : sm.size },
336
+ md: { size: md == null ? void 0 : md.size },
337
+ lg: { size: lg == null ? void 0 : lg.size },
338
+ value: inputValue,
339
+ placeholder: "Search...",
340
+ ...inputProps,
341
+ onChange: onInputChange,
342
+ ref: searchInputRef
363
343
  }
364
- ),
344
+ ) }),
365
345
  /* @__PURE__ */ jsx(
366
346
  VirtualizedList,
367
347
  {
368
348
  ...listProps,
369
- css: {
370
- paddingLeft: 4,
371
- paddingRight: 4,
349
+ sx: {
350
+ paddingInline: 4,
372
351
  ...isLoading ? { cursor: "wait", pointerEvents: "none" } : {}
373
352
  },
374
353
  options: {
@@ -1,2 +1,2 @@
1
1
  import { CascaderProps } from './types';
2
- export declare const Cascader: ({ ref, ..._props }: CascaderProps) => import("@emotion/react/jsx-runtime").JSX.Element;
2
+ export declare const Cascader: ({ ref, ..._props }: CascaderProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,4 +1,4 @@
1
- import { jsxs, jsx } from "@emotion/react/jsx-runtime";
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
2
  import { useRef } from "react";
3
3
  import { isNil } from "lodash-es";
4
4
  import { CascaderFloatingContent } from "./cascader-floating-content.js";
@@ -111,7 +111,7 @@ const Cascader = ({ ref, ..._props }) => {
111
111
  source: ArrowDownIcon,
112
112
  width: 20,
113
113
  height: 20,
114
- css: {
114
+ sx: {
115
115
  transition: "transform 150ms",
116
116
  ...isOpen ? { transform: "rotate(-180deg)" } : {}
117
117
  }
@@ -120,17 +120,15 @@ const Cascader = ({ ref, ..._props }) => {
120
120
  ...rest,
121
121
  ref,
122
122
  children: /* @__PURE__ */ jsx(
123
- "div",
123
+ Primitive,
124
124
  {
125
- css: [
126
- {
127
- flex: 1,
128
- textAlign: "left",
129
- ...truncateStyle
130
- },
131
- getTextCss(rest == null ? void 0 : rest.size)
132
- ],
133
- children: selectedPath.length > 0 ? /* @__PURE__ */ jsx("div", { children: valueRenderer ?? selectedPath.join(" / ") }) : /* @__PURE__ */ jsx("div", { css: { color: getColorVar("neutral.400") }, children: placeholder })
125
+ sx: {
126
+ flex: 1,
127
+ textAlign: "left",
128
+ ...truncateStyle,
129
+ ...getTextCss(rest == null ? void 0 : rest.size)
130
+ },
131
+ children: selectedPath.length > 0 ? /* @__PURE__ */ jsx("div", { children: valueRenderer ?? selectedPath.join(" / ") }) : /* @__PURE__ */ jsx(Primitive, { sx: { color: getColorVar("neutral.400") }, children: placeholder })
134
132
  }
135
133
  )
136
134
  }
@@ -1,2 +1,2 @@
1
1
  import { CollapseProps } from './types';
2
- export declare const Collapse: ({ children, open, collapsedSize, orientation, ...props }: CollapseProps) => import("@emotion/react/jsx-runtime").JSX.Element;
2
+ export declare const Collapse: ({ children, open, collapsedSize, orientation, sx, ...props }: CollapseProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,11 +1,13 @@
1
- import { jsx } from "@emotion/react/jsx-runtime";
1
+ import { jsx } from "react/jsx-runtime";
2
2
  import { useState, useMemo } from "react";
3
3
  import { motion } from "motion/react";
4
+ import { Stylesheet } from "../stylesheet/stylesheet.js";
4
5
  const Collapse = ({
5
6
  children,
6
7
  open = true,
7
8
  collapsedSize = 0,
8
9
  orientation = "vertical",
10
+ sx,
9
11
  ...props
10
12
  }) => {
11
13
  const [initial] = useState(() => {
@@ -30,17 +32,23 @@ const Collapse = ({
30
32
  }
31
33
  return css;
32
34
  }, [collapsedSize, open, orientation]);
33
- return /* @__PURE__ */ jsx(
35
+ return /* @__PURE__ */ jsx(Stylesheet, { children: ({ cx, css }) => /* @__PURE__ */ jsx(
34
36
  motion.div,
35
37
  {
36
- css: { overflow: "hidden" },
37
38
  animate,
38
39
  initial,
39
40
  ...props,
40
41
  transition: { duration: 0.15, ...props.transition },
42
+ className: cx(
43
+ css({
44
+ overflow: "hidden",
45
+ ...sx
46
+ }),
47
+ props.className
48
+ ),
41
49
  children
42
50
  }
43
- );
51
+ ) });
44
52
  };
45
53
  export {
46
54
  Collapse
@@ -1,7 +1,7 @@
1
1
  import { HTMLMotionProps } from 'motion/react';
2
- import { ShallowMerge } from '../../types';
3
- export type CollapseProps = ShallowMerge<HTMLMotionProps<'div'>, {
2
+ import { PropsWithSx, ShallowMerge } from '../../types';
3
+ export type CollapseProps = PropsWithSx<ShallowMerge<HTMLMotionProps<'div'>, {
4
4
  open?: boolean;
5
5
  collapsedSize?: number;
6
6
  orientation?: 'horizontal' | 'vertical';
7
- }>;
7
+ }>>;
@@ -16,6 +16,10 @@ import { CountUp } from '@janbox/storefront-ui';
16
16
  | `from` | `number` | 0 | Số bắt đầu đếm |
17
17
  | `duration` | `number` | 2 | Thời gian animation tính bằng giây |
18
18
  | `formatNumberOptions` | `FormatNumberOptions` | - | Tùy chọn format số (mở rộng từ `Intl.NumberFormatOptions` với thuộc tính `locale`). Kiểm soát số chữ số thập phân, format tiền tệ và các tùy chọn hiển thị số theo locale |
19
+ | `startOnView` | `boolean` | `true` | Chỉ chạy animation khi component cuộn vào viewport. Đặt `false` để chạy animation ngay khi mount |
20
+ | `prefix` | `React.ReactNode` | - | Nội dung hiển thị trước số |
21
+ | `suffix` | `React.ReactNode` | - | Nội dung hiển thị sau số |
22
+ | `sx` | `ToResponsiveProps<StyledCSS>` | - | Custom style responsive (hỗ trợ `sm`, `md`, `lg`) |
19
23
  | `ref` | `React.Ref<HTMLSpanElement>` | - | Ref tới phần tử span bên dưới |
20
24
 
21
25
  *Prop bắt buộc
@@ -40,6 +44,24 @@ import { CountUp } from '@janbox/storefront-ui';
40
44
  <CountUp from={0} to={99.99} duration={5} style={{ fontSize: 32, fontWeight: 'bold' }} />
41
45
  ```
42
46
 
47
+ ### Chạy animation ngay khi mount (không đợi viewport)
48
+
49
+ ```tsx
50
+ <CountUp to={1000} startOnView={false} style={{ fontSize: 32 }} />
51
+ ```
52
+
53
+ ### Custom style responsive với `sx`
54
+
55
+ ```tsx
56
+ <CountUp to={1000} sx={{ fontSize: 24, fontWeight: 700, md: { fontSize: 40 } }} />
57
+ ```
58
+
59
+ ### Prefix và suffix
60
+
61
+ ```tsx
62
+ <CountUp to={1000} prefix="$" suffix="+" style={{ fontSize: 32 }} />
63
+ ```
64
+
43
65
  ## Dependencies
44
66
 
45
67
  - motion/react
@@ -1,2 +1,2 @@
1
1
  import { CountUpProps } from './types';
2
- export declare const CountUp: ({ from, to, duration, formatNumberOptions, ref, ...props }: CountUpProps) => import("react/jsx-runtime").JSX.Element;
2
+ export declare const CountUp: ({ from, to, duration, formatNumberOptions, startOnView, sx, className, prefix, suffix, ref, ...props }: CountUpProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,11 +1,24 @@
1
- import { jsx } from "react/jsx-runtime";
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { useRef, useEffect } from "react";
3
3
  import { useMergeRefs } from "@floating-ui/react";
4
4
  import { useMotionValue, useInView, useTransform, animate, motion } from "motion/react";
5
5
  import { formatNumber } from "../../utils/index.js";
6
6
  import { useTranslation } from "../../i18n/index.js";
7
7
  import { getDecimalDigits } from "../../utils/common.js";
8
- const CountUp = ({ from = 0, to, duration = 2, formatNumberOptions, ref, ...props }) => {
8
+ import { Stylesheet } from "../stylesheet/stylesheet.js";
9
+ const CountUp = ({
10
+ from = 0,
11
+ to,
12
+ duration = 2,
13
+ formatNumberOptions,
14
+ startOnView = true,
15
+ sx,
16
+ className,
17
+ prefix,
18
+ suffix,
19
+ ref,
20
+ ...props
21
+ }) => {
9
22
  const rootRef = useRef(null);
10
23
  const { locale } = useTranslation();
11
24
  const mergedRef = useMergeRefs([ref, rootRef]);
@@ -21,13 +34,17 @@ const CountUp = ({ from = 0, to, duration = 2, formatNumberOptions, ref, ...prop
21
34
  })
22
35
  );
23
36
  useEffect(() => {
24
- if (!isInView) return;
37
+ if (startOnView && !isInView) return;
25
38
  const controls = animate(count, to, { duration });
26
39
  return () => {
27
40
  controls.stop();
28
41
  };
29
- }, [count, duration, isInView, to]);
30
- return /* @__PURE__ */ jsx(motion.span, { ...props, ref: mergedRef, children: rounded });
42
+ }, [count, duration, isInView, startOnView, to]);
43
+ return /* @__PURE__ */ jsx(Stylesheet, { children: ({ cx, css }) => /* @__PURE__ */ jsxs(motion.span, { ...props, className: cx(className, css(sx)), ref: mergedRef, children: [
44
+ prefix,
45
+ /* @__PURE__ */ jsx(motion.span, { children: rounded }),
46
+ suffix
47
+ ] }) });
31
48
  };
32
49
  export {
33
50
  CountUp
@@ -1,9 +1,15 @@
1
1
  import { HTMLMotionProps } from 'motion/react';
2
2
  import { FormatNumberOptions } from '../../utils';
3
- import { ShallowMerge } from '../../types';
4
- export type CountUpProps = ShallowMerge<HTMLMotionProps<'span'>, {
3
+ import { PropsWithSx, ShallowMerge } from '../../types';
4
+ export type CountUpProps = PropsWithSx<ShallowMerge<HTMLMotionProps<'span'>, {
5
5
  from?: number;
6
6
  to: number;
7
7
  duration?: number;
8
8
  formatNumberOptions?: FormatNumberOptions;
9
- }>;
9
+ /** Chỉ chạy animation khi element cuộn vào viewport. Mặc định `true`. */
10
+ startOnView?: boolean;
11
+ /** Nội dung hiển thị trước số */
12
+ prefix?: React.ReactNode;
13
+ /** Nội dung hiển thị sau số */
14
+ suffix?: React.ReactNode;
15
+ }>>;
@@ -9,12 +9,14 @@ import { getSizeVariantState } from "../../utils/index.js";
9
9
  import { useControllableState } from "../../hooks/use-controllable-state.js";
10
10
  import "lodash-es";
11
11
  import { getColorVar } from "../../theme/palette.js";
12
+ import { getTypographyVar } from "../../theme/typography.js";
12
13
  import CloseIcon from "../../assets/svg/times-close-delete.svg.js";
13
14
  import { createSxInterpolation } from "../../utils/stylesheet.js";
14
15
  import { TimePicker } from "../time-picker/time-picker.js";
15
16
  import { Floating } from "../floating/floating/floating.js";
16
17
  import { FloatingTrigger } from "../floating/floating-trigger/floating-trigger.js";
17
18
  import { InputMask as ForwardRefInputMask } from "../input-mask/input-mask.js";
19
+ import { Primitive } from "../primitive/primitive.js";
18
20
  import { FloatingContent } from "../floating/floating-content/floating-content.js";
19
21
  import { FormHelperText } from "../form-helper-text/form-helper-text.js";
20
22
  import { Icon } from "../icon/icon.js";
@@ -80,9 +82,9 @@ const DatePicker = (_props, ref) => {
80
82
  onChange == null ? void 0 : onChange(preset);
81
83
  };
82
84
  const portalContentRenderer = () => /* @__PURE__ */ jsxs(
83
- "div",
85
+ Primitive,
84
86
  {
85
- css: {
87
+ sx: {
86
88
  display: "flex",
87
89
  flexDirection: "column",
88
90
  justifyContent: "center",
@@ -98,11 +100,24 @@ const DatePicker = (_props, ref) => {
98
100
  children: [
99
101
  /* @__PURE__ */ jsx(Calendar, { onChange: handleChange, minDate, maxDate, date: selectedDate ?? void 0 }),
100
102
  timePicker && /* @__PURE__ */ jsxs(
101
- "div",
103
+ Primitive,
102
104
  {
103
- css: { paddingLeft: 12, paddingRight: 12, paddingBottom: 12, display: "flex", alignItems: "center", gap: 8 },
105
+ sx: {
106
+ paddingInline: 12,
107
+ paddingBottom: 12,
108
+ display: "flex",
109
+ alignItems: "center",
110
+ gap: 8
111
+ },
104
112
  children: [
105
- /* @__PURE__ */ jsx("span", { css: { fontSize: "0.75rem", lineHeight: "1rem" }, children: "Time:" }),
113
+ /* @__PURE__ */ jsx(
114
+ Primitive,
115
+ {
116
+ as: "span",
117
+ sx: { fontSize: getTypographyVar("xs").fontSize, lineHeight: getTypographyVar("xs").lineHeight },
118
+ children: "Time:"
119
+ }
120
+ ),
106
121
  /* @__PURE__ */ jsx(
107
122
  TimePicker,
108
123
  {
@@ -134,7 +149,7 @@ const DatePicker = (_props, ref) => {
134
149
  Icon,
135
150
  {
136
151
  source: CloseIcon,
137
- sx: { color: rest.disabled ? "var(--ic-ink-4s)" : "var(--ic-ink-5s)" },
152
+ sx: { color: rest.disabled ? getColorVar("neutral.400") : getColorVar("neutral.500") },
138
153
  size: getSizeVariantState(size).iconSize,
139
154
  sm: {
140
155
  size: getSizeVariantState(sm == null ? void 0 : sm.size).iconSize
@@ -163,7 +178,7 @@ const DatePicker = (_props, ref) => {
163
178
  lg: {
164
179
  size: getSizeVariantState(lg == null ? void 0 : lg.size).iconSize
165
180
  },
166
- sx: { color: rest.disabled ? "var(--ic-ink-4s)" : "var(--ic-ink-5s)" }
181
+ sx: { color: rest.disabled ? getColorVar("neutral.400") : getColorVar("neutral.500") }
167
182
  }
168
183
  );
169
184
  };
@@ -206,11 +221,11 @@ const DatePicker = (_props, ref) => {
206
221
  ...rest,
207
222
  ref,
208
223
  children: /* @__PURE__ */ jsxs(
209
- "div",
224
+ Primitive,
210
225
  {
211
- css: { flex: 1, textAlign: "left", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" },
226
+ sx: { flex: 1, textAlign: "left", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" },
212
227
  children: [
213
- !selectedDate && !!placeholder && /* @__PURE__ */ jsx("span", { css: { color: getColorVar("neutral.400") }, children: placeholder }),
228
+ !selectedDate && !!placeholder && /* @__PURE__ */ jsx(Primitive, { as: "span", sx: { color: getColorVar("neutral.400") }, children: placeholder }),
214
229
  !!selectedDate && /* @__PURE__ */ jsx("span", { children: dayjs(selectedDate).format(valueFormat) })
215
230
  ]
216
231
  }
@@ -1,2 +1,2 @@
1
1
  import { DialogProps } from './types';
2
- export declare const Dialog: (_props: DialogProps) => import("@emotion/react/jsx-runtime").JSX.Element;
2
+ export declare const Dialog: (_props: DialogProps) => import("react/jsx-runtime").JSX.Element;