solid-tom-ui 1.0.11 → 1.0.14
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 +246 -246
- package/dist/README.md +246 -246
- package/dist/components/avatar/avatar.js.map +1 -1
- package/dist/components/badge/badge.js.map +1 -1
- package/dist/components/breadcrumb/breadcrumb.js.map +1 -1
- package/dist/components/button/button.js.map +1 -1
- package/dist/components/carousel/carousel.js.map +1 -1
- package/dist/components/chat-bubble/chatBubble.js.map +1 -1
- package/dist/components/checkbox/checkbox.js.map +1 -1
- package/dist/components/collapse/collapse.js.map +1 -1
- package/dist/components/context-menu/context-menu.js.map +1 -1
- package/dist/components/context-menu/context-menu.store.js.map +1 -1
- package/dist/components/divider/divider.js.map +1 -1
- package/dist/components/dropdown/dropdown.js.map +1 -1
- package/dist/components/dropdown/dropdown.store.js.map +1 -1
- package/dist/components/float-button/float-button.js.map +1 -1
- package/dist/components/hover-3d-image/hover-3d-image.js.map +1 -1
- package/dist/components/image-preview/image-preview.js.map +1 -1
- package/dist/components/input/input.js.map +1 -1
- package/dist/components/input/input.utils.js.map +1 -1
- package/dist/components/input/variants/input-color.js.map +1 -1
- package/dist/components/input/variants/input-date.js.map +1 -1
- package/dist/components/input/variants/input-number.d.ts.map +1 -1
- package/dist/components/input/variants/input-number.js +1 -1
- package/dist/components/input/variants/input-number.js.map +1 -1
- package/dist/components/input/variants/input-otp.js.map +1 -1
- package/dist/components/input/variants/input-password.js.map +1 -1
- package/dist/components/input/variants/input-radio.js.map +1 -1
- package/dist/components/input/variants/input-range.js.map +1 -1
- package/dist/components/input/variants/input-text.d.ts.map +1 -1
- package/dist/components/input/variants/input-text.js +1 -1
- package/dist/components/input/variants/input-text.js.map +1 -1
- package/dist/components/input/variants/input-textarea.js.map +1 -1
- package/dist/components/loading/loading.js.map +1 -1
- package/dist/components/mansory/mansory.js.map +1 -1
- package/dist/components/menu/menu.js.map +1 -1
- package/dist/components/modal/modal.js.map +1 -1
- package/dist/components/modal/modalContext.js.map +1 -1
- package/dist/components/pagination/pagination.js.map +1 -1
- package/dist/components/progress-bar/progress-bar.js.map +1 -1
- package/dist/components/qr-code/qr-code.js.map +1 -1
- package/dist/components/select/select.js.map +1 -1
- package/dist/components/select-zone/select-zone.js.map +1 -1
- package/dist/components/skeleton/skeleton.js.map +1 -1
- package/dist/components/slider/slider.js.map +1 -1
- package/dist/components/splitter/splitter.js.map +1 -1
- package/dist/components/steps/steps.js.map +1 -1
- package/dist/components/swap/swap.js.map +1 -1
- package/dist/components/switch/switch.js.map +1 -1
- package/dist/components/tab/tab.js.map +1 -1
- package/dist/components/table/table.js.map +1 -1
- package/dist/components/timeline/timeline.js.map +1 -1
- package/dist/components/toast/icons/ErrorIcon.js.map +1 -1
- package/dist/components/toast/icons/IconCircle.js.map +1 -1
- package/dist/components/toast/icons/InfoIcon.js.map +1 -1
- package/dist/components/toast/icons/LoaderIcon.js.map +1 -1
- package/dist/components/toast/icons/SuccessIcon.js.map +1 -1
- package/dist/components/toast/icons/WarningIcon.js.map +1 -1
- package/dist/components/toast/toast.js.map +1 -1
- package/dist/components/toast/toast.store.js.map +1 -1
- package/dist/components/tooltip/tooltip.js.map +1 -1
- package/dist/components/tour/tour.js.map +1 -1
- package/dist/components/upload/upload.js.map +1 -1
- package/dist/components/z-index/z-index.context.js.map +1 -1
- package/dist/components/z-index/z-index.js.map +1 -1
- package/dist/components/z-index/z-index.store.js.map +1 -1
- package/dist/components/z-index/z-index.types.js.map +1 -1
- package/dist/package.json +1 -1
- package/dist/skill/avatar.skill.md.txt +255 -255
- package/dist/skill/badge.skill.md.txt +223 -223
- package/dist/skill/breadcrumb.skill.md.txt +177 -177
- package/dist/skill/button.skill.md.txt +198 -198
- package/dist/skill/carousel.skill.md.txt +406 -406
- package/dist/skill/chat-bubble.skill.md.txt +342 -342
- package/dist/skill/checkbox.skill.md.txt +326 -326
- package/dist/skill/code-preview.skill.md.txt +240 -240
- package/dist/skill/collapse.skill.md.txt +329 -329
- package/dist/skill/context-menu.skill.md.txt +233 -233
- package/dist/skill/diff.skill.md.txt +244 -244
- package/dist/skill/divider.skill.md.txt +151 -151
- package/dist/skill/doc.skill.md.txt +191 -191
- package/dist/skill/drawer.skill.md.txt +157 -157
- package/dist/skill/dropdown.skill.md.txt +198 -198
- package/dist/skill/float-button.skill.md.txt +315 -315
- package/dist/skill/hover-3d-image.skill.md.txt +120 -120
- package/dist/skill/iframe.skill.md.txt +114 -114
- package/dist/skill/image-preview.skill.md.txt +162 -162
- package/dist/skill/indicator.skill.md.txt +60 -60
- package/dist/skill/input.skill.md.txt +489 -489
- package/dist/skill/loading.skill.md.txt +127 -127
- package/dist/skill/menu.skill.md.txt +476 -476
- package/dist/skill/modal.skill.md.txt +359 -359
- package/dist/skill/pagination.skill.md.txt +405 -405
- package/dist/skill/progress-bar.skill.md.txt +207 -207
- package/dist/skill/qr-code.skill.md.txt +136 -136
- package/dist/skill/rating.skill.md.txt +167 -167
- package/dist/skill/select-zone.skill.md.txt +93 -93
- package/dist/skill/select.skill.md.txt +663 -663
- package/dist/skill/skeleton.skill.md.txt +192 -192
- package/dist/skill/slider.skill.md.txt +404 -404
- package/dist/skill/splitter.skill.md.txt +411 -411
- package/dist/skill/steps.skill.md.txt +264 -264
- package/dist/skill/swap.skill.md.txt +139 -139
- package/dist/skill/switch.skill.md.txt +191 -191
- package/dist/skill/tab.skill.md.txt +484 -484
- package/dist/skill/table.example.header.md.txt +666 -666
- package/dist/skill/table.skill.md.txt +1407 -1407
- package/dist/skill/text-rotate.skill.md.txt +186 -186
- package/dist/skill/timeline.skill.md.txt +247 -247
- package/dist/skill/toast.skill.md.txt +531 -531
- package/dist/skill/tooltip.skill.md.txt +222 -222
- package/dist/skill/tour.skill.md.txt +156 -156
- package/dist/skill/upload.skill.md.txt +358 -358
- package/dist/utils/cn.js.map +1 -1
- package/dist/utils/element-tracker.js.map +1 -1
- package/dist/utils/helper.js.map +1 -1
- package/dist/utils/hoc.js.map +1 -1
- package/package.json +132 -133
|
@@ -1,162 +1,162 @@
|
|
|
1
|
-
## COMPONENT IDENTITY
|
|
2
|
-
- **Import**: `import { ImagePreview } from 'solid-tom-ui';`
|
|
3
|
-
- **Export**: `ImagePreview` (named export), `ImagePreviewProps`, `ImagePreviewClassProps` (type exports)
|
|
4
|
-
- **Framework**: SolidJS
|
|
5
|
-
- **Purpose**: Fullscreen lightbox — renders via Portal on top of all content, locks body scroll; supports zoom, pan, rotate, flip, and optional file-info popup
|
|
6
|
-
|
|
7
|
-
## Props
|
|
8
|
-
|
|
9
|
-
| Prop | Type | Default | Description |
|
|
10
|
-
|-------------------|---------------------------|-------------|-------------|
|
|
11
|
-
| `src` | `string` | **required**| Image URL to display |
|
|
12
|
-
| `onClose` | `() => void` | **required**| Called when the user clicks the ✕ button (or backdrop if enabled) |
|
|
13
|
-
| `name` | `string` | — | File name shown in the info popup |
|
|
14
|
-
| `size` | `string` | — | Human-readable file size, e.g. `"320 KB"` |
|
|
15
|
-
| `createdAt` | `Date \| string` | — | Creation date (auto-formatted to locale string) |
|
|
16
|
-
| `modifiedAt` | `Date \| string` | — | Last-modified date |
|
|
17
|
-
| `closeOnBackdrop` | `boolean` | `false` | When `true`, clicking the dark backdrop also calls `onClose` |
|
|
18
|
-
| `class` | `ImagePreviewClassProps` | — | Override CSS classes for individual internal elements |
|
|
19
|
-
|
|
20
|
-
> The info button (ⓘ) only appears in the toolbar when at least one of `name`, `size`, `createdAt`, or `modifiedAt` is provided.
|
|
21
|
-
|
|
22
|
-
## ImagePreviewClassProps
|
|
23
|
-
|
|
24
|
-
Used to override styles for specific internal elements:
|
|
25
|
-
|
|
26
|
-
```ts
|
|
27
|
-
type ImagePreviewClassProps = {
|
|
28
|
-
backdrop?: string; // full-screen dark overlay
|
|
29
|
-
close?: string; // ✕ close button (top-right)
|
|
30
|
-
box?: string; // image wrapper / pan container
|
|
31
|
-
img?: string; // the <img> element
|
|
32
|
-
toolbar?: string; // bottom toolbar pill
|
|
33
|
-
toolBtn?: string; // each icon button in the toolbar
|
|
34
|
-
zoomLabel?: string; // "100%" zoom percentage text
|
|
35
|
-
infoPopup?: string; // floating info popup panel
|
|
36
|
-
};
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
## Built-in toolbar controls
|
|
40
|
-
|
|
41
|
-
| Action | How |
|
|
42
|
-
|--------|-----|
|
|
43
|
-
| Zoom in / out | Toolbar buttons **or** mouse wheel over the image |
|
|
44
|
-
| Zoom range | 25 % → 400 %, step 25 % |
|
|
45
|
-
| Pan | Click-drag when zoom > 100 % |
|
|
46
|
-
| Rotate CW / CCW | Toolbar buttons (90° steps) |
|
|
47
|
-
| Flip horizontal / vertical | Toolbar buttons |
|
|
48
|
-
| Reset all transforms | Toolbar reset button (disabled when already at default) |
|
|
49
|
-
| File info | Toolbar ⓘ button → popup with name, size, dimensions, dates |
|
|
50
|
-
| Close | ✕ button fixed top-right; optionally also backdrop click |
|
|
51
|
-
|
|
52
|
-
## Usage
|
|
53
|
-
|
|
54
|
-
### Minimal — controlled visibility
|
|
55
|
-
|
|
56
|
-
```tsx
|
|
57
|
-
import { createSignal } from 'solid-js';
|
|
58
|
-
import { ImagePreview } from 'solid-tom-ui';
|
|
59
|
-
|
|
60
|
-
export function App() {
|
|
61
|
-
const [open, setOpen] = createSignal(false);
|
|
62
|
-
|
|
63
|
-
return (
|
|
64
|
-
<>
|
|
65
|
-
<button onClick={() => setOpen(true)}>Open</button>
|
|
66
|
-
|
|
67
|
-
{open() && (
|
|
68
|
-
<ImagePreview
|
|
69
|
-
src="https://example.com/photo.jpg"
|
|
70
|
-
onClose={() => setOpen(false)}
|
|
71
|
-
/>
|
|
72
|
-
)}
|
|
73
|
-
</>
|
|
74
|
-
);
|
|
75
|
-
}
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
### With file metadata
|
|
79
|
-
|
|
80
|
-
```tsx
|
|
81
|
-
{open() && (
|
|
82
|
-
<ImagePreview
|
|
83
|
-
src={file.url}
|
|
84
|
-
name={file.name}
|
|
85
|
-
size="1.2 MB"
|
|
86
|
-
createdAt={new Date('2024-03-15')}
|
|
87
|
-
modifiedAt="2024-10-01T08:05:00"
|
|
88
|
-
onClose={() => setOpen(false)}
|
|
89
|
-
closeOnBackdrop
|
|
90
|
-
/>
|
|
91
|
-
)}
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
### Gallery with typed state
|
|
95
|
-
|
|
96
|
-
```tsx
|
|
97
|
-
import { createSignal, For } from 'solid-js';
|
|
98
|
-
import { ImagePreview } from 'solid-tom-ui';
|
|
99
|
-
|
|
100
|
-
type Item = { src: string; name: string; size: string };
|
|
101
|
-
|
|
102
|
-
const ITEMS: Item[] = [
|
|
103
|
-
{ src: '/img/a.jpg', name: 'a.jpg', size: '200 KB' },
|
|
104
|
-
{ src: '/img/b.jpg', name: 'b.jpg', size: '340 KB' },
|
|
105
|
-
];
|
|
106
|
-
|
|
107
|
-
export function Gallery() {
|
|
108
|
-
const [active, setActive] = createSignal<Item | null>(null);
|
|
109
|
-
|
|
110
|
-
return (
|
|
111
|
-
<>
|
|
112
|
-
<For each={ITEMS}>
|
|
113
|
-
{item => (
|
|
114
|
-
<img src={item.src} onClick={() => setActive(item)} />
|
|
115
|
-
)}
|
|
116
|
-
</For>
|
|
117
|
-
|
|
118
|
-
{active() && (
|
|
119
|
-
<ImagePreview
|
|
120
|
-
src={active()!.src}
|
|
121
|
-
name={active()!.name}
|
|
122
|
-
size={active()!.size}
|
|
123
|
-
onClose={() => setActive(null)}
|
|
124
|
-
/>
|
|
125
|
-
)}
|
|
126
|
-
</>
|
|
127
|
-
);
|
|
128
|
-
}
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
### Custom styling (themed toolbar)
|
|
132
|
-
|
|
133
|
-
Pass a `class` object to restyle individual parts without touching the component internals:
|
|
134
|
-
|
|
135
|
-
```tsx
|
|
136
|
-
<ImagePreview
|
|
137
|
-
src={img.src}
|
|
138
|
-
onClose={close}
|
|
139
|
-
class={{
|
|
140
|
-
toolbar: 'bg-purple-900/60 border-purple-400/20',
|
|
141
|
-
toolBtn: 'hover:bg-purple-400/30 hover:text-purple-100',
|
|
142
|
-
backdrop: 'bg-purple-950/90',
|
|
143
|
-
infoPopup:'border-purple-400/20 bg-purple-950/80',
|
|
144
|
-
}}
|
|
145
|
-
/>
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
## Important notes
|
|
149
|
-
|
|
150
|
-
- **Controlled only** — `ImagePreview` has no internal open/close state. Mount it conditionally (`{show() && <ImagePreview … />}`) and unmount it to close.
|
|
151
|
-
- **Portal** — rendered outside your component tree into `document.body`; `z-index: 9999`.
|
|
152
|
-
- **Body scroll lock** — automatically adds `overflow: hidden` to `document.body` on mount and restores the previous value on unmount.
|
|
153
|
-
- **Date formatting** — `createdAt` and `modifiedAt` accept `Date` objects or ISO strings. Invalid values are displayed as-is.
|
|
154
|
-
- **CSS** — base styles live in `image-preview.style.css` under `@layer components`. All class names start with `sui-lightbox-*`. Override via the `class` prop rather than targeting these selectors globally.
|
|
155
|
-
- **Drag cursor** — the image container automatically shows `cursor-grab` / `cursor-grabbing` when zoom > 100 %.
|
|
156
|
-
---
|
|
157
|
-
|
|
158
|
-
## Component Conventions
|
|
159
|
-
|
|
160
|
-
> **CSS encoding**: internal CSS classes use short encoded names (e.g. `ip01`, `ip02`) per project convention.
|
|
161
|
-
|
|
162
|
-
> **Unique IDs**: if this component needs to generate HTML `id` attributes, always use `createUniqueId()` from `solid-js` — never `Math.random()` or `Date.now()`.
|
|
1
|
+
## COMPONENT IDENTITY
|
|
2
|
+
- **Import**: `import { ImagePreview } from 'solid-tom-ui';`
|
|
3
|
+
- **Export**: `ImagePreview` (named export), `ImagePreviewProps`, `ImagePreviewClassProps` (type exports)
|
|
4
|
+
- **Framework**: SolidJS
|
|
5
|
+
- **Purpose**: Fullscreen lightbox — renders via Portal on top of all content, locks body scroll; supports zoom, pan, rotate, flip, and optional file-info popup
|
|
6
|
+
|
|
7
|
+
## Props
|
|
8
|
+
|
|
9
|
+
| Prop | Type | Default | Description |
|
|
10
|
+
|-------------------|---------------------------|-------------|-------------|
|
|
11
|
+
| `src` | `string` | **required**| Image URL to display |
|
|
12
|
+
| `onClose` | `() => void` | **required**| Called when the user clicks the ✕ button (or backdrop if enabled) |
|
|
13
|
+
| `name` | `string` | — | File name shown in the info popup |
|
|
14
|
+
| `size` | `string` | — | Human-readable file size, e.g. `"320 KB"` |
|
|
15
|
+
| `createdAt` | `Date \| string` | — | Creation date (auto-formatted to locale string) |
|
|
16
|
+
| `modifiedAt` | `Date \| string` | — | Last-modified date |
|
|
17
|
+
| `closeOnBackdrop` | `boolean` | `false` | When `true`, clicking the dark backdrop also calls `onClose` |
|
|
18
|
+
| `class` | `ImagePreviewClassProps` | — | Override CSS classes for individual internal elements |
|
|
19
|
+
|
|
20
|
+
> The info button (ⓘ) only appears in the toolbar when at least one of `name`, `size`, `createdAt`, or `modifiedAt` is provided.
|
|
21
|
+
|
|
22
|
+
## ImagePreviewClassProps
|
|
23
|
+
|
|
24
|
+
Used to override styles for specific internal elements:
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
type ImagePreviewClassProps = {
|
|
28
|
+
backdrop?: string; // full-screen dark overlay
|
|
29
|
+
close?: string; // ✕ close button (top-right)
|
|
30
|
+
box?: string; // image wrapper / pan container
|
|
31
|
+
img?: string; // the <img> element
|
|
32
|
+
toolbar?: string; // bottom toolbar pill
|
|
33
|
+
toolBtn?: string; // each icon button in the toolbar
|
|
34
|
+
zoomLabel?: string; // "100%" zoom percentage text
|
|
35
|
+
infoPopup?: string; // floating info popup panel
|
|
36
|
+
};
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Built-in toolbar controls
|
|
40
|
+
|
|
41
|
+
| Action | How |
|
|
42
|
+
|--------|-----|
|
|
43
|
+
| Zoom in / out | Toolbar buttons **or** mouse wheel over the image |
|
|
44
|
+
| Zoom range | 25 % → 400 %, step 25 % |
|
|
45
|
+
| Pan | Click-drag when zoom > 100 % |
|
|
46
|
+
| Rotate CW / CCW | Toolbar buttons (90° steps) |
|
|
47
|
+
| Flip horizontal / vertical | Toolbar buttons |
|
|
48
|
+
| Reset all transforms | Toolbar reset button (disabled when already at default) |
|
|
49
|
+
| File info | Toolbar ⓘ button → popup with name, size, dimensions, dates |
|
|
50
|
+
| Close | ✕ button fixed top-right; optionally also backdrop click |
|
|
51
|
+
|
|
52
|
+
## Usage
|
|
53
|
+
|
|
54
|
+
### Minimal — controlled visibility
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
import { createSignal } from 'solid-js';
|
|
58
|
+
import { ImagePreview } from 'solid-tom-ui';
|
|
59
|
+
|
|
60
|
+
export function App() {
|
|
61
|
+
const [open, setOpen] = createSignal(false);
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<>
|
|
65
|
+
<button onClick={() => setOpen(true)}>Open</button>
|
|
66
|
+
|
|
67
|
+
{open() && (
|
|
68
|
+
<ImagePreview
|
|
69
|
+
src="https://example.com/photo.jpg"
|
|
70
|
+
onClose={() => setOpen(false)}
|
|
71
|
+
/>
|
|
72
|
+
)}
|
|
73
|
+
</>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### With file metadata
|
|
79
|
+
|
|
80
|
+
```tsx
|
|
81
|
+
{open() && (
|
|
82
|
+
<ImagePreview
|
|
83
|
+
src={file.url}
|
|
84
|
+
name={file.name}
|
|
85
|
+
size="1.2 MB"
|
|
86
|
+
createdAt={new Date('2024-03-15')}
|
|
87
|
+
modifiedAt="2024-10-01T08:05:00"
|
|
88
|
+
onClose={() => setOpen(false)}
|
|
89
|
+
closeOnBackdrop
|
|
90
|
+
/>
|
|
91
|
+
)}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Gallery with typed state
|
|
95
|
+
|
|
96
|
+
```tsx
|
|
97
|
+
import { createSignal, For } from 'solid-js';
|
|
98
|
+
import { ImagePreview } from 'solid-tom-ui';
|
|
99
|
+
|
|
100
|
+
type Item = { src: string; name: string; size: string };
|
|
101
|
+
|
|
102
|
+
const ITEMS: Item[] = [
|
|
103
|
+
{ src: '/img/a.jpg', name: 'a.jpg', size: '200 KB' },
|
|
104
|
+
{ src: '/img/b.jpg', name: 'b.jpg', size: '340 KB' },
|
|
105
|
+
];
|
|
106
|
+
|
|
107
|
+
export function Gallery() {
|
|
108
|
+
const [active, setActive] = createSignal<Item | null>(null);
|
|
109
|
+
|
|
110
|
+
return (
|
|
111
|
+
<>
|
|
112
|
+
<For each={ITEMS}>
|
|
113
|
+
{item => (
|
|
114
|
+
<img src={item.src} onClick={() => setActive(item)} />
|
|
115
|
+
)}
|
|
116
|
+
</For>
|
|
117
|
+
|
|
118
|
+
{active() && (
|
|
119
|
+
<ImagePreview
|
|
120
|
+
src={active()!.src}
|
|
121
|
+
name={active()!.name}
|
|
122
|
+
size={active()!.size}
|
|
123
|
+
onClose={() => setActive(null)}
|
|
124
|
+
/>
|
|
125
|
+
)}
|
|
126
|
+
</>
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Custom styling (themed toolbar)
|
|
132
|
+
|
|
133
|
+
Pass a `class` object to restyle individual parts without touching the component internals:
|
|
134
|
+
|
|
135
|
+
```tsx
|
|
136
|
+
<ImagePreview
|
|
137
|
+
src={img.src}
|
|
138
|
+
onClose={close}
|
|
139
|
+
class={{
|
|
140
|
+
toolbar: 'bg-purple-900/60 border-purple-400/20',
|
|
141
|
+
toolBtn: 'hover:bg-purple-400/30 hover:text-purple-100',
|
|
142
|
+
backdrop: 'bg-purple-950/90',
|
|
143
|
+
infoPopup:'border-purple-400/20 bg-purple-950/80',
|
|
144
|
+
}}
|
|
145
|
+
/>
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Important notes
|
|
149
|
+
|
|
150
|
+
- **Controlled only** — `ImagePreview` has no internal open/close state. Mount it conditionally (`{show() && <ImagePreview … />}`) and unmount it to close.
|
|
151
|
+
- **Portal** — rendered outside your component tree into `document.body`; `z-index: 9999`.
|
|
152
|
+
- **Body scroll lock** — automatically adds `overflow: hidden` to `document.body` on mount and restores the previous value on unmount.
|
|
153
|
+
- **Date formatting** — `createdAt` and `modifiedAt` accept `Date` objects or ISO strings. Invalid values are displayed as-is.
|
|
154
|
+
- **CSS** — base styles live in `image-preview.style.css` under `@layer components`. All class names start with `sui-lightbox-*`. Override via the `class` prop rather than targeting these selectors globally.
|
|
155
|
+
- **Drag cursor** — the image container automatically shows `cursor-grab` / `cursor-grabbing` when zoom > 100 %.
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## Component Conventions
|
|
159
|
+
|
|
160
|
+
> **CSS encoding**: internal CSS classes use short encoded names (e.g. `ip01`, `ip02`) per project convention.
|
|
161
|
+
|
|
162
|
+
> **Unique IDs**: if this component needs to generate HTML `id` attributes, always use `createUniqueId()` from `solid-js` — never `Math.random()` or `Date.now()`.
|
|
@@ -1,60 +1,60 @@
|
|
|
1
|
-
## COMPONENT IDENTITY
|
|
2
|
-
- **Import**: `import { Indicator } from 'solid-tom-ui';`
|
|
3
|
-
- **Export**: `Indicator` (named export)
|
|
4
|
-
- **Framework**: SolidJS
|
|
5
|
-
- **Purpose**: Displays a notification count badge at the top-right corner of a child element; suitable for icons, buttons, avatars, or any element needing an unread count
|
|
6
|
-
|
|
7
|
-
## Props
|
|
8
|
-
|
|
9
|
-
| Prop | Type | Default | Description |
|
|
10
|
-
|-------------|---------------------|-------------|----------------------------------------------------------------------|
|
|
11
|
-
| `count` | `number` | `0` | Number to display. When `0`, badge is hidden |
|
|
12
|
-
| `showExact` | `boolean` | `false` | `true` to show large numbers exactly (e.g. `12345`) |
|
|
13
|
-
| `color` | `BaseColorProps` | `'error'` | Badge color via the project color system |
|
|
14
|
-
| `top` | `number \| string` | `0` | Vertical offset from corner (px number or CSS string) |
|
|
15
|
-
| `right` | `number \| string` | `0` | Horizontal offset from corner (px number or CSS string) |
|
|
16
|
-
| `class` | `{ root?, badge? }` | `undefined` | Override classes for wrapper (`root`) or badge (`badge`) |
|
|
17
|
-
| `children` | `JSX.Element` | — | The element to attach the badge to |
|
|
18
|
-
|
|
19
|
-
## Display behavior
|
|
20
|
-
|
|
21
|
-
- `count = 0` → badge hidden
|
|
22
|
-
- `count = 1–99` → **circular** compact badge
|
|
23
|
-
- `count ≥ 100` (and `showExact = false`) → shows `99+`, **pill** shape
|
|
24
|
-
- `showExact = true` → shows exact number (e.g. `12345`), elongated pill
|
|
25
|
-
|
|
26
|
-
## Usage examples
|
|
27
|
-
|
|
28
|
-
```tsx
|
|
29
|
-
// Basic — red badge on button
|
|
30
|
-
<Indicator count={5}>
|
|
31
|
-
<button class="btn">Messages</button>
|
|
32
|
-
</Indicator>
|
|
33
|
-
|
|
34
|
-
// Custom color
|
|
35
|
-
<Indicator count={42} color="primary">
|
|
36
|
-
<div class="size-10 rounded-full bg-gray-200" />
|
|
37
|
-
</Indicator>
|
|
38
|
-
|
|
39
|
-
// Show exact large number
|
|
40
|
-
<Indicator count={1234} showExact>
|
|
41
|
-
<button class="btn">Notifications</button>
|
|
42
|
-
</Indicator>
|
|
43
|
-
|
|
44
|
-
// Adjust position
|
|
45
|
-
<Indicator count={3} top={4} right={4}>
|
|
46
|
-
<button class="btn">Inbox</button>
|
|
47
|
-
</Indicator>
|
|
48
|
-
|
|
49
|
-
// Custom badge style
|
|
50
|
-
<Indicator count={7} class={{ badge: 'bg-gradient-to-r from-purple-500 to-pink-500' }}>
|
|
51
|
-
<button class="btn">Items</button>
|
|
52
|
-
</Indicator>
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
## Notes
|
|
56
|
-
|
|
57
|
-
- The `<Indicator>` wraps its child in `div.relative.inline-flex` — this is expected behavior.
|
|
58
|
-
- `top` / `right` accept a `number` (treated as px) or any valid CSS string (e.g. `'8px'`, `'0.5rem'`).
|
|
59
|
-
- Badge uses `transform: translate(50%, -50%)` for precise corner placement — no extra adjustment needed in most cases.
|
|
60
|
-
- To increase badge size, use `class={{ badge: 'size-6 text-xs' }}` rather than adding new props.
|
|
1
|
+
## COMPONENT IDENTITY
|
|
2
|
+
- **Import**: `import { Indicator } from 'solid-tom-ui';`
|
|
3
|
+
- **Export**: `Indicator` (named export)
|
|
4
|
+
- **Framework**: SolidJS
|
|
5
|
+
- **Purpose**: Displays a notification count badge at the top-right corner of a child element; suitable for icons, buttons, avatars, or any element needing an unread count
|
|
6
|
+
|
|
7
|
+
## Props
|
|
8
|
+
|
|
9
|
+
| Prop | Type | Default | Description |
|
|
10
|
+
|-------------|---------------------|-------------|----------------------------------------------------------------------|
|
|
11
|
+
| `count` | `number` | `0` | Number to display. When `0`, badge is hidden |
|
|
12
|
+
| `showExact` | `boolean` | `false` | `true` to show large numbers exactly (e.g. `12345`) |
|
|
13
|
+
| `color` | `BaseColorProps` | `'error'` | Badge color via the project color system |
|
|
14
|
+
| `top` | `number \| string` | `0` | Vertical offset from corner (px number or CSS string) |
|
|
15
|
+
| `right` | `number \| string` | `0` | Horizontal offset from corner (px number or CSS string) |
|
|
16
|
+
| `class` | `{ root?, badge? }` | `undefined` | Override classes for wrapper (`root`) or badge (`badge`) |
|
|
17
|
+
| `children` | `JSX.Element` | — | The element to attach the badge to |
|
|
18
|
+
|
|
19
|
+
## Display behavior
|
|
20
|
+
|
|
21
|
+
- `count = 0` → badge hidden
|
|
22
|
+
- `count = 1–99` → **circular** compact badge
|
|
23
|
+
- `count ≥ 100` (and `showExact = false`) → shows `99+`, **pill** shape
|
|
24
|
+
- `showExact = true` → shows exact number (e.g. `12345`), elongated pill
|
|
25
|
+
|
|
26
|
+
## Usage examples
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
// Basic — red badge on button
|
|
30
|
+
<Indicator count={5}>
|
|
31
|
+
<button class="btn">Messages</button>
|
|
32
|
+
</Indicator>
|
|
33
|
+
|
|
34
|
+
// Custom color
|
|
35
|
+
<Indicator count={42} color="primary">
|
|
36
|
+
<div class="size-10 rounded-full bg-gray-200" />
|
|
37
|
+
</Indicator>
|
|
38
|
+
|
|
39
|
+
// Show exact large number
|
|
40
|
+
<Indicator count={1234} showExact>
|
|
41
|
+
<button class="btn">Notifications</button>
|
|
42
|
+
</Indicator>
|
|
43
|
+
|
|
44
|
+
// Adjust position
|
|
45
|
+
<Indicator count={3} top={4} right={4}>
|
|
46
|
+
<button class="btn">Inbox</button>
|
|
47
|
+
</Indicator>
|
|
48
|
+
|
|
49
|
+
// Custom badge style
|
|
50
|
+
<Indicator count={7} class={{ badge: 'bg-gradient-to-r from-purple-500 to-pink-500' }}>
|
|
51
|
+
<button class="btn">Items</button>
|
|
52
|
+
</Indicator>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Notes
|
|
56
|
+
|
|
57
|
+
- The `<Indicator>` wraps its child in `div.relative.inline-flex` — this is expected behavior.
|
|
58
|
+
- `top` / `right` accept a `number` (treated as px) or any valid CSS string (e.g. `'8px'`, `'0.5rem'`).
|
|
59
|
+
- Badge uses `transform: translate(50%, -50%)` for precise corner placement — no extra adjustment needed in most cases.
|
|
60
|
+
- To increase badge size, use `class={{ badge: 'size-6 text-xs' }}` rather than adding new props.
|