@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.
- package/README.md +681 -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/date-picker/date-picker.js +2 -1
- 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/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/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
- package/dist/style.css +0 -823
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Grid
|
|
2
|
+
|
|
3
|
+
A CSS Grid layout component that renders a responsive grid container with configurable column counts. It works in tandem with the Cell component, which supports colSpan for spanning multiple columns.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { Grid } from '@janbox/storefront-ui';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Props
|
|
12
|
+
|
|
13
|
+
| Prop | Type | Default | Description |
|
|
14
|
+
|------|------|---------|-------------|
|
|
15
|
+
| `cols` | `number` | 1 | Number of equal-width columns in the grid. Generates `grid-template-columns: repeat(cols, minmax(0, 1fr))`. Supports responsive variants via sm/md/lg. |
|
|
16
|
+
| `sm` | `GridResponsiveProps` | - | Responsive overrides applied at the sm breakpoint (≥768px). Accepts `{ cols?: number }`. |
|
|
17
|
+
| `md` | `GridResponsiveProps` | - | Responsive overrides applied at the md breakpoint (≥1280px). Accepts `{ cols?: number }`. |
|
|
18
|
+
| `lg` | `GridResponsiveProps` | - | Responsive overrides applied at the lg breakpoint (≥1680px). Accepts `{ cols?: number }`. |
|
|
19
|
+
| `container` | `boolean` | false | When true, applies the shared responsive container styles (padding and max-width) from `containerStyle`. |
|
|
20
|
+
| `sx` | `ToResponsiveProps<StyledCSS>` | - | Escape-hatch for inline Emotion styles. Supports responsive keys (sm, md, lg) alongside base styles. |
|
|
21
|
+
| `children` | `React.ReactNode` | - | Grid children, typically Cell components. |
|
|
22
|
+
| `ref` | `React.Ref<HTMLDivElement>` | - | Forwarded ref to the underlying div element. |
|
|
23
|
+
|
|
24
|
+
## Examples
|
|
25
|
+
|
|
26
|
+
### Two-column grid
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
<Grid cols={2} style={{ width: 600 }}>
|
|
30
|
+
<Cell style={{ padding: 8, background: '#e0f0ff' }}>Cell 1</Cell>
|
|
31
|
+
<Cell style={{ padding: 8, background: '#f0ffe0' }}>Cell 2</Cell>
|
|
32
|
+
<Cell style={{ padding: 8, background: '#fff0e0' }}>Cell 3</Cell>
|
|
33
|
+
<Cell style={{ padding: 8, background: '#f0e0ff' }}>Cell 4</Cell>
|
|
34
|
+
</Grid>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Three-column grid with colSpan
|
|
38
|
+
|
|
39
|
+
```tsx
|
|
40
|
+
<Grid cols={3} style={{ width: 600 }}>
|
|
41
|
+
<Cell colSpan={2} style={{ padding: 8, background: '#e0f0ff' }}>Span 2 columns</Cell>
|
|
42
|
+
<Cell style={{ padding: 8, background: '#f0ffe0' }}>Cell 2</Cell>
|
|
43
|
+
<Cell style={{ padding: 8, background: '#fff0e0' }}>Cell 3</Cell>
|
|
44
|
+
<Cell style={{ padding: 8, background: '#f0e0ff' }}>Cell 4</Cell>
|
|
45
|
+
</Grid>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Responsive columns (1 on mobile, 2 on tablet, 4 on desktop)
|
|
49
|
+
|
|
50
|
+
```tsx
|
|
51
|
+
<Grid cols={1} sm={{ cols: 2 }} md={{ cols: 4 }} container>
|
|
52
|
+
<Cell>Item 1</Cell>
|
|
53
|
+
<Cell>Item 2</Cell>
|
|
54
|
+
<Cell>Item 3</Cell>
|
|
55
|
+
<Cell>Item 4</Cell>
|
|
56
|
+
</Grid>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Related Components
|
|
60
|
+
|
|
61
|
+
- [Cell](./cell/README.md)
|
|
62
|
+
- [Primitive](../primitive/README.md)
|
|
63
|
+
|
|
64
|
+
## Dependencies
|
|
65
|
+
|
|
66
|
+
- lodash-es
|
|
67
|
+
|
|
68
|
+
## See Also
|
|
69
|
+
|
|
70
|
+
- [Component Source](./index.ts)
|
|
71
|
+
- [Storybook Stories](./grid.stories.tsx)
|
|
72
|
+
- [Main README](../../README.md)
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# HighlightWords
|
|
2
|
+
|
|
3
|
+
Renders a text string with specified search words highlighted using bold font weight. Built on top of `highlight-words-core`, it is useful for search result UIs where matched terms need to be visually distinguished within a body of text.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { HighlightWords } from '@janbox/storefront-ui';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Props
|
|
12
|
+
|
|
13
|
+
| Prop | Type | Default | Description |
|
|
14
|
+
|------|------|---------|-------------|
|
|
15
|
+
| `textToHighlight*` | `string` | - | The full text string to display and search within. |
|
|
16
|
+
| `searchWords*` | `string[]` | - | Array of words or phrases to highlight within the text. |
|
|
17
|
+
| `highlightClassName` | `string` | - | Optional CSS class name(s) applied to the highlighted `<span>` elements. Useful for custom highlight styling (e.g. background color). |
|
|
18
|
+
| `caseSensitive` | `boolean` | `false` | Whether the search matching should be case-sensitive. Defaults to false (case-insensitive). |
|
|
19
|
+
| `autoEscape` | `boolean` | `false` | Whether to escape special regex characters in the search words before matching. |
|
|
20
|
+
| `sanitize` | `(text: string) => string` | - | Optional function to sanitize/normalize text before matching (e.g. removing diacritics). |
|
|
21
|
+
| `findChunks` | `(args: FindChunksArgs) => Chunk[]` | - | Custom chunk-finding function to override the default highlight-words-core matching logic. |
|
|
22
|
+
|
|
23
|
+
*Required props
|
|
24
|
+
|
|
25
|
+
## Examples
|
|
26
|
+
|
|
27
|
+
### Basic usage
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
<HighlightWords
|
|
31
|
+
textToHighlight="The quick brown fox jumps over the lazy dog"
|
|
32
|
+
searchWords={["fox", "dog"]}
|
|
33
|
+
/>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Case-sensitive matching
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
<HighlightWords
|
|
40
|
+
textToHighlight="Hello World hello world"
|
|
41
|
+
searchWords={["Hello"]}
|
|
42
|
+
caseSensitive
|
|
43
|
+
/>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Custom highlight class
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
<HighlightWords
|
|
50
|
+
textToHighlight="React is a JavaScript library for building user interfaces"
|
|
51
|
+
searchWords={["React", "JavaScript"]}
|
|
52
|
+
highlightClassName="bg-yellow-200 font-bold"
|
|
53
|
+
/>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Dependencies
|
|
57
|
+
|
|
58
|
+
- highlight-words-core
|
|
59
|
+
|
|
60
|
+
## See Also
|
|
61
|
+
|
|
62
|
+
- [Component Source](./index.ts)
|
|
63
|
+
- [Storybook Stories](./highlightwords.stories.tsx)
|
|
64
|
+
- [Main README](../../README.md)
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { jsx } from "@emotion/react/jsx-runtime";
|
|
2
2
|
import { Fragment } from "react";
|
|
3
3
|
import { findAll } from "highlight-words-core";
|
|
4
|
-
import { clsx } from "clsx";
|
|
5
4
|
const HighlightWords = ({ highlightClassName, ...props }) => {
|
|
6
5
|
const chunks = findAll(props);
|
|
7
6
|
return /* @__PURE__ */ jsx(Fragment, { children: chunks.map((chunk, index) => {
|
|
8
7
|
const { end, highlight, start } = chunk;
|
|
9
8
|
const text = props.textToHighlight.substring(start, end);
|
|
10
|
-
return /* @__PURE__ */ jsx(Fragment, { children: highlight ? /* @__PURE__ */ jsx("span", { css: { fontWeight: 500 }, className:
|
|
9
|
+
return /* @__PURE__ */ jsx(Fragment, { children: highlight ? /* @__PURE__ */ jsx("span", { css: { fontWeight: 500 }, className: highlightClassName, children: text }) : text }, index);
|
|
11
10
|
}) });
|
|
12
11
|
};
|
|
13
12
|
export {
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Icon
|
|
2
|
+
|
|
3
|
+
A responsive SVG icon component that renders raw SVG strings via the SvgLoader component. Supports numeric size control with responsive breakpoint overrides (sm/md/lg) and the sx prop for custom styling.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { Icon } from '@janbox/storefront-ui';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Props
|
|
12
|
+
|
|
13
|
+
| Prop | Type | Default | Description |
|
|
14
|
+
|------|------|---------|-------------|
|
|
15
|
+
| `source*` | `string` | - | Raw SVG string to render. Typically imported via Vite's ?raw query (e.g. import MyIcon from '@/assets/svg/my-icon.svg?raw'). |
|
|
16
|
+
| `size` | `number` | 24 | Width and height of the icon in pixels. Applied as the base (mobile-first) size. |
|
|
17
|
+
| `sm` | `{ size?: number }` | - | Responsive overrides applied at the sm breakpoint (≥768px). Accepts an object with the same responsive props. |
|
|
18
|
+
| `md` | `{ size?: number }` | - | Responsive overrides applied at the md breakpoint (≥1280px). Accepts an object with the same responsive props. |
|
|
19
|
+
| `lg` | `{ size?: number }` | - | Responsive overrides applied at the lg breakpoint (≥1680px). Accepts an object with the same responsive props. |
|
|
20
|
+
| `sx` | `ToResponsiveProps<StyledCSS>` | - | Escape hatch for custom Emotion CSS. Supports responsive keys (sm/md/lg) for breakpoint-scoped styles. |
|
|
21
|
+
| `...svgProps` | `JSX.IntrinsicElements['svg']` | - | All native SVG element attributes (e.g. className, style, aria-label, onClick) are forwarded to the underlying svg element. |
|
|
22
|
+
|
|
23
|
+
*Required props
|
|
24
|
+
|
|
25
|
+
## Examples
|
|
26
|
+
|
|
27
|
+
### Default icon at 24px
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
import HomeIcon from '@/assets/svg/home.svg?raw';
|
|
31
|
+
|
|
32
|
+
<Icon source={HomeIcon} />
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Custom size with accessible label
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
import StarIcon from '@/assets/svg/star.svg?raw';
|
|
39
|
+
|
|
40
|
+
<Icon source={StarIcon} size={32} aria-label="Favourite" />
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Responsive size across breakpoints
|
|
44
|
+
|
|
45
|
+
```tsx
|
|
46
|
+
import SearchIcon from '@/assets/svg/search.svg?raw';
|
|
47
|
+
|
|
48
|
+
<Icon
|
|
49
|
+
source={SearchIcon}
|
|
50
|
+
size={20}
|
|
51
|
+
sm={{ size: 20 }}
|
|
52
|
+
md={{ size: 24 }}
|
|
53
|
+
lg={{ size: 28 }}
|
|
54
|
+
/>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Related Components
|
|
58
|
+
|
|
59
|
+
- [SvgLoader](../svgloader/README.md)
|
|
60
|
+
|
|
61
|
+
## Dependencies
|
|
62
|
+
|
|
63
|
+
- @emotion/react
|
|
64
|
+
|
|
65
|
+
## See Also
|
|
66
|
+
|
|
67
|
+
- [Component Source](./index.ts)
|
|
68
|
+
- [Storybook Stories](./icon.stories.tsx)
|
|
69
|
+
- [Main README](../../README.md)
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# IconButton
|
|
2
|
+
|
|
3
|
+
A button component that renders an icon (and optionally children) with support for contained, outlined, and text variants. Designed for icon-only or icon-with-label actions, with built-in loading state, ripple effect, and responsive sizing.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { IconButton } from '@janbox/storefront-ui';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Props
|
|
12
|
+
|
|
13
|
+
| Prop | Type | Default | Description |
|
|
14
|
+
|------|------|---------|-------------|
|
|
15
|
+
| `icon` | `IconProps` | - | Icon to render inside the button. Accepts an SVG raw string via `source` plus any Icon component props (size, sx, responsive breakpoints). |
|
|
16
|
+
| `variant` | `'contained' \| 'outlined' \| 'text'` | `'text'` | Visual style of the button. |
|
|
17
|
+
| `color` | `'primary' \| 'secondary' \| 'green' \| 'red' \| 'orange' \| 'blue' \| 'neutral'` | `'primary'` | Color variant that controls background, border, and icon color based on the design token palette. |
|
|
18
|
+
| `size` | `'xs' \| 'sm' \| 'md' \| 'lg'` | `'md'` | Controls the minimum width/height of the button and icon size. |
|
|
19
|
+
| `isLoading` | `boolean` | `false` | When true, hides the icon and shows a spinning loading indicator. Disables pointer events. |
|
|
20
|
+
| `sx` | `ToResponsiveProps<StyledCSS>` | - | Escape hatch for custom Emotion CSS styles, including responsive overrides at sm/md/lg breakpoints. |
|
|
21
|
+
| `sm` | `IconButtonResponsiveProps` | - | Responsive size override applied at the sm breakpoint (≥768px). |
|
|
22
|
+
| `md` | `IconButtonResponsiveProps` | - | Responsive size override applied at the md breakpoint (≥1280px). |
|
|
23
|
+
| `lg` | `IconButtonResponsiveProps` | - | Responsive size override applied at the lg breakpoint (≥1680px). |
|
|
24
|
+
| `disabled` | `boolean` | `false` | Native HTML disabled attribute. Disables pointer events and applies neutral disabled colors. |
|
|
25
|
+
| `aria-disabled` | `boolean \| 'true' \| 'false'` | - | Aria-disabled state. Applies disabled styling without removing the element from the tab order. |
|
|
26
|
+
| `children` | `React.ReactNode` | - | Optional content rendered alongside the icon (e.g. a label). |
|
|
27
|
+
| `onClick` | `React.MouseEventHandler<HTMLButtonElement>` | - | Click handler forwarded from native button props. |
|
|
28
|
+
|
|
29
|
+
## Examples
|
|
30
|
+
|
|
31
|
+
### Text variant (default) with a star icon
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
<IconButton icon={{ source: starSvg }} onClick={handleClick} />
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Contained primary button with loading state
|
|
38
|
+
|
|
39
|
+
```tsx
|
|
40
|
+
<IconButton
|
|
41
|
+
icon={{ source: searchSvg }}
|
|
42
|
+
variant="contained"
|
|
43
|
+
color="primary"
|
|
44
|
+
isLoading={isFetching}
|
|
45
|
+
/>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Outlined small close button with aria-disabled
|
|
49
|
+
|
|
50
|
+
```tsx
|
|
51
|
+
<IconButton
|
|
52
|
+
icon={{ source: closeSvg }}
|
|
53
|
+
variant="outlined"
|
|
54
|
+
color="red"
|
|
55
|
+
size="sm"
|
|
56
|
+
aria-disabled={!canClose}
|
|
57
|
+
/>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Responsive size — nhỏ trên mobile, lớn hơn trên desktop
|
|
61
|
+
|
|
62
|
+
```tsx
|
|
63
|
+
<IconButton
|
|
64
|
+
icon={{ source: filterSvg }}
|
|
65
|
+
variant="outlined"
|
|
66
|
+
size="sm"
|
|
67
|
+
md={{ size: 'md' }}
|
|
68
|
+
/>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Icon button với label
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
<IconButton icon={{ source: editSvg }} variant="text" color="primary">
|
|
75
|
+
Chỉnh sửa
|
|
76
|
+
</IconButton>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Related Components
|
|
80
|
+
|
|
81
|
+
- [Icon](../icon/README.md)
|
|
82
|
+
- [RippleEffect](../ripple-effect/README.md)
|
|
83
|
+
|
|
84
|
+
## Dependencies
|
|
85
|
+
|
|
86
|
+
- `@emotion/react`
|
|
87
|
+
|
|
88
|
+
## See Also
|
|
89
|
+
|
|
90
|
+
- [Component Source](./index.ts)
|
|
91
|
+
- [Storybook Stories](./icon-button.stories.tsx)
|
|
92
|
+
- [Main README](../../README.md)
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Image
|
|
2
|
+
|
|
3
|
+
A polymorphic image component that wraps the native `<img>` element with built-in fallback support and sensible defaults. It automatically handles broken image sources by swapping in a fallback URL or a default placeholder, and applies `loading="lazy"` and `object-fit: cover` out of the box.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { Image } from '@janbox/storefront-ui';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Props
|
|
12
|
+
|
|
13
|
+
| Prop | Type | Default | Description |
|
|
14
|
+
|------|------|---------|-------------|
|
|
15
|
+
| `src` | `string` | - | The URL of the image to display. If empty or undefined, the fallback source is used instead. |
|
|
16
|
+
| `alt` | `string` | "" | Alternative text for the image. Defaults to an empty string if not provided. |
|
|
17
|
+
| `fallback` | `string \| boolean` | true | Controls fallback behavior when the image fails to load. Pass `true` to use the built-in IMAGE_PLACEHOLDER constant, a string URL to use a custom fallback image, or `false` to disable fallback entirely. |
|
|
18
|
+
| `loading` | `"lazy" \| "eager"` | "lazy" | Native img loading attribute. Defaults to 'lazy' for performance. |
|
|
19
|
+
| `sx` | `ToResponsiveProps<StyledCSS>` | { objectFit: 'cover' } | Responsive style overrides via the Emotion sx prop. Base styles apply `objectFit: 'cover'` and `maxHeight: '100%'`. |
|
|
20
|
+
| `width` | `number \| string` | - | Native img width attribute. |
|
|
21
|
+
| `height` | `number \| string` | - | Native img height attribute. |
|
|
22
|
+
| `onError` | `React.ReactEventHandler<HTMLImageElement>` | - | Called after the fallback logic runs when the image fails to load. The component handles src replacement internally before invoking this callback. |
|
|
23
|
+
| `as` | `React.ElementType` | "img" | Polymorphic tag override inherited from Primitive. Defaults to 'img'. |
|
|
24
|
+
| `ref` | `React.Ref<HTMLImageElement>` | - | Forwarded ref to the underlying img element. |
|
|
25
|
+
|
|
26
|
+
## Examples
|
|
27
|
+
|
|
28
|
+
### Default usage
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
<Image
|
|
32
|
+
src="https://via.placeholder.com/300x200"
|
|
33
|
+
alt="Placeholder image"
|
|
34
|
+
width={300}
|
|
35
|
+
height={200}
|
|
36
|
+
/>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Custom fallback URL on error
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
<Image
|
|
43
|
+
src="https://invalid-url.example.com/image.jpg"
|
|
44
|
+
alt="Image with fallback"
|
|
45
|
+
fallback="https://via.placeholder.com/300x200?text=Fallback"
|
|
46
|
+
width={300}
|
|
47
|
+
height={200}
|
|
48
|
+
/>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Built-in placeholder fallback with responsive sx
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
<Image
|
|
55
|
+
src="https://cdn.example.com/product.jpg"
|
|
56
|
+
alt="Product thumbnail"
|
|
57
|
+
fallback={true}
|
|
58
|
+
width={120}
|
|
59
|
+
height={120}
|
|
60
|
+
sx={{
|
|
61
|
+
borderRadius: 8,
|
|
62
|
+
objectFit: 'contain',
|
|
63
|
+
md: { width: 160, height: 160 },
|
|
64
|
+
}}
|
|
65
|
+
/>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Related Components
|
|
69
|
+
|
|
70
|
+
- [Primitive](../primitive/README.md)
|
|
71
|
+
|
|
72
|
+
## Dependencies
|
|
73
|
+
|
|
74
|
+
- lodash-es
|
|
75
|
+
|
|
76
|
+
## See Also
|
|
77
|
+
|
|
78
|
+
- [Component Source](./index.ts)
|
|
79
|
+
- [Storybook Stories](./image.stories.tsx)
|
|
80
|
+
- [Main README](../../README.md)
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Input
|
|
2
|
+
|
|
3
|
+
A flexible text input component with support for prefix/suffix slots, start/end icons, password visibility toggle, error state, helper text, debounced onChange, and responsive sizing. Designed for form fields across all sizes of the design system.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { Input } from '@janbox/storefront-ui';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Props
|
|
12
|
+
|
|
13
|
+
| Prop | Type | Default | Description |
|
|
14
|
+
|------|------|---------|-------------|
|
|
15
|
+
| `size` | `SizeVariant ('xs' \| 'sm' \| 'md' \| 'lg')` | `md` | Controls height, padding, and font size of the input via the size variant scale. |
|
|
16
|
+
| `sm` | `InputResponsiveProps ({ size?: SizeVariant })` | - | Responsive overrides applied at the sm breakpoint (≥768px). |
|
|
17
|
+
| `md` | `InputResponsiveProps ({ size?: SizeVariant })` | - | Responsive overrides applied at the md breakpoint (≥1280px). |
|
|
18
|
+
| `lg` | `InputResponsiveProps ({ size?: SizeVariant })` | - | Responsive overrides applied at the lg breakpoint (≥1680px). |
|
|
19
|
+
| `sx` | `ToResponsiveProps<StyledCSS>` | - | Escape-hatch for custom Emotion CSS styles, passed to the container element. |
|
|
20
|
+
| `error` | `boolean` | `false` | Puts the input into an error state, showing a red border and applying error styling to the helper text. |
|
|
21
|
+
| `helperText` | `string` | - | Descriptive or validation text rendered below the input via FormHelperText. Color changes when `error` is `true`. |
|
|
22
|
+
| `prefix` | `React.ReactNode` | - | Arbitrary node rendered at the far-left of the input wrapper, outside the icon slots (e.g. a country code badge). |
|
|
23
|
+
| `suffix` | `React.ReactNode` | - | Arbitrary node rendered at the far-right of the input wrapper, outside the icon slots. |
|
|
24
|
+
| `startIcon` | `IconProps` | - | Icon displayed on the left side of the input field, inside the wrapper. Size tracks the current size variant automatically. |
|
|
25
|
+
| `endIcon` | `IconProps` | - | Icon displayed on the right side of the input field, inside the wrapper. Size tracks the current size variant automatically. |
|
|
26
|
+
| `containerProps` | `PrimitiveProps<JSX.IntrinsicElements['div']>` | - | Props forwarded to the outermost wrapper div (position: relative, flex column container). |
|
|
27
|
+
| `mainProps` | `PrimitiveProps<JSX.IntrinsicElements['div']>` | - | Props forwarded to the inner wrapper div that renders the border, background, and layout for the input row. |
|
|
28
|
+
| `value` | `string` | - | Controlled value of the input. When provided alongside `debounce` or `mode='onBlur'`, the component buffers the typing value internally. |
|
|
29
|
+
| `defaultValue` | `string` | - | Uncontrolled default value for the input. |
|
|
30
|
+
| `transform` | `(value: string) => string` | - | Optional function applied to the raw input value on every change event before propagating it (e.g. uppercase, numeric-only filter). |
|
|
31
|
+
| `mode` | `'onChange' \| 'onBlur'` | `onChange` | Determines when `onChange` fires. `'onBlur'` defers the call until the user leaves the field; `'onChange'` fires on every keystroke (subject to `debounce`). |
|
|
32
|
+
| `debounce` | `number` | `0` | Milliseconds to debounce the `onChange` callback. Set to `0` to disable debouncing. |
|
|
33
|
+
| `type` | `string (HTML input type)` | - | Standard HTML input type. When set to `'password'`, a visibility toggle icon is automatically appended. |
|
|
34
|
+
| `disabled` | `boolean` | - | Disables the input and applies a neutral muted style to the wrapper via CSS `:has` selector. |
|
|
35
|
+
| `placeholder` | `string` | - | Placeholder text shown when the input is empty. |
|
|
36
|
+
| `onChange` | `React.ChangeEventHandler<HTMLInputElement>` | - | Change handler. May be deferred depending on `mode` and `debounce` settings. |
|
|
37
|
+
|
|
38
|
+
## Examples
|
|
39
|
+
|
|
40
|
+
### Default input with placeholder
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
<Input placeholder="Enter text..." onChange={handleChange} />
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Error state with helper text
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
<Input
|
|
50
|
+
placeholder="Enter email..."
|
|
51
|
+
error={true}
|
|
52
|
+
helperText="Invalid email address"
|
|
53
|
+
onChange={handleChange}
|
|
54
|
+
/>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Password input with debounced onChange
|
|
58
|
+
|
|
59
|
+
```tsx
|
|
60
|
+
<Input
|
|
61
|
+
type="password"
|
|
62
|
+
placeholder="Enter password..."
|
|
63
|
+
mode="onChange"
|
|
64
|
+
debounce={300}
|
|
65
|
+
value={password}
|
|
66
|
+
onChange={(e) => setPassword(e.target.value)}
|
|
67
|
+
/>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Input với icon và prefix/suffix
|
|
71
|
+
|
|
72
|
+
```tsx
|
|
73
|
+
<Input
|
|
74
|
+
placeholder="Tìm kiếm..."
|
|
75
|
+
startIcon={{ source: SearchIcon }}
|
|
76
|
+
suffix={<span>VND</span>}
|
|
77
|
+
size="lg"
|
|
78
|
+
/>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Responsive sizing
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
<Input
|
|
85
|
+
size="sm"
|
|
86
|
+
sm={{ size: 'md' }}
|
|
87
|
+
md={{ size: 'lg' }}
|
|
88
|
+
placeholder="Responsive input"
|
|
89
|
+
/>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### onBlur mode với transform
|
|
93
|
+
|
|
94
|
+
```tsx
|
|
95
|
+
<Input
|
|
96
|
+
mode="onBlur"
|
|
97
|
+
transform={(val) => val.toUpperCase()}
|
|
98
|
+
placeholder="Uppercase on blur"
|
|
99
|
+
onChange={(e) => console.log(e.target.value)}
|
|
100
|
+
/>
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Related Components
|
|
104
|
+
|
|
105
|
+
- [Icon](../icon/README.md)
|
|
106
|
+
- [FormHelperText](../formhelpertext/README.md)
|
|
107
|
+
- [Primitive](../primitive/README.md)
|
|
108
|
+
|
|
109
|
+
## Dependencies
|
|
110
|
+
|
|
111
|
+
- `@floating-ui/react`
|
|
112
|
+
- `lodash-es`
|
|
113
|
+
|
|
114
|
+
## See Also
|
|
115
|
+
|
|
116
|
+
- [Component Source](./index.ts)
|
|
117
|
+
- [Storybook Stories](./input.stories.tsx)
|
|
118
|
+
- [Main README](../../README.md)
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# InputMask
|
|
2
|
+
|
|
3
|
+
Wrapper component cung cấp container input có style với hỗ trợ icons, prefix/suffix slots, trạng thái lỗi, và responsive sizing. Được dùng làm visual shell cho các custom input component cần layout bordered, padded nhất quán với icon placement.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { InputMask } from '@janbox/storefront-ui';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Props
|
|
12
|
+
|
|
13
|
+
| Prop | Type | Default | Description |
|
|
14
|
+
|------|------|---------|-------------|
|
|
15
|
+
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Kiểm soát chiều cao và horizontal padding của container. Loại trừ `'xs'` khỏi SizeVariant. |
|
|
16
|
+
| `outline` | `{ top?: number; right?: number; bottom?: number; left?: number }` | - | Override border width riêng lẻ trên pseudo-element outline. Hữu ích khi cần bỏ một cạnh cụ thể (ví dụ: chỉ hiện border bottom). |
|
|
17
|
+
| `prefix` | `React.ReactNode` | - | Nội dung render trước startIcon và children. Thường dùng cho text label hoặc ký hiệu tiền tệ đặt ngoài inner flow. |
|
|
18
|
+
| `suffix` | `React.ReactNode` | - | Nội dung render sau children và endIcon. Thường dùng cho đơn vị hoặc trailing label. |
|
|
19
|
+
| `startIcon` | `IconProps` | - | Icon hiển thị bên trái, trước children. Nhận raw SVG qua IconProps. Size tự động lấy từ size variant hiện tại. |
|
|
20
|
+
| `endIcon` | `IconProps` | - | Icon hiển thị bên phải, sau children. Nhận raw SVG qua IconProps. Size tự động lấy từ size variant hiện tại. |
|
|
21
|
+
| `error` | `boolean` | `false` | Khi `true`, render border outline màu đỏ (`--color-red-600`) để báo lỗi validation. |
|
|
22
|
+
| `sm` | `InputMaskResponsiveProps` | - | Responsive overrides tại breakpoint sm (≥768px). Nhận `size` và `outline`. |
|
|
23
|
+
| `md` | `InputMaskResponsiveProps` | - | Responsive overrides tại breakpoint md (≥1280px). Nhận `size` và `outline`. |
|
|
24
|
+
| `lg` | `InputMaskResponsiveProps` | - | Responsive overrides tại breakpoint lg (≥1680px). Nhận `size` và `outline`. |
|
|
25
|
+
| `sx` | `ToResponsiveProps<StyledCSS>` | - | Escape hatch cho custom Emotion CSS styles, hỗ trợ responsive keys (`sm`, `md`, `lg`). |
|
|
26
|
+
| `children` | `React.ReactNode` | - | Inner input element hoặc nội dung render giữa startIcon và endIcon. |
|
|
27
|
+
| `as` | `React.ElementType` | - | Polymorphic prop kế thừa từ PrimitiveProps. Cho phép render thành HTML element hoặc component khác. |
|
|
28
|
+
|
|
29
|
+
## Examples
|
|
30
|
+
|
|
31
|
+
### Mặc định
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
<InputMask placeholder="Input mask..." />
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Trạng thái lỗi với size nhỏ
|
|
38
|
+
|
|
39
|
+
```tsx
|
|
40
|
+
<InputMask size="sm" error placeholder="Enter value..." />
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Với start icon, suffix, và responsive sizing
|
|
44
|
+
|
|
45
|
+
```tsx
|
|
46
|
+
<InputMask
|
|
47
|
+
size="md"
|
|
48
|
+
sm={{ size: 'lg' }}
|
|
49
|
+
startIcon={{ source: SearchIcon }}
|
|
50
|
+
suffix={<span>.00</span>}
|
|
51
|
+
>
|
|
52
|
+
<input placeholder="Search..." />
|
|
53
|
+
</InputMask>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Bottom-only border (outline override)
|
|
57
|
+
|
|
58
|
+
```tsx
|
|
59
|
+
<InputMask outline={{ top: 0, left: 0, right: 0 }}>
|
|
60
|
+
<input placeholder="Underline style..." />
|
|
61
|
+
</InputMask>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Prefix và suffix label
|
|
65
|
+
|
|
66
|
+
```tsx
|
|
67
|
+
<InputMask
|
|
68
|
+
prefix={<span>USD</span>}
|
|
69
|
+
suffix={<span>/month</span>}
|
|
70
|
+
>
|
|
71
|
+
<input type="number" placeholder="0" />
|
|
72
|
+
</InputMask>
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Related Components
|
|
76
|
+
|
|
77
|
+
- [Icon](../icon/README.md)
|
|
78
|
+
- [Primitive](../primitive/README.md)
|
|
79
|
+
|
|
80
|
+
## Dependencies
|
|
81
|
+
|
|
82
|
+
- @emotion/react
|
|
83
|
+
|
|
84
|
+
## See Also
|
|
85
|
+
|
|
86
|
+
- [Component Source](./index.ts)
|
|
87
|
+
- [Storybook Stories](./inputmask.stories.tsx)
|
|
88
|
+
- [Main README](../../README.md)
|