@janbox/storefront-ui 2.0.29 → 2.0.31
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/README.md +692 -0
- package/dist/lib/accordion/README.md +81 -0
- package/dist/lib/avatar/README.md +74 -0
- package/dist/lib/badge/README.md +58 -0
- package/dist/lib/box/README.md +69 -0
- package/dist/lib/breadcrumbs/README.md +70 -0
- package/dist/lib/button/README.md +115 -0
- package/dist/lib/cascader/README.md +128 -0
- package/dist/lib/checkbox/README.md +74 -0
- package/dist/lib/checkbox/checkbox.js +107 -12
- package/dist/lib/checkbox/types.d.ts +2 -2
- package/dist/lib/chip/README.md +72 -0
- package/dist/lib/collapse/README.md +78 -0
- package/dist/lib/container/README.md +59 -0
- package/dist/lib/count-up/README.md +52 -0
- package/dist/lib/countdown-timer/README.md +77 -0
- package/dist/lib/date-picker/README.md +94 -0
- package/dist/lib/dialog/README.md +109 -0
- package/dist/lib/drawer/README.md +97 -0
- package/dist/lib/filter-panel/README.md +146 -0
- package/dist/lib/flag/README.md +58 -0
- package/dist/lib/flexbox/README.md +59 -0
- package/dist/lib/floating/README.md +109 -0
- package/dist/lib/form-helper-text/README.md +54 -0
- package/dist/lib/form-label/README.md +50 -0
- package/dist/lib/grid/README.md +72 -0
- package/dist/lib/highlight-words/README.md +64 -0
- package/dist/lib/highlight-words/highlight-words.js +1 -2
- package/dist/lib/icon/README.md +69 -0
- package/dist/lib/icon-button/README.md +92 -0
- package/dist/lib/image/README.md +80 -0
- package/dist/lib/input/README.md +118 -0
- package/dist/lib/input-mask/README.md +88 -0
- package/dist/lib/input-number/README.md +92 -0
- package/dist/lib/input-range/README.md +85 -0
- package/dist/lib/lightbox/README.md +107 -0
- package/dist/lib/linear-progress/README.md +54 -0
- package/dist/lib/link/README.md +67 -0
- package/dist/lib/loading/README.md +65 -0
- package/dist/lib/marquee/README.md +83 -0
- package/dist/lib/marquee/marquee/marquee.js +1 -1
- package/dist/lib/menu/README.md +92 -0
- package/dist/lib/multiple-select/README.md +108 -0
- package/dist/lib/nav-link/README.md +61 -0
- package/dist/lib/notifications/README.md +103 -0
- package/dist/lib/otp-input/README.md +71 -0
- package/dist/lib/pagination/README.md +84 -0
- package/dist/lib/phone-input/README.md +80 -0
- package/dist/lib/popover/README.md +93 -0
- package/dist/lib/price-label/README.md +78 -0
- package/dist/lib/primitive/README.md +80 -0
- package/dist/lib/progress/README.md +50 -0
- package/dist/lib/radio-button/README.md +89 -0
- package/dist/lib/radio-button/radio-button.js +98 -7
- package/dist/lib/ripple-effect/README.md +66 -0
- package/dist/lib/select/README.md +124 -0
- package/dist/lib/star-rating/README.md +67 -0
- package/dist/lib/stepper/README.md +99 -0
- package/dist/lib/suspense-query/README.md +78 -0
- package/dist/lib/swiper/README.md +99 -0
- package/dist/lib/switch/README.md +73 -0
- package/dist/lib/switch/switch.d.ts +1 -1
- package/dist/lib/switch/switch.js +110 -11
- package/dist/lib/table/README.md +115 -0
- package/dist/lib/tabs/README.md +103 -0
- package/dist/lib/text/README.md +59 -0
- package/dist/lib/textarea/README.md +76 -0
- package/dist/lib/time-picker/README.md +100 -0
- package/dist/lib/tooltip/README.md +106 -0
- package/dist/lib/unordered-list/README.md +85 -0
- package/dist/lib/video/README.md +88 -0
- package/dist/style.css +1 -244
- package/package.json +5 -5
- package/dist/lib/checkbox/checkbox.module.scss.js +0 -23
- package/dist/lib/radio-button/radio-button.module.scss.js +0 -17
- package/dist/lib/switch/switch.module.scss.js +0 -14
|
@@ -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)
|