@janbox/storefront-ui 3.0.0 → 3.0.2

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 (73) hide show
  1. package/README.md +72 -37
  2. package/dist/components/svg-loader.d.ts +4 -3
  3. package/dist/components/svg-loader.js +12 -7
  4. package/dist/constants/emotion.d.ts +0 -2
  5. package/dist/constants/emotion.js +0 -24
  6. package/dist/index.js +2 -0
  7. package/dist/lib/accordion/accordion-content/accordion-content.d.ts +1 -1
  8. package/dist/lib/accordion/accordion-content/accordion-content.js +24 -13
  9. package/dist/lib/accordion/accordion-summary/accordion-summary.d.ts +1 -1
  10. package/dist/lib/accordion/accordion-summary/accordion-summary.js +21 -13
  11. package/dist/lib/accordion/accordion-summary/types.d.ts +4 -3
  12. package/dist/lib/box/README.md +1 -11
  13. package/dist/lib/box/box.js +1 -3
  14. package/dist/lib/box/types.d.ts +1 -5
  15. package/dist/lib/cascader/cascader.js +9 -12
  16. package/dist/lib/cascader/types.d.ts +3 -2
  17. package/dist/lib/chip/chip.d.ts +1 -1
  18. package/dist/lib/chip/chip.js +35 -31
  19. package/dist/lib/chip/types.d.ts +5 -4
  20. package/dist/lib/container/README.md +7 -18
  21. package/dist/lib/container/container.d.ts +1 -1
  22. package/dist/lib/container/container.js +4 -88
  23. package/dist/lib/container/helpers.js +24 -1
  24. package/dist/lib/container/types.d.ts +2 -8
  25. package/dist/lib/filter-panel/checkbox-filter-panel.js +3 -2
  26. package/dist/lib/filter-panel/price-range-filter-panel.d.ts +1 -1
  27. package/dist/lib/filter-panel/price-range-filter-panel.js +4 -3
  28. package/dist/lib/filter-panel/radio-filter-panel.js +2 -1
  29. package/dist/lib/flexbox/README.md +1 -2
  30. package/dist/lib/flexbox/flex-item/flex-item.d.ts +1 -1
  31. package/dist/lib/flexbox/flex-item/flex-item.js +13 -8
  32. package/dist/lib/flexbox/flex-item/types.d.ts +2 -2
  33. package/dist/lib/flexbox/flexbox/flexbox.d.ts +1 -1
  34. package/dist/lib/flexbox/flexbox/flexbox.js +1 -3
  35. package/dist/lib/flexbox/flexbox/types.d.ts +2 -6
  36. package/dist/lib/grid/cell/README.md +66 -0
  37. package/dist/lib/grid/{README.md → grid/README.md} +5 -6
  38. package/dist/lib/grid/grid/grid.js +1 -3
  39. package/dist/lib/grid/grid/types.d.ts +4 -5
  40. package/dist/lib/icon/icon.d.ts +1 -1
  41. package/dist/lib/icon/icon.js +23 -21
  42. package/dist/lib/icon-button/icon-button.js +5 -3
  43. package/dist/lib/index.d.ts +1 -0
  44. package/dist/lib/lightbox/lightbox.js +2 -1
  45. package/dist/lib/pagination/pagination.js +1 -1
  46. package/dist/lib/popover/popover-content/popover-content.d.ts +1 -1
  47. package/dist/lib/popover/popover-content/popover-content.js +6 -5
  48. package/dist/lib/primitive/primitive.js +3 -4
  49. package/dist/lib/select/select.js +4 -4
  50. package/dist/lib/stepper/stepper.js +2 -1
  51. package/dist/lib/stylesheet/index.d.ts +2 -0
  52. package/dist/lib/stylesheet/stylesheet.d.ts +2 -0
  53. package/dist/lib/stylesheet/stylesheet.js +23 -0
  54. package/dist/lib/stylesheet/types.d.ts +9 -0
  55. package/dist/lib/table/table/table.d.ts +1 -1
  56. package/dist/lib/table/table/table.js +7 -6
  57. package/dist/lib/table/table/types.d.ts +2 -2
  58. package/dist/lib/table/table-body/table-body.d.ts +1 -1
  59. package/dist/lib/table/table-body/table-body.js +21 -22
  60. package/dist/lib/table/table-body/types.d.ts +2 -2
  61. package/dist/lib/table/table-footer/table-footer.d.ts +1 -1
  62. package/dist/lib/table/table-footer/table-footer.js +4 -4
  63. package/dist/lib/table/table-footer/types.d.ts +2 -2
  64. package/dist/lib/table/table-head/table-head.d.ts +1 -1
  65. package/dist/lib/table/table-head/table-head.js +19 -20
  66. package/dist/lib/table/table-head/types.d.ts +2 -2
  67. package/dist/lib/tabs/tab-indicator/tab-indicator.d.ts +1 -1
  68. package/dist/lib/tabs/tab-indicator/tab-indicator.js +12 -14
  69. package/dist/lib/tabs/tabs/tabs.js +2 -3
  70. package/dist/lib/time-picker/time-picker.js +15 -11
  71. package/dist/lib/video/video.d.ts +1 -1
  72. package/dist/lib/video/video.js +3 -3
  73. package/package.json +1 -1
package/README.md CHANGED
@@ -250,43 +250,7 @@ const formatted = formatPrice(1000000, 'VND', 'vi-VN'); // "1.000.000 ₫"
250
250
 
251
251
  ### Component Categories
252
252
 
253
- Thư viện cung cấp 60+ components được tổ chức theo các nhóm:
254
-
255
- #### Layout
256
-
257
- `Box`, `Flexbox`, `Grid`, `Container`
258
-
259
- #### Typography
260
-
261
- `Text`, `Link`, `HighlightWords`
262
-
263
- #### Form Controls
264
-
265
- `Input`, `InputNumber`, `InputRange`, `InputMask`, `Textarea`, `Select`, `MultipleSelect`, `Checkbox`, `RadioButton`, `Switch`, `DatePicker`, `TimePicker`, `PhoneInput`, `OtpInput`, `Cascader`
266
-
267
- #### Buttons
268
-
269
- `Button`, `IconButton`, `NavLink`
270
-
271
- #### Feedback
272
-
273
- `Loading`, `Progress`, `LinearProgress`, `Dialog`, `Drawer`, `Tooltip`, `Popover`, `Notifications`
274
-
275
- #### Data Display
276
-
277
- `Badge`, `Chip`, `Avatar`, `Table`, `Pagination`, `Stepper`, `Tabs`, `Accordion`, `Collapse`, `Breadcrumbs`, `StarRating`, `PriceLabel`, `CountUp`, `CountdownTimer`, `Flag`
278
-
279
- #### Media
280
-
281
- `Image`, `Video`, `Icon`, `Lightbox`, `Swiper`
282
-
283
- #### Navigation
284
-
285
- `Menu`, `FilterPanel`
286
-
287
- #### Utilities
288
-
289
- `Primitive`, `RippleEffect`, `SuspenseQuery`, `Marquee`, `Floating`
253
+ Thư viện cung cấp 60+ components được tổ chức theo các nhóm. Xem danh sách README theo từng component tại [Component Documentation](#component-documentation).
290
254
 
291
255
  ### Export Paths
292
256
 
@@ -491,6 +455,77 @@ export const Xxx = ({ ref, ..._props }: XxxProps) => {
491
455
 
492
456
  ---
493
457
 
458
+ ## Component Documentation
459
+
460
+ Mọi component đều có README riêng với API reference, examples, và usage notes.
461
+
462
+ - [Accordion](./dist/lib/accordion/README.md)
463
+ - [Avatar](./dist/lib/avatar/README.md)
464
+ - [Badge](./dist/lib/badge/README.md)
465
+ - [Box](./dist/lib/box/README.md)
466
+ - [Breadcrumbs](./dist/lib/breadcrumbs/README.md)
467
+ - [Button](./dist/lib/button/README.md)
468
+ - [Cascader](./dist/lib/cascader/README.md)
469
+ - [Cell](./dist/lib/grid/cell/README.md)
470
+ - [Checkbox](./dist/lib/checkbox/README.md)
471
+ - [Chip](./dist/lib/chip/README.md)
472
+ - [Collapse](./dist/lib/collapse/README.md)
473
+ - [Container](./dist/lib/container/README.md)
474
+ - [CountUp](./dist/lib/count-up/README.md)
475
+ - [CountdownTimer](./dist/lib/countdown-timer/README.md)
476
+ - [DatePicker](./dist/lib/date-picker/README.md)
477
+ - [Dialog](./dist/lib/dialog/README.md)
478
+ - [Drawer](./dist/lib/drawer/README.md)
479
+ - [FilterPanel](./dist/lib/filter-panel/README.md)
480
+ - [Flag](./dist/lib/flag/README.md)
481
+ - [Flexbox](./dist/lib/flexbox/README.md)
482
+ - [Floating](./dist/lib/floating/README.md)
483
+ - [FormHelperText](./dist/lib/form-helper-text/README.md)
484
+ - [FormLabel](./dist/lib/form-label/README.md)
485
+ - [Grid](./dist/lib/grid/grid/README.md)
486
+ - [HighlightWords](./dist/lib/highlight-words/README.md)
487
+ - [Icon](./dist/lib/icon/README.md)
488
+ - [IconButton](./dist/lib/icon-button/README.md)
489
+ - [Image](./dist/lib/image/README.md)
490
+ - [Input](./dist/lib/input/README.md)
491
+ - [InputMask](./dist/lib/input-mask/README.md)
492
+ - [InputNumber](./dist/lib/input-number/README.md)
493
+ - [InputRange](./dist/lib/input-range/README.md)
494
+ - [Lightbox](./dist/lib/lightbox/README.md)
495
+ - [LinearProgress](./dist/lib/linear-progress/README.md)
496
+ - [Link](./dist/lib/link/README.md)
497
+ - [Loading](./dist/lib/loading/README.md)
498
+ - [Marquee](./dist/lib/marquee/README.md)
499
+ - [Menu](./dist/lib/menu/README.md)
500
+ - [MultipleSelect](./dist/lib/multiple-select/README.md)
501
+ - [NavLink](./dist/lib/nav-link/README.md)
502
+ - [Notifications](./dist/lib/notifications/README.md)
503
+ - [OtpInput](./dist/lib/otp-input/README.md)
504
+ - [Pagination](./dist/lib/pagination/README.md)
505
+ - [PhoneInput](./dist/lib/phone-input/README.md)
506
+ - [Popover](./dist/lib/popover/README.md)
507
+ - [PriceLabel](./dist/lib/price-label/README.md)
508
+ - [Primitive](./dist/lib/primitive/README.md)
509
+ - [Progress](./dist/lib/progress/README.md)
510
+ - [RadioButton](./dist/lib/radio-button/README.md)
511
+ - [RippleEffect](./dist/lib/ripple-effect/README.md)
512
+ - [Select](./dist/lib/select/README.md)
513
+ - [StarRating](./dist/lib/star-rating/README.md)
514
+ - [Stepper](./dist/lib/stepper/README.md)
515
+ - [SuspenseQuery](./dist/lib/suspense-query/README.md)
516
+ - [Swiper](./dist/lib/swiper/README.md)
517
+ - [Switch](./dist/lib/switch/README.md)
518
+ - [Table](./dist/lib/table/README.md)
519
+ - [Tabs](./dist/lib/tabs/README.md)
520
+ - [Text](./dist/lib/text/README.md)
521
+ - [Textarea](./dist/lib/textarea/README.md)
522
+ - [TimePicker](./dist/lib/time-picker/README.md)
523
+ - [Tooltip](./dist/lib/tooltip/README.md)
524
+ - [UnorderedList](./dist/lib/unordered-list/README.md)
525
+ - [Video](./dist/lib/video/README.md)
526
+
527
+ ---
528
+
494
529
  ## API Reference
495
530
 
496
531
  ### Documentation
@@ -1,5 +1,6 @@
1
1
  import { JSX } from 'react';
2
- export type SvgLoaderProps = JSX.IntrinsicElements['svg'] & {
2
+ import { PropsWithSx } from '../types';
3
+ export type SvgLoaderProps = PropsWithSx<JSX.IntrinsicElements['svg'] & {
3
4
  source: string;
4
- };
5
- export declare const SvgLoader: import('react').ForwardRefExoticComponent<Omit<SvgLoaderProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
5
+ }>;
6
+ export declare const SvgLoader: ({ sx, source, ref, ...props }: SvgLoaderProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,14 +1,19 @@
1
1
  import { jsx, Fragment } from "react/jsx-runtime";
2
- import { forwardRef, useId, useMemo, cloneElement } from "react";
2
+ import { useId, useMemo, cloneElement } from "react";
3
3
  import { parseSvgString } from "../utils/common.js";
4
- const SvgLoader = forwardRef(({ source, ...props }, ref) => {
4
+ import { Stylesheet } from "../lib/stylesheet/stylesheet.js";
5
+ const SvgLoader = ({ sx, source, ref, ...props }) => {
5
6
  const uniqueId = useId();
6
7
  const jsxSvg = useMemo(() => parseSvgString(source, uniqueId), [source, uniqueId]);
7
- return /* @__PURE__ */ jsx(Fragment, { children: !!jsxSvg && cloneElement(jsxSvg, {
8
- ...props,
9
- ref
10
- }) });
11
- });
8
+ return /* @__PURE__ */ jsx(Stylesheet, { children: ({ cx, css }) => {
9
+ if (!jsxSvg) return /* @__PURE__ */ jsx(Fragment, {});
10
+ return cloneElement(jsxSvg, {
11
+ ...props,
12
+ className: cx(css(sx), props.className),
13
+ ref
14
+ });
15
+ } });
16
+ };
12
17
  export {
13
18
  SvgLoader
14
19
  };
@@ -3,5 +3,3 @@ export declare const scrollbarNoneStyle: StyledCSS;
3
3
  export declare const animatePulseStyle: StyledCSS;
4
4
  export declare const animateSpinStyle: StyledCSS;
5
5
  export declare const truncateStyle: StyledCSS;
6
- export declare const pointerEventsNone: StyledCSS;
7
- export declare const containerStyle: StyledCSS;
@@ -1,5 +1,4 @@
1
1
  import { keyframes } from "@emotion/react";
2
- import { breakpoint, mediaQuery } from "../theme/screens.js";
3
2
  const scrollbarNoneStyle = {
4
3
  scrollbarWidth: "none",
5
4
  "&::-webkit-scrollbar": { display: "none" }
@@ -21,32 +20,9 @@ const truncateStyle = {
21
20
  textOverflow: "ellipsis",
22
21
  whiteSpace: "nowrap"
23
22
  };
24
- const containerStyle = {
25
- width: "100%",
26
- marginLeft: "auto",
27
- marginRight: "auto",
28
- paddingLeft: `${breakpoint.xs.padding}px`,
29
- paddingRight: `${breakpoint.xs.padding}px`,
30
- [mediaQuery("sm")]: {
31
- maxWidth: `${breakpoint.sm.minWidth}px`,
32
- paddingLeft: `${breakpoint.sm.padding}px`,
33
- paddingRight: `${breakpoint.sm.padding}px`
34
- },
35
- [mediaQuery("md")]: {
36
- maxWidth: `${breakpoint.md.minWidth}px`,
37
- paddingLeft: `${breakpoint.md.padding}px`,
38
- paddingRight: `${breakpoint.md.padding}px`
39
- },
40
- [mediaQuery("lg")]: {
41
- maxWidth: `${breakpoint.lg.minWidth}px`,
42
- paddingLeft: `${breakpoint.lg.padding}px`,
43
- paddingRight: `${breakpoint.lg.padding}px`
44
- }
45
- };
46
23
  export {
47
24
  animatePulseStyle,
48
25
  animateSpinStyle,
49
- containerStyle,
50
26
  scrollbarNoneStyle,
51
27
  truncateStyle
52
28
  };
package/dist/index.js CHANGED
@@ -82,6 +82,7 @@ import { Select } from "./lib/select/select.js";
82
82
  import { StarRating } from "./lib/star-rating/star-rating.js";
83
83
  import { Step } from "./lib/stepper/step.js";
84
84
  import { Stepper } from "./lib/stepper/stepper.js";
85
+ import { Stylesheet } from "./lib/stylesheet/stylesheet.js";
85
86
  import { SuspenseQuery } from "./lib/suspense-query/suspense-query.js";
86
87
  import { Swiper } from "./lib/swiper/swiper/swiper.js";
87
88
  import { SwiperSlide } from "./lib/swiper/swiper-slide/swiper-slide.js";
@@ -229,6 +230,7 @@ export {
229
230
  StarRating,
230
231
  Step,
231
232
  Stepper,
233
+ Stylesheet,
232
234
  SuspenseQuery,
233
235
  Swiper,
234
236
  SwiperSlide,
@@ -1,2 +1,2 @@
1
1
  import { AccordionContentProps } from './types';
2
- export declare const AccordionContent: ({ children, ref, ..._props }: AccordionContentProps) => import("@emotion/react/jsx-runtime").JSX.Element;
2
+ export declare const AccordionContent: ({ children, ref, ..._props }: AccordionContentProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,34 +1,45 @@
1
- import { jsx } from "@emotion/react/jsx-runtime";
1
+ import { jsx } from "react/jsx-runtime";
2
2
  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 { createSxInterpolation } from "../../../utils/stylesheet.js";
6
+ import { Stylesheet } from "../../stylesheet/stylesheet.js";
7
7
  import { useAccordionGroupContext } from "../accordion-group/helpers.js";
8
+ import { Primitive } from "../../primitive/primitive.js";
8
9
  const AccordionContent = ({ children, ref, ..._props }) => {
9
10
  const { accordionContentProps: accordionContentPropsByGroup = {} } = useAccordionGroupContext();
10
- const { sx, containerProps, ...props } = getAccordionContentProps(accordionContentPropsByGroup, _props);
11
+ const { containerProps, ...props } = getAccordionContentProps(accordionContentPropsByGroup, _props);
11
12
  const { open } = useAccordionContext();
12
13
  const defaultOpenRef = useRef(open);
13
- const css = [
14
- {
15
- width: "100%"
16
- },
17
- createSxInterpolation(sx)
18
- ];
19
14
  const initial = defaultOpenRef.current ? { height: "auto", opacity: 1 } : { height: 0, opacity: 0 };
20
- return /* @__PURE__ */ jsx(
15
+ return /* @__PURE__ */ jsx(Stylesheet, { children: ({ cx, css }) => /* @__PURE__ */ jsx(
21
16
  motion.div,
22
17
  {
23
18
  initial,
24
19
  animate: open ? { height: "auto", opacity: 1 } : { height: 0, opacity: 0 },
25
20
  transition: { duration: 0.3 },
26
- css: { overflow: "hidden", width: "100%" },
27
21
  ...containerProps,
22
+ className: cx(
23
+ css({
24
+ overflow: "hidden",
25
+ width: "100%"
26
+ }),
27
+ containerProps == null ? void 0 : containerProps.className
28
+ ),
28
29
  ref,
29
- children: /* @__PURE__ */ jsx("div", { ...props, css, children })
30
+ children: /* @__PURE__ */ jsx(
31
+ Primitive,
32
+ {
33
+ ...props,
34
+ sx: {
35
+ width: "100%",
36
+ ...props.sx
37
+ },
38
+ children
39
+ }
40
+ )
30
41
  }
31
- );
42
+ ) });
32
43
  };
33
44
  export {
34
45
  AccordionContent
@@ -1,2 +1,2 @@
1
1
  import { AccordionSummaryProps } from './types';
2
- export declare const AccordionSummary: ({ children, ref, ..._props }: AccordionSummaryProps) => import("@emotion/react/jsx-runtime").JSX.Element;
2
+ export declare const AccordionSummary: ({ children, ref, ..._props }: AccordionSummaryProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,9 +1,9 @@
1
- import { jsxs, jsx } from "@emotion/react/jsx-runtime";
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
2
  import { getAccordionSummaryProps } from "./helpers.js";
3
3
  import { useAccordionContext } from "../accordion/helpers.js";
4
4
  import { Booleanish } from "../../../constants/index.js";
5
- import { createSxInterpolation } from "../../../utils/stylesheet.js";
6
5
  import { useAccordionGroupContext } from "../accordion-group/helpers.js";
6
+ import { Primitive } from "../../primitive/primitive.js";
7
7
  import { Icon } from "../../icon/icon.js";
8
8
  const AccordionSummary = ({ children, ref, ..._props }) => {
9
9
  const { accordionSummaryProps: accordionSummaryPropsByGroup = {} } = useAccordionGroupContext();
@@ -22,18 +22,26 @@ const AccordionSummary = ({ children, ref, ..._props }) => {
22
22
  toggle();
23
23
  (_b = rest.onClick) == null ? void 0 : _b.call(rest, e);
24
24
  };
25
- const css = [
25
+ return /* @__PURE__ */ jsxs(
26
+ Primitive,
26
27
  {
27
- display: "flex",
28
- cursor: "pointer"
29
- },
30
- createSxInterpolation(sx)
31
- ];
32
- return /* @__PURE__ */ jsxs("div", { css, "aria-hidden": true, ...rest, onClick, ref, children: [
33
- !!expandIcon && expandIcon.position === "left" && /* @__PURE__ */ jsx(ExpandIcon, { ...expandIcon }),
34
- /* @__PURE__ */ jsx("div", { css: { flex: "1 1 0%" }, children }),
35
- !!expandIcon && expandIcon.position === "right" && /* @__PURE__ */ jsx(ExpandIcon, { ...expandIcon })
36
- ] });
28
+ as: "div",
29
+ sx: {
30
+ display: "flex",
31
+ cursor: "pointer",
32
+ ...sx
33
+ },
34
+ "aria-hidden": true,
35
+ ...rest,
36
+ onClick,
37
+ ref,
38
+ children: [
39
+ !!expandIcon && expandIcon.position === "left" && /* @__PURE__ */ jsx(ExpandIcon, { ...expandIcon }),
40
+ /* @__PURE__ */ jsx(Primitive, { sx: { flex: "1 1 0%" }, children }),
41
+ !!expandIcon && expandIcon.position === "right" && /* @__PURE__ */ jsx(ExpandIcon, { ...expandIcon })
42
+ ]
43
+ }
44
+ );
37
45
  };
38
46
  const ExpandIcon = ({ source, position, size, sm, md, lg, sx }) => {
39
47
  const { open } = useAccordionContext();
@@ -1,6 +1,7 @@
1
1
  import { JSX } from 'react';
2
2
  import { IconResponsiveProps } from '../../icon';
3
3
  import { PropsWithSx, ShallowMerge, ToResponsiveProps } from '../../../types';
4
+ import { PrimitiveProps } from '../../primitive';
4
5
  export declare enum AccordionSummaryVariant {
5
6
  EndArrow = "end-arrow",
6
7
  EndPlusMinus = "end-plus-minus"
@@ -20,8 +21,8 @@ export type AccordionSummaryExpandIconProps = ToResponsiveProps<IconResponsivePr
20
21
  source: Record<AccordionState, string>;
21
22
  position: 'left' | 'right';
22
23
  } & PropsWithSx;
23
- type AccordionSummaryExtendedProps = PropsWithSx<{
24
+ type AccordionSummaryExtendedProps = {
24
25
  expandIcon?: AccordionSummaryExpandIconProps;
25
- }>;
26
- export type AccordionSummaryProps = ShallowMerge<JSX.IntrinsicElements['div'], AccordionSummaryExtendedProps>;
26
+ };
27
+ export type AccordionSummaryProps = PrimitiveProps<ShallowMerge<JSX.IntrinsicElements['div'], AccordionSummaryExtendedProps>>;
27
28
  export {};
@@ -1,6 +1,6 @@
1
1
  # Box
2
2
 
3
- A general-purpose layout primitive that renders a `div` by default. It supports responsive `sx` styling and an optional `container` mode that applies responsive max-width, horizontal centering, and breakpoint-aware padding.
3
+ A general-purpose layout primitive that renders a `div` by default. It supports responsive `sx` styling via the Emotion-powered `sx` prop.
4
4
 
5
5
  ## Import
6
6
 
@@ -12,7 +12,6 @@ import { Box } from '@janbox/storefront-ui';
12
12
 
13
13
  | Prop | Type | Default | Description |
14
14
  |------|------|---------|-------------|
15
- | `container` | `boolean` | false | When true, applies responsive container styles: full width, auto horizontal margins, and breakpoint-aware max-width and padding (xs → sm → md → lg). |
16
15
  | `sx` | `ToResponsiveProps<StyledCSS>` | - | Responsive Emotion CSS overrides. Accepts a base StyledCSS object plus optional `sm`, `md`, and `lg` breakpoint keys for responsive styles. |
17
16
  | `as` | `HTMLElementType` | "div" | Override the rendered HTML element (polymorphic). Defaults to `div`. |
18
17
  | `children` | `React.ReactNode` | - | Content rendered inside the Box. |
@@ -30,15 +29,6 @@ import { Box } from '@janbox/storefront-ui';
30
29
  </Box>
31
30
  ```
32
31
 
33
- ### Container Box
34
-
35
- ```tsx
36
- <Box container>
37
- <h1>Page title</h1>
38
- <p>Centered, max-width constrained content with responsive padding.</p>
39
- </Box>
40
- ```
41
-
42
32
  ### Responsive sx styling
43
33
 
44
34
  ```tsx
@@ -1,15 +1,13 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { getBoxProps } from "./helpers.js";
3
- import { containerStyle } from "../../constants/emotion.js";
4
3
  import { Primitive } from "../primitive/primitive.js";
5
4
  const Box = ({ children, ref, ..._props }) => {
6
- const { sx = {}, container, ...rest } = getBoxProps(_props);
5
+ const { sx = {}, ...rest } = getBoxProps(_props);
7
6
  return /* @__PURE__ */ jsx(
8
7
  Primitive,
9
8
  {
10
9
  ...rest,
11
10
  sx: {
12
- ...container ? containerStyle : {},
13
11
  ...sx,
14
12
  sm: { ...sx.sm },
15
13
  md: { ...sx.md },
@@ -1,7 +1,3 @@
1
1
  import { JSX } from 'react';
2
2
  import { PrimitiveProps } from '../primitive';
3
- type BoxExtendedProps = {
4
- container?: boolean;
5
- };
6
- export type BoxProps = PrimitiveProps<JSX.IntrinsicElements['div']> & BoxExtendedProps;
7
- export {};
3
+ export type BoxProps = PrimitiveProps<JSX.IntrinsicElements['div']>;
@@ -10,7 +10,7 @@ import { truncateStyle } from "../../constants/emotion.js";
10
10
  import { getSizeVariantState } from "../../utils/index.js";
11
11
  import { useControllableState } from "../../hooks/use-controllable-state.js";
12
12
  import { SvgLoader } from "../../components/svg-loader.js";
13
- import { createSxInterpolation } from "../../utils/stylesheet.js";
13
+ import { Primitive } from "../primitive/primitive.js";
14
14
  import { Floating } from "../floating/floating/floating.js";
15
15
  import { FloatingTrigger } from "../floating/floating-trigger/floating-trigger.js";
16
16
  import { InputMask as ForwardRefInputMask } from "../input-mask/input-mask.js";
@@ -73,19 +73,16 @@ const Cascader = ({ ref, ..._props }) => {
73
73
  if (isNil(textVariant)) return {};
74
74
  return getTypographyVar(textVariant);
75
75
  };
76
- const { sx: containerSx, ...restContainerProps } = containerProps ?? {};
77
76
  return /* @__PURE__ */ jsxs(
78
- "div",
77
+ Primitive,
79
78
  {
80
- ...restContainerProps,
81
- css: [
82
- {
83
- display: "flex",
84
- flexDirection: "column",
85
- ...fullWidth ? { width: "100%" } : {}
86
- },
87
- createSxInterpolation(containerSx)
88
- ],
79
+ ...containerProps,
80
+ sx: {
81
+ display: "flex",
82
+ flexDirection: "column",
83
+ ...fullWidth ? { width: "100%" } : {},
84
+ ...containerProps == null ? void 0 : containerProps.sx
85
+ },
89
86
  children: [
90
87
  /* @__PURE__ */ jsxs(
91
88
  Floating,
@@ -1,8 +1,9 @@
1
1
  import { HTMLAttributes, JSX, ReactNode } from 'react';
2
2
  import { Placement, UseFloatingOptions } from '@floating-ui/react';
3
- import { PropsWithSx, ShallowMerge, ToResponsiveProps } from '../../types';
3
+ import { ShallowMerge, ToResponsiveProps } from '../../types';
4
4
  import { InputProps } from '../input';
5
5
  import { InputMaskProps, InputMaskResponsiveProps } from '../input-mask';
6
+ import { PrimitiveProps } from '../primitive';
6
7
  export type CascaderResponsiveProps = InputMaskResponsiveProps;
7
8
  export type CascaderOptionValue = string | number;
8
9
  export interface CascaderOption {
@@ -47,7 +48,7 @@ interface CascaderExtendedProps extends ToResponsiveProps<CascaderResponsiveProp
47
48
  /** Helper text below the input */
48
49
  helperText?: string;
49
50
  /** Props for the container div */
50
- containerProps?: PropsWithSx<JSX.IntrinsicElements['div']>;
51
+ containerProps?: PrimitiveProps<JSX.IntrinsicElements['div'], 'div'>;
51
52
  /** Props for the search input */
52
53
  inputProps?: InputProps;
53
54
  /** Whether component takes full width */
@@ -1,2 +1,2 @@
1
1
  import { ChipProps } from './types';
2
- export declare const Chip: ({ children, ..._props }: ChipProps) => import("@emotion/react/jsx-runtime").JSX.Element;
2
+ export declare const Chip: ({ children, ..._props }: ChipProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,52 +1,56 @@
1
- import { jsx } from "@emotion/react/jsx-runtime";
1
+ import { jsx } from "react/jsx-runtime";
2
2
  import { getChipProps, getChipSizeState } from "./helpers.js";
3
3
  import { getColorShadesByVariant } from "../../utils/index.js";
4
- import { mediaQuery } from "../../theme/screens.js";
4
+ import "lodash-es";
5
5
  import "../../theme/palette.js";
6
6
  import { getTypographyVar } from "../../theme/typography.js";
7
- import { createSxInterpolation } from "../../utils/stylesheet.js";
7
+ import { Primitive } from "../primitive/primitive.js";
8
8
  const Chip = ({ children, ..._props }) => {
9
9
  const { sx, size, sm, md, lg, color = "green", ...rest } = getChipProps(_props);
10
10
  const { light, main } = getColorShadesByVariant(color);
11
11
  return /* @__PURE__ */ jsx(
12
- "div",
12
+ Primitive,
13
13
  {
14
+ as: "div",
14
15
  ...rest,
15
- css: [
16
- {
17
- width: "fit-content",
18
- maxWidth: "100%",
19
- display: "flex",
20
- alignItems: "center",
21
- backgroundColor: light,
22
- borderWidth: 1,
23
- borderColor: main,
24
- color: main
16
+ sx: {
17
+ width: "fit-content",
18
+ maxWidth: "100%",
19
+ display: "flex",
20
+ alignItems: "center",
21
+ backgroundColor: light,
22
+ borderWidth: 1,
23
+ borderColor: main,
24
+ color: main,
25
+ ...createStyle({ size }),
26
+ ...sx,
27
+ sm: {
28
+ ...createStyle(sm),
29
+ ...sx == null ? void 0 : sx.sm
25
30
  },
26
- createStyle({ size }),
27
- {
28
- [mediaQuery("sm")]: createStyle(sm),
29
- [mediaQuery("md")]: createStyle(md),
30
- [mediaQuery("lg")]: createStyle(lg)
31
+ md: {
32
+ ...createStyle(md),
33
+ ...sx == null ? void 0 : sx.md
31
34
  },
32
- createSxInterpolation(sx)
33
- ],
35
+ lg: {
36
+ ...createStyle(lg),
37
+ ...sx == null ? void 0 : sx.lg
38
+ }
39
+ },
34
40
  children
35
41
  }
36
42
  );
37
43
  };
38
44
  const createStyle = ({ size } = {}) => {
39
45
  const { inputSize, inputPaddingX, textVariant, rounded } = getChipSizeState(size);
40
- return [
41
- {
42
- paddingLeft: inputPaddingX,
43
- paddingRight: inputPaddingX,
44
- minHeight: inputSize,
45
- fontSize: textVariant ? getTypographyVar(textVariant).fontSize : void 0,
46
- lineHeight: textVariant ? getTypographyVar(textVariant).lineHeight : void 0,
47
- borderRadius: rounded
48
- }
49
- ];
46
+ return {
47
+ paddingLeft: inputPaddingX,
48
+ paddingRight: inputPaddingX,
49
+ minHeight: inputSize,
50
+ fontSize: textVariant ? getTypographyVar(textVariant).fontSize : void 0,
51
+ lineHeight: textVariant ? getTypographyVar(textVariant).lineHeight : void 0,
52
+ borderRadius: rounded
53
+ };
50
54
  };
51
55
  export {
52
56
  Chip
@@ -1,10 +1,11 @@
1
1
  import { JSX } from 'react';
2
- import { ColorVariant, PropsWithSx, ShallowMerge, SizeVariant, ToResponsiveProps } from '../../types';
2
+ import { ColorVariant, ShallowMerge, SizeVariant, ToResponsiveProps } from '../../types';
3
+ import { PrimitiveProps } from '../primitive';
3
4
  export interface ChipResponsiveProps {
4
5
  size?: SizeVariant;
5
6
  }
6
- type ChipExtendedProps = PropsWithSx<ToResponsiveProps<ChipResponsiveProps> & {
7
+ type ChipExtendedProps = ToResponsiveProps<ChipResponsiveProps> & {
7
8
  color?: ColorVariant;
8
- }>;
9
- export type ChipProps = ShallowMerge<JSX.IntrinsicElements['div'], ChipExtendedProps>;
9
+ };
10
+ export type ChipProps = PrimitiveProps<ShallowMerge<JSX.IntrinsicElements['div'], ChipExtendedProps>>;
10
11
  export {};
@@ -1,6 +1,6 @@
1
1
  # Container
2
2
 
3
- Wrapper layout responsive giúp giới hạn chiều rộng nội dung theo breakpoint và tự động xử lý padding ngang. Component căn giữa nội dung trong viewport bằng cách tính padding hai bên theo breakpoint hiện tại, đồng thời hỗ trợ căn chỉnh vị trí để nội dung có thể tràn ra cạnh trái hoặc phải.
3
+ Wrapper layout responsive giúp giới hạn chiều rộng nội dung theo breakpoint và tự động xử lý padding ngang. Component căn giữa nội dung trong viewport theo cấu hình layout nội bộ của design system.
4
4
 
5
5
  ## Import
6
6
 
@@ -12,13 +12,9 @@ import { Container } from '@janbox/storefront-ui';
12
12
 
13
13
  | Prop | Type | Default | Description |
14
14
  |------|------|---------|-------------|
15
- | `position` | `ContainerPosition` | `"center"` | Kiểm soát căn chỉnh ngang và padding của container. `'center'` áp dụng padding đều hai bên, `'start'` bỏ padding trái (nội dung tràn ra cạnh trái), `'end'` bỏ padding phải (nội dung tràn ra cạnh phải). |
16
- | `sm` | `{ position?: ContainerPosition }` | - | Responsive override tại breakpoint `sm` (min-width: 768px). Nhận giá trị `position` để thay đổi căn chỉnh ở màn hình tablet. |
17
- | `md` | `{ position?: ContainerPosition }` | - | Responsive override tại breakpoint `md` (min-width: 1280px). Nhận giá trị `position` để thay đổi căn chỉnh ở màn hình desktop. |
18
- | `lg` | `{ position?: ContainerPosition }` | - | Responsive override tại breakpoint `lg` (min-width: 1680px). Nhận giá trị `position` để thay đổi căn chỉnh ở màn hình large desktop. |
19
- | `sx` | `ToResponsiveProps<StyledCSS>` | - | Escape hatch để truyền custom Emotion CSS vào wrapper div ngoài cùng. Hỗ trợ responsive keys (`sm`, `md`, `lg`). |
15
+ | `sx` | `ToResponsiveProps<StyledCSS>` | - | Custom Emotion CSS. Hỗ trợ responsive keys (`sm`, `md`, `lg`). **Không nên override** `width`, `max-width`, `margin-left`, `margin-right`, `padding-left`, `padding-right` — các thuộc tính này do Container quản lý nội bộ. |
20
16
  | `children` | `React.ReactNode` | - | Nội dung render bên trong container. |
21
- | `...rest` | `JSX.IntrinsicElements['div']` | - | Tất cả HTML div attributes tiêu chuẩn (`className`, `style`, `onClick`, v.v.) được forward xuống div ngoài cùng. |
17
+ | `...rest` | `JSX.IntrinsicElements['div']` | - | Tất cả HTML div attributes tiêu chuẩn (`className`, `style`, `onClick`, v.v.). |
22
18
 
23
19
  ## Examples
24
20
 
@@ -30,22 +26,15 @@ import { Container } from '@janbox/storefront-ui';
30
26
  </Container>
31
27
  ```
32
28
 
33
- ### Căn trái (bleed left)
29
+ ### Custom style qua sx prop
34
30
 
35
31
  ```tsx
36
- <Container position="start">
37
- {/* Bỏ padding trái — nội dung kéo dài ra cạnh viewport bên trái */}
38
- <HeroImage />
32
+ <Container sx={{ backgroundColor: '#f0f0f0', minHeight: 100 }}>
33
+ Page content with custom visual styles
39
34
  </Container>
40
35
  ```
41
36
 
42
- ### Responsive position — căn giữa trên mobile, căn trái trên desktop
43
-
44
- ```tsx
45
- <Container position="center" md={{ position: 'start' }}>
46
- <SidebarPanel />
47
- </Container>
48
- ```
37
+ > Không dùng `sx` để override layout core của Container như `width`, `max-width`, `margin-left`, `margin-right`, `padding-left`, `padding-right`. Nếu cần layout khác, dùng wrapper component riêng thay vì thay đổi contract của Container.
49
38
 
50
39
  ## Dependencies
51
40