marz-ui 1.0.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 ADDED
@@ -0,0 +1,288 @@
1
+ # Marz UI
2
+
3
+ Framework-agnostic UI components and design system built with Web Components.
4
+
5
+ ## Features
6
+
7
+ - 🎨 **Complete Design System** - CSS tokens, typography, and theming
8
+ - 🌐 **Framework Agnostic** - Works with React, Vue, Svelte, Angular, or vanilla JS
9
+ - 🎯 **Web Components** - Standards-based Custom Elements
10
+ - 🌓 **Dark Mode** - Built-in light/dark theme support
11
+ - 📦 **Zero Dependencies** - Pure Web Components, no framework required
12
+ - 💪 **TypeScript** - Full type definitions included
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install @marz/ui
18
+ ```
19
+
20
+ ## Usage
21
+
22
+ ### Import All Components
23
+
24
+ ```typescript
25
+ import '@marz/ui';
26
+ import '@marz/ui/styles'; // Optional: Import styles separately
27
+ ```
28
+
29
+ ### Import Individual Components
30
+
31
+ ```typescript
32
+ import '@marz/ui/button';
33
+ import '@marz/ui/input';
34
+ import '@marz/ui/sidepanel';
35
+ ```
36
+
37
+ ## Components
38
+
39
+ ### Button
40
+
41
+ A versatile button component with multiple variants and sizes.
42
+
43
+ ```html
44
+ <!-- Primary button -->
45
+ <marz-button primary label="Click me"></marz-button>
46
+
47
+ <!-- Secondary button -->
48
+ <marz-button label="Cancel"></marz-button>
49
+
50
+ <!-- Different sizes -->
51
+ <marz-button size="small" label="Small"></marz-button>
52
+ <marz-button size="medium" label="Medium"></marz-button>
53
+ <marz-button size="large" label="Large"></marz-button>
54
+
55
+ <!-- Custom background color -->
56
+ <marz-button background-color="#ff0000" label="Custom"></marz-button>
57
+
58
+ <!-- No outline -->
59
+ <marz-button no-outline label="No Border"></marz-button>
60
+ ```
61
+
62
+ **Props:**
63
+ - `primary` (boolean) - Primary variant style
64
+ - `size` (string) - Button size: 'small', 'medium', 'large'
65
+ - `label` (string) - Button text
66
+ - `background-color` (string) - Custom background color
67
+ - `no-outline` (boolean) - Remove border
68
+ - `disabled` (boolean) - Disable the button
69
+
70
+ **Events:**
71
+ - `click` - Fired when button is clicked
72
+
73
+ ### Input
74
+
75
+ A labeled input component with multiple sizes.
76
+
77
+ ```html
78
+ <!-- Basic input -->
79
+ <marz-input label="Name" placeholder="Enter your name"></marz-input>
80
+
81
+ <!-- Different sizes -->
82
+ <marz-input size="small" label="Small Input"></marz-input>
83
+ <marz-input size="medium" label="Medium Input"></marz-input>
84
+ <marz-input size="large" label="Large Input"></marz-input>
85
+
86
+ <!-- With value -->
87
+ <marz-input label="Email" value="user@example.com"></marz-input>
88
+
89
+ <!-- Different input types -->
90
+ <marz-input label="Password" type="password"></marz-input>
91
+ <marz-input label="Email" type="email"></marz-input>
92
+ ```
93
+
94
+ **Props:**
95
+ - `label` (string) - Input label text
96
+ - `placeholder` (string) - Placeholder text
97
+ - `value` (string) - Input value
98
+ - `size` (string) - Input size: 'small', 'medium', 'large'
99
+ - `type` (string) - Input type (text, password, email, etc.)
100
+ - `disabled` (boolean) - Disable the input
101
+
102
+ **Events:**
103
+ - `change` - Fired when input value changes (detail: { value })
104
+
105
+ ### Sidepanel
106
+
107
+ A modal sidepanel that slides in from the right.
108
+
109
+ ```html
110
+ <marz-sidepanel id="myPanel" title="Settings">
111
+ <div slot="content">
112
+ <marz-input label="Name" placeholder="Your name"></marz-input>
113
+ <marz-input label="Email" placeholder="Your email"></marz-input>
114
+ </div>
115
+ <div slot="actions">
116
+ <marz-button label="Cancel"></marz-button>
117
+ <marz-button primary label="Save"></marz-button>
118
+ </div>
119
+ </marz-sidepanel>
120
+
121
+ <script>
122
+ const panel = document.getElementById('myPanel');
123
+
124
+ // Open the panel
125
+ panel.setAttribute('is-open', '');
126
+ // or
127
+ panel.isOpen = true;
128
+
129
+ // Close the panel
130
+ panel.removeAttribute('is-open');
131
+ // or
132
+ panel.isOpen = false;
133
+ </script>
134
+ ```
135
+
136
+ **Props:**
137
+ - `is-open` (boolean) - Whether the panel is open
138
+ - `title` (string) - Panel title
139
+
140
+ **Slots:**
141
+ - `content` - Main content area
142
+ - `actions` - Action buttons area
143
+
144
+ **Events:**
145
+ - `close` - Fired when panel is closed
146
+
147
+ ## Framework Integration
148
+
149
+ ### React
150
+
151
+ ```tsx
152
+ import '@marz/ui';
153
+
154
+ function App() {
155
+ const handleClick = () => {
156
+ console.log('Button clicked!');
157
+ };
158
+
159
+ const handleChange = (e: CustomEvent) => {
160
+ console.log('Input value:', e.detail.value);
161
+ };
162
+
163
+ return (
164
+ <div>
165
+ <marz-button
166
+ primary
167
+ label="Click me"
168
+ onClick={handleClick}
169
+ />
170
+
171
+ <marz-input
172
+ label="Name"
173
+ placeholder="Enter name"
174
+ onChange={handleChange}
175
+ />
176
+ </div>
177
+ );
178
+ }
179
+ ```
180
+
181
+ ### Vue
182
+
183
+ ```vue
184
+ <template>
185
+ <div>
186
+ <marz-button
187
+ primary
188
+ label="Click me"
189
+ @click="handleClick"
190
+ />
191
+
192
+ <marz-input
193
+ label="Name"
194
+ placeholder="Enter name"
195
+ @change="handleChange"
196
+ />
197
+ </div>
198
+ </template>
199
+
200
+ <script setup>
201
+ import '@marz/ui';
202
+
203
+ const handleClick = () => {
204
+ console.log('Button clicked!');
205
+ };
206
+
207
+ const handleChange = (e) => {
208
+ console.log('Input value:', e.detail.value);
209
+ };
210
+ </script>
211
+ ```
212
+
213
+ ### Svelte
214
+
215
+ ```svelte
216
+ <script>
217
+ import '@marz/ui';
218
+
219
+ function handleClick() {
220
+ console.log('Button clicked!');
221
+ }
222
+
223
+ function handleChange(e) {
224
+ console.log('Input value:', e.detail.value);
225
+ }
226
+ </script>
227
+
228
+ <marz-button primary label="Click me" on:click={handleClick} />
229
+ <marz-input label="Name" placeholder="Enter name" on:change={handleChange} />
230
+ ```
231
+
232
+ ## Styling
233
+
234
+ ### Import Styles
235
+
236
+ ```typescript
237
+ // Import all styles
238
+ import '@marz/ui/styles';
239
+
240
+ // Or import specific style files
241
+ import '@marz/ui/styles/tokens'; // CSS variables only
242
+ import '@marz/ui/styles/components'; // Component styles only
243
+ ```
244
+
245
+ ### CSS Variables
246
+
247
+ Marz UI uses CSS custom properties for theming:
248
+
249
+ ```css
250
+ :root {
251
+ /* Colors */
252
+ --bg: #f9fbfd;
253
+ --bg-element: rgba(0, 0, 0, 0.02);
254
+ --bg-element-2: rgba(0, 0, 0, 0.04);
255
+ --text: #3b3b3b;
256
+ --heading: #11324a;
257
+ --primary: #2b2b2b;
258
+ --secondary: #ababab;
259
+ --link: #3773E6;
260
+ --accent: #f7d706;
261
+
262
+ /* Spacing */
263
+ --small-padding: 12px;
264
+ --safe-padding: 16px;
265
+ --larger-padding: 24px;
266
+ }
267
+ ```
268
+
269
+ ### Dark Mode
270
+
271
+ Dark mode is automatically applied based on system preferences, or you can force it with a class:
272
+
273
+ ```html
274
+ <body class="dark">
275
+ <!-- Your app -->
276
+ </body>
277
+ ```
278
+
279
+ ## Browser Support
280
+
281
+ - Chrome/Edge 67+
282
+ - Firefox 63+
283
+ - Safari 13.1+
284
+ - All modern browsers with Web Components support
285
+
286
+ ## License
287
+
288
+ MIT
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Button Component Export
3
+ */
4
+ export { MarzButton, type MarzButtonProps } from './button';
5
+ //# sourceMappingURL=index.d.ts.map
6
+
7
+ declare global {
8
+ interface HTMLElementTagNameMap {
9
+ 'marz-button': import('../components/button').MarzButton;
10
+ 'marz-input': import('../components/input').MarzInput;
11
+ 'marz-sidepanel': import('../components/sidepanel').MarzSidepanel;
12
+ }
13
+ }
14
+
@@ -0,0 +1,145 @@
1
+ class s extends HTMLElement {
2
+ constructor() {
3
+ super(), this.attachShadow({ mode: "open" }), this.button = document.createElement("button"), this.button.type = "button";
4
+ const t = document.createElement("style");
5
+ t.textContent = this.getStyles(), this.shadowRoot.appendChild(t), this.shadowRoot.appendChild(this.button), this.button.addEventListener("click", () => {
6
+ this.dispatchEvent(new Event("click", { bubbles: !0, composed: !0 }));
7
+ });
8
+ }
9
+ static get observedAttributes() {
10
+ return ["primary", "background-color", "size", "label", "no-outline", "disabled"];
11
+ }
12
+ connectedCallback() {
13
+ this.render();
14
+ }
15
+ attributeChangedCallback(t, e, r) {
16
+ e !== r && this.render();
17
+ }
18
+ render() {
19
+ const t = this.hasAttribute("primary"), e = this.getAttribute("size") || "medium", r = this.getAttribute("label") || this.textContent || "", i = this.hasAttribute("no-outline"), o = this.getAttribute("background-color"), n = this.hasAttribute("disabled"), a = [
20
+ "marz-button",
21
+ `marz-button--${e}`,
22
+ t ? "marz-button--primary" : "marz-button--secondary",
23
+ i ? "marz-button--no-outline" : ""
24
+ ].filter(Boolean).join(" ");
25
+ this.button.className = a, this.button.textContent = r, this.button.disabled = n, o ? this.button.style.backgroundColor = o : this.button.style.backgroundColor = "";
26
+ }
27
+ getStyles() {
28
+ return `
29
+ :host {
30
+ display: inline-block;
31
+ width: 100%;
32
+ }
33
+
34
+ .marz-button {
35
+ display: inline-block;
36
+ cursor: pointer;
37
+ border: 0;
38
+ border-radius: 3em;
39
+ font-weight: 700;
40
+ line-height: 1;
41
+ font-family: 'Inter', sans-serif;
42
+ width: 100%;
43
+ transition: all 100ms;
44
+ box-sizing: border-box;
45
+ }
46
+
47
+ .marz-button:disabled {
48
+ opacity: 0.5;
49
+ cursor: not-allowed;
50
+ }
51
+
52
+ .marz-button--primary {
53
+ border: var(--accent, #f7d706) 1px solid;
54
+ background-color: transparent;
55
+ color: var(--primary-btn-text, #3b3b3b);
56
+ }
57
+
58
+ .marz-button--primary:hover:not(:disabled) {
59
+ border: var(--accent, #f7d706) 1px solid;
60
+ background-color: var(--accent, #f7d706);
61
+ color: var(--primary-btn-text-hover, #3b3b3b);
62
+ }
63
+
64
+ .marz-button--secondary {
65
+ border: var(--secondary, #ababab) 1px solid;
66
+ background-color: transparent;
67
+ color: var(--text, #3b3b3b);
68
+ }
69
+
70
+ .marz-button--secondary:hover:not(:disabled) {
71
+ border: var(--primary, #2b2b2b) 1px solid;
72
+ background-color: var(--bg-element, rgba(0, 0, 0, 0.02));
73
+ color: var(--text, #3b3b3b);
74
+ }
75
+
76
+ .marz-button--secondary:active:not(:disabled) {
77
+ border: var(--primary, #2b2b2b) 1px solid;
78
+ background-color: var(--bg-element-2, rgba(0, 0, 0, 0.04));
79
+ color: var(--text, #3b3b3b);
80
+ }
81
+
82
+ .marz-button--small {
83
+ padding: 10px 10px;
84
+ font-size: 12px;
85
+ min-width: 32px;
86
+ height: 32px;
87
+ }
88
+
89
+ .marz-button--medium {
90
+ padding: 11px 20px;
91
+ font-size: 14px;
92
+ }
93
+
94
+ .marz-button--large {
95
+ padding: 12px 24px;
96
+ font-size: 16px;
97
+ }
98
+
99
+ .marz-button--no-outline {
100
+ border: none !important;
101
+ }
102
+
103
+ @media only screen and (min-width: 0) {
104
+ .marz-button {
105
+ max-width: 100%;
106
+ }
107
+ }
108
+
109
+ @media only screen and (min-width: 48em) {
110
+ .marz-button {
111
+ max-width: 300px;
112
+ }
113
+ }
114
+ `;
115
+ }
116
+ // Public API for programmatic control
117
+ get primary() {
118
+ return this.hasAttribute("primary");
119
+ }
120
+ set primary(t) {
121
+ t ? this.setAttribute("primary", "") : this.removeAttribute("primary");
122
+ }
123
+ get size() {
124
+ return this.getAttribute("size") || "medium";
125
+ }
126
+ set size(t) {
127
+ this.setAttribute("size", t);
128
+ }
129
+ get label() {
130
+ return this.getAttribute("label") || "";
131
+ }
132
+ set label(t) {
133
+ this.setAttribute("label", t);
134
+ }
135
+ get disabled() {
136
+ return this.hasAttribute("disabled");
137
+ }
138
+ set disabled(t) {
139
+ t ? this.setAttribute("disabled", "") : this.removeAttribute("disabled");
140
+ }
141
+ }
142
+ customElements.get("marz-button") || customElements.define("marz-button", s);
143
+ export {
144
+ s as MarzButton
145
+ };
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Input Component Export
3
+ */
4
+ export { MarzInput, type MarzInputProps } from './input';
5
+ //# sourceMappingURL=index.d.ts.map
6
+
7
+ declare global {
8
+ interface HTMLElementTagNameMap {
9
+ 'marz-button': import('../components/button').MarzButton;
10
+ 'marz-input': import('../components/input').MarzInput;
11
+ 'marz-sidepanel': import('../components/sidepanel').MarzSidepanel;
12
+ }
13
+ }
14
+
@@ -0,0 +1,148 @@
1
+ class n extends HTMLElement {
2
+ constructor() {
3
+ super(), this.attachShadow({ mode: "open" }), this.wrapper = document.createElement("div"), this.wrapper.className = "marz-input-wrapper", this.labelElement = document.createElement("label"), this.labelElement.className = "marz-input-label", this.input = document.createElement("input");
4
+ const t = document.createElement("style");
5
+ t.textContent = this.getStyles(), this.wrapper.appendChild(this.labelElement), this.wrapper.appendChild(this.input), this.shadowRoot.appendChild(t), this.shadowRoot.appendChild(this.wrapper), this.input.addEventListener("input", () => {
6
+ const e = this.input.value;
7
+ this.setAttribute("value", e), this.dispatchEvent(new CustomEvent("change", {
8
+ detail: { value: e },
9
+ bubbles: !0,
10
+ composed: !0
11
+ }));
12
+ }), ["focus", "blur", "keydown", "keyup"].forEach((e) => {
13
+ this.input.addEventListener(e, () => {
14
+ this.dispatchEvent(new Event(e, { bubbles: !0, composed: !0 }));
15
+ });
16
+ });
17
+ }
18
+ static get observedAttributes() {
19
+ return ["size", "label", "placeholder", "value", "disabled", "type"];
20
+ }
21
+ connectedCallback() {
22
+ this.render();
23
+ }
24
+ attributeChangedCallback(t, e, i) {
25
+ e !== i && this.render();
26
+ }
27
+ render() {
28
+ const t = this.getAttribute("size") || "medium", e = this.getAttribute("label") || "", i = this.getAttribute("placeholder") || "", s = this.getAttribute("value") || "", a = this.hasAttribute("disabled"), r = this.getAttribute("type") || "text", l = [
29
+ "marz-input",
30
+ `marz-input--${t}`
31
+ ].join(" ");
32
+ this.input.className = l, this.input.placeholder = i, this.input.disabled = a, this.input.type = r, this.input.value !== s && (this.input.value = s), this.labelElement.textContent = e, this.labelElement.style.display = e ? "block" : "none";
33
+ }
34
+ getStyles() {
35
+ return `
36
+ :host {
37
+ display: block;
38
+ width: 100%;
39
+ }
40
+
41
+ .marz-input-wrapper {
42
+ display: flex;
43
+ flex-direction: column;
44
+ gap: 8px;
45
+ width: 100%;
46
+ }
47
+
48
+ .marz-input-label {
49
+ font-weight: 600;
50
+ font-size: 14px;
51
+ color: var(--text, #3b3b3b);
52
+ font-family: 'Inter', sans-serif;
53
+ }
54
+
55
+ .marz-input {
56
+ display: inline-block;
57
+ cursor: text;
58
+ border: 0;
59
+ border-radius: 1em;
60
+ font-weight: 500;
61
+ line-height: 1;
62
+ width: 100%;
63
+ transition: all 100ms;
64
+ background-color: var(--bg-element, rgba(0, 0, 0, 0.02));
65
+ color: var(--text, #3b3b3b);
66
+ border: var(--secondary, #ababab) 1px solid;
67
+ outline: none;
68
+ box-sizing: border-box;
69
+ font-family: 'Inter', sans-serif;
70
+ }
71
+
72
+ .marz-input:disabled {
73
+ opacity: 0.5;
74
+ cursor: not-allowed;
75
+ }
76
+
77
+ .marz-input:focus,
78
+ .marz-input:active,
79
+ .marz-input:hover:not(:disabled) {
80
+ border: var(--primary, #2b2b2b) 1px solid;
81
+ }
82
+
83
+ .marz-input--small {
84
+ padding: 10px 8px;
85
+ font-size: 12px;
86
+ }
87
+
88
+ .marz-input--medium {
89
+ padding: 12px 12px;
90
+ font-size: 14px;
91
+ }
92
+
93
+ .marz-input--large {
94
+ padding: 16px 8px;
95
+ font-size: 16px;
96
+ }
97
+ `;
98
+ }
99
+ // Public API for programmatic control
100
+ get size() {
101
+ return this.getAttribute("size") || "medium";
102
+ }
103
+ set size(t) {
104
+ this.setAttribute("size", t);
105
+ }
106
+ get label() {
107
+ return this.getAttribute("label") || "";
108
+ }
109
+ set label(t) {
110
+ this.setAttribute("label", t);
111
+ }
112
+ get placeholder() {
113
+ return this.getAttribute("placeholder") || "";
114
+ }
115
+ set placeholder(t) {
116
+ this.setAttribute("placeholder", t);
117
+ }
118
+ get value() {
119
+ return this.input.value;
120
+ }
121
+ set value(t) {
122
+ this.input.value = t, this.setAttribute("value", t);
123
+ }
124
+ get disabled() {
125
+ return this.hasAttribute("disabled");
126
+ }
127
+ set disabled(t) {
128
+ t ? this.setAttribute("disabled", "") : this.removeAttribute("disabled");
129
+ }
130
+ get type() {
131
+ return this.getAttribute("type") || "text";
132
+ }
133
+ set type(t) {
134
+ this.setAttribute("type", t);
135
+ }
136
+ // Method to focus the input
137
+ focus() {
138
+ this.input.focus();
139
+ }
140
+ // Method to blur the input
141
+ blur() {
142
+ this.input.blur();
143
+ }
144
+ }
145
+ customElements.get("marz-input") || customElements.define("marz-input", n);
146
+ export {
147
+ n as MarzInput
148
+ };
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Sidepanel Component Export
3
+ */
4
+ export { MarzSidepanel, type MarzSidepanelProps } from './sidepanel';
5
+ //# sourceMappingURL=index.d.ts.map
6
+
7
+ declare global {
8
+ interface HTMLElementTagNameMap {
9
+ 'marz-button': import('../components/button').MarzButton;
10
+ 'marz-input': import('../components/input').MarzInput;
11
+ 'marz-sidepanel': import('../components/sidepanel').MarzSidepanel;
12
+ }
13
+ }
14
+