@janbox/storefront-ui 4.0.9 → 4.0.11

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/dist/index.js CHANGED
@@ -133,6 +133,7 @@ import { getMultipleSelectProps } from "./lib/multiple-select/helpers.js";
133
133
  import { getPageRange, getPaginationProps } from "./lib/pagination/helpers.js";
134
134
  import { getPriceLabelProps } from "./lib/price-label/helpers.js";
135
135
  import { getRadioButtonProps } from "./lib/radio-button/helpers.js";
136
+ import { getStarRatingProps } from "./lib/star-rating/helpers.js";
136
137
  import { getSwiperProps } from "./lib/swiper/swiper/helpers.js";
137
138
  import { getTabListProps } from "./lib/tabs/tab-list/helpers.js";
138
139
  import { getTabPanelProps } from "./lib/tabs/tab-panel/helpers.js";
@@ -290,6 +291,7 @@ export {
290
291
  getPaginationProps,
291
292
  getPriceLabelProps,
292
293
  getRadioButtonProps,
294
+ getStarRatingProps,
293
295
  getSwiperProps,
294
296
  getTabListProps,
295
297
  getTabPanelProps,
@@ -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
@@ -4,6 +4,9 @@ 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 "lodash-es";
8
+ import "../../theme/palette.js";
9
+ import { getTypographyVar } from "../../theme/typography.js";
7
10
  import { Stylesheet } from "../stylesheet/stylesheet.js";
8
11
  import { getCountUpProps } from "./helpers.js";
9
12
  import { getDecimalDigits } from "../../utils/common.js";
@@ -14,6 +17,10 @@ const CountUp = ({ ref, ..._props }) => {
14
17
  duration = 2,
15
18
  formatNumberOptions,
16
19
  startOnView,
20
+ sizeVariant,
21
+ sm,
22
+ md,
23
+ lg,
17
24
  sx,
18
25
  prefix,
19
26
  suffix,
@@ -40,11 +47,34 @@ const CountUp = ({ ref, ..._props }) => {
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(css(sx), props.className), 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
@@ -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;
@@ -12,10 +12,10 @@ import { StarRating } from '@janbox/storefront-ui';
12
12
 
13
13
  | Prop | Type | Default | Description |
14
14
  |------|------|---------|-------------|
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
- | `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. |
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`. |
15
+ | `rating*` | `number` | - | Giá trị rating hiện tại (bắt buộc). 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
+ | `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. Hỗ trợ responsive qua `sm`, `md`, `lg` (VD: `md={{ size: 32 }}`). |
18
+ | `color` | `string` | `var(--color-orange-600)` | Giá trị màu CSS bất kỳ dùng cho cả stroke và fill của ngôi sao. Nhận mọi CSS color (hex, rgb, `var(...)`, ...). Dùng `getColorVar('orange.600')` cho giá trị mặc định. |
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. |
21
21
 
@@ -35,10 +35,22 @@ import { StarRating } from '@janbox/storefront-ui';
35
35
  <StarRating rating={2.5} size={32} />
36
36
  ```
37
37
 
38
- ### Max rating tùy chỉnh và color variant
38
+ ### Size responsive theo breakpoint
39
39
 
40
40
  ```tsx
41
- <StarRating rating={7} maxRating={10} color="primary" />
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
+
45
+ ### Max rating tùy chỉnh và color tùy chỉnh
46
+
47
+ ```tsx
48
+ import { getColorVar } from '@janbox/storefront-ui/theme';
49
+
50
+ <StarRating rating={7} maxRating={10} color={getColorVar('primary.600')} />
51
+
52
+ {/* Hoặc dùng CSS color trực tiếp */}
53
+ <StarRating rating={7} maxRating={10} color="#f59e0b" />
42
54
  ```
43
55
 
44
56
  ### Custom style responsive với `sx`
@@ -64,8 +76,9 @@ import { StarRating } from '@janbox/storefront-ui';
64
76
  ## Dependencies
65
77
 
66
78
  - react (useId)
67
- - @/utils (getColorShadesByVariant)
68
- - @/types (ColorScale, PropsWithSx)
79
+ - @/utils (mergeComponentProps)
80
+ - @/theme (getColorVar)
81
+ - @/types (PropsWithSx, ToResponsiveProps, StyledCSS)
69
82
  - Stylesheet (../stylesheet)
70
83
 
71
84
  ## See Also
@@ -0,0 +1,2 @@
1
+ import { StarRatingProps } from './types';
2
+ export declare const getStarRatingProps: (extended: StarRatingProps) => StarRatingProps;
@@ -0,0 +1,14 @@
1
+ import "lodash-es";
2
+ import { getColorVar } from "../../theme/palette.js";
3
+ import { mergeComponentProps } from "../../utils/index.js";
4
+ const defaultProps = {
5
+ color: getColorVar("orange.600"),
6
+ size: 24,
7
+ maxRating: 5
8
+ };
9
+ const getStarRatingProps = (extended) => {
10
+ return mergeComponentProps(defaultProps, extended);
11
+ };
12
+ export {
13
+ getStarRatingProps
14
+ };
@@ -1,2 +1,3 @@
1
- export * from './star-rating';
2
- export * from './types';
1
+ export { StarRating } from './star-rating';
2
+ export type { StarRatingProps, StarRatingResponsiveProps } from './types';
3
+ export { getStarRatingProps } from './helpers';
@@ -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: (_props: StarRatingProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,17 +1,25 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { useId } from "react";
3
- import { getColorShadesByVariant } from "../../utils/index.js";
4
3
  import { Stylesheet } from "../stylesheet/stylesheet.js";
5
- const StarRating = ({ rating, maxRating = 5, size = 24, ref, color = "orange", sx }) => {
4
+ import { getStarRatingProps } from "./helpers.js";
5
+ const StarRating = (_props) => {
6
+ const { rating, maxRating, size, sm, md, lg, ref, color, sx } = getStarRatingProps(_props);
6
7
  const id = useId();
7
- const percent = rating / maxRating * 24;
8
- const { main } = getColorShadesByVariant(color);
8
+ const percent = (() => {
9
+ return maxRating ? rating / maxRating * 24 : 0;
10
+ })();
9
11
  return /* @__PURE__ */ jsx(Stylesheet, { children: ({ css, cx }) => /* @__PURE__ */ jsxs(
10
12
  "svg",
11
13
  {
12
- className: cx(css(sx)),
13
- width: size,
14
- height: size,
14
+ className: cx(
15
+ css({
16
+ ...createStyle({ size }),
17
+ ...sx,
18
+ sm: { ...createStyle(sm), ...sx == null ? void 0 : sx.sm },
19
+ md: { ...createStyle(md), ...sx == null ? void 0 : sx.md },
20
+ lg: { ...createStyle(lg), ...sx == null ? void 0 : sx.lg }
21
+ })
22
+ ),
15
23
  viewBox: "0 0 24 24",
16
24
  xmlns: "http://www.w3.org/2000/svg",
17
25
  ref,
@@ -22,7 +30,7 @@ const StarRating = ({ rating, maxRating = 5, size = 24, ref, color = "orange", s
22
30
  {
23
31
  d: "M12 2.89648L14.935 8.88948L21.5 9.85648L16.75 14.5185L17.871 21.1045L12 17.9935L6.129 21.1045L7.25 14.5185L2.5 9.85648L9.064 8.88948L12 2.89648Z",
24
32
  fill: "white",
25
- stroke: main,
33
+ stroke: color,
26
34
  strokeWidth: "1.5",
27
35
  strokeLinecap: "round",
28
36
  strokeLinejoin: "round"
@@ -32,18 +40,24 @@ const StarRating = ({ rating, maxRating = 5, size = 24, ref, color = "orange", s
32
40
  "path",
33
41
  {
34
42
  d: "M12 2.89648L14.935 8.88948L21.5 9.85648L16.75 14.5185L17.871 21.1045L12 17.9935L6.129 21.1045L7.25 14.5185L2.5 9.85648L9.064 8.88948L12 2.89648Z",
35
- fill: main,
43
+ fill: color,
36
44
  clipPath: `url(#${id})`,
37
45
  strokeLinecap: "round",
38
46
  strokeLinejoin: "round",
39
47
  strokeWidth: "1.5",
40
- stroke: main
48
+ stroke: color
41
49
  }
42
50
  )
43
51
  ]
44
52
  }
45
53
  ) });
46
54
  };
55
+ const createStyle = ({ size } = {}) => {
56
+ return size ? {
57
+ width: size,
58
+ height: size
59
+ } : {};
60
+ };
47
61
  export {
48
62
  StarRating
49
63
  };
@@ -1,9 +1,11 @@
1
- import { ColorScale, PropsWithSx } from '../../types';
1
+ import { 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
- color?: ColorScale;
9
+ color?: string;
8
10
  ref?: Ref<SVGSVGElement>;
9
11
  }>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@janbox/storefront-ui",
3
- "version": "4.0.9",
3
+ "version": "4.0.11",
4
4
  "description": "Storefront UI component library for Janbox",
5
5
  "author": "Janbox",
6
6
  "keywords": [