modular-ui-kit-react 0.0.0-stage → 1.0.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Eugenia
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,176 @@
1
- # Temporary Holding Version
1
+ # modular-ui-kit-react
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ [![NPM Version](https://img.shields.io/npm/v/modular-ui-kit-react?color=42b883)](https://www.npmjs.com/package/modular-ui-kit-react)
4
+
5
+ [![NPM Downloads](https://img.shields.io/npm/dm/modular-ui-kit-react?color=35495e)](https://www.npmjs.com/package/modular-ui-kit-react)
6
+
7
+ [![GitHub Clones](https://img.shields.io/badge/dynamic/json?color=success&label=Clone&query=count&url=https://gist.githubusercontent.com/eugenia-vitinschii/e3f532a4d6ca634ade757fa0cea0aea9/raw/clone.json&logo=github)](https://github.com/MShawon/github-clone-count-badge)
8
+
9
+ *Modular UI Kit React* A lightweight, modular React component library powered by SASS and unified design tokens. Built for seamless developer experience and modern web UI consistency.
10
+ _________
11
+
12
+ ### ⭐️ MukText ⭐️
13
+ A flexible typography component designed to render consistent text elements (p, h1–h6, span, a, etc.) with standardized styling and semantic control via the as polymorphic prop.
14
+
15
+ #### Props
16
+
17
+ | Prop | Type | Default | Description |
18
+ | :--- | :--- | :--- | :--- |
19
+ | `as` | `ElementType` | `'p'` | Polymorphic prop. The underlying HTML element or React component to render (`'p'`, `'h1'`–`'h6'`, `'span'`, `'a'`, etc.). |
20
+ | `type` | `UITextType` | `'muk-body-text'` | Applies typography preset styles (`muk-heading`, `muk-subheading`, `muk-body-text`, `muk-caption`). |
21
+ | `variant` | `UITextVariant` | `'secondary'` | Sets the text color theme (`primary`, `secondary`, `danger`, `warning`, `muted`). |
22
+ | `align` | `UITextAlign` | `'left'` | Text alignment (`left`, `center`, `right`). |
23
+ | `children` | `ReactNode` | — | Text or elements to be rendered inside the component. |
24
+
25
+ #### Usage Example
26
+
27
+ ```ts
28
+ import { MukText } from 'modular-ui-kit-react';
29
+
30
+ // Heading
31
+ <MukText as="h1" type="muk-heading" variant="primary">
32
+ Main Header
33
+ </MukText>
34
+
35
+ // Interactive Link
36
+ <MukText as="a" href="https://example.com" variant="primary">
37
+ Read More
38
+ </MukText>
39
+
40
+ ```
41
+
42
+ _________
43
+
44
+ ### ⭐️ MukButton ⭐️
45
+ A customizable button component that supports various visual variants, sizes, and states (including dynamic loading indicators and disability). It extends standard HTML button attributes and seamlessly handles async states.
46
+
47
+ #### MukButton Props
48
+
49
+ | Prop | Type | Default | Description |
50
+ | :--- | :--- | :--- | :--- |
51
+ | `variant` | `UIButtonVariant` | `'primary'` | Visual style preset (`primary`, `secondary`, `danger`, `warning`, etc.). |
52
+ | `size` | `UISize` | `'lg'` | Button size dimensions (`sm`, `md`, `lg`). |
53
+ | `type` | `UIButtonType` | `'button'` | Native HTML button type (`button`, `submit`, `reset`). |
54
+ | `loading` | `boolean` | `false` | Displays a loading spinner and disables user interaction. |
55
+ | `disabled` | `boolean` | `false` | Disables the button and prevents click events. |
56
+ | `children` | `ReactNode` | — | Button label, icon, or nested content. |
57
+
58
+
59
+ _______
60
+
61
+ ### ⭐️ MukIconButton ⭐️
62
+ An extension of the standard button component optimized for icon-first or icon-with-text layouts. It supports standard button variants, states, and sizes, with a dedicated slot for icons (children) and an optional text slot (text), automatically applying the has-text state class when label content is present.
63
+
64
+
65
+ #### MukIconButton Props
66
+
67
+ | Prop | Type | Default | Description |
68
+ | :--- | :--- | :--- | :--- |
69
+ | `children` | `ReactNode` | — | Primary slot for the SVG icon or visual content. |
70
+ | `text` | `ReactNode` | — | Optional slot for text label next to the icon. Triggers `has-text` class when provided. |
71
+ | `variant` | `UIButtonVariant` | `'primary'` | Visual style preset (`primary`, `secondary`, `danger`, `warning`, etc.). |
72
+ | `size` | `UISize` | `'lg'` | Button size dimensions (`sm`, `md`, `lg`). |
73
+ | `type` | `UIButtonType` | `'button'` | Native HTML button type (`button`, `submit`, `reset`). |
74
+ | `loading` | `boolean` | `false` | Displays a loading spinner and disables user interaction. |
75
+ | `disabled` | `boolean` | `false` | Disables the button and prevents click events. |
76
+ | `ariaLabel` | `string \| number` | — | Accessible label for screen readers (recommended when using icon-only mode). |
77
+
78
+ _________
79
+
80
+ ### ⭐️ MukInput ⭐️
81
+ A flexible and accessible text input component that supports floating labels, error/hint messages, and an optional built-in password visibility toggle. It extends native input attributes and seamlessly handles custom change events and validation states.
82
+
83
+ #### MukInput Props
84
+
85
+ | Prop | Type | Default | Description |
86
+ | :--- | :--- | :--- | :--- |
87
+ | `value` | `string \| number` | `''` | The current value of the input (controlled component state). |
88
+ | `onChange` | `(value: string) => void` | — | Callback function triggered when the input value changes. |
89
+ | `label` | `string` | — | Top floating label displayed above the input field. |
90
+ | `placeholder` | `string` | — | Placeholder text shown when the input is empty. |
91
+ | `hint` | `string` | — | Helper text displayed below the input (hidden if an error is present). |
92
+ | `error` | `string` | — | Error message string. Applies `is-error` style and takes precedence over hint. |
93
+ | `type` | `UIInputType` | `'text'` | Native HTML input type (`text`, `password`, `email`, etc.). |
94
+ | `showPasswordToggle` | `boolean` | `true` | Automatically adds a show/hide eye icon button when `type="password"`. |
95
+ | `id` | `string` | `useId()` | Unique identifier for the input, automatically generated if not provided. |
96
+ | `disabled` | `boolean` | `false` | Disables user interaction and applies disabled styles. |
97
+ | `autoComplete` | `string` | — | Native autocomplete attribute for browser autofill. |
98
+
99
+ _________
100
+
101
+ ### ⭐️ MukCheckbox ⭐️
102
+
103
+ An accessible and customizable checkbox component with a custom visual box, flexible label positioning, and support for error and hint validation states. It handles boolean states (checked/unchecked) seamlessly while maintaining native HTML input accessibility (aria-invalid, aria-describedby).
104
+
105
+
106
+ ### MukCheckbox Props
107
+
108
+ | Prop | Type | Default | Description |
109
+ | :--- | :--- | :--- | :--- |
110
+ | `value` | `boolean` | `false` | Controls the checked state of the checkbox (`true` for checked, `false` for unchecked). |
111
+ | `onChange` | `(value: boolean) => void` | — | Callback function triggered when the state toggles, returning the new boolean value. |
112
+ | `label` | `string` | — | Side label text displayed next to the checkbox. |
113
+ | `hint` | `string` | — | Helper text displayed below the checkbox (hidden if an error is present). |
114
+ | `error` | `string` | — | Error message string. Applies `is-error` style and takes precedence over hint. |
115
+ | `id` | `string` | `useId()` | Unique identifier for the input, automatically generated if not provided. |
116
+ | `disabled` | `boolean` | `false` | Disables user interaction and applies disabled visual styles. |
117
+ _________
118
+
119
+ ### ⭐️ MukRadio ⭐️
120
+
121
+ An accessible and customizable radio button component designed to work seamlessly within group selections. It supports custom selection states, side labels, and built-in error/hint validation messages, while fully respecting native HTML radio accessibility standards (aria-invalid, aria-describedby).
122
+
123
+
124
+ ### MukRadio Props
125
+
126
+ | Prop | Type | Default | Description |
127
+ | :--- | :--- | :--- | :--- |
128
+ | `value` | `string \| number \| boolean` | *Required* | The unique value associated with this specific radio button. |
129
+ | `selectedValue` | `string \| number \| boolean \| null` | — | The currently selected value of the entire radio group (used to determine `checked` state). |
130
+ | `onChange` | `(value: string \| number \| boolean) => void` | — | Callback function triggered when selected, returning this button's value. |
131
+ | `label` | `string` | — | Side label text displayed next to the radio circle. |
132
+ | `name` | `string` | — | Native HTML `name` attribute to group radio buttons together. |
133
+ | `hint` | `string` | — | Helper text displayed below the radio (hidden if an error is present). |
134
+ | `error` | `string` | — | Error message string. Applies `is-error` style and takes precedence over hint. |
135
+ | `id` | `string` | `useId()` | Unique identifier for the input, automatically generated if not provided. |
136
+ | `disabled` | `boolean` | `false` | Disables user interaction and applies disabled visual styles. |
137
+
138
+ _________
139
+
140
+ ### ⭐️ MukSelect ⭐️
141
+
142
+ An accessible dropdown select component built over the native HTML `<select>` element. It accepts a list of options, supports custom placeholders, labels, built-in validation states (errors and hints), and maintains full accessibility standards (aria-invalid, aria-describedby).
143
+
144
+ ### MukSelect Props
145
+
146
+ | Prop | Type | Default | Description |
147
+ | :--- | :--- | :--- | :--- |
148
+ | `value` | `string \| number` | `''` | The currently selected option value (controlled state). |
149
+ | `onChange` | `(value: string) => void` | — | Callback function triggered when a new option is selected. |
150
+ | `options` | `MukSelectOption[]` | `[]` | Array of option objects (`{ value: string \| number, label: string }`). |
151
+ | `label` | `string` | — | Label displayed above the select element. |
152
+ | `placeholder` | `string` | — | Default unselectable option text shown when no value is selected. |
153
+ | `hint` | `string` | — | Helper text displayed below the select (hidden if an error is present). |
154
+ | `error` | `string` | — | Error message string. Applies `is-error` style and takes precedence over hint. |
155
+ | `id` | `string` | `useId()` | Unique identifier for the select, automatically generated if not provided. |
156
+ | `disabled` | `boolean` | `false` | Disables user interaction and applies disabled visual styles. |
157
+
158
+ _________
159
+
160
+ ### ⭐️ MukTextarea ⭐️
161
+
162
+ A flexible and accessible multi-line text input component built over the native HTML `<textarea>`. It supports custom rows, auto-generated unique IDs, top labels, and built-in error/hint validation states while maintaining strict accessibility standards (`aria-invalid`, `aria-describedby`).
163
+
164
+ ### MukTextarea Props
165
+
166
+ | Prop | Type | Default | Description |
167
+ | :--- | :--- | :--- | :--- |
168
+ | `value` | `string \| number` | `''` | The current text value of the textarea (controlled component state). |
169
+ | `onChange` | `(value: string) => void` | — | Callback function triggered when the text changes, returning the new string. |
170
+ | `label` | `string` | — | Label displayed above the textarea element. |
171
+ | `placeholder` | `string` | — | Placeholder text shown when the textarea is empty. |
172
+ | `rows` | `number` | `6` | Number of visible text lines for the textarea control. |
173
+ | `hint` | `string` | — | Helper text displayed below the textarea (hidden if an error is present). |
174
+ | `error` | `string` | — | Error message string. Applies `is-error` style and takes precedence over hint. |
175
+ | `id` | `string` | `useId()` | Unique identifier for the textarea, automatically generated if not provided. |
176
+ | `disabled` | `boolean` | `false` | Disables user interaction and applies disabled visual styles. |
package/dist/index.cjs ADDED
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("react/jsx-runtime"),t=require("react");var n=({variant:t=`secondary`,align:n=`left`,as:r=`p`,type:i=`muk-body-text`,children:a,className:o=``,...s})=>{let c=[i,`muk-txt--${n}`,`muk-txt--${t}`,o].filter(Boolean).join(` `);return(0,e.jsx)(r,{className:c,...s,children:a})},r=({variant:t=`primary`,type:n=`button`,size:r=`lg`,loading:i=!1,disabled:a=!1,className:o=``,children:s,...c})=>{let l=[`muk-btn`,`muk-btn--${t}`,`muk-btn--${r}`,i?`isLoading`:``,o].filter(Boolean).join(` `);return(0,e.jsx)(`button`,{type:n,className:l,disabled:a||i,"aria-busy":i,...c,children:i?(0,e.jsxs)(e.Fragment,{children:[(0,e.jsx)(`span`,{className:`muk-btn-spinner`,"aria-hidden":`true`}),(0,e.jsx)(`span`,{className:`visually-hidden`,children:`Loading`})]}):(0,e.jsx)(`span`,{className:`muk-btn__content`,children:s})})},i=({variant:t=`primary`,type:n=`button`,size:r=`lg`,loading:i=!1,disabled:a=!1,className:o=``,ariaLabel:s,text:c,children:l,...u})=>{let d=[`muk-btn-icon`,`muk-btn-icon--${t}`,`muk-btn-icon--${r}`,i?`isLoading`:``,c?`has-text`:``,o].filter(Boolean).join(` `);return(0,e.jsx)(`button`,{type:n,className:d,disabled:a||i,"aria-busy":i,"artia-label":s?String(s):void 0,...u,children:i?(0,e.jsxs)(e.Fragment,{children:[(0,e.jsx)(`span`,{className:`muk-btn-spinner`,"aria-hidden":`true`}),(0,e.jsx)(`span`,{className:`visually-hidden`,children:`Loading`})]}):(0,e.jsxs)(`span`,{className:`muk-btn-icon__content`,children:[l,c]})})},a=({type:n=`text`,value:r=``,onChange:a,label:o,error:s,hint:c,showPasswordToggle:l=!0,disabled:u=!1,placeholder:d,id:f,className:p=``,...m})=>{let h=(0,t.useId)(),g=f||h,[_,v]=(0,t.useState)(!1),y=n===`password`&&l,b=y?_?`text`:`password`:n,x=[`muk-input`,y?`muk-input-password`:``,p].filter(Boolean).join(` `),S=[`muk-input__field`,s?`is-error`:``].filter(Boolean).join(` `),C=()=>{v(e=>!e)};return(0,e.jsxs)(`div`,{className:x,children:[o&&(0,e.jsx)(`label`,{htmlFor:`inputId`,className:`muk-form-label muk-form-label--top`,children:o}),(0,e.jsxs)(`div`,{className:`muk-input__wrapper`,children:[(0,e.jsx)(`input`,{id:g,type:b,value:r,disabled:u,placeholder:d,className:S,onChange:e=>a?.(e.target.value),"aria-invalid":!!s,"aria-describedby":s?`${g}-error`:c?`${g}-hint`:void 0,...m}),y&&(0,e.jsx)(i,{className:`muk-input__button`,onClick:C,ariaLabel:_?`Hide password`:`Show password`,children:_?(0,e.jsx)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 -960 960 960`,children:(0,e.jsx)(`path`,{d:`M403.5-423.5Q372-455 372-500t31.5-76.5Q435-608 480-608t76.5 31.5Q588-545 588-500t-31.5 76.5Q525-392 480-392t-76.5-31.5ZM480-200q-146 0-266-81.5T40-500q54-137 174-218.5T480-800q141 0 257.5 76T912-520h-91q-52-93-143-146.5T480-720q-113 0-207.5 59.5T128-500q50 101 144.5 160.5T480-280q20 0 40-2t40-6v81q-20 3-40 5t-40 2Zm0-120q22 0 42.5-5t38.5-14q5-50 31.5-90t67.5-64v-7q0-75-52.5-127.5T480-680q-75 0-127.5 52.5T300-500q0 75 52.5 127.5T480-320Zm-5-180Zm205 380q-17 0-28.5-11.5T640-160v-120q0-17 11.5-28.5T680-320v-40q0-33 23.5-56.5T760-440q33 0 56.5 23.5T840-360v40q17 0 28.5 11.5T880-280v120q0 17-11.5 28.5T840-120H680Zm40-200h80v-40q0-17-11.5-28.5T760-400q-17 0-28.5 11.5T720-360v40Z`})}):(0,e.jsx)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 -960 960 960`,children:(0,e.jsx)(`path`,{d:`M607.5-372.5Q660-425 660-500t-52.5-127.5Q555-680 480-680t-127.5 52.5Q300-575 300-500t52.5 127.5Q405-320 480-320t127.5-52.5Zm-204-51Q372-455 372-500t31.5-76.5Q435-608 480-608t76.5 31.5Q588-545 588-500t-31.5 76.5Q525-392 480-392t-76.5-31.5ZM214-281.5Q94-363 40-500q54-137 174-218.5T480-800q146 0 266 81.5T920-500q-54 137-174 218.5T480-200q-146 0-266-81.5ZM480-500Zm207.5 160.5Q782-399 832-500q-50-101-144.5-160.5T480-720q-113 0-207.5 59.5T128-500q50 101 144.5 160.5T480-280q113 0 207.5-59.5Z`})})})]}),s?(0,e.jsx)(`p`,{className:`muk-form-error`,id:`${g}-error`,children:s}):c?(0,e.jsx)(`p`,{className:`muk-form-hint`,id:`${g}-hint`,children:c}):null]})},o=({value:n=!1,onChange:r,label:i,error:a,hint:o,disabled:s=!1,id:c,className:l=``,...u})=>{let d=(0,t.useId)(),f=c||d,p=[`muk-checkbox`,a?`is-error`:``,s?`is-disabled`:``,l].filter(Boolean).join(` `);return(0,e.jsxs)(`div`,{className:p,children:[(0,e.jsx)(`label`,{htmlFor:f,className:`muk-checkbox__wrapper`,children:(0,e.jsxs)(`div`,{className:`muk-checkbox__data`,children:[(0,e.jsx)(`input`,{type:`checkbox`,className:`muk-checkbox__field`,id:f,checked:n,disabled:s,onChange:e=>r?.(e.target.checked),"aria-invalid":!!a,"aria-describedby":a?`${f}-error`:o?`${f}-hint`:void 0,...u}),(0,e.jsx)(`span`,{className:`muk-checkbox__box`,children:(0,e.jsx)(`span`,{className:`muk-checkbox__check`,children:`✓`})}),i&&(0,e.jsxs)(`span`,{className:`muk-form-label muk-form-label--side`,children:[` `,i]})]})}),(0,e.jsx)(`div`,{className:`muk-checkbox__info`,children:a?(0,e.jsx)(`p`,{className:`muk-form-error`,id:`${f}-error`,children:a}):o?(0,e.jsx)(`p`,{className:`muk-form-hint`,id:`${f}-hint`,children:o}):null})]})},s=({onChange:n,value:r,selectedValue:i,label:a,error:o,hint:s,name:c,disabled:l=!1,id:u,className:d=``,...f})=>{let p=(0,t.useId)(),m=u||p,h=i===void 0?f.checked:i===r,g=[`muk-radio`,o?`is-error`:``,l?`is-disabled`:``,d].filter(Boolean).join(` `);return(0,e.jsxs)(`div`,{className:g,children:[(0,e.jsx)(`label`,{htmlFor:m,className:`muk-radio__wrapper`,children:(0,e.jsxs)(`div`,{className:`muk-radio__data`,children:[(0,e.jsx)(`input`,{type:`radio`,className:`muk-radio__field`,name:c,id:m,checked:h,disabled:l,onChange:()=>n?.(r),"aria-invalid":!!o,"aria-describedby":o?`${m}-error`:s?`${m}-hint`:void 0,...f}),(0,e.jsx)(`span`,{className:`muk-radio__box`,children:(0,e.jsx)(`span`,{className:`muk-radio__circle`,"aria-hidden":`true`})}),a&&(0,e.jsx)(`span`,{className:`muk-form-label muk-form-label--side`,children:a})]})}),(0,e.jsx)(`div`,{className:`muk-radio__info`,children:o?(0,e.jsx)(`p`,{className:`muk-form-error`,id:`${m}-error`,children:o}):s?(0,e.jsx)(`p`,{className:`muk-form-hint`,id:`${m}-hint`,children:s}):null})]})},c=({onChange:n,value:r,options:i=[],label:a,error:o,hint:s,name:c,placeholder:l,disabled:u=!1,id:d,className:f=``,...p})=>{let m=(0,t.useId)(),h=d||m,g=[`muk-select`,o?`is-error`:``,u?`is-disabled`:``,f].filter(Boolean).join(` `);return(0,e.jsxs)(`div`,{className:g,children:[a&&(0,e.jsx)(`label`,{htmlFor:h,className:`muk-form-label muk-form-label--top`,children:a}),(0,e.jsxs)(`div`,{className:`muk-select__wrapper`,children:[(0,e.jsxs)(`select`,{className:`muk-select__field`,name:c,id:h,disabled:u,value:r??``,onChange:e=>n?.(e.target.value),"aria-invalid":!!o,"aria-describedby":o?`${h}-error`:s?`${h}-hint`:void 0,...p,children:[i.map(t=>(0,e.jsx)(`option`,{value:t.value,children:t.label},t.value)),l&&(0,e.jsx)(`option`,{disabled:!0,children:l})]}),(0,e.jsx)(`span`,{className:`muk-select__icon`,children:`↓`})]})]})},l=({value:n=``,onChange:r,label:i,error:a,hint:o,rows:s=6,disabled:c=!1,placeholder:l,id:u,className:d=``,...f})=>{let p=(0,t.useId)(),m=u||p,h=[`muk-textarea`,a?`is-error`:``,c?`is-disabled`:``,d].filter(Boolean).join(` `);return(0,e.jsxs)(`div`,{className:h,children:[i&&(0,e.jsx)(`label`,{htmlFor:m,className:`muk-form-label muk-form-label--top`,children:i}),(0,e.jsx)(`textarea`,{className:`muk-textarea__field`,id:m,value:n,onChange:e=>r?.(e.target.value),placeholder:l,rows:s,disabled:c,"aria-invalid":!!a,"aria-describedby":a?`${m}-error`:o?`${m}-hint`:void 0,...f}),a?(0,e.jsx)(`p`,{className:`muk-form-error`,id:`${m}-error`,children:a}):o?(0,e.jsx)(`p`,{className:`muk-form-hint`,id:`${m}-hint`,children:o}):null]})};exports.MukButton=r,exports.MukCheckbox=o,exports.MukIconButton=i,exports.MukInput=a,exports.MukRadio=s,exports.MukSelect=c,exports.MukText=n,exports.MukTextarea=l;
package/dist/index.js ADDED
@@ -0,0 +1,306 @@
1
+ import { Fragment as e, jsx as t, jsxs as n } from "react/jsx-runtime";
2
+ import { useId as r, useState as i } from "react";
3
+ //#region src/lib/components/typography/MukText.tsx
4
+ var a = ({ variant: e = "secondary", align: n = "left", as: r = "p", type: i = "muk-body-text", children: a, className: o = "", ...s }) => {
5
+ let c = [
6
+ i,
7
+ `muk-txt--${n}`,
8
+ `muk-txt--${e}`,
9
+ o
10
+ ].filter(Boolean).join(" ");
11
+ return /* @__PURE__ */ t(r, {
12
+ className: c,
13
+ ...s,
14
+ children: a
15
+ });
16
+ }, o = ({ variant: r = "primary", type: i = "button", size: a = "lg", loading: o = !1, disabled: s = !1, className: c = "", children: l, ...u }) => {
17
+ let d = [
18
+ "muk-btn",
19
+ `muk-btn--${r}`,
20
+ `muk-btn--${a}`,
21
+ o ? "isLoading" : "",
22
+ c
23
+ ].filter(Boolean).join(" ");
24
+ return /* @__PURE__ */ t("button", {
25
+ type: i,
26
+ className: d,
27
+ disabled: s || o,
28
+ "aria-busy": o,
29
+ ...u,
30
+ children: o ? /* @__PURE__ */ n(e, { children: [/* @__PURE__ */ t("span", {
31
+ className: "muk-btn-spinner",
32
+ "aria-hidden": "true"
33
+ }), /* @__PURE__ */ t("span", {
34
+ className: "visually-hidden",
35
+ children: "Loading"
36
+ })] }) : /* @__PURE__ */ t("span", {
37
+ className: "muk-btn__content",
38
+ children: l
39
+ })
40
+ });
41
+ }, s = ({ variant: r = "primary", type: i = "button", size: a = "lg", loading: o = !1, disabled: s = !1, className: c = "", ariaLabel: l, text: u, children: d, ...f }) => {
42
+ let p = [
43
+ "muk-btn-icon",
44
+ `muk-btn-icon--${r}`,
45
+ `muk-btn-icon--${a}`,
46
+ o ? "isLoading" : "",
47
+ u ? "has-text" : "",
48
+ c
49
+ ].filter(Boolean).join(" ");
50
+ return /* @__PURE__ */ t("button", {
51
+ type: i,
52
+ className: p,
53
+ disabled: s || o,
54
+ "aria-busy": o,
55
+ "artia-label": l ? String(l) : void 0,
56
+ ...f,
57
+ children: o ? /* @__PURE__ */ n(e, { children: [/* @__PURE__ */ t("span", {
58
+ className: "muk-btn-spinner",
59
+ "aria-hidden": "true"
60
+ }), /* @__PURE__ */ t("span", {
61
+ className: "visually-hidden",
62
+ children: "Loading"
63
+ })] }) : /* @__PURE__ */ n("span", {
64
+ className: "muk-btn-icon__content",
65
+ children: [d, u]
66
+ })
67
+ });
68
+ }, c = ({ type: e = "text", value: a = "", onChange: o, label: c, error: l, hint: u, showPasswordToggle: d = !0, disabled: f = !1, placeholder: p, id: m, className: h = "", ...g }) => {
69
+ let _ = r(), v = m || _, [y, b] = i(!1), x = e === "password" && d, S = x ? y ? "text" : "password" : e, C = [
70
+ "muk-input",
71
+ x ? "muk-input-password" : "",
72
+ h
73
+ ].filter(Boolean).join(" "), w = ["muk-input__field", l ? "is-error" : ""].filter(Boolean).join(" "), T = () => {
74
+ b((e) => !e);
75
+ };
76
+ return /* @__PURE__ */ n("div", {
77
+ className: C,
78
+ children: [
79
+ c && /* @__PURE__ */ t("label", {
80
+ htmlFor: "inputId",
81
+ className: "muk-form-label muk-form-label--top",
82
+ children: c
83
+ }),
84
+ /* @__PURE__ */ n("div", {
85
+ className: "muk-input__wrapper",
86
+ children: [/* @__PURE__ */ t("input", {
87
+ id: v,
88
+ type: S,
89
+ value: a,
90
+ disabled: f,
91
+ placeholder: p,
92
+ className: w,
93
+ onChange: (e) => o?.(e.target.value),
94
+ "aria-invalid": !!l,
95
+ "aria-describedby": l ? `${v}-error` : u ? `${v}-hint` : void 0,
96
+ ...g
97
+ }), x && /* @__PURE__ */ t(s, {
98
+ className: "muk-input__button",
99
+ onClick: T,
100
+ ariaLabel: y ? "Hide password" : "Show password",
101
+ children: y ? /* @__PURE__ */ t("svg", {
102
+ xmlns: "http://www.w3.org/2000/svg",
103
+ viewBox: "0 -960 960 960",
104
+ children: /* @__PURE__ */ t("path", { d: "M403.5-423.5Q372-455 372-500t31.5-76.5Q435-608 480-608t76.5 31.5Q588-545 588-500t-31.5 76.5Q525-392 480-392t-76.5-31.5ZM480-200q-146 0-266-81.5T40-500q54-137 174-218.5T480-800q141 0 257.5 76T912-520h-91q-52-93-143-146.5T480-720q-113 0-207.5 59.5T128-500q50 101 144.5 160.5T480-280q20 0 40-2t40-6v81q-20 3-40 5t-40 2Zm0-120q22 0 42.5-5t38.5-14q5-50 31.5-90t67.5-64v-7q0-75-52.5-127.5T480-680q-75 0-127.5 52.5T300-500q0 75 52.5 127.5T480-320Zm-5-180Zm205 380q-17 0-28.5-11.5T640-160v-120q0-17 11.5-28.5T680-320v-40q0-33 23.5-56.5T760-440q33 0 56.5 23.5T840-360v40q17 0 28.5 11.5T880-280v120q0 17-11.5 28.5T840-120H680Zm40-200h80v-40q0-17-11.5-28.5T760-400q-17 0-28.5 11.5T720-360v40Z" })
105
+ }) : /* @__PURE__ */ t("svg", {
106
+ xmlns: "http://www.w3.org/2000/svg",
107
+ viewBox: "0 -960 960 960",
108
+ children: /* @__PURE__ */ t("path", { d: "M607.5-372.5Q660-425 660-500t-52.5-127.5Q555-680 480-680t-127.5 52.5Q300-575 300-500t52.5 127.5Q405-320 480-320t127.5-52.5Zm-204-51Q372-455 372-500t31.5-76.5Q435-608 480-608t76.5 31.5Q588-545 588-500t-31.5 76.5Q525-392 480-392t-76.5-31.5ZM214-281.5Q94-363 40-500q54-137 174-218.5T480-800q146 0 266 81.5T920-500q-54 137-174 218.5T480-200q-146 0-266-81.5ZM480-500Zm207.5 160.5Q782-399 832-500q-50-101-144.5-160.5T480-720q-113 0-207.5 59.5T128-500q50 101 144.5 160.5T480-280q113 0 207.5-59.5Z" })
109
+ })
110
+ })]
111
+ }),
112
+ l ? /* @__PURE__ */ t("p", {
113
+ className: "muk-form-error",
114
+ id: `${v}-error`,
115
+ children: l
116
+ }) : u ? /* @__PURE__ */ t("p", {
117
+ className: "muk-form-hint",
118
+ id: `${v}-hint`,
119
+ children: u
120
+ }) : null
121
+ ]
122
+ });
123
+ }, l = ({ value: e = !1, onChange: i, label: a, error: o, hint: s, disabled: c = !1, id: l, className: u = "", ...d }) => {
124
+ let f = r(), p = l || f, m = [
125
+ "muk-checkbox",
126
+ o ? "is-error" : "",
127
+ c ? "is-disabled" : "",
128
+ u
129
+ ].filter(Boolean).join(" ");
130
+ return /* @__PURE__ */ n("div", {
131
+ className: m,
132
+ children: [/* @__PURE__ */ t("label", {
133
+ htmlFor: p,
134
+ className: "muk-checkbox__wrapper",
135
+ children: /* @__PURE__ */ n("div", {
136
+ className: "muk-checkbox__data",
137
+ children: [
138
+ /* @__PURE__ */ t("input", {
139
+ type: "checkbox",
140
+ className: "muk-checkbox__field",
141
+ id: p,
142
+ checked: e,
143
+ disabled: c,
144
+ onChange: (e) => i?.(e.target.checked),
145
+ "aria-invalid": !!o,
146
+ "aria-describedby": o ? `${p}-error` : s ? `${p}-hint` : void 0,
147
+ ...d
148
+ }),
149
+ /* @__PURE__ */ t("span", {
150
+ className: "muk-checkbox__box",
151
+ children: /* @__PURE__ */ t("span", {
152
+ className: "muk-checkbox__check",
153
+ children: "✓"
154
+ })
155
+ }),
156
+ a && /* @__PURE__ */ n("span", {
157
+ className: "muk-form-label muk-form-label--side",
158
+ children: [" ", a]
159
+ })
160
+ ]
161
+ })
162
+ }), /* @__PURE__ */ t("div", {
163
+ className: "muk-checkbox__info",
164
+ children: o ? /* @__PURE__ */ t("p", {
165
+ className: "muk-form-error",
166
+ id: `${p}-error`,
167
+ children: o
168
+ }) : s ? /* @__PURE__ */ t("p", {
169
+ className: "muk-form-hint",
170
+ id: `${p}-hint`,
171
+ children: s
172
+ }) : null
173
+ })]
174
+ });
175
+ }, u = ({ onChange: e, value: i, selectedValue: a, label: o, error: s, hint: c, name: l, disabled: u = !1, id: d, className: f = "", ...p }) => {
176
+ let m = r(), h = d || m, g = a === void 0 ? p.checked : a === i, _ = [
177
+ "muk-radio",
178
+ s ? "is-error" : "",
179
+ u ? "is-disabled" : "",
180
+ f
181
+ ].filter(Boolean).join(" ");
182
+ return /* @__PURE__ */ n("div", {
183
+ className: _,
184
+ children: [/* @__PURE__ */ t("label", {
185
+ htmlFor: h,
186
+ className: "muk-radio__wrapper",
187
+ children: /* @__PURE__ */ n("div", {
188
+ className: "muk-radio__data",
189
+ children: [
190
+ /* @__PURE__ */ t("input", {
191
+ type: "radio",
192
+ className: "muk-radio__field",
193
+ name: l,
194
+ id: h,
195
+ checked: g,
196
+ disabled: u,
197
+ onChange: () => e?.(i),
198
+ "aria-invalid": !!s,
199
+ "aria-describedby": s ? `${h}-error` : c ? `${h}-hint` : void 0,
200
+ ...p
201
+ }),
202
+ /* @__PURE__ */ t("span", {
203
+ className: "muk-radio__box",
204
+ children: /* @__PURE__ */ t("span", {
205
+ className: "muk-radio__circle",
206
+ "aria-hidden": "true"
207
+ })
208
+ }),
209
+ o && /* @__PURE__ */ t("span", {
210
+ className: "muk-form-label muk-form-label--side",
211
+ children: o
212
+ })
213
+ ]
214
+ })
215
+ }), /* @__PURE__ */ t("div", {
216
+ className: "muk-radio__info",
217
+ children: s ? /* @__PURE__ */ t("p", {
218
+ className: "muk-form-error",
219
+ id: `${h}-error`,
220
+ children: s
221
+ }) : c ? /* @__PURE__ */ t("p", {
222
+ className: "muk-form-hint",
223
+ id: `${h}-hint`,
224
+ children: c
225
+ }) : null
226
+ })]
227
+ });
228
+ }, d = ({ onChange: e, value: i, options: a = [], label: o, error: s, hint: c, name: l, placeholder: u, disabled: d = !1, id: f, className: p = "", ...m }) => {
229
+ let h = r(), g = f || h, _ = [
230
+ "muk-select",
231
+ s ? "is-error" : "",
232
+ d ? "is-disabled" : "",
233
+ p
234
+ ].filter(Boolean).join(" ");
235
+ return /* @__PURE__ */ n("div", {
236
+ className: _,
237
+ children: [o && /* @__PURE__ */ t("label", {
238
+ htmlFor: g,
239
+ className: "muk-form-label muk-form-label--top",
240
+ children: o
241
+ }), /* @__PURE__ */ n("div", {
242
+ className: "muk-select__wrapper",
243
+ children: [/* @__PURE__ */ n("select", {
244
+ className: "muk-select__field",
245
+ name: l,
246
+ id: g,
247
+ disabled: d,
248
+ value: i ?? "",
249
+ onChange: (t) => e?.(t.target.value),
250
+ "aria-invalid": !!s,
251
+ "aria-describedby": s ? `${g}-error` : c ? `${g}-hint` : void 0,
252
+ ...m,
253
+ children: [a.map((e) => /* @__PURE__ */ t("option", {
254
+ value: e.value,
255
+ children: e.label
256
+ }, e.value)), u && /* @__PURE__ */ t("option", {
257
+ disabled: !0,
258
+ children: u
259
+ })]
260
+ }), /* @__PURE__ */ t("span", {
261
+ className: "muk-select__icon",
262
+ children: "↓"
263
+ })]
264
+ })]
265
+ });
266
+ }, f = ({ value: e = "", onChange: i, label: a, error: o, hint: s, rows: c = 6, disabled: l = !1, placeholder: u, id: d, className: f = "", ...p }) => {
267
+ let m = r(), h = d || m, g = [
268
+ "muk-textarea",
269
+ o ? "is-error" : "",
270
+ l ? "is-disabled" : "",
271
+ f
272
+ ].filter(Boolean).join(" ");
273
+ return /* @__PURE__ */ n("div", {
274
+ className: g,
275
+ children: [
276
+ a && /* @__PURE__ */ t("label", {
277
+ htmlFor: h,
278
+ className: "muk-form-label muk-form-label--top",
279
+ children: a
280
+ }),
281
+ /* @__PURE__ */ t("textarea", {
282
+ className: "muk-textarea__field",
283
+ id: h,
284
+ value: e,
285
+ onChange: (e) => i?.(e.target.value),
286
+ placeholder: u,
287
+ rows: c,
288
+ disabled: l,
289
+ "aria-invalid": !!o,
290
+ "aria-describedby": o ? `${h}-error` : s ? `${h}-hint` : void 0,
291
+ ...p
292
+ }),
293
+ o ? /* @__PURE__ */ t("p", {
294
+ className: "muk-form-error",
295
+ id: `${h}-error`,
296
+ children: o
297
+ }) : s ? /* @__PURE__ */ t("p", {
298
+ className: "muk-form-hint",
299
+ id: `${h}-hint`,
300
+ children: s
301
+ }) : null
302
+ ]
303
+ });
304
+ };
305
+ //#endregion
306
+ export { o as MukButton, l as MukCheckbox, s as MukIconButton, c as MukInput, u as MukRadio, d as MukSelect, a as MukText, f as MukTextarea };
@@ -0,0 +1,2 @@
1
+ @import "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap";:root{--muk-text:#eceef2;--muk-text-muted:#8a93a6;--muk-bg:#0b0d11;--muk-bg-soft:#12151c;--muk-bg-card:#171b24;--muk-bg-code:#1e2330;--muk-primary:#6366f1;--muk-primary-hover:#4f46e5;--muk-danger:#ff4a6b;--muk-success:#10b981;--muk-warning:#f59e0b;--muk-font-family:"Inter", system-ui, -apple-system, sans-serif;--muk-font-heading:26px;--muk-font-subheading:19px;--muk-font-body:16px;--muk-caption:14px;--muk-font-heading-md:24px;--muk-font-subheading-md:18px;--muk-font-body-md:15px;--muk-caption-md:13px;--muk-font-heading-sm:20px;--muk-font-subheading-sm:16px;--muk-font-body-sm:14px;--muk-caption-sm:13px;--muk-border-color:#eceef214;--muk-border-width:1px;--muk-border-style:solid;--muk-border-radius:5px;--muk-space-content-sm:6px;--muk-space-content-md:10px;--muk-space-content-lg:14px;--muk-space-container-sm:16px;--muk-space-container-md:24px;--muk-space-container-lg:32px;--muk-transition:all .3s ease-out;--muk-opacity:.4}.muk-wrapper{background:var(--muk-bg);flex-direction:column;min-height:100vh;display:flex}.muk-header{flex:none}.muk-content{flex:1 0 auto;padding:20px 0 0}.muk-footer{background:var(--muk-bg-card);flex:none;padding:20px 0}.muk-footer__wrapper{flex-direction:column;align-items:center;gap:10px;display:flex}.muk-container{max-width:1400px;margin:0 auto;padding:0 20px}.muk-heading{font-size:var(--muk-font-heading);font-weight:600;line-height:34px}.muk-subheading{font-size:var(--muk-font-subheading);font-weight:500;line-height:28px}.muk-body-text{font-size:var(--muk-font-body);font-weight:400;line-height:24px}.muk-caption{font-size:var(--muk-caption);font-weight:400;line-height:24px}@media (width<=1024px){.muk-heading{font-size:var(--muk-font-heading-md);line-height:30px}.muk-subheading{font-size:var(--muk-font-subheading-md);line-height:24px}.muk-body-text{font-size:var(--muk-font-body-md);line-height:22px}.muk-caption{font-size:var(--muk-caption-md);line-height:16px}}@media (width<=767px){.muk-heading{font-size:var(--muk-font-heading-sm);line-height:26px}.muk-subheading{font-size:var(--muk-font-subheading-sm);line-height:22px}.muk-body-text{font-size:var(--muk-font-body-sm);line-height:20px}.muk-caption{font-size:var(--muk-caption-sm);line-height:14px}}a{transition:var(--muk-transition);text-underline-offset:4px;display:block}a:hover{opacity:.8}a:active{opacity:.6;filter:brightness(.9)}*,:before,:after{box-sizing:border-box}:focus,:active,a:focus,a:active{outline:none}body,#app{font-family:var(--muk-font-family)}nav,footer,aside{display:block}html,body{-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;-ms-text-size-adjust:100%;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-rendering:optimizelegibility;background:#232222;height:100%;margin:0;padding:0;font-size:100%;line-height:1.5}input,textarea,button,select{font-family:inherit}select{appearance:none}input::-ms-clear{display:none}button{cursor:pointer;background:0 0;border:none}button::-moz-focus-inner{border:0;padding:0}a,a:visited{cursor:pointer;text-decoration:none}button,a:hover{text-decoration:none}h1,h2,h3,h4,h5,h6{font-weight:400}ul{padding-inline-start:0}ul li{margin:0;list-style:none}img{max-width:100%;display:block}.muk-shimmer{position:relative;overflow:hidden}.muk-shimmer:before{content:"";background:linear-gradient(to right, transparent 0%, var(--muk-text-muted) 50%, transparent 100%);width:150px;height:100%;animation:2.6s infinite loading;position:absolute;top:0;left:-150px}@keyframes loading{0%{left:-150px}to{left:100%}}.fade-enter-active,.fade-leave-active{transition:opacity .25s}.fade-enter-from,.fade-leave-to{opacity:0}.muk-pop-enter-active{animation:.35s cubic-bezier(.175,.885,.32,1.275) muk-heart-bounce}.muk-pop-leave-active{opacity:0;transition:opacity .1s,transform .1s;transform:scale(.5)}.visually-hidden{clip:rect(0, 0, 0, 0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.muk-section{border:var(--muk-border-width) var(--muk-border-style) var(--muk-bg);border-radius:var(--muk-border-radius);background:var(--muk-bg-card);width:100%;transition:var(--muk-transition);padding:var(--muk-space-container-lg);margin:var(--muk-space-container-lg) 0px}@media (width<=1024px){.muk-section{padding:var(--muk-space-container-md);margin:var(--muk-space-container-md) 0px}}@media (width<=768px){.muk-section{padding:var(--muk-space-container-sm);margin:var(--muk-space-container-sm) 0px}}.muk-section__item{background:var(--muk-bg-card);width:100%;transition:var(--muk-transition);padding:var(--muk-space-content-lg);margin:var(--muk-space-content-lg) 0px}@media (width<=1024px){.muk-section__item{padding:var(--muk-space-content-md);margin:var(--muk-space-content-md) 0px}}@media (width<=768px){.muk-section__item{padding:var(--muk-space-content-sm);margin:var(--muk-space-content-sm) 0px}}.muk-page__wrapper{flex-direction:column;min-height:100dvh;display:flex}.muk-page__header{flex:none}.muk-page__content{flex:1 0 auto}.muk-page__footer{flex:none}.muk-page__info{padding:30px}.muk-svg-icon{flex-shrink:0;justify-content:center;align-items:center;width:40px;height:40px;display:flex}.muk-svg-icon svg{width:32px;height:32px;fill:var(--muk-text)}@media (width<=767px){.muk-svg-icon{width:32px;height:32px}.muk-svg-icon svg{width:28px;height:28px}}.muk-txt--primary{color:var(--muk-primary)}.muk-txt--danger{color:var(--muk-danger)}.muk-txt--warning{color:var(--muk-warning)}.muk-txt--success{color:var(--muk-success)}.muk-txt--secondary{color:var(--muk-text)}.muk-txt--muted{color:var(--muk-text-muted)}.muk-txt--left{text-align:left}.muk-txt--center{text-align:center}.muk-txt--right{text-align:right}.muk-btn{-webkit-user-select:none;user-select:none;white-space:nowrap;cursor:pointer;transition:var(--muk-transition);border:none;outline:none;justify-content:center;align-items:center;gap:8px;font-family:inherit;font-weight:500;line-height:1.2;display:inline-flex}.muk-btn--sm{--spinner-size:14px;padding:3px 14px;font-size:14px}.muk-btn--md{--spinner-size:18px;padding:3px 16px;font-size:15px}.muk-btn--lg{--spinner-size:22px;padding:3px 18px;font-size:16px}.muk-btn--primary{border:var(--muk-border-width) var(--muk-border-style) var(--muk-primary);background:var(--muk-bg-card);color:var(--muk-text);--spinner-color:var(--muk-primary);border-radius:10px}.muk-btn--primary:hover:not(:disabled):not(.is-loading){background:var(--muk-primary)}.muk-btn--primary:active:not(:disabled):not(.is-loading){filter:brightness(.9);transform:scale(.97)}.muk-btn--primary:disabled{cursor:not-allowed;opacity:var(--muk-opacity);transform:none}.muk-btn--primary.is-loading{cursor:wait}.muk-btn--secondary{border:var(--muk-border-width) var(--muk-border-style) var(--muk-text-muted);background:var(--muk-bg-card);color:var(--muk-text);--spinner-color:var(--muk-text-muted);border-radius:10px}.muk-btn--secondary:hover:not(:disabled):not(.is-loading){background:var(--muk-text-muted)}.muk-btn--secondary:active:not(:disabled):not(.is-loading){filter:brightness(.9);transform:scale(.97)}.muk-btn--secondary:disabled{cursor:not-allowed;opacity:var(--muk-opacity);transform:none}.muk-btn--secondary.is-loading{cursor:wait}.muk-btn--success{border:var(--muk-border-width) var(--muk-border-style) var(--muk-success);background:var(--muk-bg-card);color:var(--muk-text);--spinner-color:var(--muk-success);border-radius:10px}.muk-btn--success:hover:not(:disabled):not(.is-loading){background:var(--muk-success)}.muk-btn--success:active:not(:disabled):not(.is-loading){filter:brightness(.9);transform:scale(.97)}.muk-btn--success:disabled{cursor:not-allowed;opacity:var(--muk-opacity);transform:none}.muk-btn--success.is-loading{cursor:wait}.muk-btn--warning{border:var(--muk-border-width) var(--muk-border-style) var(--muk-warning);background:var(--muk-bg-card);color:var(--muk-text);--spinner-color:var(--muk-warning);border-radius:10px}.muk-btn--warning:hover:not(:disabled):not(.is-loading){background:var(--muk-warning)}.muk-btn--warning:active:not(:disabled):not(.is-loading){filter:brightness(.9);transform:scale(.97)}.muk-btn--warning:disabled{cursor:not-allowed;opacity:var(--muk-opacity);transform:none}.muk-btn--warning.is-loading{cursor:wait}.muk-btn--danger{border:var(--muk-border-width) var(--muk-border-style) var(--muk-danger);background:var(--muk-bg-card);color:var(--muk-text);--spinner-color:var(--muk-danger);border-radius:10px}.muk-btn--danger:hover:not(:disabled):not(.is-loading){background:var(--muk-danger)}.muk-btn--danger:active:not(:disabled):not(.is-loading){filter:brightness(.9);transform:scale(.97)}.muk-btn--danger:disabled{cursor:not-allowed;opacity:var(--muk-opacity);transform:none}.muk-btn--danger.is-loading{cursor:wait}.muk-btn--ghost{border:var(--muk-border-width) var(--muk-border-style) var(--muk-bg);background:var(--muk-bg-card);color:var(--muk-text-muted);--spinner-color:var(--muk-bg);border-radius:10px}.muk-btn--ghost:hover:not(:disabled):not(.is-loading){filter:brightness(1.1)}.muk-btn--ghost:active:not(:disabled):not(.is-loading){filter:brightness(.9);transform:scale(.97)}.muk-btn--ghost:disabled{cursor:not-allowed;opacity:var(--muk-opacity);transform:none}.muk-btn--ghost.is-loading{cursor:wait}.muk-btn-spinner{width:var(--spinner-size,18px);height:var(--spinner-size,18px);border:2px solid var(--spinner-color,currentColor);border-right-color:#0000;border-radius:50%;flex-shrink:0;animation:.8s linear infinite spin;display:inline-block}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.muk-btn-icon{cursor:pointer;transition:var(--muk-transition);background:0 0;border:none;justify-content:start;align-items:center;margin:0;padding:0;display:inline-flex}.muk-btn-icon__content{justify-content:flex-start;align-items:center;gap:6px;display:inline-flex}.muk-btn-icon svg{transition:var(--muk-transition);pointer-events:none;width:1em;height:1em;display:block}.muk-btn-icon.has-text{width:auto}.muk-btn-icon--sm{min-width:32px;height:32px;min-height:32px}.muk-btn-icon--sm svg{width:18px;height:18px}.muk-btn-icon--sm span,.muk-btn-icon--sm p{font-size:13px}.muk-btn-icon--sm{--spinner-size:14px}.muk-btn-icon--md{min-width:40px;height:40px;min-height:40px}.muk-btn-icon--md svg{width:22px;height:22px}.muk-btn-icon--md span,.muk-btn-icon--md p{font-size:15px}.muk-btn-icon--md{--spinner-size:18px}.muk-btn-icon--lg{min-width:48px;height:48px;min-height:48px}.muk-btn-icon--lg svg{width:26px;height:26px}.muk-btn-icon--lg span,.muk-btn-icon--lg p{font-size:17px}.muk-btn-icon--lg{--spinner-size:22px}.muk-btn-icon--primary{color:var(--muk-primary);background:0 0}.muk-btn-icon--primary svg{fill:currentColor}.muk-btn-icon--primary:hover:not(:disabled):not(.is-loading){color:var(--muk-primary-hover)}.muk-btn-icon--primary:active:not(:disabled):not(.is-loading){transform:scale(.92)}.muk-btn-icon--primary:disabled{opacity:var(--muk-opacity);cursor:not-allowed;transform:none}.muk-btn-icon--primary.is-loading{cursor:wait}.muk-btn-icon--secondary{color:var(--muk-text);background:0 0}.muk-btn-icon--secondary svg{fill:currentColor}.muk-btn-icon--secondary:hover:not(:disabled):not(.is-loading){color:var(--muk-primary-hover)}.muk-btn-icon--secondary:active:not(:disabled):not(.is-loading){transform:scale(.92)}.muk-btn-icon--secondary:disabled{opacity:var(--muk-opacity);cursor:not-allowed;transform:none}.muk-btn-icon--secondary.is-loading{cursor:wait}.muk-btn-icon--success{color:var(--muk-success);background:0 0}.muk-btn-icon--success svg{fill:currentColor}.muk-btn-icon--success:hover:not(:disabled):not(.is-loading){filter:brightness(1.2)}.muk-btn-icon--success:active:not(:disabled):not(.is-loading){transform:scale(.92)}.muk-btn-icon--success:disabled{opacity:var(--muk-opacity);cursor:not-allowed;transform:none}.muk-btn-icon--success.is-loading{cursor:wait}.muk-btn-icon--warning{color:var(--muk-warning);background:0 0}.muk-btn-icon--warning svg{fill:currentColor}.muk-btn-icon--warning:hover:not(:disabled):not(.is-loading){filter:brightness(1.2)}.muk-btn-icon--warning:active:not(:disabled):not(.is-loading){transform:scale(.92)}.muk-btn-icon--warning:disabled{opacity:var(--muk-opacity);cursor:not-allowed;transform:none}.muk-btn-icon--warning.is-loading{cursor:wait}.muk-btn-icon--danger{color:var(--muk-danger);background:0 0}.muk-btn-icon--danger svg{fill:currentColor}.muk-btn-icon--danger:hover:not(:disabled):not(.is-loading){filter:brightness(1.2)}.muk-btn-icon--danger:active:not(:disabled):not(.is-loading){transform:scale(.92)}.muk-btn-icon--danger:disabled{opacity:var(--muk-opacity);cursor:not-allowed;transform:none}.muk-btn-icon--danger.is-loading{cursor:wait}.muk-btn-icon--ghost{color:var(--muk-text-muted);background:0 0}.muk-btn-icon--ghost svg{fill:currentColor}.muk-btn-icon--ghost:hover:not(:disabled):not(.is-loading){color:var(--muk-text)}.muk-btn-icon--ghost:active:not(:disabled):not(.is-loading){transform:scale(.92)}.muk-btn-icon--ghost:disabled{opacity:var(--muk-opacity);cursor:not-allowed;transform:none}.muk-btn-icon--ghost.is-loading{cursor:wait}.muk-input{flex-direction:column;display:flex}.muk-input__wrapper{flex-direction:row;align-items:center;display:flex;position:relative}.muk-input__field{border:var(--muk-border-width) var(--muk-border-style) var(--muk-bg);border-radius:var(--muk-border-radius);background:var(--muk-bg-soft);padding:var(--muk-space-content-md);transition:var(--muk-transition);color:var(--muk-text);margin-top:5px}.muk-input__field:focus,.muk-input__field:focus-visible{border-color:var(--muk-primary-hover);box-shadow:0 0 0 4px rgba(var(--muk-primary), .15);outline:none}.muk-input__field:disabled{opacity:var(--muk-opacity);cursor:not-allowed}.muk-input__field.is-error{border-color:var(--muk-danger)}.muk-input__field.is-error:focus,.muk-input__field.is-error:focus-visible{box-shadow:0 0 0 4px rgba(var(--muk-danger), .15);border-color:var(--muk-danger)!important}.muk-input__field{width:100%}.muk-input__button{position:absolute;top:0;right:20px}input[type=date]::-webkit-calendar-picker-indicator{filter:invert(98%)sepia(1%)saturate(678%)hue-rotate(181deg)brightness(98%)contrast(94%)}.muk-form-error{color:var(--muk-danger);font-size:13px}.muk-form-hint{color:var(--muk-text-muted);font-size:13px}.muk-form-label{color:var(--muk-text);font-size:13px}.muk-form-label--top{margin:20px 0 10px}.muk-form-label--side{margin:10px}.muk-form__item{background:var(--muk-bg-card);width:100%;transition:var(--muk-transition);padding:var(--muk-space-content-lg);margin:var(--muk-space-content-lg) 0px}@media (width<=1024px){.muk-form__item{padding:var(--muk-space-content-md);margin:var(--muk-space-content-md) 0px}}@media (width<=768px){.muk-form__item{padding:var(--muk-space-content-sm);margin:var(--muk-space-content-sm) 0px}}.muk-form__actions{background:var(--muk-bg-card);width:100%;transition:var(--muk-transition);padding:var(--muk-space-content-lg);margin:var(--muk-space-content-lg) 0px}@media (width<=1024px){.muk-form__actions{padding:var(--muk-space-content-md);margin:var(--muk-space-content-md) 0px}}@media (width<=768px){.muk-form__actions{padding:var(--muk-space-content-sm);margin:var(--muk-space-content-sm) 0px}}.muk-form__actions{flex-direction:row;justify-content:start;align-items:center;gap:10px;display:flex}.muk-checkbox{position:relative}.muk-checkbox__wrapper{cursor:pointer;flex-direction:column;width:100%;display:flex}.muk-checkbox__data{-webkit-user-select:none;user-select:none;align-items:center;margin-bottom:6px;display:inline-flex}.muk-checkbox__field{opacity:0;appearance:none;width:0;height:0;position:absolute}.muk-checkbox__field:focus-visible+.muk-checkbox__box{border-color:var(--muk-primary-hover)}.muk-checkbox__field:checked+.muk-checkbox__box{border-color:var(--muk-primary)}.muk-checkbox__field:checked+.muk-checkbox__box .muk-checkbox__check{transform:scale(1)}.muk-checkbox__field:disabled+.muk-checkbox__box{opacity:var(--muk-opacity);cursor:not-allowed}.muk-checkbox__box{border:var(--muk-border-width) var(--muk-border-style) var(--muk-bg);border-radius:var(--muk-border-radius);background:var(--muk-bg-soft);padding:var(--muk-space-content-md);transition:var(--muk-transition);color:var(--muk-text);margin-top:5px}.muk-checkbox__box:focus,.muk-checkbox__box:focus-visible{border-color:var(--muk-primary-hover);box-shadow:0 0 0 4px rgba(var(--muk-primary), .15);outline:none}.muk-checkbox__box:disabled{opacity:var(--muk-opacity);cursor:not-allowed}.muk-checkbox__box.is-error{border-color:var(--muk-danger)}.muk-checkbox__box.is-error:focus,.muk-checkbox__box.is-error:focus-visible{box-shadow:0 0 0 4px rgba(var(--muk-danger), .15);border-color:var(--muk-danger)!important}.muk-checkbox__box{border-radius:0;flex-shrink:0;justify-content:center;align-items:center;width:20px;height:20px;margin-bottom:4px;display:flex}.muk-checkbox__check{color:var(--muk-text);transition:var(--muk-transition);border-radius:50%;transform:scale(0)}.muk-radio{position:relative}.muk-radio__wrapper{cursor:pointer;flex-direction:column;width:100%;display:flex}.muk-radio__data{-webkit-user-select:none;user-select:none;align-items:center;margin-bottom:6px;display:inline-flex;position:relative}.muk-radio__field{opacity:0;appearance:none;width:0;height:0;position:absolute}.muk-radio__field:checked+.muk-radio__box{border-color:var(--muk-primary)}.muk-radio__field:checked+.muk-radio__box .muk-radio__circle{background:var(--muk-text);transform:scale(1)}.muk-radio__field:disabled+.muk-radio__box{opacity:var(--muk-opacity);cursor:not-allowed}.muk-radio__box{border:var(--muk-border-width) var(--muk-border-style) var(--muk-bg);border-radius:var(--muk-border-radius);background:var(--muk-bg-soft);padding:var(--muk-space-content-md);transition:var(--muk-transition);color:var(--muk-text);margin-top:5px}.muk-radio__box:focus,.muk-radio__box:focus-visible{border-color:var(--muk-primary-hover);box-shadow:0 0 0 4px rgba(var(--muk-primary), .15);outline:none}.muk-radio__box:disabled{opacity:var(--muk-opacity);cursor:not-allowed}.muk-radio__box.is-error{border-color:var(--muk-danger)}.muk-radio__box.is-error:focus,.muk-radio__box.is-error:focus-visible{box-shadow:0 0 0 4px rgba(var(--muk-danger), .15);border-color:var(--muk-danger)!important}.muk-radio__box{border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;width:20px;height:20px;margin-bottom:5px;display:flex}.muk-radio__circle{transition:var(--muk-transition);background:0 0;border-radius:50%;flex-shrink:0;width:10px;height:10px;display:block;transform:scale(0)}.muk-select{flex-direction:column;display:flex}.muk-select__wrapper{position:relative}.muk-select__field{border:var(--muk-border-width) var(--muk-border-style) var(--muk-bg);border-radius:var(--muk-border-radius);background:var(--muk-bg-soft);padding:var(--muk-space-content-md);transition:var(--muk-transition);color:var(--muk-text);margin-top:5px}.muk-select__field:focus,.muk-select__field:focus-visible{border-color:var(--muk-primary-hover);box-shadow:0 0 0 4px rgba(var(--muk-primary), .15);outline:none}.muk-select__field:disabled{opacity:var(--muk-opacity);cursor:not-allowed}.muk-select__field.is-error{border-color:var(--muk-danger)}.muk-select__field.is-error:focus,.muk-select__field.is-error:focus-visible{box-shadow:0 0 0 4px rgba(var(--muk-danger), .15);border-color:var(--muk-danger)!important}.muk-select__field{cursor:pointer;width:100%}.muk-select__icon{pointer-events:none;color:var(--muk-text-muted);font-size:14px;position:absolute;top:50%;right:14px;transform:translateY(-50%)}.muk-textarea{flex-direction:column;display:flex}.muk-textarea__field{border:var(--muk-border-width) var(--muk-border-style) var(--muk-bg);border-radius:var(--muk-border-radius);background:var(--muk-bg-soft);padding:var(--muk-space-content-md);transition:var(--muk-transition);color:var(--muk-text);margin-top:5px}.muk-textarea__field:focus,.muk-textarea__field:focus-visible{border-color:var(--muk-primary-hover);box-shadow:0 0 0 4px rgba(var(--muk-primary), .15);outline:none}.muk-textarea__field:disabled{opacity:var(--muk-opacity);cursor:not-allowed}.muk-textarea__field.is-error{border-color:var(--muk-danger)}.muk-textarea__field.is-error:focus,.muk-textarea__field.is-error:focus-visible{box-shadow:0 0 0 4px rgba(var(--muk-danger), .15);border-color:var(--muk-danger)!important}.muk-textarea__field{resize:vertical;min-height:120px}.muk-textarea__field::placeholder{color:var(--muk-text-muted)}
2
+ /*$vite$:1*/
@@ -0,0 +1,10 @@
1
+ import { ButtonHTMLAttributes, FC } from 'react';
2
+ import { UIButtonType, UIButtonVariant, UISize } from '../../types/ui.types';
3
+ export interface MukButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
4
+ variant?: UIButtonVariant;
5
+ size?: UISize;
6
+ type?: UIButtonType;
7
+ loading?: boolean;
8
+ disabled?: boolean;
9
+ }
10
+ export declare const MukButton: FC<MukButtonProps>;
@@ -0,0 +1,13 @@
1
+ import { ButtonHTMLAttributes, FC, ReactNode } from 'react';
2
+ import { UIButtonType, UIButtonVariant, UISize } from '../../types/ui.types';
3
+ export interface MukIconButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
4
+ ariaLabel?: string | number;
5
+ variant?: UIButtonVariant;
6
+ size?: UISize;
7
+ type?: UIButtonType;
8
+ loading?: boolean;
9
+ disabled?: boolean;
10
+ children?: ReactNode;
11
+ text?: ReactNode;
12
+ }
13
+ export declare const MukIconButton: FC<MukIconButtonProps>;
@@ -0,0 +1,9 @@
1
+ import { InputHTMLAttributes, FC } from 'react';
2
+ export interface MukCheckboxProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'value'> {
3
+ value?: boolean;
4
+ onChange?: (value: boolean) => void;
5
+ label?: string;
6
+ hint?: string;
7
+ error?: string;
8
+ }
9
+ export declare const MukCheckbox: FC<MukCheckboxProps>;
@@ -0,0 +1,12 @@
1
+ import { InputHTMLAttributes, FC } from 'react';
2
+ import { UIInputType } from '../../types/ui.types';
3
+ export interface MukInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'onChange'> {
4
+ value?: string | number;
5
+ onChange?: (value: string) => void;
6
+ label?: string;
7
+ hint?: string;
8
+ error?: string;
9
+ showPasswordToggle?: boolean;
10
+ type?: UIInputType;
11
+ }
12
+ export declare const MukInput: FC<MukInputProps>;
@@ -0,0 +1,10 @@
1
+ import { InputHTMLAttributes, FC } from 'react';
2
+ export interface MukRadioProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'onChange' | "value"> {
3
+ value: boolean | string | number;
4
+ selectedValue?: boolean | string | number | null;
5
+ onChange?: (value: boolean | string | number | null) => void;
6
+ label?: string;
7
+ hint?: string;
8
+ error?: string;
9
+ }
10
+ export declare const MukRadio: FC<MukRadioProps>;
@@ -0,0 +1,15 @@
1
+ import { FC, SelectHTMLAttributes } from 'react';
2
+ export interface MukSelectOption {
3
+ value: string | number;
4
+ label: string;
5
+ }
6
+ export interface MukSelectProps extends Omit<SelectHTMLAttributes<HTMLSelectElement>, 'onChange' | "value"> {
7
+ value: string | number;
8
+ onChange?: (value: string) => void;
9
+ options: MukSelectOption[];
10
+ label?: string;
11
+ hint?: string;
12
+ error?: string;
13
+ placeholder?: string;
14
+ }
15
+ export declare const MukSelect: FC<MukSelectProps>;
@@ -0,0 +1,10 @@
1
+ import { TextareaHTMLAttributes, FC } from 'react';
2
+ export interface MukTextareaProps extends Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, 'onChange'> {
3
+ value?: string | number;
4
+ onChange?: (value: string) => void;
5
+ label?: string;
6
+ hint?: string;
7
+ error?: string;
8
+ rows?: number;
9
+ }
10
+ export declare const MukTextarea: FC<MukTextareaProps>;
@@ -0,0 +1,11 @@
1
+ import { FC, HTMLAttributes } from 'react';
2
+ import { UITextAlign, UITextType, UITextVariant } from '../../types/ui.types';
3
+ export interface MukTextProps extends HTMLAttributes<HTMLElement> {
4
+ variant?: UITextVariant;
5
+ as?: React.ElementType;
6
+ type?: UITextType;
7
+ align?: UITextAlign;
8
+ children?: React.ReactNode;
9
+ [key: string]: any;
10
+ }
11
+ export declare const MukText: FC<MukTextProps>;
@@ -0,0 +1,17 @@
1
+ export { MukText } from './components/typography/MukText';
2
+ export { MukButton } from './components/buttons/MukButton';
3
+ export { MukIconButton } from './components/buttons/MukIconButton';
4
+ export { MukInput } from './components/form/MukInput';
5
+ export { MukCheckbox } from './components/form/MukCheckbox';
6
+ export { MukRadio } from './components/form/MukRadio';
7
+ export { MukSelect } from './components/form/MukSelect';
8
+ export { MukTextarea } from './components/form/MukTextarea';
9
+ export type { MukTextProps } from './components/typography/MukText';
10
+ export type { MukButtonProps } from './components/buttons/MukButton';
11
+ export type { MukIconButtonProps } from './components/buttons/MukIconButton';
12
+ export type { MukInputProps } from './components/form/MukInput';
13
+ export type { MukCheckboxProps } from './components/form/MukCheckbox';
14
+ export type { MukRadioProps } from './components/form/MukRadio';
15
+ export type { MukSelectProps, MukSelectOption } from './components/form/MukSelect';
16
+ export type { MukTextareaProps } from './components/form/MukTextarea';
17
+ export type { UIVariant, UISize, UITextType, UITextAlign, UITextVariant, UIButtonVariant, UIButtonType, UIInputType } from './types/ui.types';
@@ -0,0 +1,8 @@
1
+ export type UIVariant = 'primary' | 'danger' | 'warning' | 'success' | 'secondary';
2
+ export type UISize = 'sm' | 'md' | 'lg';
3
+ export type UITextType = 'muk-heading' | 'muk-subheading' | 'muk-body-text' | 'muk-caption' | 'muk-none';
4
+ export type UITextAlign = 'left' | 'center' | 'right';
5
+ export type UITextVariant = UIVariant | 'muted';
6
+ export type UIButtonVariant = UIVariant | 'ghost';
7
+ export type UIButtonType = "button" | "submit" | "reset";
8
+ export type UIInputType = "text" | "email" | "password" | "search" | "date" | "tel" | "number";
package/package.json CHANGED
@@ -1,6 +1,78 @@
1
1
  {
2
2
  "name": "modular-ui-kit-react",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "1.0.1",
4
+ "description": "A modular, accessible TypeScript-driven UI library for React.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": "Eugenia Vitinschii",
8
+ "main": "./dist/index.cjs",
9
+ "module": "./dist/index.js",
10
+ "types": "./dist/src/lib/index.d.ts",
11
+ "style": "./dist/modular-ui-kit-react.css",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/src/lib/index.d.ts",
15
+ "import": "./dist/index.js",
16
+ "require": "./dist/index.cjs"
17
+ },
18
+ "./modular-ui-kit-react.css": {
19
+ "default": "./dist/modular-ui-kit-react.css"
20
+ },
21
+ "./*.css": {
22
+ "default": "./dist/*.css"
23
+ }
24
+ },
25
+ "files": [
26
+ "dist"
27
+ ],
28
+ "keywords": [
29
+ "react",
30
+ "react18",
31
+ "react19",
32
+ "react-components",
33
+ "ui-kit",
34
+ "component-library",
35
+ "typescript",
36
+ "sass",
37
+ "design-system",
38
+ "frontend",
39
+ "responsive-ui"
40
+ ],
41
+ "homepage": "https://github.com/eugenia-vitinschii/modular-ui-kit-react#readme",
42
+ "repository": {
43
+ "type": "git",
44
+ "url": "git+https://github.com/eugenia-vitinschii/modular-ui-kit-react.git"
45
+ },
46
+ "bugs": {
47
+ "url": "https://github.com/eugenia-vitinschii/modular-ui-kit-react/issues"
48
+ },
49
+ "scripts": {
50
+ "dev": "vite",
51
+ "build": "tsc && vite build",
52
+ "preview": "vite preview"
53
+ },
54
+ "peerDependencies": {
55
+ "react": ">=18.0.0",
56
+ "react-dom": ">=18.0.0"
57
+ },
58
+ "devDependencies": {
59
+ "@eslint/js": "^10.0.1",
60
+ "@types/node": "^24.19.2",
61
+ "@types/react": "^19.3.0",
62
+ "@types/react-dom": "^19.3.0",
63
+ "@vitejs/plugin-react": "^6.1.2",
64
+ "eslint": "^10.13.0",
65
+ "eslint-plugin-react-hooks": "^7.1.1",
66
+ "eslint-plugin-react-refresh": "^0.5.7",
67
+ "globals": "^17.13.0",
68
+ "react": "^19.3.1",
69
+ "react-dom": "^19.3.1",
70
+ "react-router-dom": "^7.18.4",
71
+ "sass": "^1.105.2",
72
+ "typescript": "~6.0.3",
73
+ "typescript-eslint": "^8.71.2",
74
+ "vite": "^8.3.4",
75
+ "vite-plugin-dts": "^4.5.4",
76
+ "vite-plugin-lib-inject-css": "^2.2.2"
77
+ }
78
+ }