@janbox/storefront-ui 2.0.29 → 2.0.30

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 (76) hide show
  1. package/README.md +681 -0
  2. package/dist/lib/accordion/README.md +81 -0
  3. package/dist/lib/avatar/README.md +74 -0
  4. package/dist/lib/badge/README.md +58 -0
  5. package/dist/lib/box/README.md +69 -0
  6. package/dist/lib/breadcrumbs/README.md +70 -0
  7. package/dist/lib/button/README.md +115 -0
  8. package/dist/lib/cascader/README.md +128 -0
  9. package/dist/lib/checkbox/README.md +74 -0
  10. package/dist/lib/checkbox/checkbox.js +107 -12
  11. package/dist/lib/checkbox/types.d.ts +2 -2
  12. package/dist/lib/chip/README.md +72 -0
  13. package/dist/lib/collapse/README.md +78 -0
  14. package/dist/lib/container/README.md +59 -0
  15. package/dist/lib/count-up/README.md +52 -0
  16. package/dist/lib/countdown-timer/README.md +77 -0
  17. package/dist/lib/date-picker/README.md +94 -0
  18. package/dist/lib/date-picker/date-picker.js +2 -1
  19. package/dist/lib/dialog/README.md +109 -0
  20. package/dist/lib/drawer/README.md +97 -0
  21. package/dist/lib/filter-panel/README.md +146 -0
  22. package/dist/lib/flag/README.md +58 -0
  23. package/dist/lib/flexbox/README.md +59 -0
  24. package/dist/lib/floating/README.md +109 -0
  25. package/dist/lib/form-helper-text/README.md +54 -0
  26. package/dist/lib/form-label/README.md +50 -0
  27. package/dist/lib/grid/README.md +72 -0
  28. package/dist/lib/highlight-words/README.md +64 -0
  29. package/dist/lib/highlight-words/highlight-words.js +1 -2
  30. package/dist/lib/icon/README.md +69 -0
  31. package/dist/lib/icon-button/README.md +92 -0
  32. package/dist/lib/image/README.md +80 -0
  33. package/dist/lib/input/README.md +118 -0
  34. package/dist/lib/input-mask/README.md +88 -0
  35. package/dist/lib/input-number/README.md +92 -0
  36. package/dist/lib/input-range/README.md +85 -0
  37. package/dist/lib/lightbox/README.md +107 -0
  38. package/dist/lib/linear-progress/README.md +54 -0
  39. package/dist/lib/link/README.md +67 -0
  40. package/dist/lib/loading/README.md +65 -0
  41. package/dist/lib/marquee/README.md +83 -0
  42. package/dist/lib/menu/README.md +92 -0
  43. package/dist/lib/multiple-select/README.md +108 -0
  44. package/dist/lib/nav-link/README.md +61 -0
  45. package/dist/lib/notifications/README.md +103 -0
  46. package/dist/lib/otp-input/README.md +71 -0
  47. package/dist/lib/pagination/README.md +84 -0
  48. package/dist/lib/phone-input/README.md +80 -0
  49. package/dist/lib/popover/README.md +93 -0
  50. package/dist/lib/price-label/README.md +78 -0
  51. package/dist/lib/primitive/README.md +80 -0
  52. package/dist/lib/progress/README.md +50 -0
  53. package/dist/lib/radio-button/README.md +89 -0
  54. package/dist/lib/radio-button/radio-button.js +98 -7
  55. package/dist/lib/ripple-effect/README.md +66 -0
  56. package/dist/lib/select/README.md +124 -0
  57. package/dist/lib/star-rating/README.md +67 -0
  58. package/dist/lib/stepper/README.md +99 -0
  59. package/dist/lib/suspense-query/README.md +78 -0
  60. package/dist/lib/swiper/README.md +99 -0
  61. package/dist/lib/switch/README.md +73 -0
  62. package/dist/lib/switch/switch.d.ts +1 -1
  63. package/dist/lib/switch/switch.js +110 -11
  64. package/dist/lib/table/README.md +115 -0
  65. package/dist/lib/tabs/README.md +103 -0
  66. package/dist/lib/text/README.md +59 -0
  67. package/dist/lib/textarea/README.md +76 -0
  68. package/dist/lib/time-picker/README.md +100 -0
  69. package/dist/lib/tooltip/README.md +106 -0
  70. package/dist/lib/unordered-list/README.md +85 -0
  71. package/dist/lib/video/README.md +88 -0
  72. package/package.json +5 -5
  73. package/dist/lib/checkbox/checkbox.module.scss.js +0 -23
  74. package/dist/lib/radio-button/radio-button.module.scss.js +0 -17
  75. package/dist/lib/switch/switch.module.scss.js +0 -14
  76. package/dist/style.css +0 -823
@@ -0,0 +1,92 @@
1
+ # InputNumber
2
+
3
+ A numeric input field that extends the base Input component with number-specific constraints and optional increment/decrement controls. Use it when you need validated numeric entry with min/max bounds, step controls, or decimal precision.
4
+
5
+ ## Import
6
+
7
+ ```tsx
8
+ import { InputNumber } from '@janbox/storefront-ui';
9
+ ```
10
+
11
+ ## Props
12
+
13
+ | Prop | Type | Default | Description |
14
+ |------|------|---------|-------------|
15
+ | `value` | `number \| string` | - | Controlled value of the input. |
16
+ | `defaultValue` | `number` | - | Uncontrolled initial value. |
17
+ | `min` | `number` | 0 | Minimum allowed value. Defaults to 0. Also suppresses negative sign when min >= 0. |
18
+ | `max` | `number` | Infinity | Maximum allowed value. |
19
+ | `step` | `number` | 0 | Increment/decrement step. When > 0, renders plus and minus IconButton controls in the suffix and prefix slots. |
20
+ | `fractionDigits` | `number \| 'auto'` | 0 | Number of decimal digits to allow. 0 strips decimals entirely; 'auto' allows up to 10 digits. |
21
+ | `size` | `'xs' \| 'sm' \| 'md' \| 'lg'` | 'md' | Size variant inherited from Input. Supports responsive values via sm/md/lg breakpoint keys. |
22
+ | `error` | `boolean` | false | Renders the input in an error state with red border styling. |
23
+ | `helperText` | `string` | - | Helper or validation message displayed below the input. |
24
+ | `prefix` | `React.ReactNode` | - | Content rendered before the input. Overrides the built-in minus IconButton when step > 0. |
25
+ | `suffix` | `React.ReactNode` | - | Content rendered after the input. Overrides the built-in plus IconButton when step > 0. |
26
+ | `startIcon` | `IconProps` | - | Icon rendered inside the left edge of the input field. |
27
+ | `endIcon` | `IconProps` | - | Icon rendered inside the right edge of the input field. |
28
+ | `mode` | `'onChange' \| 'onBlur'` | 'onChange' | When set to 'onBlur', clamps the value to min on blur rather than on every keystroke. |
29
+ | `debounce` | `number` | - | Debounce delay in milliseconds for the onChange callback. |
30
+ | `transform` | `(value: string) => string` | - | Custom transform function applied to the raw string value after built-in number sanitisation. |
31
+ | `disabled` | `boolean` | false | Disables the input and step controls. |
32
+ | `placeholder` | `string` | - | Placeholder text shown when the input is empty. |
33
+ | `className` | `string` | - | Additional CSS class applied to the input element. |
34
+ | `sx` | `ToResponsiveProps<StyledCSS>` | - | Emotion sx prop for inline responsive styles. |
35
+ | `containerProps` | `PrimitiveProps<JSX.IntrinsicElements['div']>` | - | Props forwarded to the outer wrapper div. |
36
+ | `mainProps` | `PrimitiveProps<JSX.IntrinsicElements['div']>` | - | Props forwarded to the inner main container div. |
37
+ | `onChange` | `React.ChangeEventHandler<HTMLInputElement>` | - | Change event handler. Receives the raw input change event. |
38
+ | `ref` | `React.Ref<HTMLInputElement>` | - | Forwarded ref to the underlying input element. |
39
+
40
+ ## Examples
41
+
42
+ ### Basic numeric input with min/max bounds
43
+
44
+ ```tsx
45
+ <InputNumber
46
+ min={0}
47
+ max={100}
48
+ defaultValue={50}
49
+ placeholder="0 - 100"
50
+ onChange={(e) => console.log(e.target.value)}
51
+ />
52
+ ```
53
+
54
+ ### Stepper input with increment/decrement buttons
55
+
56
+ ```tsx
57
+ <InputNumber
58
+ step={5}
59
+ min={0}
60
+ max={50}
61
+ defaultValue={10}
62
+ placeholder="Step by 5"
63
+ />
64
+ ```
65
+
66
+ ### Decimal input with validation error
67
+
68
+ ```tsx
69
+ <InputNumber
70
+ fractionDigits={2}
71
+ defaultValue={3.14}
72
+ error={true}
73
+ helperText="Value must be between 0 and 100"
74
+ placeholder="Decimal number"
75
+ />
76
+ ```
77
+
78
+ ## Related Components
79
+
80
+ - [Input](../input/README.md)
81
+ - [IconButton](../icon-button/README.md)
82
+
83
+ ## Dependencies
84
+
85
+ - @floating-ui/react
86
+ - lodash-es
87
+
88
+ ## See Also
89
+
90
+ - [Component Source](./index.ts)
91
+ - [Storybook Stories](./inputnumber.stories.tsx)
92
+ - [Main README](../../README.md)
@@ -0,0 +1,85 @@
1
+ # InputRange
2
+
3
+ A dual-input numeric range component that renders two InputNumber fields (from/to) in a single bordered container, connected by an arrow icon. Designed for filtering scenarios like price ranges or quantity ranges where users need to specify a minimum and maximum value.
4
+
5
+ ## Import
6
+
7
+ ```tsx
8
+ import { InputRange } from '@janbox/storefront-ui';
9
+ ```
10
+
11
+ ## Props
12
+
13
+ | Prop | Type | Default | Description |
14
+ |------|------|---------|-------------|
15
+ | `inputs` | `[InputNumberProps, InputNumberProps]` | - | Tuple of two InputNumber prop objects — first for the 'from' (min) input, second for the 'to' (max) input. Supports all InputNumber props including value, defaultValue, placeholder, min, max, etc. |
16
+ | `size` | `SizeVariant ('xs' \| 'sm' \| 'md' \| 'lg')` | `'md'` | Controls the size of both inputs and icons within the range component. |
17
+ | `sm` | `{ size?: SizeVariant }` | - | Responsive size override applied at the sm breakpoint (≥768px). |
18
+ | `md` | `{ size?: SizeVariant }` | - | Responsive size override applied at the md breakpoint (≥1280px). |
19
+ | `lg` | `{ size?: SizeVariant }` | - | Responsive size override applied at the lg breakpoint (≥1680px). |
20
+ | `error` | `boolean` | - | Puts the component in an error state. Visually indicates invalid input and styles the helper text in red. |
21
+ | `helperText` | `string` | - | Helper or validation message displayed below the input container. Styled as error text when `error=true`. |
22
+ | `onChange` | `(e: React.ChangeEvent<HTMLInputElement>, edge: InputRangeEdge) => void` | - | Change handler called when either input changes. The `edge` parameter indicates which input triggered the change: `'from'` for the left input, `'to'` for the right input. |
23
+ | `prefix` | `React.ReactNode` | - | Content rendered before the start icon and the first input, inside the container border. |
24
+ | `suffix` | `React.ReactNode` | - | Content rendered after the end icon and the last input, inside the container border. |
25
+ | `startIcon` | `IconProps` | - | Icon displayed at the left side of the container, before the first (from) input. |
26
+ | `endIcon` | `IconProps` | - | Icon displayed at the right side of the container, after the second (to) input. |
27
+ | `sx` | `ToResponsiveProps<StyledCSS>` | - | Responsive CSS overrides applied to the outer wrapper element via Emotion. |
28
+
29
+ ## Examples
30
+
31
+ ### With placeholders
32
+
33
+ ```tsx
34
+ <InputRange
35
+ inputs={[
36
+ { placeholder: 'Min' },
37
+ { placeholder: 'Max' },
38
+ ]}
39
+ onChange={(e, edge) => console.log(edge, e.target.value)}
40
+ />
41
+ ```
42
+
43
+ ### With default values and error state
44
+
45
+ ```tsx
46
+ <InputRange
47
+ error={true}
48
+ helperText="Max must be greater than min"
49
+ inputs={[
50
+ { defaultValue: 100, placeholder: 'Min' },
51
+ { defaultValue: 10, placeholder: 'Max' },
52
+ ]}
53
+ onChange={(e, edge) => handleRangeChange(e, edge)}
54
+ />
55
+ ```
56
+
57
+ ### Small size with responsive override
58
+
59
+ ```tsx
60
+ <InputRange
61
+ size="sm"
62
+ md={{ size: 'md' }}
63
+ inputs={[
64
+ { placeholder: 'From', min: 0 },
65
+ { placeholder: 'To', max: 10000 },
66
+ ]}
67
+ onChange={(e, edge) => {
68
+ if (edge === 'from') setMinPrice(Number(e.target.value));
69
+ else setMaxPrice(Number(e.target.value));
70
+ }}
71
+ />
72
+ ```
73
+
74
+ ## Related Components
75
+
76
+ - [InputNumber](../inputnumber/README.md)
77
+ - [Icon](../icon/README.md)
78
+ - [FormHelperText](../formhelpertext/README.md)
79
+ - [Primitive](../primitive/README.md)
80
+
81
+ ## See Also
82
+
83
+ - [Component Source](./index.ts)
84
+ - [Storybook Stories](./inputrange.stories.tsx)
85
+ - [Main README](../../README.md)
@@ -0,0 +1,107 @@
1
+ # Lightbox
2
+
3
+ A full-screen media viewer overlay that supports image zoom/pan and video playback with slide navigation. Built on top of the Floating component, it renders a backdrop overlay with swipeable slides, prev/next navigation, zoom controls for images, and a close button.
4
+
5
+ ## Import
6
+
7
+ ```tsx
8
+ import { Lightbox } from '@janbox/storefront-ui';
9
+ ```
10
+
11
+ ## Props
12
+
13
+ | Prop | Type | Default | Description |
14
+ | ---- | ---- | ------- | ----------- |
15
+ | `slides*` | `LightboxSlide[]` | - | Array of slides to display. Each slide has a `source` (image or video) and an optional `title`. ImageSource: `{ type: 'image'; src: string }`. VideoSource: `{ type: 'video'; src: string; thumbnail?: string }`. |
16
+ | `defaultActiveIndex` | `number` | 0 | Zero-based index of the slide to show when the lightbox first opens. |
17
+ | `open` | `boolean` | - | Controlled open state of the lightbox (inherited from FloatingProps). |
18
+ | `onOpenChange` | `(open: boolean, event?: Event, reason?: OpenChangeReason) => void` | - | Callback fired when the open state changes (inherited from FloatingProps). |
19
+ | `placement` | `Placement` | - | Floating UI placement — typically not needed for lightbox usage (inherited from FloatingProps). |
20
+ | `dismissProps` | `UseDismissProps` | - | Options for dismiss behavior (click outside, Escape key). Enabled by default in Lightbox (inherited from FloatingProps). |
21
+ | `clickProps` | `UseClickProps` | - | Options for click interaction that opens/closes the lightbox (inherited from FloatingProps). |
22
+ | `hoverProps` | `UseHoverProps` | - | Options for hover interaction (inherited from FloatingProps). |
23
+ | `focusProps` | `UseFocusProps` | - | Options for focus interaction (inherited from FloatingProps). |
24
+ | `offsetOptions` | `OffsetOptions` | - | Offset distance from the reference element (inherited from FloatingProps). |
25
+ | `children` | `React.ReactNode` | - | Trigger element — should be wrapped in a FloatingTrigger to wire up open/close interaction. |
26
+
27
+ *Required props
28
+
29
+ ## Examples
30
+
31
+ ### Image gallery with multiple slides
32
+
33
+ ```tsx
34
+ <Lightbox
35
+ slides={[
36
+ { source: { type: 'image', src: 'https://example.com/photo1.jpg' }, title: 'Photo 1' },
37
+ { source: { type: 'image', src: 'https://example.com/photo2.jpg' }, title: 'Photo 2' },
38
+ { source: { type: 'image', src: 'https://example.com/photo3.jpg' }, title: 'Photo 3' },
39
+ ]}
40
+ >
41
+ <FloatingTrigger>
42
+ <button>Open Gallery</button>
43
+ </FloatingTrigger>
44
+ </Lightbox>
45
+ ```
46
+
47
+ ### Open at a specific slide index
48
+
49
+ ```tsx
50
+ <Lightbox
51
+ defaultActiveIndex={1}
52
+ slides={[
53
+ { source: { type: 'image', src: 'https://example.com/photo1.jpg' }, title: 'First' },
54
+ { source: { type: 'image', src: 'https://example.com/photo2.jpg' }, title: 'Second' },
55
+ ]}
56
+ >
57
+ <FloatingTrigger>
58
+ <button>Open at Second Image</button>
59
+ </FloatingTrigger>
60
+ </Lightbox>
61
+ ```
62
+
63
+ ### Mixed image and video slides
64
+
65
+ ```tsx
66
+ <Lightbox
67
+ slides={[
68
+ { source: { type: 'image', src: 'https://example.com/thumbnail.jpg' }, title: 'Product Photo' },
69
+ {
70
+ source: {
71
+ type: 'video',
72
+ src: 'https://example.com/product-demo.mp4',
73
+ thumbnail: 'https://example.com/video-thumb.jpg',
74
+ },
75
+ title: 'Product Demo',
76
+ },
77
+ ]}
78
+ >
79
+ <FloatingTrigger>
80
+ <button>View Media</button>
81
+ </FloatingTrigger>
82
+ </Lightbox>
83
+ ```
84
+
85
+ ## Related Components
86
+
87
+ - [Floating](../floating/README.md)
88
+ - [FloatingClose](../floatingclose/README.md)
89
+ - [FloatingContent](../floatingcontent/README.md)
90
+ - [IconButton](../iconbutton/README.md)
91
+ - [Image](../image/README.md)
92
+ - [Swiper](../swiper/README.md)
93
+ - [SwiperSlide](../swiperslide/README.md)
94
+
95
+ ## Dependencies
96
+
97
+ - motion/react
98
+ - react-player
99
+ - react-zoom-pan-pinch
100
+ - @floating-ui/react
101
+ - lodash-es
102
+
103
+ ## See Also
104
+
105
+ - [Component Source](./index.ts)
106
+ - [Storybook Stories](./lightbox.stories.tsx)
107
+ - [Main README](../../README.md)
@@ -0,0 +1,54 @@
1
+ # LinearProgress
2
+
3
+ A horizontal progress bar component that supports both determinate (known progress value) and indeterminate (loading/unknown) states. Commonly used to indicate file upload progress, page load status, or any operation with measurable or unknown completion.
4
+
5
+ ## Import
6
+
7
+ ```tsx
8
+ import { LinearProgress } from '@janbox/storefront-ui';
9
+ ```
10
+
11
+ ## Props
12
+
13
+ | Prop | Type | Default | Description |
14
+ |------|------|---------|-------------|
15
+ | `value` | `number` | - | Progress value as a percentage (0–100). When omitted, the component falls back to indeterminate mode automatically. |
16
+ | `variant` | `'determinate' \| 'indeterminate'` | - | Explicitly set the progress mode. If not provided, inferred from whether `value` is set: defined value → determinate, undefined value → indeterminate. |
17
+ | `color` | `ColorVariant` | `primary` | Color theme of the progress bar. Accepts any ColorVariant token: `'primary' \| 'secondary' \| 'green' \| 'red' \| 'orange' \| 'blue' \| 'neutral'`. |
18
+ | `size` | `number` | `4` | Height of the progress bar in pixels. Border-radius is automatically set to `size/2` to keep pill shape. |
19
+ | `sm` | `LinearProgressResponsiveProps` | - | Responsive overrides at the `sm` breakpoint (≥768px). Accepts `{ size?: number }`. |
20
+ | `md` | `LinearProgressResponsiveProps` | - | Responsive overrides at the `md` breakpoint (≥1280px). Accepts `{ size?: number }`. |
21
+ | `lg` | `LinearProgressResponsiveProps` | - | Responsive overrides at the `lg` breakpoint (≥1680px). Accepts `{ size?: number }`. |
22
+ | `duration` | `number` | - | Khai báo trong props type nhưng chưa được sử dụng trong implementation hiện tại — reserved cho việc kiểm soát animation duration trong tương lai. |
23
+
24
+ ## Examples
25
+
26
+ ### Determinate progress at 70%
27
+
28
+ ```tsx
29
+ <LinearProgress value={70} color="primary" style={{ width: 400 }} />
30
+ ```
31
+
32
+ ### Indeterminate (loading) state
33
+
34
+ ```tsx
35
+ <LinearProgress variant="indeterminate" style={{ width: '100%' }} />
36
+ ```
37
+
38
+ ### Thick success bar with green color
39
+
40
+ ```tsx
41
+ <LinearProgress value={100} color="green" size={8} style={{ width: 400 }} />
42
+ ```
43
+
44
+ ## Dependencies
45
+
46
+ - motion/react
47
+ - lodash-es
48
+ - @emotion/react
49
+
50
+ ## See Also
51
+
52
+ - [Component Source](./index.ts)
53
+ - [Storybook Stories](./linearprogress.stories.tsx)
54
+ - [Main README](../../README.md)
@@ -0,0 +1,67 @@
1
+ # Link
2
+
3
+ A navigation link component built on top of React Router's Link, supporting typography variants, optional underline effects, and responsive styling via the sx prop. Use it for internal and external navigation within a React Router context.
4
+
5
+ ## Import
6
+
7
+ ```tsx
8
+ import { Link } from '@janbox/storefront-ui';
9
+ ```
10
+
11
+ ## Props
12
+
13
+ | Prop | Type | Default | Description |
14
+ |------|------|---------|-------------|
15
+ | `to` | `ReactRouterLinkProps['to']` | - | Navigation destination — can be a path string, URL object, or React Router To value. If omitted, click events are prevented. |
16
+ | `underline` | `boolean` | false | When true, applies a hover underline animation effect via createUnderlineEffect(). |
17
+ | `textVariant` | `TypographySizeVariant` | - | Typography size variant applied to the link text. Accepts 'xs' | 'sm' | 'base' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl' | '6xl'. Supports responsive overrides via sm/md/lg. |
18
+ | `sm` | `LinkResponsiveProps` | - | Responsive overrides applied at the sm breakpoint (≥768px). Accepts { textVariant }. |
19
+ | `md` | `LinkResponsiveProps` | - | Responsive overrides applied at the md breakpoint (≥1280px). Accepts { textVariant }. |
20
+ | `lg` | `LinkResponsiveProps` | - | Responsive overrides applied at the lg breakpoint (≥1680px). Accepts { textVariant }. |
21
+ | `sx` | `ToResponsiveProps<StyledCSS>` | - | Escape-hatch for custom Emotion CSS styles, including responsive overrides via sx.sm / sx.md / sx.lg. |
22
+ | `children` | `React.ReactNode` | - | Content rendered inside the anchor element. |
23
+ | `ref` | `Ref<HTMLAnchorElement>` | - | Forwarded ref to the underlying anchor element. |
24
+ | `aria-disabled` | `string` | - | When set to 'true', click events are prevented and pointer-events are set to none, making the link non-interactive without removing it from the DOM. |
25
+ | `target` | `string` | - | Standard HTML anchor target attribute, e.g. '_blank' for external links. Passed through to the underlying ReactRouterLink. |
26
+
27
+ ## Examples
28
+
29
+ ### Default navigation link
30
+
31
+ ```tsx
32
+ <Link to="/products">Browse products</Link>
33
+ ```
34
+
35
+ ### Link with underline hover effect and typography variant
36
+
37
+ ```tsx
38
+ <Link to="/about" underline textVariant="sm">
39
+ Learn more about us
40
+ </Link>
41
+ ```
42
+
43
+ ### External link opening in new tab, responsive text size
44
+
45
+ ```tsx
46
+ <Link
47
+ to="https://example.com"
48
+ target="_blank"
49
+ textVariant="xs"
50
+ md={{ textVariant: 'sm' }}
51
+ sx={{ color: 'var(--color-primary-600)' }}
52
+ >
53
+ Visit external site
54
+ </Link>
55
+ ```
56
+
57
+ ## Dependencies
58
+
59
+ - react-router
60
+ - @emotion/react
61
+ - lodash-es
62
+
63
+ ## See Also
64
+
65
+ - [Component Source](./index.ts)
66
+ - [Storybook Stories](./link.stories.tsx)
67
+ - [Main README](../../README.md)
@@ -0,0 +1,65 @@
1
+ # LoadingOverlay
2
+
3
+ A suite of loading/skeleton components for displaying placeholder states and loading indicators. Includes BlockSkeleton, ImageSkeleton, TextSkeleton (animated pulse placeholders) and LoadingOverlay (spinning icon overlay for async content).
4
+
5
+ ## Import
6
+
7
+ ```tsx
8
+ import { LoadingOverlay } from '@janbox/storefront-ui';
9
+ ```
10
+
11
+ ## Props
12
+
13
+ | Prop | Type | Default | Description |
14
+ |------|------|---------|-------------|
15
+ | `isLoading` | `boolean` | false | Controls whether the loading overlay spinner is visible over the content. |
16
+ | `size` | `number` | 32 | Size in pixels for the spinning loader icon and minimum dimensions of the container. |
17
+ | `color` | `ColorVariant` | 'primary' | Color variant for the spinning loader icon. Accepts 'primary' | 'secondary' | 'green' | 'red' | 'orange' | 'blue' | 'neutral'. |
18
+ | `iconProps` | `PrimitiveProps<JSX.IntrinsicElements['div']>` | - | Additional props passed to the overlay container div that wraps the spinner icon. |
19
+ | `children` | `React.ReactNode` | - | Content rendered beneath the overlay. Visible when isLoading is false; obscured by the spinner when isLoading is true. |
20
+ | `sx` | `ToResponsiveProps<StyledCSS>` | - | Responsive style overrides via the sx prop, inherited from PrimitiveProps. |
21
+ | `style` | `React.CSSProperties` | - | Inline style for the root container. Merged with the minWidth/minHeight derived from size. |
22
+
23
+ ## Examples
24
+
25
+ ### LoadingOverlay wrapping async content
26
+
27
+ ```tsx
28
+ <LoadingOverlay isLoading style={{ width: 300, height: 200, position: 'relative' }}>
29
+ <div style={{ padding: 16 }}>Content behind overlay</div>
30
+ </LoadingOverlay>
31
+ ```
32
+
33
+ ### Skeleton placeholders for a card layout
34
+
35
+ ```tsx
36
+ <div style={{ width: 300 }}>
37
+ <ImageSkeleton style={{ width: 300, height: 160, marginBottom: 12 }} />
38
+ <TextSkeleton sx={{ width: 160 }} style={{ marginBottom: 8 }} />
39
+ <TextSkeleton style={{ marginBottom: 8, width: '80%' }} />
40
+ <TextSkeleton style={{ width: '60%' }} />
41
+ </div>
42
+ ```
43
+
44
+ ### BlockSkeleton for generic placeholder blocks
45
+
46
+ ```tsx
47
+ <BlockSkeleton style={{ width: 300, height: 100 }} />
48
+ ```
49
+
50
+ ## Related Components
51
+
52
+ - [Primitive](../primitive/README.md)
53
+ - [SvgLoader](../svgloader/README.md)
54
+
55
+ ## Dependencies
56
+
57
+ - @emotion/react
58
+ - @janbox/storefront-ui/constants (animatePulseStyle, animateSpinStyle)
59
+ - @janbox/storefront-ui/theme (getColorVar, getColorShadesByVariant)
60
+
61
+ ## See Also
62
+
63
+ - [Component Source](./index.ts)
64
+ - [Storybook Stories](./loadingoverlay.stories.tsx)
65
+ - [Main README](../../README.md)
@@ -0,0 +1,83 @@
1
+ # Marquee
2
+
3
+ A horizontally auto-scrolling carousel component built on top of Embla Carousel with the AutoScroll plugin. Use it to display a continuous looping ticker of items — logos, tags, or any inline content — with configurable spacing and an optional separator icon between items.
4
+
5
+ ## Import
6
+
7
+ ```tsx
8
+ import { Marquee } from '@janbox/storefront-ui';
9
+ ```
10
+
11
+ ## Props
12
+
13
+ | Prop | Type | Default | Description |
14
+ |------|------|---------|-------------|
15
+ | `spaceBetween` | `number` | - | Gap in pixels between each marquee slide. Supports responsive variants via sm/md/lg props. |
16
+ | `sm` | `MarqueeResponsiveProps` | - | Responsive overrides for screens ≥768px. Accepts { spaceBetween?: number }. |
17
+ | `md` | `MarqueeResponsiveProps` | - | Responsive overrides for screens ≥1280px. Accepts { spaceBetween?: number }. |
18
+ | `lg` | `MarqueeResponsiveProps` | - | Responsive overrides for screens ≥1680px. Accepts { spaceBetween?: number }. |
19
+ | `autoScrollOptions` | `AutoScrollOptionsType` | { playOnInit: true, stopOnFocusIn: false, stopOnInteraction: false, stopOnMouseEnter: false } | Options passed directly to the embla-carousel-auto-scroll plugin. Controls playback behaviour such as playOnInit, stopOnMouseEnter, stopOnInteraction, and stopOnFocusIn. |
20
+ | `separatorIcon` | `IconProps` | - | Optional icon rendered as a separator slide between every content item. |
21
+ | `children` | `React.ReactNode` | - | Slide content. Each direct child is wrapped in an individual slide. Intended to be composed with MarqueeItem. |
22
+ | `sx` | `ToResponsiveProps<StyledCSS>` | - | Emotion sx prop for custom responsive styles on the root container. |
23
+
24
+ ## Examples
25
+
26
+ ### Default — basic text items
27
+
28
+ ```tsx
29
+ <div style={{ width: 400 }}>
30
+ <Marquee spaceBetween={16}>
31
+ {Array.from({ length: 10 }).map((_, index) => (
32
+ <MarqueeItem key={index}>Item {index + 1}</MarqueeItem>
33
+ ))}
34
+ </Marquee>
35
+ </div>
36
+ ```
37
+
38
+ ### Logo ticker with separator icon
39
+
40
+ ```tsx
41
+ <Marquee
42
+ spaceBetween={24}
43
+ separatorIcon={{ source: DotIcon, size: 8 }}
44
+ >
45
+ <MarqueeItem><img src="/logo-a.svg" alt="Brand A" /></MarqueeItem>
46
+ <MarqueeItem><img src="/logo-b.svg" alt="Brand B" /></MarqueeItem>
47
+ <MarqueeItem><img src="/logo-c.svg" alt="Brand C" /></MarqueeItem>
48
+ </Marquee>
49
+ ```
50
+
51
+ ### Pause on mouse enter with responsive spacing
52
+
53
+ ```tsx
54
+ <Marquee
55
+ spaceBetween={8}
56
+ sm={{ spaceBetween: 16 }}
57
+ md={{ spaceBetween: 24 }}
58
+ autoScrollOptions={{ playOnInit: true, stopOnMouseEnter: true }}
59
+ >
60
+ {tags.map((tag) => (
61
+ <MarqueeItem key={tag}>
62
+ <Badge color="primary">{tag}</Badge>
63
+ </MarqueeItem>
64
+ ))}
65
+ </Marquee>
66
+ ```
67
+
68
+ ## Related Components
69
+
70
+ - [Icon](../icon/README.md)
71
+ - [Primitive](../primitive/README.md)
72
+
73
+ ## Dependencies
74
+
75
+ - embla-carousel-react
76
+ - embla-carousel-auto-scroll
77
+ - @floating-ui/react
78
+
79
+ ## See Also
80
+
81
+ - [Component Source](./index.ts)
82
+ - [Storybook Stories](./marquee.stories.tsx)
83
+ - [Main README](../../README.md)
@@ -0,0 +1,92 @@
1
+ # Menu
2
+
3
+ Dropdown menu component hiển thị danh sách actions hoặc options khi được kích hoạt. Xây dựng trên Floating UI, hỗ trợ tương tác hover và click với safe polygon hover detection.
4
+
5
+ ## Import
6
+
7
+ ```tsx
8
+ import { Menu } from '@janbox/storefront-ui';
9
+ ```
10
+
11
+ ## Props
12
+
13
+ | Prop | Type | Default | Description |
14
+ |------|------|---------|-------------|
15
+ | `placement` | `Placement` | `'bottom'` | Vị trí của menu so với trigger (vd: `'top'`, `'bottom'`, `'left'`, `'right'`, và các biến thể như `'top-start'`) |
16
+ | `open` | `boolean` | - | Controlled open state của menu |
17
+ | `onOpenChange` | `(open: boolean, event?: Event, reason?: string) => void` | - | Callback khi trạng thái open thay đổi |
18
+ | `clickProps` | `UseClickProps` | - | Cấu hình tương tác click (bật mặc định) |
19
+ | `dismissProps` | `UseDismissProps` | - | Cấu hình dismiss khi click ra ngoài (bật mặc định) |
20
+ | `hoverProps` | `UseHoverProps` | - | Cấu hình tương tác hover (dùng `safePolygon` mặc định để tránh đóng nhầm) |
21
+ | `focusProps` | `UseFocusProps` | - | Cấu hình tương tác focus |
22
+ | `offsetOptions` | `OffsetOptions` | - | Khoảng cách giữa trigger và menu content |
23
+ | `sizeOptions` | `SizeOptions` | - | Ràng buộc kích thước của floating menu |
24
+ | `autoUpdateOptions` | `AutoUpdateOptions` | - | Tùy chọn tự động cập nhật vị trí menu |
25
+ | `children` * | `ReactNode` | - | Nội dung menu (thường là `MenuTrigger` và `MenuList`) |
26
+
27
+ *Bắt buộc
28
+
29
+ ## Examples
30
+
31
+ ### Basic Menu
32
+
33
+ ```tsx
34
+ <Menu>
35
+ <MenuTrigger>
36
+ <button>Open Menu ▼</button>
37
+ </MenuTrigger>
38
+ <MenuList>
39
+ <MenuItem>Profile</MenuItem>
40
+ <MenuItem>Settings</MenuItem>
41
+ <MenuItem>Help</MenuItem>
42
+ <MenuItem>Logout</MenuItem>
43
+ </MenuList>
44
+ </Menu>
45
+ ```
46
+
47
+ ### Menu with Icons
48
+
49
+ ```tsx
50
+ <Menu>
51
+ <MenuTrigger>
52
+ <button>Actions ▼</button>
53
+ </MenuTrigger>
54
+ <MenuList>
55
+ <MenuItem>✏️ Edit</MenuItem>
56
+ <MenuItem>📋 Copy</MenuItem>
57
+ <MenuItem>🗑️ Delete</MenuItem>
58
+ </MenuList>
59
+ </Menu>
60
+ ```
61
+
62
+ ### Top Placement Menu
63
+
64
+ ```tsx
65
+ <Menu placement="top">
66
+ <MenuTrigger>
67
+ <button>Open Top ▲</button>
68
+ </MenuTrigger>
69
+ <MenuList>
70
+ <MenuItem>Option 1</MenuItem>
71
+ <MenuItem>Option 2</MenuItem>
72
+ <MenuItem>Option 3</MenuItem>
73
+ </MenuList>
74
+ </Menu>
75
+ ```
76
+
77
+ ## Related Components
78
+
79
+ - [Floating](../floating/README.md)
80
+ - [FloatingTrigger](../floating-trigger/README.md)
81
+ - [FloatingContent](../floating-content/README.md)
82
+ - [Button](../button/README.md)
83
+
84
+ ## Dependencies
85
+
86
+ - `@floating-ui/react`
87
+
88
+ ## See Also
89
+
90
+ - [Component Source](./index.ts)
91
+ - [Storybook Stories](./menu.stories.tsx)
92
+ - [Main README](../../README.md)