polymorph-ui-components 0.1.0
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 +354 -0
- package/dist/Accordion/Accordion.svelte +28 -0
- package/dist/Accordion/Accordion.svelte.d.ts +4 -0
- package/dist/Accordion/properties.d.ts +7 -0
- package/dist/Accordion/properties.js +1 -0
- package/dist/Animations/ModalAnimation.svelte +55 -0
- package/dist/Animations/ModalAnimation.svelte.d.ts +12 -0
- package/dist/Animations/OverlayAnimation.svelte +14 -0
- package/dist/Animations/OverlayAnimation.svelte.d.ts +7 -0
- package/dist/Avatar/Avatar.svelte +122 -0
- package/dist/Avatar/Avatar.svelte.d.ts +4 -0
- package/dist/Avatar/properties.d.ts +15 -0
- package/dist/Avatar/properties.js +1 -0
- package/dist/Badge/Badge.svelte +53 -0
- package/dist/Badge/Badge.svelte.d.ts +4 -0
- package/dist/Badge/properties.d.ts +6 -0
- package/dist/Badge/properties.js +1 -0
- package/dist/Banner/Banner.svelte +158 -0
- package/dist/Banner/Banner.svelte.d.ts +4 -0
- package/dist/Banner/properties.d.ts +19 -0
- package/dist/Banner/properties.js +1 -0
- package/dist/Book/Book.svelte +281 -0
- package/dist/Book/Book.svelte.d.ts +4 -0
- package/dist/Book/properties.d.ts +24 -0
- package/dist/Book/properties.js +1 -0
- package/dist/Browser/Browser.svelte +176 -0
- package/dist/Browser/Browser.svelte.d.ts +3 -0
- package/dist/Browser/properties.d.ts +14 -0
- package/dist/Browser/properties.js +1 -0
- package/dist/Button/Button.svelte +153 -0
- package/dist/Button/Button.svelte.d.ts +4 -0
- package/dist/Button/properties.d.ts +24 -0
- package/dist/Button/properties.js +1 -0
- package/dist/Calendar/Calendar.svelte +477 -0
- package/dist/Calendar/Calendar.svelte.d.ts +4 -0
- package/dist/Calendar/properties.d.ts +30 -0
- package/dist/Calendar/properties.js +1 -0
- package/dist/Carousel/Carousel.svelte +258 -0
- package/dist/Carousel/Carousel.svelte.d.ts +4 -0
- package/dist/Carousel/properties.d.ts +20 -0
- package/dist/Carousel/properties.js +1 -0
- package/dist/CheckListItem/CheckListItem.svelte +65 -0
- package/dist/CheckListItem/CheckListItem.svelte.d.ts +4 -0
- package/dist/CheckListItem/properties.d.ts +15 -0
- package/dist/CheckListItem/properties.js +1 -0
- package/dist/Checkbox/Checkbox.svelte +157 -0
- package/dist/Checkbox/Checkbox.svelte.d.ts +4 -0
- package/dist/Checkbox/properties.d.ts +17 -0
- package/dist/Checkbox/properties.js +1 -0
- package/dist/Choicebox/Choicebox.svelte +85 -0
- package/dist/Choicebox/Choicebox.svelte.d.ts +4 -0
- package/dist/Choicebox/properties.d.ts +14 -0
- package/dist/Choicebox/properties.js +1 -0
- package/dist/ColorPicker/ColorPicker.svelte +583 -0
- package/dist/ColorPicker/ColorPicker.svelte.d.ts +4 -0
- package/dist/ColorPicker/properties.d.ts +15 -0
- package/dist/ColorPicker/properties.js +1 -0
- package/dist/Combobox/Combobox.svelte +432 -0
- package/dist/Combobox/Combobox.svelte.d.ts +6 -0
- package/dist/Combobox/properties.d.ts +42 -0
- package/dist/Combobox/properties.js +1 -0
- package/dist/CommandMenu/CommandMenu.svelte +452 -0
- package/dist/CommandMenu/CommandMenu.svelte.d.ts +4 -0
- package/dist/CommandMenu/properties.d.ts +26 -0
- package/dist/CommandMenu/properties.js +1 -0
- package/dist/ContextMenu/ContextMenu.svelte +308 -0
- package/dist/ContextMenu/ContextMenu.svelte.d.ts +4 -0
- package/dist/ContextMenu/properties.d.ts +26 -0
- package/dist/ContextMenu/properties.js +1 -0
- package/dist/Gauge/Gauge.svelte +70 -0
- package/dist/Gauge/Gauge.svelte.d.ts +4 -0
- package/dist/Gauge/properties.d.ts +9 -0
- package/dist/Gauge/properties.js +1 -0
- package/dist/GridItem/GridItem.svelte +145 -0
- package/dist/GridItem/GridItem.svelte.d.ts +4 -0
- package/dist/GridItem/properties.d.ts +15 -0
- package/dist/GridItem/properties.js +1 -0
- package/dist/Icon/Icon.svelte +61 -0
- package/dist/Icon/Icon.svelte.d.ts +4 -0
- package/dist/Icon/properties.d.ts +12 -0
- package/dist/Icon/properties.js +1 -0
- package/dist/IconStack/IconStack.svelte +55 -0
- package/dist/IconStack/IconStack.svelte.d.ts +4 -0
- package/dist/IconStack/properties.d.ts +9 -0
- package/dist/IconStack/properties.js +1 -0
- package/dist/Img/Img.svelte +37 -0
- package/dist/Img/Img.svelte.d.ts +4 -0
- package/dist/Img/properties.d.ts +13 -0
- package/dist/Img/properties.js +1 -0
- package/dist/Input/Input.svelte +349 -0
- package/dist/Input/Input.svelte.d.ts +8 -0
- package/dist/Input/properties.d.ts +45 -0
- package/dist/Input/properties.js +1 -0
- package/dist/InputButton/InputButton.svelte +252 -0
- package/dist/InputButton/InputButton.svelte.d.ts +7 -0
- package/dist/InputButton/properties.d.ts +22 -0
- package/dist/InputButton/properties.js +1 -0
- package/dist/KeyboardInput/KeyboardInput.svelte +93 -0
- package/dist/KeyboardInput/KeyboardInput.svelte.d.ts +4 -0
- package/dist/KeyboardInput/properties.d.ts +12 -0
- package/dist/KeyboardInput/properties.js +1 -0
- package/dist/ListItem/ListItem.svelte +309 -0
- package/dist/ListItem/ListItem.svelte.d.ts +4 -0
- package/dist/ListItem/properties.d.ts +34 -0
- package/dist/ListItem/properties.js +1 -0
- package/dist/Loader/Loader.svelte +90 -0
- package/dist/Loader/Loader.svelte.d.ts +4 -0
- package/dist/Loader/properties.d.ts +4 -0
- package/dist/Loader/properties.js +1 -0
- package/dist/LoadingDots/LoadingDots.svelte +59 -0
- package/dist/LoadingDots/LoadingDots.svelte.d.ts +3 -0
- package/dist/LoadingDots/properties.d.ts +8 -0
- package/dist/LoadingDots/properties.js +1 -0
- package/dist/Menu/Menu.svelte +356 -0
- package/dist/Menu/Menu.svelte.d.ts +4 -0
- package/dist/Menu/properties.d.ts +28 -0
- package/dist/Menu/properties.js +1 -0
- package/dist/Modal/Modal.svelte +357 -0
- package/dist/Modal/Modal.svelte.d.ts +4 -0
- package/dist/Modal/properties.d.ts +39 -0
- package/dist/Modal/properties.js +1 -0
- package/dist/Pagination/Pagination.svelte +148 -0
- package/dist/Pagination/Pagination.svelte.d.ts +4 -0
- package/dist/Pagination/properties.d.ts +14 -0
- package/dist/Pagination/properties.js +1 -0
- package/dist/Phone/Phone.svelte +234 -0
- package/dist/Phone/Phone.svelte.d.ts +3 -0
- package/dist/Phone/properties.d.ts +11 -0
- package/dist/Phone/properties.js +1 -0
- package/dist/Pill/Pill.svelte +130 -0
- package/dist/Pill/Pill.svelte.d.ts +4 -0
- package/dist/Pill/properties.d.ts +16 -0
- package/dist/Pill/properties.js +1 -0
- package/dist/Progress/Progress.svelte +68 -0
- package/dist/Progress/Progress.svelte.d.ts +4 -0
- package/dist/Progress/properties.d.ts +10 -0
- package/dist/Progress/properties.js +1 -0
- package/dist/Radio/Radio.svelte +124 -0
- package/dist/Radio/Radio.svelte.d.ts +4 -0
- package/dist/Radio/properties.d.ts +15 -0
- package/dist/Radio/properties.js +1 -0
- package/dist/RelativeTime/RelativeTime.svelte +109 -0
- package/dist/RelativeTime/RelativeTime.svelte.d.ts +4 -0
- package/dist/RelativeTime/properties.d.ts +13 -0
- package/dist/RelativeTime/properties.js +1 -0
- package/dist/Scroller/Scroller.svelte +390 -0
- package/dist/Scroller/Scroller.svelte.d.ts +4 -0
- package/dist/Scroller/properties.d.ts +30 -0
- package/dist/Scroller/properties.js +1 -0
- package/dist/Select/Select.svelte +472 -0
- package/dist/Select/Select.svelte.d.ts +4 -0
- package/dist/Select/properties.d.ts +20 -0
- package/dist/Select/properties.js +1 -0
- package/dist/Sheet/Sheet.svelte +264 -0
- package/dist/Sheet/Sheet.svelte.d.ts +4 -0
- package/dist/Sheet/properties.d.ts +19 -0
- package/dist/Sheet/properties.js +1 -0
- package/dist/Shimmer/Shimmer.svelte +44 -0
- package/dist/Shimmer/Shimmer.svelte.d.ts +4 -0
- package/dist/Shimmer/properties.d.ts +4 -0
- package/dist/Shimmer/properties.js +1 -0
- package/dist/Slider/Slider.svelte +147 -0
- package/dist/Slider/Slider.svelte.d.ts +4 -0
- package/dist/Slider/properties.d.ts +17 -0
- package/dist/Slider/properties.js +1 -0
- package/dist/Snippet/Snippet.svelte +123 -0
- package/dist/Snippet/Snippet.svelte.d.ts +4 -0
- package/dist/Snippet/properties.d.ts +15 -0
- package/dist/Snippet/properties.js +1 -0
- package/dist/SplitButton/SplitButton.svelte +145 -0
- package/dist/SplitButton/SplitButton.svelte.d.ts +4 -0
- package/dist/SplitButton/properties.d.ts +17 -0
- package/dist/SplitButton/properties.js +1 -0
- package/dist/SplitInput/SplitInput.svelte +225 -0
- package/dist/SplitInput/SplitInput.svelte.d.ts +7 -0
- package/dist/SplitInput/properties.d.ts +20 -0
- package/dist/SplitInput/properties.js +1 -0
- package/dist/Stepper/Step.svelte +88 -0
- package/dist/Stepper/Step.svelte.d.ts +4 -0
- package/dist/Stepper/Stepper.svelte +64 -0
- package/dist/Stepper/Stepper.svelte.d.ts +4 -0
- package/dist/Stepper/properties.d.ts +27 -0
- package/dist/Stepper/properties.js +1 -0
- package/dist/Table/Table.svelte +357 -0
- package/dist/Table/Table.svelte.d.ts +4 -0
- package/dist/Table/properties.d.ts +26 -0
- package/dist/Table/properties.js +1 -0
- package/dist/Tabs/Tabs.svelte +303 -0
- package/dist/Tabs/Tabs.svelte.d.ts +4 -0
- package/dist/Tabs/properties.d.ts +30 -0
- package/dist/Tabs/properties.js +1 -0
- package/dist/ThemeSwitcher/ThemeSwitcher.svelte +249 -0
- package/dist/ThemeSwitcher/ThemeSwitcher.svelte.d.ts +4 -0
- package/dist/ThemeSwitcher/properties.d.ts +19 -0
- package/dist/ThemeSwitcher/properties.js +1 -0
- package/dist/Toast/Toast.svelte +220 -0
- package/dist/Toast/Toast.svelte.d.ts +4 -0
- package/dist/Toast/properties.d.ts +24 -0
- package/dist/Toast/properties.js +1 -0
- package/dist/Toggle/Toggle.svelte +99 -0
- package/dist/Toggle/Toggle.svelte.d.ts +4 -0
- package/dist/Toggle/properties.d.ts +9 -0
- package/dist/Toggle/properties.js +1 -0
- package/dist/Toolbar/Toolbar.svelte +142 -0
- package/dist/Toolbar/Toolbar.svelte.d.ts +4 -0
- package/dist/Toolbar/properties.d.ts +16 -0
- package/dist/Toolbar/properties.js +1 -0
- package/dist/Tooltip/Tooltip.svelte +153 -0
- package/dist/Tooltip/Tooltip.svelte.d.ts +4 -0
- package/dist/Tooltip/properties.d.ts +13 -0
- package/dist/Tooltip/properties.js +1 -0
- package/dist/assets/back.svg +3 -0
- package/dist/assets/battery.svg +5 -0
- package/dist/assets/checkmark.svg +3 -0
- package/dist/assets/chevron-down-sm.svg +3 -0
- package/dist/assets/chevron-down.svg +3 -0
- package/dist/assets/chevron-left-lg.svg +3 -0
- package/dist/assets/chevron-left.svg +3 -0
- package/dist/assets/chevron-right-lg.svg +3 -0
- package/dist/assets/chevron-right.svg +3 -0
- package/dist/assets/chevron-up.svg +3 -0
- package/dist/assets/close.svg +4 -0
- package/dist/assets/copy.svg +4 -0
- package/dist/assets/error-circle.svg +5 -0
- package/dist/assets/lock.svg +3 -0
- package/dist/assets/minus.svg +3 -0
- package/dist/assets/monitor.svg +5 -0
- package/dist/assets/moon.svg +3 -0
- package/dist/assets/palette.svg +7 -0
- package/dist/assets/search.svg +4 -0
- package/dist/assets/signal.svg +6 -0
- package/dist/assets/sort-default.svg +4 -0
- package/dist/assets/sun.svg +11 -0
- package/dist/assets/swap-vertical.svg +6 -0
- package/dist/assets/wifi.svg +3 -0
- package/dist/index.d.ts +103 -0
- package/dist/index.js +55 -0
- package/dist/types.d.ts +42 -0
- package/dist/types.js +1 -0
- package/dist/utils.d.ts +28 -0
- package/dist/utils.js +294 -0
- package/package.json +91 -0
package/README.md
ADDED
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# polymorph-ui-components
|
|
4
|
+
|
|
5
|
+
### One set of components. Every design system. Zero overrides.
|
|
6
|
+
|
|
7
|
+
A **themeable Svelte 5 component library** where _every_ visual property is a CSS custom property.
|
|
8
|
+
Unstyled by default — you bring the design system, the components render it.
|
|
9
|
+
|
|
10
|
+
[](https://www.npmjs.com/package/polymorph-ui-components)
|
|
11
|
+
[](https://svelte.dev)
|
|
12
|
+
[](#-use-it-anywhere-web-components)
|
|
13
|
+
[](#-ai-native-mcp-server)
|
|
14
|
+
[](#-components)
|
|
15
|
+
[](#-license)
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install polymorph-ui-components
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Why it's different
|
|
26
|
+
|
|
27
|
+
Most component libraries ship with a **fixed look**. Re-skinning them means fighting `!important`, patching internals through `:global()`, or forking the whole thing.
|
|
28
|
+
|
|
29
|
+
polymorph takes the opposite stance: **components own behavior, accessibility, and structure — and stay completely opinion-free about appearance.** Every color, space, radius, shadow, and font is a `var(--…)` you control from your own stylesheet. No source changes. No wrapper divs. No fights.
|
|
30
|
+
|
|
31
|
+
```svelte
|
|
32
|
+
<!-- The same Button, themed three different ways — no overrides -->
|
|
33
|
+
<div class="brand"><Button text="Continue" /></div>
|
|
34
|
+
<div class="danger"><Button text="Delete" /></div>
|
|
35
|
+
<div class="ghost"><Button text="Cancel" /></div>
|
|
36
|
+
|
|
37
|
+
<style>
|
|
38
|
+
.brand {
|
|
39
|
+
--button-color: #6d28d9;
|
|
40
|
+
--button-text-color: #fff;
|
|
41
|
+
--button-border-radius: 8px;
|
|
42
|
+
}
|
|
43
|
+
.danger {
|
|
44
|
+
--button-color: #e11d48;
|
|
45
|
+
--button-text-color: #fff;
|
|
46
|
+
}
|
|
47
|
+
.ghost {
|
|
48
|
+
--button-color: transparent;
|
|
49
|
+
--button-text-color: #111;
|
|
50
|
+
--button-border: 1px solid #ddd;
|
|
51
|
+
}
|
|
52
|
+
</style>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
> 📐 The full reasoning behind this approach lives in **[DESIGN_PRINCIPLES.md](./DESIGN_PRINCIPLES.md)**.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## ✨ Highlights
|
|
60
|
+
|
|
61
|
+
| | |
|
|
62
|
+
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
|
|
63
|
+
| 🎨 **Theme with CSS variables** | Every visual decision is a `var(--component-element-property)`. Define a theme once on an ancestor; the whole subtree inherits it. |
|
|
64
|
+
| 🧩 **50+ behavioral primitives** | Modals, sheets, menus, comboboxes, calendars, tables, toasts, steppers — focus traps, roving tabindex, and state machines included. |
|
|
65
|
+
| 🌍 **Framework-agnostic** | Ships as a Svelte library **and** as native Web Components (`<pui-*>`). Use it in React, Vue, Angular, or plain HTML. |
|
|
66
|
+
| 🤖 **AI-native** | A bundled **MCP server** exposes every component's props, events, and CSS variables to your AI coding assistant. |
|
|
67
|
+
| ♿ **Accessible by default** | ARIA wiring, keyboard navigation, focus management, and semantic HTML are baseline — not a premium add-on. |
|
|
68
|
+
| ⚡ **Built on Svelte 5** | `$props`, `$state`, `$derived`, `$bindable`, and `Snippet` throughout. Fully typed, tree-shakeable. |
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## 🚀 Quick Start
|
|
73
|
+
|
|
74
|
+
```svelte
|
|
75
|
+
<script lang="ts">
|
|
76
|
+
import { Button, Input, Toggle } from 'polymorph-ui-components';
|
|
77
|
+
|
|
78
|
+
let dark = $state(false);
|
|
79
|
+
</script>
|
|
80
|
+
|
|
81
|
+
<Button text="Submit" onclick={() => console.log('clicked')} />
|
|
82
|
+
|
|
83
|
+
<Input
|
|
84
|
+
value=""
|
|
85
|
+
placeholder="Enter email"
|
|
86
|
+
dataType="email"
|
|
87
|
+
onstatechange={(state) => console.log(state)}
|
|
88
|
+
/>
|
|
89
|
+
|
|
90
|
+
<Toggle checked={dark} text="Dark mode" onclick={(on) => (dark = on)} />
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## 🎨 Theming in 30 seconds
|
|
96
|
+
|
|
97
|
+
Every component reads its visuals from CSS variables with sensible neutral defaults. Define them on **any ancestor** and you have a theme:
|
|
98
|
+
|
|
99
|
+
```svelte
|
|
100
|
+
<div class="my-design-system">
|
|
101
|
+
<Button text="Save" onclick={save} />
|
|
102
|
+
<Input value="" placeholder="Search…" />
|
|
103
|
+
</div>
|
|
104
|
+
|
|
105
|
+
<style>
|
|
106
|
+
.my-design-system {
|
|
107
|
+
--button-color: #0070f3;
|
|
108
|
+
--button-text-color: #fff;
|
|
109
|
+
--button-border-radius: 6px;
|
|
110
|
+
--button-padding: 10px 20px;
|
|
111
|
+
|
|
112
|
+
--input-background: #fafafa;
|
|
113
|
+
--input-border: 1px solid #eaeaea;
|
|
114
|
+
--input-radius: 6px;
|
|
115
|
+
--input-focus-border: 1px solid #0070f3;
|
|
116
|
+
|
|
117
|
+
--modal-border-radius: 12px;
|
|
118
|
+
--modal-overlay-background-color: #00000066;
|
|
119
|
+
}
|
|
120
|
+
</style>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**Variants are your CSS classes, not our props.** Need a `danger` button? Write `.btn-danger { --button-color: #e11d48 }` and pass `classes="btn-danger"`. Because variables cascade, you can even **scope different themes** to different parts of the same page.
|
|
124
|
+
|
|
125
|
+
The naming convention is predictable everywhere:
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
--{component}-{element}-{property}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
`--button-color` · `--input-error-msg-text-color` · `--modal-footer-primary-button-border-radius`
|
|
132
|
+
|
|
133
|
+
Each component documents its **complete** variable surface in [`docs/`](docs/).
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## 🌍 Use it anywhere (Web Components)
|
|
138
|
+
|
|
139
|
+
The same components compile to **framework-agnostic custom elements** — theming works identically because it's pure CSS.
|
|
140
|
+
|
|
141
|
+
```html
|
|
142
|
+
<script type="module" src="polymorph-ui-components/wc"></script>
|
|
143
|
+
|
|
144
|
+
<pui-button text="Save"></pui-button>
|
|
145
|
+
<pui-input placeholder="Search…"></pui-input>
|
|
146
|
+
|
|
147
|
+
<style>
|
|
148
|
+
pui-button {
|
|
149
|
+
--button-color: #0070f3;
|
|
150
|
+
--button-text-color: #fff;
|
|
151
|
+
}
|
|
152
|
+
</style>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Drop them into React, Vue, Angular, Astro, or a plain `.html` file — no build step required.
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## 🤖 AI-native (MCP server)
|
|
160
|
+
|
|
161
|
+
A companion **Model Context Protocol** server ships as a separate package so your AI assistant can _query the component catalogue directly_ — props, events, types, and every CSS variable.
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
npm install polymorph-ui-components-mcp
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
```jsonc
|
|
168
|
+
// .mcp.json (or any MCP client config)
|
|
169
|
+
{
|
|
170
|
+
"mcpServers": {
|
|
171
|
+
"polymorph-ui": {
|
|
172
|
+
"command": "npx",
|
|
173
|
+
"args": ["-y", "polymorph-ui-components-mcp"]
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Now you can ask: _"Using the polymorph-ui MCP, theme the Select to match my brand and map my custom option rendering onto its snippets."_ — and the assistant has the real API in context.
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## 🧩 Components
|
|
184
|
+
|
|
185
|
+
<details open>
|
|
186
|
+
<summary><b>Inputs & Form Controls</b></summary>
|
|
187
|
+
|
|
188
|
+
| Component | Description | |
|
|
189
|
+
| --------------- | -------------------------------------------------------------------------------------------------------------------- | --------------------------- |
|
|
190
|
+
| **Button** | Action trigger with circular loader, progress bar, icon/children snippets, and `aria-expanded`. | [docs](docs/Button.md) |
|
|
191
|
+
| **Input** | Text field with built-in validation (email, phone, password, custom patterns), text transformers, and textarea mode. | [docs](docs/Input.md) |
|
|
192
|
+
| **InputButton** | Input fused with action buttons — search bars, OTP entry, coupon codes. | [docs](docs/InputButton.md) |
|
|
193
|
+
| **Select** | Dropdown with searchable single-select and multi-select (dismissible pills) plus custom content slots. | [docs](docs/Select.md) |
|
|
194
|
+
| **Combobox** | Autocomplete input with filtered listbox, `aria-activedescendant`, and keyboard navigation. | [docs](docs/Combobox.md) |
|
|
195
|
+
| **Toggle** | Labeled on/off switch with sliding animation. | [docs](docs/Toggle.md) |
|
|
196
|
+
| **Checkbox** | Tri-state checkbox with custom SVG checkmark and `aria-checked=mixed`. | [docs](docs/Checkbox.md) |
|
|
197
|
+
| **Radio** | Grouped radio with custom indicator over a native input. | [docs](docs/Radio.md) |
|
|
198
|
+
| **Slider** | Range slider with min/max/step and derived fill. | [docs](docs/Slider.md) |
|
|
199
|
+
| **Choicebox** | Selectable option box with radio/checkbox semantics and custom content. | [docs](docs/Choicebox.md) |
|
|
200
|
+
| **SplitInput** | Segmented input (OTP / PIN) with paste distribution and auto-advance. | [docs](docs/SplitInput.md) |
|
|
201
|
+
| **ColorPicker** | HSV color picker with pointer-drag saturation panel and hue slider. | [docs](docs/ColorPicker.md) |
|
|
202
|
+
| **Calendar** | Date / range picker with roving-tabindex grid and `Intl` formatting. | [docs](docs/Calendar.md) |
|
|
203
|
+
|
|
204
|
+
</details>
|
|
205
|
+
|
|
206
|
+
<details>
|
|
207
|
+
<summary><b>Overlays & Panels</b></summary>
|
|
208
|
+
|
|
209
|
+
| Component | Description | |
|
|
210
|
+
| ----------------------------------------- | ----------------------------------------------------------------------------------------------------- | ------------------------------ |
|
|
211
|
+
| **Modal** | Dialog overlay with size/alignment, header, footer, transitions, scroll-lock, and back-press support. | [docs](docs/Modal.md) |
|
|
212
|
+
| **Sheet** | Slide-in panel from any edge with header, scrollable body, footer, and focus trap. | [docs](docs/Sheet.md) |
|
|
213
|
+
| **Menu** | Dropdown action menu with keyboard navigation, typeahead, disabled/danger items, and separators. | [docs](docs/Menu.md) |
|
|
214
|
+
| **ContextMenu** | Right-click menu with separators, disabled/danger items, and keyboard navigation. | [docs](docs/ContextMenu.md) |
|
|
215
|
+
| **CommandMenu** | Command palette (Ctrl/Cmd+K) with search, grouped commands, and keyboard navigation. | [docs](docs/CommandMenu.md) |
|
|
216
|
+
| **Tooltip** | Hover/focus tooltip with configurable position and delay. | [docs](docs/Tooltip.md) |
|
|
217
|
+
| **ModalAnimation** / **OverlayAnimation** | Fly/fade transition wrappers. | [docs](docs/ModalAnimation.md) |
|
|
218
|
+
|
|
219
|
+
</details>
|
|
220
|
+
|
|
221
|
+
<details>
|
|
222
|
+
<summary><b>Display & Data</b></summary>
|
|
223
|
+
|
|
224
|
+
| Component | Description | |
|
|
225
|
+
| ---------------------------------- | ----------------------------------------------------------------------- | ----------------------------- |
|
|
226
|
+
| **Table** | Sortable data table with sticky headers and per-cell scrolling. | [docs](docs/Table.md) |
|
|
227
|
+
| **ListItem** | Multi-section list row with images, labels, and accordion expansion. | [docs](docs/ListItem.md) |
|
|
228
|
+
| **Avatar** | Circular avatar with image fallback or derived initials. | [docs](docs/Avatar.md) |
|
|
229
|
+
| **Badge** | Icon with a numeric/text badge overlay. | [docs](docs/Badge.md) |
|
|
230
|
+
| **Pill** | Compact label/tag, optionally clickable with a11y. | [docs](docs/Pill.md) |
|
|
231
|
+
| **Icon** / **IconStack** / **Img** | Clickable icon, overlapping icon stack, image with load-error fallback. | [docs](docs/Icon.md) |
|
|
232
|
+
| **GridItem** | Grid cell with icon, label, and loading overlay. | [docs](docs/GridItem.md) |
|
|
233
|
+
| **RelativeTime** | Auto-updating "5 minutes ago" with locale support. | [docs](docs/RelativeTime.md) |
|
|
234
|
+
| **KeyboardInput** | Keyboard-shortcut display with styled key caps. | [docs](docs/KeyboardInput.md) |
|
|
235
|
+
|
|
236
|
+
</details>
|
|
237
|
+
|
|
238
|
+
<details>
|
|
239
|
+
<summary><b>Navigation & Structure</b></summary>
|
|
240
|
+
|
|
241
|
+
| Component | Description | |
|
|
242
|
+
| ---------------------- | -------------------------------------------------------------------- | ----------------------------- |
|
|
243
|
+
| **Tabs** | Tabbed interface with animated indicator and overflow scrolling. | [docs](docs/Tabs.md) |
|
|
244
|
+
| **Pagination** | Windowed page navigation with ellipsis truncation. | [docs](docs/Pagination.md) |
|
|
245
|
+
| **Stepper** / **Step** | Multi-step progress indicator with completed/active/pending states. | [docs](docs/Stepper.md) |
|
|
246
|
+
| **Accordion** | Collapsible container with CSS grid animation. | [docs](docs/Accordion.md) |
|
|
247
|
+
| **Carousel** | Swipeable content slider with autoplay and pagination dots. | [docs](docs/Carousel.md) |
|
|
248
|
+
| **Scroller** | Overflowing list with arrow nav, gradient edges, and drag-to-scroll. | [docs](docs/Scroller.md) |
|
|
249
|
+
| **CheckListItem** | Checklist row with checkbox, label, and checked state. | [docs](docs/CheckListItem.md) |
|
|
250
|
+
| **Toolbar** | Header bar with back button, title, and customizable content areas. | [docs](docs/Toolbar.md) |
|
|
251
|
+
| **ThemeSwitcher** | Segmented light/dark/system control with `prefers-color-scheme`. | [docs](docs/ThemeSwitcher.md) |
|
|
252
|
+
|
|
253
|
+
</details>
|
|
254
|
+
|
|
255
|
+
<details>
|
|
256
|
+
<summary><b>Feedback & Loading</b></summary>
|
|
257
|
+
|
|
258
|
+
| Component | Description | |
|
|
259
|
+
| ------------------------------------------ | ----------------------------------------------------------------------- | ------------------------ |
|
|
260
|
+
| **Toast** | Animated slide-in notification with auto-dismiss and per-direction fly. | [docs](docs/Toast.md) |
|
|
261
|
+
| **Banner** | Notification banner with icon snippet, link text, and dismiss. | [docs](docs/Banner.md) |
|
|
262
|
+
| **Progress** | Animated horizontal progress bar (determinate / indeterminate). | [docs](docs/Progress.md) |
|
|
263
|
+
| **Gauge** | Full-circle ring gauge (0–100) with animated SVG arc. | [docs](docs/Gauge.md) |
|
|
264
|
+
| **Loader** / **LoadingDots** / **Shimmer** | Spinner, animated dots, and skeleton shimmer — all CSS-variable themed. | [docs](docs/Loader.md) |
|
|
265
|
+
|
|
266
|
+
</details>
|
|
267
|
+
|
|
268
|
+
<details>
|
|
269
|
+
<summary><b>Actions, Code & Scenery</b></summary>
|
|
270
|
+
|
|
271
|
+
| Component | Description | |
|
|
272
|
+
| ---------------------------------- | ------------------------------------------------------------------------------------------ | --------------------------- |
|
|
273
|
+
| **SplitButton** | Primary action button with a dropdown of secondary actions. | [docs](docs/SplitButton.md) |
|
|
274
|
+
| **Snippet** | Code/command block with a copy button. | [docs](docs/Snippet.md) |
|
|
275
|
+
| **Book** / **Browser** / **Phone** | Decorative frames — flip-book, browser chrome, device mockup — for previews and marketing. | [docs](docs/Browser.md) |
|
|
276
|
+
|
|
277
|
+
</details>
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## ♿ Accessibility & Svelte 5
|
|
282
|
+
|
|
283
|
+
Interactive components own their accessibility: focus traps (`Modal`, `Sheet`), roving tabindex (`Calendar`, `Menu`, `Tabs`), `aria-activedescendant` wiring (`Combobox`, `Select`), live regions (`Toast`), and internal Enter/Space handling on every custom control.
|
|
284
|
+
|
|
285
|
+
Under the hood it's modern Svelte 5 — `$props()`, `$state()`/`$derived()`, `$bindable()` two-way props, and `Snippet` content slots:
|
|
286
|
+
|
|
287
|
+
```svelte
|
|
288
|
+
<script lang="ts">
|
|
289
|
+
import { Sheet } from 'polymorph-ui-components';
|
|
290
|
+
let open = $state(false);
|
|
291
|
+
</script>
|
|
292
|
+
|
|
293
|
+
<button onclick={() => (open = true)}>Open</button>
|
|
294
|
+
|
|
295
|
+
<Sheet bind:open title="Settings" side="right">
|
|
296
|
+
{#snippet content()}
|
|
297
|
+
<p>Sheet body goes here.</p>
|
|
298
|
+
{/snippet}
|
|
299
|
+
{#snippet footer()}
|
|
300
|
+
<button onclick={() => (open = false)}>Done</button>
|
|
301
|
+
{/snippet}
|
|
302
|
+
</Sheet>
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
Every component exports its types:
|
|
306
|
+
|
|
307
|
+
```typescript
|
|
308
|
+
import type {
|
|
309
|
+
ButtonProperties,
|
|
310
|
+
InputProperties,
|
|
311
|
+
ModalProperties,
|
|
312
|
+
SelectProperties,
|
|
313
|
+
MenuItem
|
|
314
|
+
} from 'polymorph-ui-components';
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
## 🛠 Development
|
|
320
|
+
|
|
321
|
+
```bash
|
|
322
|
+
pnpm install # install dependencies
|
|
323
|
+
pnpm dev # dev server with hot reload (component playground)
|
|
324
|
+
pnpm build # build library (vite + svelte-package + publint)
|
|
325
|
+
pnpm test # integration + unit tests
|
|
326
|
+
pnpm lint # formatting + lint
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
```
|
|
330
|
+
src/lib/{Component}/{Component}.svelte # implementation
|
|
331
|
+
src/lib/{Component}/properties.ts # typed props
|
|
332
|
+
src/lib/index.ts # public exports
|
|
333
|
+
src/wc/ # Web Component wrappers
|
|
334
|
+
docs/ # one markdown reference per component
|
|
335
|
+
mcp/ # MCP server package
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
Releases are automated: pushing to `release` lints, derives the semver bump from the conventional-commit message, bumps the version, generates a changelog, builds, tags a GitHub release, and publishes to npm.
|
|
339
|
+
|
|
340
|
+
---
|
|
341
|
+
|
|
342
|
+
## 🙏 Credits
|
|
343
|
+
|
|
344
|
+
**polymorph-ui-components** is built on top of [`@juspay/svelte-ui-components`](https://github.com/juspay/svelte-ui-components) — it began as that library and carries forward its CSS-variable-driven theming foundation. It no longer depends on or pulls from the upstream package; instead it **builds on that groundwork and evolves independently**. Thanks to the original authors for the foundation. 🙌
|
|
345
|
+
|
|
346
|
+
---
|
|
347
|
+
|
|
348
|
+
## 📄 License
|
|
349
|
+
|
|
350
|
+
[MIT](LICENSE) — peer dependencies: `svelte ^5.41.2`.
|
|
351
|
+
|
|
352
|
+
<div align="center">
|
|
353
|
+
<sub>Build any design system. In any framework. Discoverable by humans and AI alike.</sub>
|
|
354
|
+
</div>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { AccordionProperties } from './properties';
|
|
3
|
+
|
|
4
|
+
let { expand = false, children, testId, classes }: AccordionProperties = $props();
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<div class="accordion {classes ?? ''}" class:expanded={expand} data-pw={testId}>
|
|
8
|
+
<div class="accordion-content">
|
|
9
|
+
{@render children?.()}
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
<style>
|
|
14
|
+
.accordion {
|
|
15
|
+
display: grid;
|
|
16
|
+
grid-template-rows: 0fr;
|
|
17
|
+
overflow: hidden;
|
|
18
|
+
transition: grid-template-rows 0.2s ease-out;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.accordion.expanded {
|
|
22
|
+
grid-template-rows: 1fr;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.accordion-content {
|
|
26
|
+
min-height: 0;
|
|
27
|
+
}
|
|
28
|
+
</style>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import { fly, fade } from 'svelte/transition';
|
|
4
|
+
import type { ModalAlign } from '../Modal/properties';
|
|
5
|
+
import type { ModalTransition } from '../types';
|
|
6
|
+
|
|
7
|
+
type Props = {
|
|
8
|
+
enable?: boolean;
|
|
9
|
+
align?: ModalAlign;
|
|
10
|
+
transitionType?: ModalTransition;
|
|
11
|
+
children?: Snippet;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
let { enable = true, align = 'bottom', transitionType = 'ALL', children }: Props = $props();
|
|
15
|
+
|
|
16
|
+
let flyAnimationProperties = $derived.by(() => {
|
|
17
|
+
const base = { x: 0, y: 0, duration: 380 };
|
|
18
|
+
|
|
19
|
+
switch (align) {
|
|
20
|
+
case 'top':
|
|
21
|
+
return { ...base, y: -30 };
|
|
22
|
+
case 'bottom':
|
|
23
|
+
return { ...base, y: 300 };
|
|
24
|
+
default:
|
|
25
|
+
return base;
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
let fadeAnimationProperties = { duration: 300 };
|
|
30
|
+
|
|
31
|
+
let useFlyAnimation = $derived(align === 'top' || align === 'bottom');
|
|
32
|
+
let useOutTransition = $derived(transitionType === 'ALL');
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
{#if enable}
|
|
36
|
+
{#if useFlyAnimation && useOutTransition}
|
|
37
|
+
<div in:fly|global={flyAnimationProperties} out:fly|global={flyAnimationProperties}>
|
|
38
|
+
{@render children?.()}
|
|
39
|
+
</div>
|
|
40
|
+
{:else if useFlyAnimation}
|
|
41
|
+
<div in:fly|global={flyAnimationProperties}>
|
|
42
|
+
{@render children?.()}
|
|
43
|
+
</div>
|
|
44
|
+
{:else if useOutTransition}
|
|
45
|
+
<div in:fade|global={fadeAnimationProperties} out:fade|global={fadeAnimationProperties}>
|
|
46
|
+
{@render children?.()}
|
|
47
|
+
</div>
|
|
48
|
+
{:else}
|
|
49
|
+
<div in:fade|global={fadeAnimationProperties}>
|
|
50
|
+
{@render children?.()}
|
|
51
|
+
</div>
|
|
52
|
+
{/if}
|
|
53
|
+
{:else}
|
|
54
|
+
{@render children?.()}
|
|
55
|
+
{/if}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { ModalAlign } from '../Modal/properties';
|
|
3
|
+
import type { ModalTransition } from '../types';
|
|
4
|
+
type Props = {
|
|
5
|
+
enable?: boolean;
|
|
6
|
+
align?: ModalAlign;
|
|
7
|
+
transitionType?: ModalTransition;
|
|
8
|
+
children?: Snippet;
|
|
9
|
+
};
|
|
10
|
+
declare const ModalAnimation: import("svelte").Component<Props, {}, "">;
|
|
11
|
+
type ModalAnimation = ReturnType<typeof ModalAnimation>;
|
|
12
|
+
export default ModalAnimation;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { fade } from 'svelte/transition';
|
|
3
|
+
import type { Snippet } from 'svelte';
|
|
4
|
+
|
|
5
|
+
type Props = {
|
|
6
|
+
children?: Snippet;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
let { children }: Props = $props();
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<div out:fade={{ duration: 350 }}>
|
|
13
|
+
{@render children?.()}
|
|
14
|
+
</div>
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { AvatarProperties } from './properties';
|
|
3
|
+
import Img from '../Img/Img.svelte';
|
|
4
|
+
|
|
5
|
+
let { src, alt, name, size = 'medium', testId, onclick, classes }: AvatarProperties = $props();
|
|
6
|
+
|
|
7
|
+
let imageError = $state(false);
|
|
8
|
+
|
|
9
|
+
let showImage = $derived(typeof src === 'string' && src.length > 0 && !imageError);
|
|
10
|
+
|
|
11
|
+
let initials = $derived.by(() => {
|
|
12
|
+
if (typeof name !== 'string' || name.trim().length === 0) {
|
|
13
|
+
return '';
|
|
14
|
+
}
|
|
15
|
+
const words = name.trim().split(/\s+/);
|
|
16
|
+
if (words.length === 0) {
|
|
17
|
+
return '';
|
|
18
|
+
}
|
|
19
|
+
const firstWord = words.at(0);
|
|
20
|
+
const lastWord = words.at(-1);
|
|
21
|
+
const first = typeof firstWord === 'string' && firstWord.length > 0 ? firstWord.charAt(0) : '';
|
|
22
|
+
const last =
|
|
23
|
+
words.length > 1 && typeof lastWord === 'string' && lastWord.length > 0
|
|
24
|
+
? lastWord.charAt(0)
|
|
25
|
+
: '';
|
|
26
|
+
return (first + last).toUpperCase();
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
function handleImageError(): void {
|
|
30
|
+
imageError = true;
|
|
31
|
+
}
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
{#snippet content()}
|
|
35
|
+
{#if showImage && typeof src === 'string'}
|
|
36
|
+
<span class="avatar-img-wrapper">
|
|
37
|
+
<Img {src} {alt} onerror={handleImageError} />
|
|
38
|
+
</span>
|
|
39
|
+
{:else}
|
|
40
|
+
<span class="avatar-initials">{initials}</span>
|
|
41
|
+
{/if}
|
|
42
|
+
{/snippet}
|
|
43
|
+
|
|
44
|
+
{#if typeof onclick === 'function'}
|
|
45
|
+
<button
|
|
46
|
+
class="avatar avatar-{size} {classes ?? ''}"
|
|
47
|
+
type="button"
|
|
48
|
+
aria-label={alt}
|
|
49
|
+
data-pw={testId}
|
|
50
|
+
{onclick}
|
|
51
|
+
>
|
|
52
|
+
{@render content()}
|
|
53
|
+
</button>
|
|
54
|
+
{:else}
|
|
55
|
+
<div class="avatar avatar-{size} {classes ?? ''}" role="img" aria-label={alt} data-pw={testId}>
|
|
56
|
+
{@render content()}
|
|
57
|
+
</div>
|
|
58
|
+
{/if}
|
|
59
|
+
|
|
60
|
+
<style>
|
|
61
|
+
.avatar {
|
|
62
|
+
display: inline-flex;
|
|
63
|
+
align-items: center;
|
|
64
|
+
justify-content: center;
|
|
65
|
+
padding: 0;
|
|
66
|
+
border-radius: var(--avatar-border-radius, 50%);
|
|
67
|
+
border: var(--avatar-border, none);
|
|
68
|
+
box-shadow: var(--avatar-box-shadow, none);
|
|
69
|
+
cursor: var(--avatar-cursor, default);
|
|
70
|
+
overflow: hidden;
|
|
71
|
+
background-color: var(--avatar-background, #a1a1aa);
|
|
72
|
+
font-family: inherit;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.avatar:hover {
|
|
76
|
+
opacity: var(--avatar-hover-opacity, 1);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.avatar-small {
|
|
80
|
+
width: var(--avatar-small-width, 32px);
|
|
81
|
+
height: var(--avatar-small-height, 32px);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.avatar-medium {
|
|
85
|
+
width: var(--avatar-medium-width, 40px);
|
|
86
|
+
height: var(--avatar-medium-height, 40px);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.avatar-large {
|
|
90
|
+
width: var(--avatar-large-width, 56px);
|
|
91
|
+
height: var(--avatar-large-height, 56px);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.avatar-img-wrapper {
|
|
95
|
+
display: contents;
|
|
96
|
+
--image-width: 100%;
|
|
97
|
+
--image-height: 100%;
|
|
98
|
+
--image-object-fit: var(--avatar-object-fit, cover);
|
|
99
|
+
--image-border-radius: 0px;
|
|
100
|
+
--image-padding: 0px;
|
|
101
|
+
--image-margin: 0px;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.avatar-initials {
|
|
105
|
+
color: var(--avatar-text-color, #18181b);
|
|
106
|
+
font-weight: var(--avatar-font-weight, 600);
|
|
107
|
+
font-family: var(--avatar-font-family, inherit);
|
|
108
|
+
user-select: none;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.avatar-small .avatar-initials {
|
|
112
|
+
font-size: var(--avatar-small-font-size, 12px);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.avatar-medium .avatar-initials {
|
|
116
|
+
font-size: var(--avatar-medium-font-size, 14px);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.avatar-large .avatar-initials {
|
|
120
|
+
font-size: var(--avatar-large-font-size, 20px);
|
|
121
|
+
}
|
|
122
|
+
</style>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type AvatarSize = 'small' | 'medium' | 'large';
|
|
2
|
+
export type AvatarProperties = MandatoryAvatarProperties & OptionalAvatarProperties & AvatarEventProperties;
|
|
3
|
+
export type MandatoryAvatarProperties = {
|
|
4
|
+
alt: string;
|
|
5
|
+
};
|
|
6
|
+
export type OptionalAvatarProperties = {
|
|
7
|
+
src?: string;
|
|
8
|
+
name?: string;
|
|
9
|
+
size?: AvatarSize;
|
|
10
|
+
testId?: string;
|
|
11
|
+
classes?: string;
|
|
12
|
+
};
|
|
13
|
+
export type AvatarEventProperties = {
|
|
14
|
+
onclick?: (event: MouseEvent) => void;
|
|
15
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|