@janbox/storefront-ui 4.0.8 → 4.0.10

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.
@@ -1,6 +1,6 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import { OverlayScrollbarsComponent } from "overlayscrollbars-react";
3
2
  import { Stylesheet } from "../lib/stylesheet/stylesheet.js";
3
+ import { OverlayScrollbarsComponent } from "overlayscrollbars-react";
4
4
  const ScrollView = ({ children, options, sx, ...props }) => {
5
5
  return /* @__PURE__ */ jsx(Stylesheet, { children: ({ cx, css }) => /* @__PURE__ */ jsx(
6
6
  OverlayScrollbarsComponent,
package/dist/index.js CHANGED
@@ -115,6 +115,7 @@ import { getButtonCssBySize, getButtonProps } from "./lib/button/helpers.js";
115
115
  import { getCellProps } from "./lib/grid/cell/helpers.js";
116
116
  import { getChipProps, getChipSizeState } from "./lib/chip/helpers.js";
117
117
  import { getContainerProps } from "./lib/container/helpers.js";
118
+ import { getCountUpProps } from "./lib/count-up/helpers.js";
118
119
  import { getDatePickerProps } from "./lib/date-picker/helpers.js";
119
120
  import { getDialogProps, getDialogSizeInNumber, useDialogContext } from "./lib/dialog/dialog/helpers.js";
120
121
  import { getFlagProps } from "./lib/flag/helpers.js";
@@ -269,6 +270,7 @@ export {
269
270
  getChipProps,
270
271
  getChipSizeState,
271
272
  getContainerProps,
273
+ getCountUpProps,
272
274
  getDatePickerProps,
273
275
  getDialogProps,
274
276
  getDialogSizeInNumber,
@@ -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 { useAccordionGroupContext } from "../accordion-group/helpers.js";
7
6
  import { Stylesheet } from "../../stylesheet/stylesheet.js";
7
+ import { useAccordionGroupContext } from "../accordion-group/helpers.js";
8
8
  import { Primitive } from "../../primitive/primitive.js";
9
9
  const AccordionContent = ({ children, ref, ..._props }) => {
10
10
  const { accordionContentProps: accordionContentPropsByGroup = {} } = useAccordionGroupContext();
@@ -17,6 +17,7 @@ import { CountUp } from '@janbox/storefront-ui';
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
19
  | `startOnView` | `boolean` | `true` | Chỉ chạy animation khi component cuộn vào viewport. Đặt `false` để chạy animation ngay khi mount |
20
+ | `sizeVariant` | `TypographySizeVariant` | - | Typography size variant — điều khiển `fontSize` và `lineHeight` theo design token. Hỗ trợ responsive qua `sm`, `md`, `lg` (VD: `md={{ sizeVariant: '2xl' }}`) |
20
21
  | `prefix` | `React.ReactNode` | - | Nội dung hiển thị trước số |
21
22
  | `suffix` | `React.ReactNode` | - | Nội dung hiển thị sau số |
22
23
  | `sx` | `ToResponsiveProps<StyledCSS>` | - | Custom style responsive (hỗ trợ `sm`, `md`, `lg`) |
@@ -56,6 +57,13 @@ import { CountUp } from '@janbox/storefront-ui';
56
57
  <CountUp to={1000} sx={{ fontSize: 24, fontWeight: 700, md: { fontSize: 40 } }} />
57
58
  ```
58
59
 
60
+ ### Size variant responsive theo breakpoint
61
+
62
+ ```tsx
63
+ {/* base = lg, md trở lên = 2xl, lg trở lên = 4xl */}
64
+ <CountUp to={1000} sizeVariant="lg" md={{ sizeVariant: '2xl' }} lg={{ sizeVariant: '4xl' }} />
65
+ ```
66
+
59
67
  ### Prefix và suffix
60
68
 
61
69
  ```tsx
@@ -1,2 +1,2 @@
1
1
  import { CountUpProps } from './types';
2
- export declare const CountUp: ({ from, to, duration, formatNumberOptions, startOnView, sx, className, prefix, suffix, ref, ...props }: CountUpProps) => import("react/jsx-runtime").JSX.Element;
2
+ export declare const CountUp: ({ ref, ..._props }: CountUpProps) => import("react/jsx-runtime").JSX.Element;
@@ -4,21 +4,28 @@ 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
- import { getDecimalDigits } from "../../utils/common.js";
7
+ import "lodash-es";
8
+ import "../../theme/palette.js";
9
+ import { getTypographyVar } from "../../theme/typography.js";
8
10
  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
- }) => {
11
+ import { getCountUpProps } from "./helpers.js";
12
+ import { getDecimalDigits } from "../../utils/common.js";
13
+ const CountUp = ({ ref, ..._props }) => {
14
+ const {
15
+ from = 0,
16
+ to,
17
+ duration = 2,
18
+ formatNumberOptions,
19
+ startOnView,
20
+ sizeVariant,
21
+ sm,
22
+ md,
23
+ lg,
24
+ sx,
25
+ prefix,
26
+ suffix,
27
+ ...props
28
+ } = getCountUpProps(_props);
22
29
  const rootRef = useRef(null);
23
30
  const { locale } = useTranslation();
24
31
  const mergedRef = useMergeRefs([ref, rootRef]);
@@ -40,11 +47,34 @@ const CountUp = ({
40
47
  controls.stop();
41
48
  };
42
49
  }, [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
- ] }) });
50
+ return /* @__PURE__ */ jsx(Stylesheet, { children: ({ cx, css }) => /* @__PURE__ */ jsxs(
51
+ motion.span,
52
+ {
53
+ ...props,
54
+ className: cx(
55
+ css({
56
+ ...createStyle({ sizeVariant }),
57
+ ...sx,
58
+ sm: { ...createStyle(sm), ...sx == null ? void 0 : sx.sm },
59
+ md: { ...createStyle(md), ...sx == null ? void 0 : sx.md },
60
+ lg: { ...createStyle(lg), ...sx == null ? void 0 : sx.lg }
61
+ }),
62
+ props.className
63
+ ),
64
+ ref: mergedRef,
65
+ children: [
66
+ prefix,
67
+ /* @__PURE__ */ jsx(motion.span, { children: rounded }),
68
+ suffix
69
+ ]
70
+ }
71
+ ) });
72
+ };
73
+ const createStyle = ({ sizeVariant } = {}) => {
74
+ return sizeVariant ? {
75
+ fontSize: getTypographyVar(sizeVariant).fontSize,
76
+ lineHeight: getTypographyVar(sizeVariant).lineHeight
77
+ } : {};
48
78
  };
49
79
  export {
50
80
  CountUp
@@ -0,0 +1,2 @@
1
+ import { CountUpProps } from './types';
2
+ export declare const getCountUpProps: (extended: CountUpProps) => CountUpProps;
@@ -0,0 +1,12 @@
1
+ import { mergeComponentProps } from "../../utils/index.js";
2
+ const defaultProps = {
3
+ from: 0,
4
+ duration: 2,
5
+ startOnView: true
6
+ };
7
+ const getCountUpProps = (extended) => {
8
+ return mergeComponentProps(defaultProps, extended);
9
+ };
10
+ export {
11
+ getCountUpProps
12
+ };
@@ -1,2 +1,3 @@
1
- export * from './count-up';
2
- export * from './types';
1
+ export { CountUp } from './count-up';
2
+ export { type CountUpProps } from './types';
3
+ export { getCountUpProps } from './helpers';
@@ -1,7 +1,12 @@
1
1
  import { HTMLMotionProps } from 'motion/react';
2
2
  import { FormatNumberOptions } from '../../utils';
3
- import { PropsWithSx, ShallowMerge } from '../../types';
4
- export type CountUpProps = PropsWithSx<ShallowMerge<HTMLMotionProps<'span'>, {
3
+ import { TypographySizeVariant } from '../../theme';
4
+ import { PropsWithSx, ShallowMerge, ToResponsiveProps } from '../../types';
5
+ export interface CountUpResponsiveProps {
6
+ /** Typography size variant — điều khiển `fontSize` và `lineHeight`. */
7
+ sizeVariant?: TypographySizeVariant;
8
+ }
9
+ export type CountUpProps = PropsWithSx<ShallowMerge<HTMLMotionProps<'span'>, ToResponsiveProps<CountUpResponsiveProps> & {
5
10
  from?: number;
6
11
  to: number;
7
12
  duration?: number;
@@ -1,5 +1,5 @@
1
1
  import { default as React } from 'react';
2
2
  import { DatePickerProps } from './types';
3
- declare const DatePicker: (_props: DatePickerProps, ref?: React.ForwardedRef<HTMLButtonElement>) => import("@emotion/react/jsx-runtime").JSX.Element;
3
+ declare const DatePicker: (_props: DatePickerProps, ref?: React.ForwardedRef<HTMLDivElement>) => import("@emotion/react/jsx-runtime").JSX.Element;
4
4
  declare const ForwardRefDatePicker: typeof DatePicker;
5
5
  export { ForwardRefDatePicker as DatePicker };
@@ -214,9 +214,8 @@ const DatePicker = (_props, ref) => {
214
214
  /* @__PURE__ */ jsx(FloatingTrigger, { children: /* @__PURE__ */ jsx(
215
215
  ForwardRefInputMask,
216
216
  {
217
- type: "button",
218
217
  error: isOpen ? false : error,
219
- as: "button",
218
+ role: "button",
220
219
  suffix: getSuffix(),
221
220
  ...rest,
222
221
  ref,
@@ -1,4 +1,4 @@
1
- import { JSX } from 'react';
1
+ import { JSX, Ref } from 'react';
2
2
  import { Placement, UseFloatingOptions } from '@floating-ui/react';
3
3
  import { InputRange } from 'react-date-range';
4
4
  import { PropsWithSx, SizeVariant, ToResponsiveProps } from '../../types';
@@ -30,6 +30,7 @@ type DatePickerBaseProps = {
30
30
  error?: boolean;
31
31
  helperText?: string;
32
32
  disabled?: boolean;
33
+ ref?: Ref<HTMLDivElement>;
33
34
  };
34
35
  export type DatePickerProps = PropsWithSx<DatePickerBaseProps & ToResponsiveProps<DateResponsiveProps>>;
35
36
  export {};
@@ -2,10 +2,10 @@ import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { useMemo } from "react";
3
3
  import { motion } from "motion/react";
4
4
  import { FLOATING_Z_INDEX } from "../../../theme/index.js";
5
+ import { Stylesheet } from "../../stylesheet/stylesheet.js";
5
6
  import { Floating } from "../../floating/floating/floating.js";
6
7
  import { FloatingContent } from "../../floating/floating-content/floating-content.js";
7
8
  import { Primitive } from "../../primitive/primitive.js";
8
- import { Stylesheet } from "../../stylesheet/stylesheet.js";
9
9
  const Drawer = ({ children, placement = "left", ...props }) => {
10
10
  const initial = useMemo(() => {
11
11
  switch (placement) {
@@ -4,8 +4,8 @@ import { AnimatePresence, motion } from "motion/react";
4
4
  import { useFloatingContext } from "../floating/helpers.js";
5
5
  import { FLOATING_Z_INDEX } from "../../../theme/index.js";
6
6
  import { useIsHydrated } from "../../../hooks/use-is-hydrated/index.js";
7
- import { usePortalContainer } from "../../../theme/provider.js";
8
7
  import { Stylesheet } from "../../stylesheet/stylesheet.js";
8
+ import { usePortalContainer } from "../../../theme/provider.js";
9
9
  const FloatingContent = ({
10
10
  style,
11
11
  floatingPortalProps,
@@ -10,12 +10,12 @@ import ZoomPlusIcon from "../../assets/svg/search-add-plus-middle.svg.js";
10
10
  import ZoomMinusIcon from "../../assets/svg/search-minus.svg.js";
11
11
  import CloseIcon from "../../assets/svg/times-close-delete.svg.js";
12
12
  import { FLOATING_Z_INDEX } from "../../theme/index.js";
13
+ import { Stylesheet } from "../stylesheet/stylesheet.js";
13
14
  import { Swiper } from "../swiper/swiper/swiper.js";
14
15
  import { SwiperSlide } from "../swiper/swiper-slide/swiper-slide.js";
15
16
  import { Floating } from "../floating/floating/floating.js";
16
17
  import { FloatingContent } from "../floating/floating-content/floating-content.js";
17
18
  import { Primitive } from "../primitive/primitive.js";
18
- import { Stylesheet } from "../stylesheet/stylesheet.js";
19
19
  import { Image } from "../image/image.js";
20
20
  import { FloatingClose } from "../floating/floating-close/floating-close.js";
21
21
  import { IconButton } from "../icon-button/icon-button.js";
@@ -1,9 +1,9 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { animatePulseStyle } from "../../../constants/emotion.js";
3
+ import { Stylesheet } from "../../stylesheet/stylesheet.js";
3
4
  import "lodash-es";
4
5
  import { getColorVar } from "../../../theme/palette.js";
5
6
  import { Primitive } from "../../primitive/primitive.js";
6
- import { Stylesheet } from "../../stylesheet/stylesheet.js";
7
7
  const ImageSkeleton = (props) => {
8
8
  return /* @__PURE__ */ jsx(
9
9
  Primitive,
@@ -7,9 +7,9 @@ import { notificationStore } from "./helpers.js";
7
7
  import { getColorShadesByVariant } from "../../utils/index.js";
8
8
  import { FLOATING_Z_INDEX } from "../../theme/index.js";
9
9
  import CloseIcon from "../../assets/svg/times-close-delete.svg.js";
10
+ import { Stylesheet } from "../stylesheet/stylesheet.js";
10
11
  import { usePortalContainer } from "../../theme/provider.js";
11
12
  import { Primitive } from "../primitive/primitive.js";
12
- import { Stylesheet } from "../stylesheet/stylesheet.js";
13
13
  import { getTypographyVar } from "../../theme/typography.js";
14
14
  import { IconButton } from "../icon-button/icon-button.js";
15
15
  const Notifications = () => {
@@ -14,7 +14,7 @@ import { StarRating } from '@janbox/storefront-ui';
14
14
  |------|------|---------|-------------|
15
15
  | `rating*` | `number` | - | Giá trị rating hiện tại. Kiểm soát mức độ tô màu ngôi sao qua clip-path. Hỗ trợ giá trị thập phân (VD: 2.5). |
16
16
  | `maxRating` | `number` | 5 | Giá trị rating tối đa. Dùng để tính phần trăm tô màu của ngôi sao. |
17
- | `size` | `number` | 24 | Chiều rộng và chiều cao của SVG tính bằng pixel. ViewBox nội bộ luôn là 24x24 nên giá trị này scale output. |
17
+ | `size` | `number` | 24 | Chiều rộng và chiều cao của SVG tính bằng pixel. ViewBox nội bộ luôn là 24x24 nên giá trị này scale output. Hỗ trợ responsive qua `sm`, `md`, `lg` (VD: `md={{ size: 32 }}`). |
18
18
  | `color` | `ColorScale` | `"orange"` | Color variant dùng cho cả stroke và fill của ngôi sao. Ánh xạ tới design token color shades qua `getColorShadesByVariant`. |
19
19
  | `sx` | `ToResponsiveProps<StyledCSS>` | - | Custom style responsive (hỗ trợ `sm`, `md`, `lg`) áp dụng lên root SVG element. |
20
20
  | `ref` | `React.Ref<SVGSVGElement>` | - | Ref tới phần tử SVG bên dưới. |
@@ -35,6 +35,13 @@ import { StarRating } from '@janbox/storefront-ui';
35
35
  <StarRating rating={2.5} size={32} />
36
36
  ```
37
37
 
38
+ ### Size responsive theo breakpoint
39
+
40
+ ```tsx
41
+ {/* 24px mặc định, 32px từ md, 40px từ lg */}
42
+ <StarRating rating={4} size={24} md={{ size: 32 }} lg={{ size: 40 }} />
43
+ ```
44
+
38
45
  ### Max rating tùy chỉnh và color variant
39
46
 
40
47
  ```tsx
@@ -1,2 +1,2 @@
1
1
  import { StarRatingProps } from './types';
2
- export declare const StarRating: ({ rating, maxRating, size, ref, color, sx }: StarRatingProps) => import("react/jsx-runtime").JSX.Element;
2
+ export declare const StarRating: ({ rating, maxRating, size, sm, md, lg, ref, color, sx, }: StarRatingProps) => import("react/jsx-runtime").JSX.Element;
@@ -2,16 +2,32 @@ import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { useId } from "react";
3
3
  import { getColorShadesByVariant } from "../../utils/index.js";
4
4
  import { Stylesheet } from "../stylesheet/stylesheet.js";
5
- const StarRating = ({ rating, maxRating = 5, size = 24, ref, color = "orange", sx }) => {
5
+ const StarRating = ({
6
+ rating,
7
+ maxRating = 5,
8
+ size = 24,
9
+ sm,
10
+ md,
11
+ lg,
12
+ ref,
13
+ color = "orange",
14
+ sx
15
+ }) => {
6
16
  const id = useId();
7
17
  const percent = rating / maxRating * 24;
8
18
  const { main } = getColorShadesByVariant(color);
9
19
  return /* @__PURE__ */ jsx(Stylesheet, { children: ({ css, cx }) => /* @__PURE__ */ jsxs(
10
20
  "svg",
11
21
  {
12
- className: cx(css(sx)),
13
- width: size,
14
- height: size,
22
+ className: cx(
23
+ css({
24
+ ...createStyle({ size }),
25
+ ...sx,
26
+ sm: { ...createStyle(sm), ...sx == null ? void 0 : sx.sm },
27
+ md: { ...createStyle(md), ...sx == null ? void 0 : sx.md },
28
+ lg: { ...createStyle(lg), ...sx == null ? void 0 : sx.lg }
29
+ })
30
+ ),
15
31
  viewBox: "0 0 24 24",
16
32
  xmlns: "http://www.w3.org/2000/svg",
17
33
  ref,
@@ -44,6 +60,12 @@ const StarRating = ({ rating, maxRating = 5, size = 24, ref, color = "orange", s
44
60
  }
45
61
  ) });
46
62
  };
63
+ const createStyle = ({ size } = {}) => {
64
+ return size ? {
65
+ width: size,
66
+ height: size
67
+ } : {};
68
+ };
47
69
  export {
48
70
  StarRating
49
71
  };
@@ -1,9 +1,11 @@
1
- import { ColorScale, PropsWithSx } from '../../types';
1
+ import { ColorScale, PropsWithSx, ToResponsiveProps } from '../../types';
2
2
  import { Ref } from 'react';
3
- export type StarRatingProps = PropsWithSx<{
3
+ export type StarRatingResponsiveProps = {
4
+ size?: number;
5
+ };
6
+ export type StarRatingProps = PropsWithSx<ToResponsiveProps<StarRatingResponsiveProps> & {
4
7
  rating: number;
5
8
  maxRating?: number;
6
- size?: number;
7
9
  color?: ColorScale;
8
10
  ref?: Ref<SVGSVGElement>;
9
11
  }>;
@@ -6,8 +6,8 @@ import { motion } from "motion/react";
6
6
  import { getColorVar } from "../../../theme/palette.js";
7
7
  import { usePortalContainer } from "../../../theme/provider.js";
8
8
  import { useIsHydrated } from "../../../hooks/use-is-hydrated/index.js";
9
- import { Primitive } from "../../primitive/primitive.js";
10
9
  import { Stylesheet } from "../../stylesheet/stylesheet.js";
10
+ import { Primitive } from "../../primitive/primitive.js";
11
11
  const SWIPER_DOTS_SIZE_VAR = "--swiper-dots-size";
12
12
  const SWIPER_DOTS_OFFSET_VAR = "--swiper-dots-offset";
13
13
  const SWIPER_DOTS_SPACING_VAR = "--swiper-dots-spacing";
@@ -1,8 +1,8 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { useRef, useState, useEffect } from "react";
3
3
  import { motion } from "motion/react";
4
- import { useTabsContext } from "../tabs/helpers.js";
5
4
  import { Stylesheet } from "../../stylesheet/stylesheet.js";
5
+ import { useTabsContext } from "../tabs/helpers.js";
6
6
  const TabIndicator = () => {
7
7
  const { activeIndex, tabIndicatorProps } = useTabsContext();
8
8
  const indicatorEl = useRef(null);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@janbox/storefront-ui",
3
- "version": "4.0.8",
3
+ "version": "4.0.10",
4
4
  "description": "Storefront UI component library for Janbox",
5
5
  "author": "Janbox",
6
6
  "keywords": [