tsp-form 0.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/.babelrc ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "presets": [
3
+ "@babel/preset-env",
4
+ ["@babel/preset-react", { "runtime": "automatic" }],
5
+ "@babel/preset-typescript"
6
+ ]
7
+ }
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ /*! For license information please see index.js.LICENSE.txt */
2
+ !function(r,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("react"),require("clsx")):"function"==typeof define&&define.amd?define("MyUIComponents",["react","clsx"],e):"object"==typeof exports?exports.MyUIComponents=e(require("react"),require("clsx")):r.MyUIComponents=e(r.React,r.clsx)}(this,(r,e)=>(()=>{"use strict";var n={12:e=>{e.exports=r},56:(r,e,n)=>{r.exports=function(r){var e=n.nc;e&&r.setAttribute("nonce",e)}},72:r=>{var e=[];function n(r){for(var n=-1,t=0;t<e.length;t++)if(e[t].identifier===r){n=t;break}return n}function t(r,t){for(var a={},c=[],i=0;i<r.length;i++){var l=r[i],s=t.base?l[0]+t.base:l[0],u=a[s]||0,f="".concat(s," ").concat(u);a[s]=u+1;var p=n(f),d={css:l[1],media:l[2],sourceMap:l[3],supports:l[4],layer:l[5]};if(-1!==p)e[p].references++,e[p].updater(d);else{var v=o(d,t);t.byIndex=i,e.splice(i,0,{identifier:f,updater:v,references:1})}c.push(f)}return c}function o(r,e){var n=e.domAPI(e);return n.update(r),function(e){if(e){if(e.css===r.css&&e.media===r.media&&e.sourceMap===r.sourceMap&&e.supports===r.supports&&e.layer===r.layer)return;n.update(r=e)}else n.remove()}}r.exports=function(r,o){var a=t(r=r||[],o=o||{});return function(r){r=r||[];for(var c=0;c<a.length;c++){var i=n(a[c]);e[i].references--}for(var l=t(r,o),s=0;s<a.length;s++){var u=n(a[s]);0===e[u].references&&(e[u].updater(),e.splice(u,1))}a=l}}},113:r=>{r.exports=function(r,e){if(e.styleSheet)e.styleSheet.cssText=r;else{for(;e.firstChild;)e.removeChild(e.firstChild);e.appendChild(document.createTextNode(r))}}},314:r=>{r.exports=function(r){var e=[];return e.toString=function(){return this.map(function(e){var n="",t=void 0!==e[5];return e[4]&&(n+="@supports (".concat(e[4],") {")),e[2]&&(n+="@media ".concat(e[2]," {")),t&&(n+="@layer".concat(e[5].length>0?" ".concat(e[5]):""," {")),n+=r(e),t&&(n+="}"),e[2]&&(n+="}"),e[4]&&(n+="}"),n}).join("")},e.i=function(r,n,t,o,a){"string"==typeof r&&(r=[[null,r,void 0]]);var c={};if(t)for(var i=0;i<this.length;i++){var l=this[i][0];null!=l&&(c[l]=!0)}for(var s=0;s<r.length;s++){var u=[].concat(r[s]);t&&c[u[0]]||(void 0!==a&&(void 0===u[5]||(u[1]="@layer".concat(u[5].length>0?" ".concat(u[5]):""," {").concat(u[1],"}")),u[5]=a),n&&(u[2]?(u[1]="@media ".concat(u[2]," {").concat(u[1],"}"),u[2]=n):u[2]=n),o&&(u[4]?(u[1]="@supports (".concat(u[4],") {").concat(u[1],"}"),u[4]=o):u[4]="".concat(o)),e.push(u))}},e}},405:(r,e,n)=>{n.d(e,{A:()=>i});var t=n(601),o=n.n(t),a=n(314),c=n.n(a)()(o());c.push([r.id,".cpanel {\n border: 1px solid var(--color-line);\n border-radius: var(--radius-control);\n overflow: hidden;\n}\n\n.cpanel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n text-align: left;\n border-bottom: 1px solid var(--color-line);\n}\n\n.cpanel-header-title {\n padding: var(--spacing-title-y) var(--spacing-title-x);\n letter-spacing: var(--text-title--letter-spacing);\n font-size: var(--text-title);\n line-height: var(--text-title--line-height);\n font-weight: var(--text-title--font-weight);\n}\n\n.cpanel-header:focus {\n outline: none;\n}\n\n.cpanel-header:focus-visible {\n box-shadow: 0 0 0 1px var(--color-primary);\n}\n\n.cpanel-chevron {\n flex-shrink: 0;\n display: flex;\n justify-content: center;\n align-items: center;\n width: var(--spacing-title-h);\n height: var(--spacing-title-h);\n border-left: var(--spacing-line) solid var(--color-line);\n cursor: pointer;\n}\n\n.cpanel-content.open {\n display: block;\n}\n\n.cpanel-content {\n display: none;\n}",""]);const i=c},525:(r,e,n)=>{n.d(e,{A:()=>i});var t=n(601),o=n.n(t),a=n(314),c=n.n(a)()(o());c.push([r.id,".rotate-0 {\n transform: rotate(0deg);\n}\n\n.rotate-90 {\n transform: rotate(90deg);\n}\n\n.rotate-180 {\n transform: rotate(180deg);\n}\n\n.-rotate-90 {\n transform: rotate(-90deg);\n}\n\n.chevron-animated {\n transition: transform 200ms ease-out;\n}",""]);const i=c},540:r=>{r.exports=function(r){var e=document.createElement("style");return r.setAttributes(e,r.attributes),r.insert(e,r.options),e}},601:r=>{r.exports=function(r){return r[1]}},659:r=>{var e={};r.exports=function(r,n){var t=function(r){if(void 0===e[r]){var n=document.querySelector(r);if(window.HTMLIFrameElement&&n instanceof window.HTMLIFrameElement)try{n=n.contentDocument.head}catch(r){n=null}e[r]=n}return e[r]}(r);if(!t)throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");t.appendChild(n)}},698:(r,e)=>{var n=Symbol.for("react.transitional.element");function t(r,e,t){var o=null;if(void 0!==t&&(o=""+t),void 0!==e.key&&(o=""+e.key),"key"in e)for(var a in t={},e)"key"!==a&&(t[a]=e[a]);else t=e;return e=t.ref,{$$typeof:n,type:r,key:o,ref:void 0!==e?e:null,props:t}}Symbol.for("react.fragment"),e.jsx=t,e.jsxs=t},825:r=>{r.exports=function(r){if("undefined"==typeof document)return{update:function(){},remove:function(){}};var e=r.insertStyleElement(r);return{update:function(n){!function(r,e,n){var t="";n.supports&&(t+="@supports (".concat(n.supports,") {")),n.media&&(t+="@media ".concat(n.media," {"));var o=void 0!==n.layer;o&&(t+="@layer".concat(n.layer.length>0?" ".concat(n.layer):""," {")),t+=n.css,o&&(t+="}"),n.media&&(t+="}"),n.supports&&(t+="}");var a=n.sourceMap;a&&"undefined"!=typeof btoa&&(t+="\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(a))))," */")),e.styleTagTransform(t,r,e.options)}(e,r,n)},remove:function(){!function(r){if(null===r.parentNode)return!1;r.parentNode.removeChild(r)}(e)}}}},848:(r,e,n)=>{r.exports=n(698)},894:r=>{r.exports=e},998:(r,e,n)=>{n.d(e,{A:()=>i});var t=n(601),o=n.n(t),a=n(314),c=n.n(a)()(o());c.push([r.id,".btn {\n --color-text: var(--color-fg);\n --color-bg: var(--color-surface);\n --color-border: var(--color-surface);\n --color-bg-hover: var(--color-fg);\n --color-border-hover: var(--color-fg);\n --color-text-hover: var(--color-fg-contrast);\n padding: var(--spacing-control-y) var(--spacing-control-x);\n border-radius: var(--radius-control);\n border: 1px solid var(--color-border);\n cursor: pointer;\n background: var(--color-bg);\n color: var(--color-text);\n transition: all 0.2s ease-in-out;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-weight: 600;\n}\n\n.btn:hover {\n background: var(--color-bg-hover);\n border-color: var(--color-border-hover);\n color: var(--color-text-hover);\n}\n\n.btn.disabled {\n opacity: 0.5;\n pointer-events: none;\n}\n\n.btn-sm {\n padding: var(--spacing-control-compact-y) var(--spacing-control-compact-x);\n}\n\n.btn-lg {\n padding: var(--spacing-control-relaxed-y) var(--spacing-control-relaxed-x);\n}\n\n.btn-primary {\n --color-text: var(--color-primary-contrast);\n --color-bg: var(--color-primary);\n --color-border: var(--color-primary);\n}\n\n.btn-secondary {\n --color-text: var(--color-secondary-contrast);\n --color-bg: var(--color-secondary);\n --color-border: var(--color-secondary);\n}\n\n.btn-danger {\n --color-text: var(--color-danger-contrast);\n --color-bg: var(--color-danger);\n --color-border: var(--color-danger);\n}\n\n.btn-outline-default {\n --color-text: var(--color-fg);\n --color-bg: transparent;\n --color-border: var(--color-line);\n}\n\n.btn-outline-primary {\n --color-text: var(--color-primary);\n --color-border: var(--color-primary);\n --color-text-hover: var(--color-primary-contrast);\n --color-bg-hover: var(--color-primary);\n --color-border-hover: var(--color-primary);\n}\n\n.btn-outline-secondary {\n --color-text: var(--color-secondary);\n --color-border: var(--color-secondary);\n --color-text-hover: var(--color-secondary-contrast);\n --color-bg-hover: var(--color-secondary);\n --color-border-hover: var(--color-secondary);\n}\n\n.btn-outline-danger {\n --color-text: var(--color-danger);\n --color-border: var(--color-danger);\n --color-text-hover: var(--color-danger-contrast);\n --color-bg-hover: var(--color-danger);\n --color-border-hover: var(--color-danger);\n}\n\n.btn-ghost-default {\n --color-text: var(--color-fg);\n --color-bg: transparent;\n --color-border: transparent;\n --color-text-hover: var(--color-fg);\n --color-bg-hover: var(--color-surface);\n --color-border-hover: var(--color-surface);\n}\n\n.btn-ghost-primary {\n --color-text: var(--color-primary);\n --color-bg: transparent;\n --color-border: transparent;\n --color-text-hover: var(--color-fg);\n --color-bg-hover: var(--color-surface);\n --color-border-hover: var(--color-surface);\n}\n\n.btn-ghost-secondary {\n --color-text: var(--color-secondary);\n --color-bg: transparent;\n --color-border: transparent;\n --color-text-hover: var(--color-fg);\n --color-bg-hover: var(--color-surface);\n --color-border-hover: var(--color-surface);\n}\n\n.btn-ghost-danger {\n --color-text: var(--color-danger);\n --color-bg: transparent;\n --color-border: transparent;\n}\n",""]);const i=c}},t={};function o(r){var e=t[r];if(void 0!==e)return e.exports;var a=t[r]={id:r,exports:{}};return n[r](a,a.exports,o),a.exports}o.n=r=>{var e=r&&r.__esModule?()=>r.default:()=>r;return o.d(e,{a:e}),e},o.d=(r,e)=>{for(var n in e)o.o(e,n)&&!o.o(r,n)&&Object.defineProperty(r,n,{enumerable:!0,get:e[n]})},o.o=(r,e)=>Object.prototype.hasOwnProperty.call(r,e),o.r=r=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(r,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(r,"__esModule",{value:!0})},o.nc=void 0;var a={};o.r(a),o.d(a,{Button:()=>E,Chevron:()=>U,ExpandablePanel:()=>F});var c=o(12),i=o(894),l=o.n(i),s=o(72),u=o.n(s),f=o(825),p=o.n(f),d=o(659),v=o.n(d),b=o(56),y=o.n(b),m=o(540),g=o.n(m),h=o(113),x=o.n(h),O=o(998),j={};j.styleTagTransform=x(),j.setAttributes=y(),j.insert=v().bind(null,"head"),j.domAPI=p(),j.insertStyleElement=g(),u()(O.A,j),O.A&&O.A.locals&&O.A.locals;var w=o(848);function S(r){return S="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(r){return typeof r}:function(r){return r&&"function"==typeof Symbol&&r.constructor===Symbol&&r!==Symbol.prototype?"symbol":typeof r},S(r)}var P=["color","variant","size","className","disabled","type"];function A(r,e){var n=Object.keys(r);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(r);e&&(t=t.filter(function(e){return Object.getOwnPropertyDescriptor(r,e).enumerable})),n.push.apply(n,t)}return n}function k(r,e,n){return(e=function(r){var e=function(r){if("object"!=S(r)||!r)return r;var e=r[Symbol.toPrimitive];if(void 0!==e){var n=e.call(r,"string");if("object"!=S(n))return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(r)}(r);return"symbol"==S(e)?e:e+""}(e))in r?Object.defineProperty(r,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):r[e]=n,r}var E=(0,c.forwardRef)(function(r,e){var n=r.color,t=void 0===n?"default":n,o=r.variant,a=void 0===o?"solid":o,c=r.size,i=void 0===c?"md":c,s=r.className,u=r.disabled,f=r.type,p=void 0===f?"button":f,d=function(r,e){if(null==r)return{};var n,t,o=function(r,e){if(null==r)return{};var n={};for(var t in r)if({}.hasOwnProperty.call(r,t)){if(-1!==e.indexOf(t))continue;n[t]=r[t]}return n}(r,e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(r);for(t=0;t<a.length;t++)n=a[t],-1===e.indexOf(n)&&{}.propertyIsEnumerable.call(r,n)&&(o[n]=r[n])}return o}(r,P),v=function(r,e,n,t){var o=["btn","btn-".concat(n),t];switch(r){case"solid":o.push("btn-".concat(e));break;case"outline":o.push("btn-outline-".concat(e));break;case"ghost":o.push("btn-ghost-".concat(e))}return l()(o)}(a,t,i,s);return(0,w.jsx)("button",function(r){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{};e%2?A(Object(n),!0).forEach(function(e){k(r,e,n[e])}):Object.getOwnPropertyDescriptors?Object.defineProperties(r,Object.getOwnPropertyDescriptors(n)):A(Object(n)).forEach(function(e){Object.defineProperty(r,e,Object.getOwnPropertyDescriptor(n,e))})}return r}({ref:e,type:p,className:v,disabled:u},d))});E.displayName="Button";var T=o(525),N={};function I(r){return I="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(r){return typeof r}:function(r){return r&&"function"==typeof Symbol&&r.constructor===Symbol&&r!==Symbol.prototype?"symbol":typeof r},I(r)}N.styleTagTransform=x(),N.setAttributes=y(),N.insert=v().bind(null,"head"),N.domAPI=p(),N.insertStyleElement=g(),u()(T.A,N),T.A&&T.A.locals&&T.A.locals;var C=["direction","open","size","strokeWidth","className","title","animated"];function M(r,e){var n=Object.keys(r);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(r);e&&(t=t.filter(function(e){return Object.getOwnPropertyDescriptor(r,e).enumerable})),n.push.apply(n,t)}return n}function D(r){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{};e%2?M(Object(n),!0).forEach(function(e){z(r,e,n[e])}):Object.getOwnPropertyDescriptors?Object.defineProperties(r,Object.getOwnPropertyDescriptors(n)):M(Object(n)).forEach(function(e){Object.defineProperty(r,e,Object.getOwnPropertyDescriptor(n,e))})}return r}function z(r,e,n){return(e=function(r){var e=function(r){if("object"!=I(r)||!r)return r;var e=r[Symbol.toPrimitive];if(void 0!==e){var n=e.call(r,"string");if("object"!=I(n))return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(r)}(r);return"symbol"==I(e)?e:e+""}(e))in r?Object.defineProperty(r,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):r[e]=n,r}function U(r){var e=r.direction,n=void 0===e?"down":e,t=r.open,o=r.size,a=void 0===o?16:o,c=r.strokeWidth,i=void 0===c?2:c,s=r.className,u=r.title,f=r.animated,p=void 0===f||f,d=function(r,e){if(null==r)return{};var n,t,o=function(r,e){if(null==r)return{};var n={};for(var t in r)if({}.hasOwnProperty.call(r,t)){if(-1!==e.indexOf(t))continue;n[t]=r[t]}return n}(r,e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(r);for(t=0;t<a.length;t++)n=a[t],-1===e.indexOf(n)&&{}.propertyIsEnumerable.call(r,n)&&(o[n]=r[n])}return o}(r,C),v={down:0,up:180,left:90,right:-90},b=void 0===t?v[n]:"down"===n?t?180:0:"right"===n?t?0:-90:v[n],y=0===b?"rotate-0":180===b?"rotate-180":90===b?"rotate-90":-90===b?"-rotate-90":"rotate-0";return(0,w.jsxs)("svg",D(D({xmlns:"http://www.w3.org/2000/svg",width:a,height:a,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:i,strokeLinecap:"round",strokeLinejoin:"round",className:l()("shrink-0",p&&"chevron-animated",y,s),"aria-hidden":!d["aria-label"]||void 0,role:d["aria-label"]?"img":void 0},d),{},{children:[u?(0,w.jsx)("title",{children:u}):null,(0,w.jsx)("path",{d:"M6 9l6 6 6-6"})]}))}var q=o(405),L={};function R(r){return R="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(r){return typeof r}:function(r){return r&&"function"==typeof Symbol&&r.constructor===Symbol&&r!==Symbol.prototype?"symbol":typeof r},R(r)}function _(r,e){var n=Object.keys(r);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(r);e&&(t=t.filter(function(e){return Object.getOwnPropertyDescriptor(r,e).enumerable})),n.push.apply(n,t)}return n}function B(r){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{};e%2?_(Object(n),!0).forEach(function(e){W(r,e,n[e])}):Object.getOwnPropertyDescriptors?Object.defineProperties(r,Object.getOwnPropertyDescriptors(n)):_(Object(n)).forEach(function(e){Object.defineProperty(r,e,Object.getOwnPropertyDescriptor(n,e))})}return r}function W(r,e,n){return(e=function(r){var e=function(r){if("object"!=R(r)||!r)return r;var e=r[Symbol.toPrimitive];if(void 0!==e){var n=e.call(r,"string");if("object"!=R(n))return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(r)}(r);return"symbol"==R(e)?e:e+""}(e))in r?Object.defineProperty(r,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):r[e]=n,r}function $(r,e){(null==e||e>r.length)&&(e=r.length);for(var n=0,t=Array(e);n<e;n++)t[n]=r[n];return t}L.styleTagTransform=x(),L.setAttributes=y(),L.insert=v().bind(null,"head"),L.domAPI=p(),L.insertStyleElement=g(),u()(q.A,L),q.A&&q.A.locals&&q.A.locals;var F=function(r){var e,n,t=r.title,o=r.children,a=r.className,i=r.chevronProps,s=r.defaultOpen,u=void 0===s||s,f=(e=(0,c.useState)(u),n=2,function(r){if(Array.isArray(r))return r}(e)||function(r,e){var n=null==r?null:"undefined"!=typeof Symbol&&r[Symbol.iterator]||r["@@iterator"];if(null!=n){var t,o,a,c,i=[],l=!0,s=!1;try{if(a=(n=n.call(r)).next,0===e){if(Object(n)!==n)return;l=!1}else for(;!(l=(t=a.call(n)).done)&&(i.push(t.value),i.length!==e);l=!0);}catch(r){s=!0,o=r}finally{try{if(!l&&null!=n.return&&(c=n.return(),Object(c)!==c))return}finally{if(s)throw o}}return i}}(e,n)||function(r,e){if(r){if("string"==typeof r)return $(r,e);var n={}.toString.call(r).slice(8,-1);return"Object"===n&&r.constructor&&(n=r.constructor.name),"Map"===n||"Set"===n?Array.from(r):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?$(r,e):void 0}}(e,n)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()),p=f[0],d=f[1];return(0,w.jsxs)("div",{className:l()("cpanel",a),children:[(0,w.jsxs)("div",{className:"cpanel-header",onClick:function(){return d(function(r){return!r})},"aria-expanded":p,children:[(0,w.jsx)("div",{className:"cpanel-header-title",children:t}),(0,w.jsx)("div",{className:"cpanel-chevron",children:(0,w.jsx)(U,B({direction:"right",open:p,className:"text-current cursor-pointer",size:24},i))})]}),(0,w.jsx)("div",{className:l()("cpanel-content",p&&"open"),children:o})]})};return a})());
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @license React
3
+ * react-jsx-runtime.production.js
4
+ *
5
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
6
+ *
7
+ * This source code is licensed under the MIT license found in the
8
+ * LICENSE file in the root directory of this source tree.
9
+ */
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "tsp-form",
3
+ "version": "0.0.1",
4
+ "description": "A unified Tailwind 4 variables compatible UI component library for my own projects.",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.esm.js",
7
+ "types": "dist/index.d.ts",
8
+ "scripts": {
9
+ "dev": "webpack serve --mode development --env APP_MODE=example",
10
+ "build": "webpack --mode production --env APP_MODE=library",
11
+ "clean": "rm -rf dist",
12
+ "build:lib": "webpack --env APP_MODE=library",
13
+ "build:example": "webpack",
14
+ "start:example": "webpack serve",
15
+ "test": "echo \"Error: no test specified\" && exit 1"
16
+ },
17
+ "keywords": [
18
+ "react",
19
+ "component",
20
+ "ui",
21
+ "tailwind"
22
+ ],
23
+ "author": "Tsupol",
24
+ "license": "MIT",
25
+ "dependencies": {
26
+ "clsx": "^2.1.1",
27
+ "react": "^19.1.0",
28
+ "react-dom": "^19.1.0",
29
+ "react-hook-form": "^7.62.0"
30
+ },
31
+ "devDependencies": {
32
+ "@babel/core": "^7.28.3",
33
+ "@babel/preset-env": "^7.28.3",
34
+ "@babel/preset-react": "^7.27.1",
35
+ "@babel/preset-typescript": "^7.27.1",
36
+ "@types/react": "^19.1.12",
37
+ "@types/react-dom": "^19.1.9",
38
+ "babel-loader": "^10.0.0",
39
+ "css-loader": "^7.1.2",
40
+ "html-webpack-plugin": "^5.6.4",
41
+ "style-loader": "^4.0.0",
42
+ "typescript": "^5.9.2",
43
+ "webpack": "^5.101.3",
44
+ "webpack-cli": "^6.0.1",
45
+ "webpack-dev-server": "^5.2.2"
46
+ }
47
+ }
@@ -0,0 +1,59 @@
1
+ import React, { forwardRef } from "react";
2
+ import clsx from "clsx";
3
+ import "../styles/button.css";
4
+
5
+ export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
6
+ color?: string;
7
+ variant?: string;
8
+ size?: string;
9
+ className?: string;
10
+ }
11
+
12
+ function getClassName(variant: string, color: string, size: string, className?: string) {
13
+ const classes = ['btn', `btn-${size}`, className];
14
+ switch (variant) {
15
+ case 'solid':
16
+ classes.push(`btn-${color}`);
17
+ break;
18
+ case 'outline':
19
+ classes.push(`btn-outline-${color}`);
20
+ break;
21
+ case 'ghost':
22
+ classes.push(`btn-ghost-${color}`);
23
+ break;
24
+ default:
25
+ break;
26
+ }
27
+ return clsx(classes);
28
+ }
29
+
30
+ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
31
+ (
32
+ {
33
+ color = "default",
34
+ variant = "solid",
35
+ size = "md",
36
+ className,
37
+ disabled,
38
+ type = "button",
39
+ ...props
40
+ },
41
+ ref
42
+ ) => {
43
+ const classes = getClassName(variant, color, size, className);
44
+
45
+ return (
46
+ <button
47
+ ref={ref}
48
+ type={type}
49
+ className={classes}
50
+ disabled={disabled}
51
+ {...props}
52
+ />
53
+ );
54
+ }
55
+ );
56
+
57
+ Button.displayName = "Button";
58
+
59
+ export default Button;
@@ -0,0 +1,84 @@
1
+ import React from 'react';
2
+ import clsx from 'clsx';
3
+ import '../styles/chevron.css';
4
+
5
+ type Direction = 'down' | 'up' | 'left' | 'right';
6
+
7
+ export type ChevronProps = {
8
+ direction?: Direction; // visual direction when "closed"
9
+ open?: boolean; // if provided, animates to an "expanded" angle
10
+ size?: number | string; // 16 | 20 | '1em' | '24px' ...
11
+ strokeWidth?: number; // 1 to 2.5 typically
12
+ className?: string;
13
+ title?: string;
14
+ 'aria-label'?: string;
15
+ animated?: boolean; // enables CSS transition
16
+ };
17
+
18
+ export function Chevron({
19
+ direction = 'down',
20
+ open,
21
+ size = 16,
22
+ strokeWidth = 2,
23
+ className,
24
+ title,
25
+ animated = true,
26
+ ...aria
27
+ }: ChevronProps) {
28
+ // Base rotation angles for the "closed" state
29
+ const baseAngle: Record<Direction, number> = {
30
+ down: 0,
31
+ up: 180,
32
+ left: 90,
33
+ right: -90,
34
+ };
35
+
36
+ // If `open` is provided, rotate to a sensible expanded angle
37
+ const angle = (() => {
38
+ if (open === undefined) return baseAngle[direction];
39
+ if (direction === 'down') return open ? 180 : 0; // caret flips up when open
40
+ if (direction === 'right') return open ? 0 : -90; // caret points down when open
41
+ // For 'up' and 'left' keep base angle unless you want a custom behavior
42
+ return baseAngle[direction];
43
+ })();
44
+
45
+ // Map to Tailwind rotation classes we actually use
46
+ const angleClass =
47
+ angle === 0
48
+ ? 'rotate-0'
49
+ : angle === 180
50
+ ? 'rotate-180'
51
+ : angle === 90
52
+ ? 'rotate-90'
53
+ : angle === -90
54
+ ? '-rotate-90'
55
+ : 'rotate-0';
56
+
57
+ // Inline SVG chevron (stroke follows currentColor)
58
+ return (
59
+ <svg
60
+ xmlns="http://www.w3.org/2000/svg"
61
+ width={size as number}
62
+ height={size as number}
63
+ viewBox="0 0 24 24"
64
+ fill="none"
65
+ stroke="currentColor"
66
+ strokeWidth={strokeWidth}
67
+ strokeLinecap="round"
68
+ strokeLinejoin="round"
69
+ className={clsx(
70
+ 'shrink-0',
71
+ animated && 'chevron-animated',
72
+ angleClass,
73
+ className
74
+ )}
75
+ aria-hidden={aria['aria-label'] ? undefined : true}
76
+ role={aria['aria-label'] ? 'img' : undefined}
77
+ {...aria}
78
+ >
79
+ {title ? <title>{title}</title> : null}
80
+ {/* ChevronDown path */}
81
+ <path d="M6 9l6 6 6-6" />
82
+ </svg>
83
+ );
84
+ }
@@ -0,0 +1,39 @@
1
+ import React, { useState } from 'react';
2
+ import clsx from 'clsx';
3
+ import { Chevron } from './Chevron';
4
+ import '../styles/collapsible-panel.css';
5
+
6
+ export const ExpandablePanel = ({
7
+ title,
8
+ children,
9
+ className,
10
+ chevronProps,
11
+ defaultOpen = true,
12
+ }: {
13
+ title: string;
14
+ className?: string;
15
+ children: React.ReactNode;
16
+ chevronProps?: React.ComponentProps<typeof Chevron>;
17
+ defaultOpen?: boolean;
18
+ }) => {
19
+ const [open, setOpen] = useState(defaultOpen);
20
+
21
+ return (
22
+ <div className={clsx('cpanel', className)}>
23
+ <div
24
+ className="cpanel-header"
25
+ onClick={() => setOpen((v) => !v)}
26
+ aria-expanded={open}
27
+ >
28
+ <div className="cpanel-header-title">{title}</div>
29
+ <div className="cpanel-chevron">
30
+ <Chevron direction="right" open={open} className="text-current cursor-pointer" size={24} {...chevronProps}/>
31
+ </div>
32
+ </div>
33
+
34
+ <div className={clsx('cpanel-content', open && 'open')}>
35
+ {children}
36
+ </div>
37
+ </div>
38
+ );
39
+ };
@@ -0,0 +1,131 @@
1
+ import React from 'react';
2
+ import { ContentPanel } from './components/ContentPanel';
3
+ import Button from '../components/Button';
4
+
5
+ export function ExampleButtons() {
6
+ return (
7
+ <div className="grid gap-4">
8
+ <ContentPanel title="CSS Buttons">
9
+ <div className="flex gap-2 border border-line bg-surface p-card">
10
+ <button className="btn">
11
+ Button
12
+ </button>
13
+ <button className="btn btn-primary">
14
+ Button Primary
15
+ </button>
16
+ <button className="btn btn-secondary">
17
+ Button Secondary
18
+ </button>
19
+ <button className="btn btn-secondary disabled">
20
+ Button Secondary
21
+ </button>
22
+ </div>
23
+ <div className="flex gap-2 border border-line bg-surface p-card">
24
+ <button className="btn btn-outline-default">
25
+ Button
26
+ </button>
27
+ <button className="btn btn-outline-primary">
28
+ Button Primary
29
+ </button>
30
+ <button className="btn btn-outline-secondary">
31
+ Outline Secondary
32
+ </button>
33
+ <button className="btn btn-outline-secondary disabled">
34
+ Outline Secondary
35
+ </button>
36
+ </div>
37
+ <div className="flex gap-2 border border-line bg-surface p-card">
38
+ <button className="btn btn-ghost-default">
39
+ Ghost
40
+ </button>
41
+ <button className="btn btn-ghost-primary">
42
+ Ghost Primary
43
+ </button>
44
+ <button className="btn btn-ghost-secondary">
45
+ Ghost Secondary
46
+ </button>
47
+ <button className="btn btn-ghost-secondary disabled">
48
+ Ghost Secondary
49
+ </button>
50
+ </div>
51
+ <div className="flex gap-2 border border-line bg-surface p-card">
52
+ <button className="btn btn-lg">
53
+ Large
54
+ </button>
55
+ <button className="btn btn-sm">
56
+ Small
57
+ </button>
58
+ <button className="btn btn-outline-default btn-lg">
59
+ Large
60
+ </button>
61
+ <div>
62
+ <button className="btn btn-outline-secondary btn-sm">
63
+ Small
64
+ </button>
65
+ </div>
66
+ </div>
67
+ </ContentPanel>
68
+ <ContentPanel title="React Buttons">
69
+ <div className="flex gap-2 border border-line bg-surface p-card">
70
+ <Button>
71
+ Button
72
+ </Button>
73
+ <Button color="primary">
74
+ Button Primary
75
+ </Button>
76
+ <Button color="secondary">
77
+ Button Secondary
78
+ </Button>
79
+ <Button color="secondary" disabled>
80
+ Button Secondary
81
+ </Button>
82
+ </div>
83
+ <div className="flex gap-2 border border-line bg-surface p-card">
84
+ <Button variant="outline">
85
+ Button
86
+ </Button>
87
+ <Button variant="outline" color="primary">
88
+ Button Primary
89
+ </Button>
90
+ <Button variant="outline" color="secondary">
91
+ Outline Secondary
92
+ </Button>
93
+ <Button variant="outline" color="secondary" disabled>
94
+ Outline Secondary
95
+ </Button>
96
+ </div>
97
+ <div className="flex gap-2 border border-line bg-surface p-card">
98
+ <Button variant="ghost">
99
+ Ghost
100
+ </Button>
101
+ <Button variant="ghost" color="primary">
102
+ Ghost Primary
103
+ </Button>
104
+ <Button variant="ghost" color="secondary">
105
+ Ghost Secondary
106
+ </Button>
107
+ <Button variant="ghost" color="secondary" disabled>
108
+ Ghost Secondary
109
+ </Button>
110
+ </div>
111
+ <div className="flex gap-2 border border-line bg-surface p-card">
112
+ <Button size="lg">
113
+ Large
114
+ </Button>
115
+ <Button size="sm">
116
+ Small
117
+ </Button>
118
+ <Button variant="outline" size="lg">
119
+ Large
120
+ </Button>
121
+ <div>
122
+ <Button variant="outline" color="secondary" size="sm">
123
+ Small
124
+ </Button>
125
+ </div>
126
+ </div>
127
+
128
+ </ContentPanel>
129
+ </div>
130
+ );
131
+ }
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+
3
+ export const ContentPanel = ({ title, children }: { title: string; children: React.ReactNode}) => {
4
+ return (
5
+ <div className="content-panel">
6
+ <div className="content-panel-header-wrapper">
7
+ <span className="content-panel-header">{title}</span>
8
+ </div>
9
+ {children}
10
+ </div>
11
+ )
12
+ }
@@ -0,0 +1,83 @@
1
+ @import '../global.css';
2
+ @import './styles/components.css';
3
+ @import './styles/utils.css';
4
+
5
+ :root {
6
+ --color-danger: #ff0000;
7
+ --color-danger-contrast: #ffffff;
8
+ --spacing-main-sidebar: 10rem;
9
+ --spacing-mini-sidebar: 2.5rem;
10
+ --spacing-card: 1rem;
11
+
12
+ --color-fg: #cccccc;
13
+ --color-fg-contrast: #000000;
14
+ --color-bg: #0a0a0a;
15
+ --color-bg-contrast: #ffffff;
16
+
17
+ --color-line: #2a2a2a;
18
+ --color-link: #0070f3;
19
+
20
+ --color-surface: rgba(255, 255, 255, 0.025);
21
+ --color-surface-hover: rgba(255, 255, 255, 0.05);
22
+ --color-surface-shallow: rgba(255, 255, 255, 0.01);
23
+ --color-surface-elevated: rgba(255, 255, 255, 0.05);
24
+
25
+ --spacing-line: 1px;
26
+
27
+ --color-primary: #0070f3;
28
+ --color-primary-hover: #005bb5;
29
+ --color-primary-active: #004c9b;
30
+ --color-primary-contrast: #ffffff;
31
+ --color-primary-light: rgba(0, 112, 243, 0.1);
32
+
33
+ --color-secondary: #8200ff;
34
+ --color-secondary-hover: #6800cc;
35
+ --color-secondary-active: #5300a8;
36
+ --color-secondary-contrast: #ffffff;
37
+
38
+ --spacing-control-y: 0.625rem;
39
+ --spacing-control-x: 1rem;
40
+ --spacing-control-compact-y: 0.25rem;
41
+ --spacing-control-compact-x: 0.5rem;
42
+ --spacing-control-relaxed-y: 1rem;
43
+ --spacing-control-relaxed-x: 2rem;
44
+ --radius-control: .5rem;
45
+ --text-control: 1rem;
46
+ --text-control--letter-spacing: 0em;
47
+ --text-control--line-height: 1.5;
48
+ --text-control--font-weight: 400;
49
+
50
+ --space-scrollbar-track: .5rem;
51
+ --color-scrollbar-track: rgba(125, 125, 125, 0.1);
52
+ --color-scrollbar-thumb: rgba(125, 125, 125, 0.25);
53
+ --color-bg-control: transparent;
54
+ --color-label-control: #888888;
55
+
56
+ --space-title-x: 1rem;
57
+ --space-title-y: 1rem;
58
+ --text-title: 1.5rem;
59
+ --text-title--letter-spacing: -0.025em;
60
+ --text-title--line-height: 1.25;
61
+ --text-title--font-weight: 600;
62
+
63
+ --spacing-title-y: 1rem;
64
+ --spacing-title-x: 1rem;
65
+ --spacing-title-h: calc(var(--spacing-title-y) * 2 + var(--text-title) * var(--text-title--line-height));
66
+
67
+ --text-base: 1rem;
68
+ --text-base--letter-spacing: 0em;
69
+ --text-base--line-height: 1.5;
70
+ --text-base--font-weight: 400;
71
+ }
72
+
73
+ html, body {
74
+ background: var(--color-bg);
75
+ color: var(--color-fg);
76
+ font-family: Arial, Helvetica, sans-serif;
77
+ font-size: var(--text-base);
78
+ line-height: var(--text-base--line-height);
79
+ }
80
+
81
+ .page-content {
82
+ padding: 1rem 2rem;
83
+ }
@@ -0,0 +1,12 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Button Component Example</title>
7
+ </head>
8
+ <body>
9
+ <div id="root"></div>
10
+ <!-- Webpack will inject the bundle.js here -->
11
+ </body>
12
+ </html>
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+ import { createRoot } from 'react-dom/client';
3
+ import { ExpandablePanel } from '../components/ExpandablePanel';
4
+ import { ExampleButtons } from './ExampleButtons';
5
+ import './example.css';
6
+
7
+ const App = () => {
8
+ return (
9
+ <div>
10
+ <ExpandablePanel title="Buttons">
11
+ <ExampleButtons />
12
+ </ExpandablePanel>
13
+ </div>
14
+ );
15
+ };
16
+
17
+ const container = document.getElementById('root');
18
+ if (container) {
19
+ const root = createRoot(container);
20
+ root.render(<App />);
21
+ }
@@ -0,0 +1,14 @@
1
+ .content-panel {
2
+ padding: 1rem;
3
+ }
4
+
5
+ .content-panel-header-wrapper {
6
+ padding-left: .5rem;
7
+ padding-bottom: .5rem;
8
+ border-left: .5rem solid var(--color-primary);
9
+ }
10
+
11
+ .content-panel-header {
12
+ font-size: 1.25rem;
13
+ font-weight: 600;
14
+ }
@@ -0,0 +1,23 @@
1
+ .flex {
2
+ display: flex;
3
+ }
4
+
5
+ .gap-2 {
6
+ gap: 0.5rem;
7
+ }
8
+
9
+ .border {
10
+ border: 1px solid var(--color-line);
11
+ }
12
+
13
+ .border-line {
14
+ border-color: var(--color-line);
15
+ }
16
+
17
+ .bg-surface {
18
+ background-color: var(--color-surface);
19
+ }
20
+
21
+ .p-card {
22
+ padding: 1rem;
23
+ }
package/src/global.css ADDED
@@ -0,0 +1,2 @@
1
+ @import "./styles/form.css";
2
+ @import "./styles/button.css";
package/src/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ export * from './components/Button';
2
+ export * from './components/ExpandablePanel';
3
+ export * from './components/Chevron';
@@ -0,0 +1,119 @@
1
+ .btn {
2
+ --color-text: var(--color-fg);
3
+ --color-bg: var(--color-surface);
4
+ --color-border: var(--color-surface);
5
+ --color-bg-hover: var(--color-fg);
6
+ --color-border-hover: var(--color-fg);
7
+ --color-text-hover: var(--color-fg-contrast);
8
+ padding: var(--spacing-control-y) var(--spacing-control-x);
9
+ border-radius: var(--radius-control);
10
+ border: 1px solid var(--color-border);
11
+ cursor: pointer;
12
+ background: var(--color-bg);
13
+ color: var(--color-text);
14
+ transition: all 0.2s ease-in-out;
15
+ display: inline-flex;
16
+ align-items: center;
17
+ justify-content: center;
18
+ font-weight: 600;
19
+ }
20
+
21
+ .btn:hover {
22
+ background: var(--color-bg-hover);
23
+ border-color: var(--color-border-hover);
24
+ color: var(--color-text-hover);
25
+ }
26
+
27
+ .btn.disabled {
28
+ opacity: 0.5;
29
+ pointer-events: none;
30
+ }
31
+
32
+ .btn-sm {
33
+ padding: var(--spacing-control-compact-y) var(--spacing-control-compact-x);
34
+ }
35
+
36
+ .btn-lg {
37
+ padding: var(--spacing-control-relaxed-y) var(--spacing-control-relaxed-x);
38
+ }
39
+
40
+ .btn-primary {
41
+ --color-text: var(--color-primary-contrast);
42
+ --color-bg: var(--color-primary);
43
+ --color-border: var(--color-primary);
44
+ }
45
+
46
+ .btn-secondary {
47
+ --color-text: var(--color-secondary-contrast);
48
+ --color-bg: var(--color-secondary);
49
+ --color-border: var(--color-secondary);
50
+ }
51
+
52
+ .btn-danger {
53
+ --color-text: var(--color-danger-contrast);
54
+ --color-bg: var(--color-danger);
55
+ --color-border: var(--color-danger);
56
+ }
57
+
58
+ .btn-outline-default {
59
+ --color-text: var(--color-fg);
60
+ --color-bg: transparent;
61
+ --color-border: var(--color-line);
62
+ }
63
+
64
+ .btn-outline-primary {
65
+ --color-text: var(--color-primary);
66
+ --color-border: var(--color-primary);
67
+ --color-text-hover: var(--color-primary-contrast);
68
+ --color-bg-hover: var(--color-primary);
69
+ --color-border-hover: var(--color-primary);
70
+ }
71
+
72
+ .btn-outline-secondary {
73
+ --color-text: var(--color-secondary);
74
+ --color-border: var(--color-secondary);
75
+ --color-text-hover: var(--color-secondary-contrast);
76
+ --color-bg-hover: var(--color-secondary);
77
+ --color-border-hover: var(--color-secondary);
78
+ }
79
+
80
+ .btn-outline-danger {
81
+ --color-text: var(--color-danger);
82
+ --color-border: var(--color-danger);
83
+ --color-text-hover: var(--color-danger-contrast);
84
+ --color-bg-hover: var(--color-danger);
85
+ --color-border-hover: var(--color-danger);
86
+ }
87
+
88
+ .btn-ghost-default {
89
+ --color-text: var(--color-fg);
90
+ --color-bg: transparent;
91
+ --color-border: transparent;
92
+ --color-text-hover: var(--color-fg);
93
+ --color-bg-hover: var(--color-surface);
94
+ --color-border-hover: var(--color-surface);
95
+ }
96
+
97
+ .btn-ghost-primary {
98
+ --color-text: var(--color-primary);
99
+ --color-bg: transparent;
100
+ --color-border: transparent;
101
+ --color-text-hover: var(--color-fg);
102
+ --color-bg-hover: var(--color-surface);
103
+ --color-border-hover: var(--color-surface);
104
+ }
105
+
106
+ .btn-ghost-secondary {
107
+ --color-text: var(--color-secondary);
108
+ --color-bg: transparent;
109
+ --color-border: transparent;
110
+ --color-text-hover: var(--color-fg);
111
+ --color-bg-hover: var(--color-surface);
112
+ --color-border-hover: var(--color-surface);
113
+ }
114
+
115
+ .btn-ghost-danger {
116
+ --color-text: var(--color-danger);
117
+ --color-bg: transparent;
118
+ --color-border: transparent;
119
+ }
@@ -0,0 +1,19 @@
1
+ .rotate-0 {
2
+ transform: rotate(0deg);
3
+ }
4
+
5
+ .rotate-90 {
6
+ transform: rotate(90deg);
7
+ }
8
+
9
+ .rotate-180 {
10
+ transform: rotate(180deg);
11
+ }
12
+
13
+ .-rotate-90 {
14
+ transform: rotate(-90deg);
15
+ }
16
+
17
+ .chevron-animated {
18
+ transition: transform 200ms ease-out;
19
+ }
@@ -0,0 +1,48 @@
1
+ .cpanel {
2
+ border: 1px solid var(--color-line);
3
+ border-radius: var(--radius-control);
4
+ overflow: hidden;
5
+ }
6
+
7
+ .cpanel-header {
8
+ display: flex;
9
+ align-items: center;
10
+ justify-content: space-between;
11
+ text-align: left;
12
+ border-bottom: 1px solid var(--color-line);
13
+ }
14
+
15
+ .cpanel-header-title {
16
+ padding: var(--spacing-title-y) var(--spacing-title-x);
17
+ letter-spacing: var(--text-title--letter-spacing);
18
+ font-size: var(--text-title);
19
+ line-height: var(--text-title--line-height);
20
+ font-weight: var(--text-title--font-weight);
21
+ }
22
+
23
+ .cpanel-header:focus {
24
+ outline: none;
25
+ }
26
+
27
+ .cpanel-header:focus-visible {
28
+ box-shadow: 0 0 0 1px var(--color-primary);
29
+ }
30
+
31
+ .cpanel-chevron {
32
+ flex-shrink: 0;
33
+ display: flex;
34
+ justify-content: center;
35
+ align-items: center;
36
+ width: var(--spacing-title-h);
37
+ height: var(--spacing-title-h);
38
+ border-left: var(--spacing-line) solid var(--color-line);
39
+ cursor: pointer;
40
+ }
41
+
42
+ .cpanel-content.open {
43
+ display: block;
44
+ }
45
+
46
+ .cpanel-content {
47
+ display: none;
48
+ }
@@ -0,0 +1,47 @@
1
+ @layer utilities {
2
+ .form-control {
3
+ border: 1px solid var(--color-line, #d1d5db);
4
+ border-radius: var(--radius-control, 0.375rem);
5
+ background-color: var(--color-bg-control, #ffffff);
6
+ padding: var(--spacing-control-y, 0.5rem) var(--spacing-control-y, 0.75rem);
7
+ transition: border-color 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
8
+ font-size: var(--text-control, 0.875rem);
9
+ font-weight: var(--text-control--font-weight, 400);
10
+ letter-spacing: var(--text-control--letter-spacing, 0em);
11
+ line-height: var(--text-control--line-height, 1.25);
12
+ min-height: calc(
13
+ var(--text-control--line-height) * var(--text-control, 0.875rem) +
14
+ 2 * var(--spacing-control-y) +
15
+ 2 * 1px /* Assuming 1px border*/
16
+ );
17
+
18
+ }
19
+
20
+ .form-error-border .form-control, /* for Select */
21
+ .form-error-border {
22
+ border-color: var(--color-danger);
23
+ }
24
+
25
+ .form-control:focus-within {
26
+ border-color: var(--color-primary); /* Focus border color */
27
+ box-shadow: none;
28
+ outline: none;
29
+ }
30
+
31
+ .form-control:disabled {
32
+ opacity: 0.5;
33
+ cursor: not-allowed;
34
+ }
35
+
36
+ .form-label {
37
+ font-size: 0.875rem;
38
+ font-weight: 600;
39
+ color: var(--color-label-control);
40
+ }
41
+
42
+ .form-error {
43
+ color: var(--color-danger);
44
+ font-size: 0.75rem;
45
+ }
46
+
47
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es2019",
4
+ "module": "esnext",
5
+ "jsx": "react-jsx",
6
+ "strict": true,
7
+ "esModuleInterop": true,
8
+ "skipLibCheck": true,
9
+ "forceConsistentCasingInFileNames": true,
10
+ "moduleResolution": "node",
11
+ "declaration": true,
12
+ "outDir": "./dist",
13
+ "baseUrl": "./",
14
+ "lib": ["dom", "dom.iterable", "esnext"]
15
+ },
16
+ "include": ["src"],
17
+ "exclude": ["node_modules", "dist", "src/example"] // Added: Exclude src/example
18
+
19
+ }
@@ -0,0 +1,107 @@
1
+ const path = require('path');
2
+ const HtmlWebpackPlugin = require('html-webpack-plugin');
3
+
4
+ module.exports = (env) => {
5
+ const isLibraryBuild = env.APP_MODE === 'library';
6
+
7
+ const commonConfig = {
8
+ resolve: {
9
+ extensions: ['.ts', '.tsx', '.js', '.jsx'],
10
+ },
11
+ module: {
12
+ rules: [
13
+ {
14
+ test: /\.(ts|tsx|js|jsx)$/,
15
+ exclude: /node_modules/,
16
+ use: {
17
+ loader: 'babel-loader',
18
+ options: {
19
+ cacheDirectory: true,
20
+ },
21
+ },
22
+ },
23
+ // Add this rule for CSS files
24
+ {
25
+ test: /\.css$/,
26
+ use: ['style-loader', 'css-loader'],
27
+ },
28
+ ],
29
+ },
30
+ };
31
+
32
+ if (isLibraryBuild) {
33
+ return {
34
+ ...commonConfig,
35
+ entry: './src/index.ts', // Entry point for the component library
36
+ output: {
37
+ path: path.resolve(__dirname, 'dist'),
38
+ filename: 'index.js',
39
+ library: {
40
+ name: 'MyUIComponents',
41
+ type: 'umd', // Universal Module Definition (CJS, AMD, global)
42
+ },
43
+ globalObject: 'this', // For UMD to work correctly in different environments
44
+ clean: true, // Clean the dist folder before each build
45
+ libraryTarget: 'umd', // Legacy, prefer 'library.type'
46
+ umdNamedDefine: true, // Give a name to the AMD module
47
+ auxiliaryComment: 'Button Component Library',
48
+ },
49
+ externals: {
50
+ // Don't bundle React and ReactDOM, expect them to be provided by the consumer
51
+ react: {
52
+ commonjs: 'react',
53
+ commonjs2: 'react',
54
+ amd: 'react',
55
+ root: 'React',
56
+ },
57
+ 'react-dom': {
58
+ commonjs: 'react-dom',
59
+ commonjs2: 'react-dom',
60
+ amd: 'react-dom',
61
+ root: 'ReactDOM',
62
+ },
63
+ clsx: {
64
+ commonjs: 'clsx',
65
+ commonjs2: 'clsx',
66
+ amd: 'clsx',
67
+ root: 'clsx',
68
+ },
69
+ 'react-hook-form': {
70
+ commonjs: 'react-hook-form',
71
+ commonjs2: 'react-hook-form',
72
+ amd: 'react-hook-form',
73
+ root: 'ReactHookForm',
74
+ },
75
+
76
+ },
77
+ optimization: {
78
+ minimize: true,
79
+ },
80
+ };
81
+ } else {
82
+ // Development server for the example app
83
+ return {
84
+ ...commonConfig,
85
+ entry: './src/example/index.tsx', // Changed: Entry point for the example app
86
+ output: {
87
+ path: path.resolve(__dirname, 'dist'),
88
+ filename: 'bundle.js',
89
+ },
90
+ plugins: [
91
+ new HtmlWebpackPlugin({
92
+ template: path.resolve(__dirname, 'src/example/index.html'), // Changed: Path to your HTML template
93
+ }),
94
+ ],
95
+ devServer: {
96
+ static: {
97
+ directory: path.join(__dirname, 'dist'), // The static directory should point to where webpack-dev-server serves files
98
+ },
99
+ compress: true,
100
+ port: 3000,
101
+ open: true,
102
+ hot: true,
103
+ },
104
+ devtool: 'eval-source-map',
105
+ };
106
+ }
107
+ };