@dropi/ui 0.1.23 → 0.1.25

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.
@@ -69,15 +69,15 @@ const DropiButton = class {
69
69
  const hasText = this.text !== '';
70
70
  const showPostIcon = this.postIcon !== '' || this.type === 'dropdown';
71
71
  const dropdownIcon = this.type === 'dropdown' ? 'Dropdown-down' : this.postIcon;
72
- return (h("button", { key: 'd21aeb2274c317795bb0daad6d30c2bc9f3ede9f', class: {
72
+ return (h("button", { key: '878f01cf2b73d67ad393c46c47dbf71d4589573b', class: {
73
73
  btn: true,
74
74
  'without-text': !hasText,
75
- [this.severity]: true,
76
- [this.type]: true,
77
- [this.size]: true,
78
- [this.state]: true,
75
+ [this.severity ?? 'primary']: true,
76
+ [this.type ?? 'default']: true,
77
+ [this.size ?? 'normal']: true,
78
+ [this.state ?? 'default']: true,
79
79
  'full-width': this.fullWidth,
80
- }, disabled: isDisabled, onClick: (e) => this.handleClick(e) }, this.preIcon && (h("dropi-icon", { key: '6711ece5a9c871db989e6bc4572c0d0ebfa7f899', name: this.preIcon, width: this.iconSize, height: this.iconSize, color: this.fontColor })), hasText && h("span", { key: '9fc49de08b5672c6e2dae9b3cea9587d451fac0d', class: "text" }, this.text), showPostIcon && (h("dropi-icon", { key: '1ce254e23b16fb7013469fb3e2d71fe70dba5a9d', name: dropdownIcon, width: this.iconSize, height: this.iconSize, color: this.fontColor })), this.state === 'loading' && this.renderLoadingSpinner(), h("slot", { key: '72857295b27aa6ef6981276d68497f33958a584c' })));
80
+ }, disabled: isDisabled, onClick: (e) => this.handleClick(e) }, this.preIcon && (h("dropi-icon", { key: 'd42a3e52d105b985c9cbc72241e363baaaad25a8', name: this.preIcon, width: this.iconSize, height: this.iconSize, color: this.fontColor })), hasText && h("span", { key: 'e88b6ef2c3cf63aec13f1fa4bfe289333acdd8b9', class: "text" }, this.text), showPostIcon && (h("dropi-icon", { key: '596a8227042757ffe942290a1e776b981bb89136', name: dropdownIcon, width: this.iconSize, height: this.iconSize, color: this.fontColor })), this.state === 'loading' && this.renderLoadingSpinner(), h("slot", { key: 'e46a00e52792e690b3b4cb24e6af1b1843f7384f' })));
81
81
  }
82
82
  };
83
83
  DropiButton.style = dropiButtonCss();
@@ -1 +1 @@
1
- {"file":"dropi-button.entry.js","mappings":"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","names":[],"sources":["src/components/dropi-button/dropi-button.css?tag=dropi-button&encapsulation=shadow","src/components/dropi-button/dropi-button.tsx"],"sourcesContent":[":host {\n display: inline-block;\n}\n\n:host([full-width]) {\n display: flex;\n width: 100%;\n}\n:host([full-width]) .btn {\n width: 100%;\n}\n\n*, *::before, *::after { box-sizing: border-box; }\n\n.btn {\n all: unset;\n box-sizing: border-box;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: var(--Size-1, 4px);\n border-radius: var(--Border-2, 8px);\n font-weight: var(--font-weight-bold);\n min-width: 33px;\n line-height: 110%;\n cursor: pointer;\n white-space: nowrap;\n transition:\n background 0.25s ease,\n color 0.25s ease,\n border-color 0.25s ease,\n transform 0.25s ease;\n}\n\n.btn:active {\n transition: transform 0.01s ease-out;\n transform: scale(0.98);\n}\n\n.btn:hover:not(:active) {\n transform: scale(1.01);\n}\n\n.btn.without-text {\n gap: 0;\n}\n\n/* ── Sizes ─────────────────────────────────────────────────── */\n.btn.large { padding: var(--Size-4, 16px); font-size: var(--Size-4, 16px); height: 48px; }\n.btn.normal { padding: var(--Size-3, 12px); font-size: var(--font-size-s, 12px); height: 40px; }\n.btn.small { padding: var(--Size-2, 8px); font-size: var(--font-size-s, 12px); height: 29px; }\n\n/* ── Disabled / Loading ─────────────────────────────────────── */\n.btn.disabled,\n.btn.loading {\n cursor: not-allowed;\n pointer-events: none;\n}\n\n/* ══════════════════════════════════════════════════════════════\n PRIMARY severity\n═══════════════════════════════════════════════════════════════ */\n.btn.primary.default { background: var(--Primary-Primary-500, #f49a3d); color: var(--Neutral-White, #ffffff); }\n.btn.primary.default:hover { background: var(--Primary-Primary-600, #e58017); }\n\n.btn.primary.success { background: var(--Success-Success-500, #0abb87); color: var(--Neutral-White, #ffffff); }\n.btn.primary.success:hover { background: var(--Success-Success-600, #09aa7b); }\n\n.btn.primary.info { background: var(--Info-Info-500, #50a5f1); color: var(--Neutral-White, #ffffff); }\n.btn.primary.info:hover { background: var(--Info-Info-600, #4996db); }\n\n.btn.primary.error { background: var(--Error-Error-500, #f46a6b); color: var(--Neutral-White, #ffffff); }\n.btn.primary.error:hover { background: var(--Error-Error-600, #de6061); }\n\n.btn.primary.warning { background: var(--Warning-Warning-500, #f1b44c); color: var(--Neutral-White, #ffffff); }\n.btn.primary.warning:hover { background: var(--Warning-Warning-600, #dba445); }\n\n.btn.primary.legacy { background: var(--Secondary-Secondary-500, #008dbf); color: var(--Neutral-White, #ffffff); }\n.btn.primary.legacy:hover { background: var(--Secondary-Secondary-600, #007199); }\n\n/* Disabled primary */\n.btn.primary.disabled.default { background: var(--Primary-Primary-300, #f2bc85); color: var(--Neutral-White, #ffffff); }\n.btn.primary.disabled.success { background: var(--Success-Success-300, #5bd1af); color: var(--Neutral-White, #ffffff); }\n.btn.primary.disabled.info { background: var(--Info-Info-300, #8ac3f6); color: var(--Neutral-White, #ffffff); }\n.btn.primary.disabled.error { background: var(--Error-Error-300, #f89b9c); color: var(--Neutral-White, #ffffff); }\n.btn.primary.disabled.warning { background: var(--Warning-Warning-300, #f6cd87); color: var(--Neutral-White, #ffffff); }\n.btn.primary.disabled.legacy { background: var(--Secondary-Secondary-300, #62bad9); color: var(--Neutral-White, #ffffff); }\n\n/* ══════════════════════════════════════════════════════════════\n SECONDARY severity\n═══════════════════════════════════════════════════════════════ */\n.btn.secondary {\n background: var(--Neutral-White, #ffffff);\n border: 1px solid;\n}\n\n.btn.secondary.default { border-color: var(--Primary-Primary-500, #f49a3d); color: var(--Primary-Primary-500, #f49a3d); }\n.btn.secondary.default:hover { color: var(--Primary-Primary-600, #e58017); border-color: var(--Primary-Primary-600, #e58017); }\n\n.btn.secondary.success { border-color: var(--Success-Success-500, #0abb87); color: var(--Success-Success-500, #0abb87); }\n.btn.secondary.success:hover { color: var(--Success-Success-600, #09aa7b); border-color: var(--Success-Success-600, #09aa7b); }\n\n.btn.secondary.info { border-color: var(--Info-Info-500, #50a5f1); color: var(--Info-Info-500, #50a5f1); }\n.btn.secondary.info:hover { color: var(--Info-Info-600, #4996db); border-color: var(--Info-Info-600, #4996db); }\n\n.btn.secondary.error { border-color: var(--Error-Error-500, #f46a6b); color: var(--Error-Error-500, #f46a6b); }\n.btn.secondary.error:hover { color: var(--Error-Error-600, #de6061); border-color: var(--Error-Error-600, #de6061); }\n\n.btn.secondary.warning { border-color: var(--Warning-Warning-500, #f1b44c); color: var(--Warning-Warning-500, #f1b44c); }\n.btn.secondary.warning:hover { color: var(--Warning-Warning-600, #dba445); border-color: var(--Warning-Warning-600, #dba445); }\n\n.btn.secondary.legacy { border-color: var(--Secondary-Secondary-500, #008dbf); color: var(--Secondary-Secondary-500, #008dbf); }\n.btn.secondary.legacy:hover { color: var(--Secondary-Secondary-600, #007199); border-color: var(--Secondary-Secondary-600, #007199); }\n\n/* Disabled secondary */\n.btn.secondary.disabled.default { border-color: var(--Primary-Primary-300, #f2bc85); color: var(--Primary-Primary-300, #f2bc85); }\n.btn.secondary.disabled.success { border-color: var(--Success-Success-300, #5bd1af); color: var(--Success-Success-300, #5bd1af); }\n.btn.secondary.disabled.info { border-color: var(--Info-Info-300, #8ac3f6); color: var(--Info-Info-300, #8ac3f6); }\n.btn.secondary.disabled.error { border-color: var(--Error-Error-300, #f89b9c); color: var(--Error-Error-300, #f89b9c); }\n.btn.secondary.disabled.warning { border-color: var(--Warning-Warning-300, #f6cd87); color: var(--Warning-Warning-300, #f6cd87); }\n.btn.secondary.disabled.legacy { border-color: var(--Secondary-Secondary-300, #62bad9); color: var(--Secondary-Secondary-300, #62bad9); }\n\n/* ══════════════════════════════════════════════════════════════\n TERTIARY severity\n═══════════════════════════════════════════════════════════════ */\n.btn.tertiary { background: none; border: none; }\n\n.btn.tertiary.default,\n.btn.tertiary.legacy {\n border: 1px solid var(--Gray-Gray-200, #c3c9d9);\n color: var(--Gray-Gray-500, #69738c);\n}\n.btn.tertiary.default:hover,\n.btn.tertiary.legacy:hover {\n border-color: var(--Gray-Gray-400, #858ea6);\n color: var(--Gray-Gray-600, #475066);\n}\n\n.btn.tertiary.success { color: var(--Success-Success-500, #0abb87); }\n.btn.tertiary.success:hover { background: var(--Success-Success-50, #e7f8f3); }\n\n.btn.tertiary.info { color: var(--Info-Info-500, #50a5f1); }\n.btn.tertiary.info:hover { background: var(--Info-Info-50, #eef6fe); }\n\n.btn.tertiary.error { color: var(--Error-Error-500, #f46a6b); }\n.btn.tertiary.error:hover { background: var(--Error-Error-50, #fef0f0); }\n\n.btn.tertiary.warning { color: var(--Warning-Warning-500, #f1b44c); }\n.btn.tertiary.warning:hover { background: var(--Warning-Warning-50, #fef8ed); }\n\n.btn.tertiary.dropdown {\n color: var(--Gray-Gray-500, #69738c);\n font-weight: var(--font-weight-regular);\n font-size: var(--font-size-s);\n background: transparent;\n}\n\n/* Disabled tertiary */\n.btn.tertiary.disabled.default,\n.btn.tertiary.disabled.legacy {\n border: 1px solid var(--Gray-Gray-200, #c3c9d9);\n color: var(--Gray-Gray-400, #858ea6);\n}\n.btn.tertiary.disabled.success { color: var(--Success-Success-300, #5bd1af); }\n.btn.tertiary.disabled.info { color: var(--Info-Info-300, #8ac3f6); }\n.btn.tertiary.disabled.error { color: var(--Error-Error-300, #f89b9c); }\n.btn.tertiary.disabled.warning { color: var(--Warning-Warning-300, #f6cd87); }\n\n/* ── Loading spinner ─────────────────────────────────────────── */\n.spin {\n animation: spin 1s linear infinite;\n}\n\n@keyframes spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n}\n","import { Component, Prop, Event, EventEmitter, h } from '@stencil/core';\n\nexport type ButtonType = 'legacy' | 'default' | 'success' | 'info' | 'error' | 'warning' | 'dropdown' | 'default-light';\nexport type ButtonSeverity = 'primary' | 'secondary' | 'tertiary';\nexport type ButtonSize = 'large' | 'normal' | 'small';\nexport type ButtonState = 'default' | 'disabled' | 'loading';\n\n/**\n * @component dropi-button\n * Primary action button with multiple types, severities, sizes and states.\n * Supports pre/post icons and a loading spinner.\n */\n@Component({\n tag: 'dropi-button',\n styleUrl: 'dropi-button.css',\n shadow: true,\n})\nexport class DropiButton {\n /** Visual color palette */\n @Prop() type: ButtonType = 'default';\n /** Primary (filled) | Secondary (outlined) | Tertiary (ghost) */\n @Prop() severity: ButtonSeverity = 'primary';\n /** Button size */\n @Prop() size: ButtonSize = 'normal';\n /** Button state */\n @Prop() state: ButtonState = 'default';\n /** Full width button */\n @Prop({ reflect: true }) fullWidth: boolean = false;\n /** Icon name to show before the text */\n @Prop() preIcon: string = '';\n /** Icon name to show after the text */\n @Prop() postIcon: string = '';\n /** Custom icon color override */\n @Prop() customIconColor: string = '';\n /** Button label */\n @Prop() text: string = '';\n\n /** Emitted on click (not emitted when disabled or loading) */\n @Event() onClick: EventEmitter<MouseEvent>;\n\n private readonly colorMap: Record<string, string> = {\n default: 'Primary-Primary-',\n success: 'Success-Success-',\n error: 'Error-Error-',\n info: 'Info-Info-',\n legacy: 'Secondary-Secondary-',\n warning: 'Warning-Warning-',\n dropdown: 'Gray-Gray-',\n 'default-light': 'Gray-Gray-',\n };\n\n private get iconSize(): string {\n if (this.size === 'large') return '24px';\n if (this.size === 'small') return '16px';\n return '18px';\n }\n\n private get color(): string {\n const intensity = this.state === 'disabled' ? '300' : '500';\n return (this.colorMap[this.type] ?? 'Primary-Primary-') + intensity;\n }\n\n private get fontColor(): string {\n if (this.severity === 'tertiary') {\n return this.type === 'default' || this.type === 'legacy' ? 'Gray-Gray-500' : this.color;\n }\n if (this.severity === 'secondary') return this.color;\n return 'Neutral-White';\n }\n\n private handleClick(e: MouseEvent) {\n if (this.state !== 'disabled' && this.state !== 'loading') {\n this.onClick.emit(e);\n }\n }\n\n private renderLoadingSpinner() {\n return (\n <svg\n class=\"spin\"\n width={this.iconSize}\n height={this.iconSize}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M22.8 12C23.4627 12 24.0062 11.4614 23.9401 10.802C23.8232 9.6371 23.5362 8.49339 23.0866 7.4078C22.4835 5.95189 21.5996 4.62902 20.4853 3.51472C19.371 2.40042 18.0481 1.5165 16.5922 0.913445C15.5066 0.463778 14.3629 0.17683 13.198 0.0599502C12.5386 -0.00621439 12 0.537258 12 1.2C12 1.86274 12.5393 2.39227 13.1969 2.4749C14.0463 2.58164 14.8795 2.80176 15.6738 3.13076C16.8385 3.6132 17.8968 4.32033 18.7882 5.21177C19.6797 6.10322 20.3868 7.16151 20.8692 8.32624C21.1982 9.12051 21.4184 9.95367 21.5251 10.8031C21.6077 11.4607 22.1373 12 22.8 12Z\"\n fill={`var(--${this.fontColor})`}\n />\n </svg>\n );\n }\n\n render() {\n const isDisabled = this.state === 'disabled' || this.state === 'loading';\n const hasText = this.text !== '';\n const showPostIcon = this.postIcon !== '' || this.type === 'dropdown';\n const dropdownIcon = this.type === 'dropdown' ? 'Dropdown-down' : this.postIcon;\n\n return (\n <button\n class={{\n btn: true,\n 'without-text': !hasText,\n [this.severity]: true,\n [this.type]: true,\n [this.size]: true,\n [this.state]: true,\n 'full-width': this.fullWidth,\n }}\n disabled={isDisabled}\n onClick={(e) => this.handleClick(e)}\n >\n {this.preIcon && (\n <dropi-icon\n name={this.preIcon}\n width={this.iconSize}\n height={this.iconSize}\n color={this.fontColor}\n />\n )}\n {hasText && <span class=\"text\">{this.text}</span>}\n {showPostIcon && (\n <dropi-icon\n name={dropdownIcon}\n width={this.iconSize}\n height={this.iconSize}\n color={this.fontColor}\n />\n )}\n {this.state === 'loading' && this.renderLoadingSpinner()}\n <slot />\n </button>\n );\n }\n}\n"],"version":3}
1
+ {"file":"dropi-button.entry.js","mappings":";;AAAA,MAAM,cAAc,GAAG,MAAM,CAAC,8sMAA8sM,CAAC;;MCiBhuM,WAAW,GAAA,MAAA;;;;;;IAEd,IAAI,GAAe,SAAS;;IAE5B,QAAQ,GAAmB,SAAS;;IAEpC,IAAI,GAAe,QAAQ;;IAE3B,KAAK,GAAgB,SAAS;;IAEb,SAAS,GAAY,KAAK;;IAE3C,OAAO,GAAW,EAAE;;IAEpB,QAAQ,GAAW,EAAE;;IAErB,eAAe,GAAW,EAAE;;IAE5B,IAAI,GAAW,EAAE;;AAGhB,IAAA,OAAO;AAEC,IAAA,QAAQ,GAA2B;AAClD,QAAA,OAAO,EAAE,kBAAkB;AAC3B,QAAA,OAAO,EAAE,kBAAkB;AAC3B,QAAA,KAAK,EAAE,cAAc;AACrB,QAAA,IAAI,EAAE,YAAY;AAClB,QAAA,MAAM,EAAE,sBAAsB;AAC9B,QAAA,OAAO,EAAE,kBAAkB;AAC3B,QAAA,QAAQ,EAAE,YAAY;AACtB,QAAA,eAAe,EAAE,YAAY;KAC9B;AAED,IAAA,IAAY,QAAQ,GAAA;AAClB,QAAA,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO;AAAE,YAAA,OAAO,MAAM;AACxC,QAAA,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO;AAAE,YAAA,OAAO,MAAM;AACxC,QAAA,OAAO,MAAM;;AAGf,IAAA,IAAY,KAAK,GAAA;AACf,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,KAAK,UAAU,GAAG,KAAK,GAAG,KAAK;AAC3D,QAAA,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,kBAAkB,IAAI,SAAS;;AAGrE,IAAA,IAAY,SAAS,GAAA;AACnB,QAAA,IAAI,IAAI,CAAC,QAAQ,KAAK,UAAU,EAAE;YAChC,OAAO,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,GAAG,eAAe,GAAG,IAAI,CAAC,KAAK;;AAEzF,QAAA,IAAI,IAAI,CAAC,QAAQ,KAAK,WAAW;YAAE,OAAO,IAAI,CAAC,KAAK;AACpD,QAAA,OAAO,eAAe;;AAGhB,IAAA,WAAW,CAAC,CAAa,EAAA;AAC/B,QAAA,IAAI,IAAI,CAAC,KAAK,KAAK,UAAU,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE;AACzD,YAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;;;IAIhB,oBAAoB,GAAA;QAC1B,QACE,CAAA,CAAA,KAAA,EAAA,EACE,KAAK,EAAC,MAAM,EACZ,KAAK,EAAE,IAAI,CAAC,QAAQ,EACpB,MAAM,EAAE,IAAI,CAAC,QAAQ,EACrB,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,MAAM,EACX,KAAK,EAAC,4BAA4B,EAAA,EAElC,CAAA,CAAA,MAAA,EAAA,EACE,CAAC,EAAC,uiBAAuiB,EACziB,IAAI,EAAE,CAAA,MAAA,EAAS,IAAI,CAAC,SAAS,CAAA,CAAA,CAAG,EAAA,CAChC,CACE;;IAIV,MAAM,GAAA;AACJ,QAAA,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,KAAK,UAAU,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS;AACxE,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,KAAK,EAAE;AAChC,QAAA,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,KAAK,EAAE,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU;AACrE,QAAA,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,KAAK,UAAU,GAAG,eAAe,GAAG,IAAI,CAAC,QAAQ;QAE/E,QACE,CAAA,CAAA,QAAA,EAAA,EAAA,GAAA,EAAA,0CAAA,EACE,KAAK,EAAE;AACL,gBAAA,GAAG,EAAE,IAAI;gBACT,cAAc,EAAE,CAAC,OAAO;AACxB,gBAAA,CAAC,IAAI,CAAC,QAAQ,IAAI,SAAS,GAAG,IAAI;AAClC,gBAAA,CAAC,IAAI,CAAC,IAAI,IAAI,SAAS,GAAG,IAAI;AAC9B,gBAAA,CAAC,IAAI,CAAC,IAAI,IAAI,QAAQ,GAAG,IAAI;AAC7B,gBAAA,CAAC,IAAI,CAAC,KAAK,IAAI,SAAS,GAAG,IAAI;gBAC/B,YAAY,EAAE,IAAI,CAAC,SAAS;AAC7B,aAAA,EACD,QAAQ,EAAE,UAAU,EACpB,OAAO,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAA,EAElC,IAAI,CAAC,OAAO,KACX,CAAA,CAAA,YAAA,EAAA,EAAA,GAAA,EAAA,0CAAA,EACE,IAAI,EAAE,IAAI,CAAC,OAAO,EAClB,KAAK,EAAE,IAAI,CAAC,QAAQ,EACpB,MAAM,EAAE,IAAI,CAAC,QAAQ,EACrB,KAAK,EAAE,IAAI,CAAC,SAAS,GACrB,CACH,EACA,OAAO,IAAI,6DAAM,KAAK,EAAC,MAAM,EAAA,EAAE,IAAI,CAAC,IAAI,CAAQ,EAChD,YAAY,KACX,CAAA,CAAA,YAAA,EAAA,EAAA,GAAA,EAAA,0CAAA,EACE,IAAI,EAAE,YAAY,EAClB,KAAK,EAAE,IAAI,CAAC,QAAQ,EACpB,MAAM,EAAE,IAAI,CAAC,QAAQ,EACrB,KAAK,EAAE,IAAI,CAAC,SAAS,EAAA,CACrB,CACH,EACA,IAAI,CAAC,KAAK,KAAK,SAAS,IAAI,IAAI,CAAC,oBAAoB,EAAE,EACxD,CAAA,CAAA,MAAA,EAAA,EAAA,GAAA,EAAA,0CAAA,EAAA,CAAQ,CACD;;;;;;;","names":[],"sources":["src/components/dropi-button/dropi-button.css?tag=dropi-button&encapsulation=shadow","src/components/dropi-button/dropi-button.tsx"],"sourcesContent":[":host {\n display: inline-block;\n}\n\n:host([full-width]) {\n display: flex;\n width: 100%;\n}\n:host([full-width]) .btn {\n width: 100%;\n}\n\n*, *::before, *::after { box-sizing: border-box; }\n\n.btn {\n all: unset;\n box-sizing: border-box;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: var(--Size-1, 4px);\n border-radius: var(--Border-2, 8px);\n font-weight: var(--font-weight-bold);\n min-width: 33px;\n line-height: 110%;\n cursor: pointer;\n white-space: nowrap;\n transition:\n background 0.25s ease,\n color 0.25s ease,\n border-color 0.25s ease,\n transform 0.25s ease;\n}\n\n.btn:active {\n transition: transform 0.01s ease-out;\n transform: scale(0.98);\n}\n\n.btn:hover:not(:active) {\n transform: scale(1.01);\n}\n\n.btn.without-text {\n gap: 0;\n}\n\n/* ── Sizes ─────────────────────────────────────────────────── */\n.btn.large { padding: var(--Size-4, 16px); font-size: var(--Size-4, 16px); height: 48px; }\n.btn.normal { padding: var(--Size-3, 12px); font-size: var(--font-size-s, 12px); height: 40px; }\n.btn.small { padding: var(--Size-2, 8px); font-size: var(--font-size-s, 12px); height: 29px; }\n\n/* ── Disabled / Loading ─────────────────────────────────────── */\n.btn.disabled,\n.btn.loading {\n cursor: not-allowed;\n pointer-events: none;\n}\n\n/* ══════════════════════════════════════════════════════════════\n PRIMARY severity\n═══════════════════════════════════════════════════════════════ */\n.btn.primary.default { background: var(--Primary-Primary-500, #f49a3d); color: var(--Neutral-White, #ffffff); }\n.btn.primary.default:hover { background: var(--Primary-Primary-600, #e58017); }\n\n.btn.primary.success { background: var(--Success-Success-500, #0abb87); color: var(--Neutral-White, #ffffff); }\n.btn.primary.success:hover { background: var(--Success-Success-600, #09aa7b); }\n\n.btn.primary.info { background: var(--Info-Info-500, #50a5f1); color: var(--Neutral-White, #ffffff); }\n.btn.primary.info:hover { background: var(--Info-Info-600, #4996db); }\n\n.btn.primary.error { background: var(--Error-Error-500, #f46a6b); color: var(--Neutral-White, #ffffff); }\n.btn.primary.error:hover { background: var(--Error-Error-600, #de6061); }\n\n.btn.primary.warning { background: var(--Warning-Warning-500, #f1b44c); color: var(--Neutral-White, #ffffff); }\n.btn.primary.warning:hover { background: var(--Warning-Warning-600, #dba445); }\n\n.btn.primary.legacy { background: var(--Secondary-Secondary-500, #008dbf); color: var(--Neutral-White, #ffffff); }\n.btn.primary.legacy:hover { background: var(--Secondary-Secondary-600, #007199); }\n\n/* Disabled primary */\n.btn.primary.disabled.default { background: var(--Primary-Primary-300, #f2bc85); color: var(--Neutral-White, #ffffff); }\n.btn.primary.disabled.success { background: var(--Success-Success-300, #5bd1af); color: var(--Neutral-White, #ffffff); }\n.btn.primary.disabled.info { background: var(--Info-Info-300, #8ac3f6); color: var(--Neutral-White, #ffffff); }\n.btn.primary.disabled.error { background: var(--Error-Error-300, #f89b9c); color: var(--Neutral-White, #ffffff); }\n.btn.primary.disabled.warning { background: var(--Warning-Warning-300, #f6cd87); color: var(--Neutral-White, #ffffff); }\n.btn.primary.disabled.legacy { background: var(--Secondary-Secondary-300, #62bad9); color: var(--Neutral-White, #ffffff); }\n\n/* ══════════════════════════════════════════════════════════════\n SECONDARY severity\n═══════════════════════════════════════════════════════════════ */\n.btn.secondary {\n background: var(--Neutral-White, #ffffff);\n border: 1px solid;\n}\n\n.btn.secondary.default { border-color: var(--Primary-Primary-500, #f49a3d); color: var(--Primary-Primary-500, #f49a3d); }\n.btn.secondary.default:hover { color: var(--Primary-Primary-600, #e58017); border-color: var(--Primary-Primary-600, #e58017); }\n\n.btn.secondary.success { border-color: var(--Success-Success-500, #0abb87); color: var(--Success-Success-500, #0abb87); }\n.btn.secondary.success:hover { color: var(--Success-Success-600, #09aa7b); border-color: var(--Success-Success-600, #09aa7b); }\n\n.btn.secondary.info { border-color: var(--Info-Info-500, #50a5f1); color: var(--Info-Info-500, #50a5f1); }\n.btn.secondary.info:hover { color: var(--Info-Info-600, #4996db); border-color: var(--Info-Info-600, #4996db); }\n\n.btn.secondary.error { border-color: var(--Error-Error-500, #f46a6b); color: var(--Error-Error-500, #f46a6b); }\n.btn.secondary.error:hover { color: var(--Error-Error-600, #de6061); border-color: var(--Error-Error-600, #de6061); }\n\n.btn.secondary.warning { border-color: var(--Warning-Warning-500, #f1b44c); color: var(--Warning-Warning-500, #f1b44c); }\n.btn.secondary.warning:hover { color: var(--Warning-Warning-600, #dba445); border-color: var(--Warning-Warning-600, #dba445); }\n\n.btn.secondary.legacy { border-color: var(--Secondary-Secondary-500, #008dbf); color: var(--Secondary-Secondary-500, #008dbf); }\n.btn.secondary.legacy:hover { color: var(--Secondary-Secondary-600, #007199); border-color: var(--Secondary-Secondary-600, #007199); }\n\n/* Disabled secondary */\n.btn.secondary.disabled.default { border-color: var(--Primary-Primary-300, #f2bc85); color: var(--Primary-Primary-300, #f2bc85); }\n.btn.secondary.disabled.success { border-color: var(--Success-Success-300, #5bd1af); color: var(--Success-Success-300, #5bd1af); }\n.btn.secondary.disabled.info { border-color: var(--Info-Info-300, #8ac3f6); color: var(--Info-Info-300, #8ac3f6); }\n.btn.secondary.disabled.error { border-color: var(--Error-Error-300, #f89b9c); color: var(--Error-Error-300, #f89b9c); }\n.btn.secondary.disabled.warning { border-color: var(--Warning-Warning-300, #f6cd87); color: var(--Warning-Warning-300, #f6cd87); }\n.btn.secondary.disabled.legacy { border-color: var(--Secondary-Secondary-300, #62bad9); color: var(--Secondary-Secondary-300, #62bad9); }\n\n/* ══════════════════════════════════════════════════════════════\n TERTIARY severity\n═══════════════════════════════════════════════════════════════ */\n.btn.tertiary { background: none; border: none; }\n\n.btn.tertiary.default,\n.btn.tertiary.legacy {\n border: 1px solid var(--Gray-Gray-200, #c3c9d9);\n color: var(--Gray-Gray-500, #69738c);\n}\n.btn.tertiary.default:hover,\n.btn.tertiary.legacy:hover {\n border-color: var(--Gray-Gray-400, #858ea6);\n color: var(--Gray-Gray-600, #475066);\n}\n\n.btn.tertiary.success { color: var(--Success-Success-500, #0abb87); }\n.btn.tertiary.success:hover { background: var(--Success-Success-50, #e7f8f3); }\n\n.btn.tertiary.info { color: var(--Info-Info-500, #50a5f1); }\n.btn.tertiary.info:hover { background: var(--Info-Info-50, #eef6fe); }\n\n.btn.tertiary.error { color: var(--Error-Error-500, #f46a6b); }\n.btn.tertiary.error:hover { background: var(--Error-Error-50, #fef0f0); }\n\n.btn.tertiary.warning { color: var(--Warning-Warning-500, #f1b44c); }\n.btn.tertiary.warning:hover { background: var(--Warning-Warning-50, #fef8ed); }\n\n.btn.tertiary.dropdown {\n color: var(--Gray-Gray-500, #69738c);\n font-weight: var(--font-weight-regular);\n font-size: var(--font-size-s);\n background: transparent;\n}\n\n/* Disabled tertiary */\n.btn.tertiary.disabled.default,\n.btn.tertiary.disabled.legacy {\n border: 1px solid var(--Gray-Gray-200, #c3c9d9);\n color: var(--Gray-Gray-400, #858ea6);\n}\n.btn.tertiary.disabled.success { color: var(--Success-Success-300, #5bd1af); }\n.btn.tertiary.disabled.info { color: var(--Info-Info-300, #8ac3f6); }\n.btn.tertiary.disabled.error { color: var(--Error-Error-300, #f89b9c); }\n.btn.tertiary.disabled.warning { color: var(--Warning-Warning-300, #f6cd87); }\n\n/* ── Loading spinner ─────────────────────────────────────────── */\n.spin {\n animation: spin 1s linear infinite;\n}\n\n@keyframes spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n}\n","import { Component, Prop, Event, EventEmitter, h } from '@stencil/core';\n\nexport type ButtonType = 'legacy' | 'default' | 'success' | 'info' | 'error' | 'warning' | 'dropdown' | 'default-light';\nexport type ButtonSeverity = 'primary' | 'secondary' | 'tertiary';\nexport type ButtonSize = 'large' | 'normal' | 'small';\nexport type ButtonState = 'default' | 'disabled' | 'loading';\n\n/**\n * @component dropi-button\n * Primary action button with multiple types, severities, sizes and states.\n * Supports pre/post icons and a loading spinner.\n */\n@Component({\n tag: 'dropi-button',\n styleUrl: 'dropi-button.css',\n shadow: true,\n})\nexport class DropiButton {\n /** Visual color palette */\n @Prop() type: ButtonType = 'default';\n /** Primary (filled) | Secondary (outlined) | Tertiary (ghost) */\n @Prop() severity: ButtonSeverity = 'primary';\n /** Button size */\n @Prop() size: ButtonSize = 'normal';\n /** Button state */\n @Prop() state: ButtonState = 'default';\n /** Full width button */\n @Prop({ reflect: true }) fullWidth: boolean = false;\n /** Icon name to show before the text */\n @Prop() preIcon: string = '';\n /** Icon name to show after the text */\n @Prop() postIcon: string = '';\n /** Custom icon color override */\n @Prop() customIconColor: string = '';\n /** Button label */\n @Prop() text: string = '';\n\n /** Emitted on click (not emitted when disabled or loading) */\n @Event() onClick: EventEmitter<MouseEvent>;\n\n private readonly colorMap: Record<string, string> = {\n default: 'Primary-Primary-',\n success: 'Success-Success-',\n error: 'Error-Error-',\n info: 'Info-Info-',\n legacy: 'Secondary-Secondary-',\n warning: 'Warning-Warning-',\n dropdown: 'Gray-Gray-',\n 'default-light': 'Gray-Gray-',\n };\n\n private get iconSize(): string {\n if (this.size === 'large') return '24px';\n if (this.size === 'small') return '16px';\n return '18px';\n }\n\n private get color(): string {\n const intensity = this.state === 'disabled' ? '300' : '500';\n return (this.colorMap[this.type] ?? 'Primary-Primary-') + intensity;\n }\n\n private get fontColor(): string {\n if (this.severity === 'tertiary') {\n return this.type === 'default' || this.type === 'legacy' ? 'Gray-Gray-500' : this.color;\n }\n if (this.severity === 'secondary') return this.color;\n return 'Neutral-White';\n }\n\n private handleClick(e: MouseEvent) {\n if (this.state !== 'disabled' && this.state !== 'loading') {\n this.onClick.emit(e);\n }\n }\n\n private renderLoadingSpinner() {\n return (\n <svg\n class=\"spin\"\n width={this.iconSize}\n height={this.iconSize}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M22.8 12C23.4627 12 24.0062 11.4614 23.9401 10.802C23.8232 9.6371 23.5362 8.49339 23.0866 7.4078C22.4835 5.95189 21.5996 4.62902 20.4853 3.51472C19.371 2.40042 18.0481 1.5165 16.5922 0.913445C15.5066 0.463778 14.3629 0.17683 13.198 0.0599502C12.5386 -0.00621439 12 0.537258 12 1.2C12 1.86274 12.5393 2.39227 13.1969 2.4749C14.0463 2.58164 14.8795 2.80176 15.6738 3.13076C16.8385 3.6132 17.8968 4.32033 18.7882 5.21177C19.6797 6.10322 20.3868 7.16151 20.8692 8.32624C21.1982 9.12051 21.4184 9.95367 21.5251 10.8031C21.6077 11.4607 22.1373 12 22.8 12Z\"\n fill={`var(--${this.fontColor})`}\n />\n </svg>\n );\n }\n\n render() {\n const isDisabled = this.state === 'disabled' || this.state === 'loading';\n const hasText = this.text !== '';\n const showPostIcon = this.postIcon !== '' || this.type === 'dropdown';\n const dropdownIcon = this.type === 'dropdown' ? 'Dropdown-down' : this.postIcon;\n\n return (\n <button\n class={{\n btn: true,\n 'without-text': !hasText,\n [this.severity ?? 'primary']: true,\n [this.type ?? 'default']: true,\n [this.size ?? 'normal']: true,\n [this.state ?? 'default']: true,\n 'full-width': this.fullWidth,\n }}\n disabled={isDisabled}\n onClick={(e) => this.handleClick(e)}\n >\n {this.preIcon && (\n <dropi-icon\n name={this.preIcon}\n width={this.iconSize}\n height={this.iconSize}\n color={this.fontColor}\n />\n )}\n {hasText && <span class=\"text\">{this.text}</span>}\n {showPostIcon && (\n <dropi-icon\n name={dropdownIcon}\n width={this.iconSize}\n height={this.iconSize}\n color={this.fontColor}\n />\n )}\n {this.state === 'loading' && this.renderLoadingSpinner()}\n <slot />\n </button>\n );\n }\n}\n"],"version":3}
package/hydrate/index.js CHANGED
@@ -6075,15 +6075,15 @@ class DropiButton {
6075
6075
  const hasText = this.text !== '';
6076
6076
  const showPostIcon = this.postIcon !== '' || this.type === 'dropdown';
6077
6077
  const dropdownIcon = this.type === 'dropdown' ? 'Dropdown-down' : this.postIcon;
6078
- return (hAsync("button", { key: 'd21aeb2274c317795bb0daad6d30c2bc9f3ede9f', class: {
6078
+ return (hAsync("button", { key: '878f01cf2b73d67ad393c46c47dbf71d4589573b', class: {
6079
6079
  btn: true,
6080
6080
  'without-text': !hasText,
6081
- [this.severity]: true,
6082
- [this.type]: true,
6083
- [this.size]: true,
6084
- [this.state]: true,
6081
+ [this.severity ?? 'primary']: true,
6082
+ [this.type ?? 'default']: true,
6083
+ [this.size ?? 'normal']: true,
6084
+ [this.state ?? 'default']: true,
6085
6085
  'full-width': this.fullWidth,
6086
- }, disabled: isDisabled, onClick: (e) => this.handleClick(e) }, this.preIcon && (hAsync("dropi-icon", { key: '6711ece5a9c871db989e6bc4572c0d0ebfa7f899', name: this.preIcon, width: this.iconSize, height: this.iconSize, color: this.fontColor })), hasText && hAsync("span", { key: '9fc49de08b5672c6e2dae9b3cea9587d451fac0d', class: "text" }, this.text), showPostIcon && (hAsync("dropi-icon", { key: '1ce254e23b16fb7013469fb3e2d71fe70dba5a9d', name: dropdownIcon, width: this.iconSize, height: this.iconSize, color: this.fontColor })), this.state === 'loading' && this.renderLoadingSpinner(), hAsync("slot", { key: '72857295b27aa6ef6981276d68497f33958a584c' })));
6086
+ }, disabled: isDisabled, onClick: (e) => this.handleClick(e) }, this.preIcon && (hAsync("dropi-icon", { key: 'd42a3e52d105b985c9cbc72241e363baaaad25a8', name: this.preIcon, width: this.iconSize, height: this.iconSize, color: this.fontColor })), hasText && hAsync("span", { key: 'e88b6ef2c3cf63aec13f1fa4bfe289333acdd8b9', class: "text" }, this.text), showPostIcon && (hAsync("dropi-icon", { key: '596a8227042757ffe942290a1e776b981bb89136', name: dropdownIcon, width: this.iconSize, height: this.iconSize, color: this.fontColor })), this.state === 'loading' && this.renderLoadingSpinner(), hAsync("slot", { key: 'e46a00e52792e690b3b4cb24e6af1b1843f7384f' })));
6087
6087
  }
6088
6088
  static get style() { return dropiButtonCss(); }
6089
6089
  static get cmpMeta() { return {
package/hydrate/index.mjs CHANGED
@@ -6073,15 +6073,15 @@ class DropiButton {
6073
6073
  const hasText = this.text !== '';
6074
6074
  const showPostIcon = this.postIcon !== '' || this.type === 'dropdown';
6075
6075
  const dropdownIcon = this.type === 'dropdown' ? 'Dropdown-down' : this.postIcon;
6076
- return (hAsync("button", { key: 'd21aeb2274c317795bb0daad6d30c2bc9f3ede9f', class: {
6076
+ return (hAsync("button", { key: '878f01cf2b73d67ad393c46c47dbf71d4589573b', class: {
6077
6077
  btn: true,
6078
6078
  'without-text': !hasText,
6079
- [this.severity]: true,
6080
- [this.type]: true,
6081
- [this.size]: true,
6082
- [this.state]: true,
6079
+ [this.severity ?? 'primary']: true,
6080
+ [this.type ?? 'default']: true,
6081
+ [this.size ?? 'normal']: true,
6082
+ [this.state ?? 'default']: true,
6083
6083
  'full-width': this.fullWidth,
6084
- }, disabled: isDisabled, onClick: (e) => this.handleClick(e) }, this.preIcon && (hAsync("dropi-icon", { key: '6711ece5a9c871db989e6bc4572c0d0ebfa7f899', name: this.preIcon, width: this.iconSize, height: this.iconSize, color: this.fontColor })), hasText && hAsync("span", { key: '9fc49de08b5672c6e2dae9b3cea9587d451fac0d', class: "text" }, this.text), showPostIcon && (hAsync("dropi-icon", { key: '1ce254e23b16fb7013469fb3e2d71fe70dba5a9d', name: dropdownIcon, width: this.iconSize, height: this.iconSize, color: this.fontColor })), this.state === 'loading' && this.renderLoadingSpinner(), hAsync("slot", { key: '72857295b27aa6ef6981276d68497f33958a584c' })));
6084
+ }, disabled: isDisabled, onClick: (e) => this.handleClick(e) }, this.preIcon && (hAsync("dropi-icon", { key: 'd42a3e52d105b985c9cbc72241e363baaaad25a8', name: this.preIcon, width: this.iconSize, height: this.iconSize, color: this.fontColor })), hasText && hAsync("span", { key: 'e88b6ef2c3cf63aec13f1fa4bfe289333acdd8b9', class: "text" }, this.text), showPostIcon && (hAsync("dropi-icon", { key: '596a8227042757ffe942290a1e776b981bb89136', name: dropdownIcon, width: this.iconSize, height: this.iconSize, color: this.fontColor })), this.state === 'loading' && this.renderLoadingSpinner(), hAsync("slot", { key: 'e46a00e52792e690b3b4cb24e6af1b1843f7384f' })));
6085
6085
  }
6086
6086
  static get style() { return dropiButtonCss(); }
6087
6087
  static get cmpMeta() { return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dropi/ui",
3
- "version": "0.1.23",
3
+ "version": "0.1.25",
4
4
  "description": "Dropi Design System — Web Components for Angular, React and Vue",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.js",
package/readme.md CHANGED
@@ -3,8 +3,8 @@
3
3
  Librería de Web Components del Design System de Dropi, construida con **Stencil.js v4**.
4
4
  Genera componentes reutilizables para Angular, React y Vue desde una única base de código.
5
5
 
6
- - **Paquete npm:** `@dropi/ui` (v0.1.17)
7
- - **React wrappers:** `@dropi/ui-react`
6
+ - **Paquete npm:** `@dropi/ui` (v0.1.24)
7
+ - **React wrappers:** `@dropi/ui-react` (v0.1.9)
8
8
 
9
9
  ---
10
10
 
@@ -13,7 +13,7 @@ Genera componentes reutilizables para Angular, React y Vue desde una única base
13
13
  Ejecuta este comando en la raíz de tu proyecto:
14
14
 
15
15
  ```bash
16
- npx @dropi/create-dropi-ui
16
+ npx @dropi/ui setup
17
17
  ```
18
18
 
19
19
  Detecta tu framework (Angular, React, Next.js), instala las dependencias correctas e inyecta la configuración automáticamente.
@@ -29,7 +29,7 @@ Si prefieres realizar la configuración paso a paso, consulta la [Guía de Integ
29
29
  |---|---|
30
30
  | Angular | `npm install @dropi/ui @dropi/ui-angular` |
31
31
  | React | `npm install @dropi/ui @dropi/ui-react` |
32
- | Next.js SSR | `npm install @dropi/ui @dropi/ui-react && npm install --save-dev @stencil/ssr` |
32
+ | Next.js SSR | `npm install @dropi/ui @dropi/ui-react && npm install --save-dev @stencil/ssr --legacy-peer-deps` |
33
33
 
34
34
  ### 2. Estilos e Iconos
35
35
  - **CSS**: Importar `@dropi/ui/dist/dropi-ui/dropi-ui.css`.
@@ -41,8 +41,6 @@ Si prefieres realizar la configuración paso a paso, consulta la [Guía de Integ
41
41
 
42
42
  ---
43
43
 
44
- ---
45
-
46
44
  ## 🚀 Soporte para Next.js (SSR / Zero Flash)
47
45
 
48
46
  Para habilitar el **Server Side Rendering (SSR)** y eliminar cualquier parpadeo visual, sigue estos pasos:
@@ -54,6 +52,10 @@ Envuelve tu configuración en el plugin `withStencil`:
54
52
  // next.config.ts
55
53
  import withStencil from "@stencil/ssr/next";
56
54
 
55
+ const nextConfig = {
56
+ transpilePackages: ["@dropi/ui-react", "@dropi/ui"],
57
+ };
58
+
57
59
  export default withStencil({
58
60
  from: "@dropi/ui-react",
59
61
  module: import("@dropi/ui-react/next"),
@@ -61,16 +63,29 @@ export default withStencil({
61
63
  })(nextConfig);
62
64
  ```
63
65
 
64
- ### 2. Configuración del Layout (Crítico)
66
+ ### 2. Scripts en package.json (Next.js 16)
67
+ Next.js 16 usa Turbopack por defecto, que es incompatible con `@stencil/ssr`. Agrega `--webpack`:
68
+
69
+ ```json
70
+ "dev": "next dev --webpack",
71
+ "build": "next build --webpack"
72
+ ```
73
+
74
+ ### 3. Configuración del Layout (Crítico)
65
75
  Añade `suppressHydrationWarning` al `<body>` en `layout.tsx` para evitar que el DevTools o extensiones rompan la hidratación.
66
76
 
67
77
  ```tsx
68
78
  <body suppressHydrationWarning>{children}</body>
69
79
  ```
70
80
 
71
- ### 3. Uso de Alias para Props Dinámicas
72
- En componentes con `"use client"` y props dinámicas, usa un alias en el import para evitar flashes:
73
- `import { DropiButton as Btn } from "@dropi/ui-react/next"`
81
+ ### 4. Importar desde `/next` en Server Components
82
+ En páginas o layouts (Server Components), importa desde `@dropi/ui-react/next`:
83
+
84
+ ```tsx
85
+ import { DropiButton, DropiInput } from "@dropi/ui-react/next";
86
+ ```
87
+
88
+ En componentes con `"use client"`, importa desde `@dropi/ui-react` normalmente.
74
89
 
75
90
  ---
76
91
 
@@ -84,7 +99,7 @@ Hay **dos formas válidas**, ambas funcionan:
84
99
  label="País"
85
100
  placeholder="Seleccionar"
86
101
  options={options}
87
- onDropiChange={(e) => setSelected(e.detail)}
102
+ onOnChangeSelect={(e) => setSelected(e.detail)}
88
103
  />
89
104
  ```
90
105
 
@@ -114,12 +129,14 @@ Todos los eventos son `CustomEvent`. El valor emitido **siempre viene en `e.deta
114
129
 
115
130
  ```typescript
116
131
  // ❌ Incorrecto — e es el CustomEvent completo, no el valor
117
- onDropiChange={(e) => console.log(e)}
132
+ onOnInput={(e) => console.log(e)}
118
133
 
119
134
  // ✅ Correcto — e.detail tiene el valor real
120
- onDropiChange={(e) => console.log(e.detail)}
135
+ onOnInput={(e) => console.log(e.detail)}
121
136
  ```
122
137
 
138
+ > **Nombres de eventos en React:** Los wrappers React siguen el patrón `on<EventName>`. Si el evento Stencil empieza con `on` (ej. `onClick`), el wrapper lo duplica: `onOnClick`. Si empieza con `dropi` (ej. `dropiChange`), queda `onDropiChange`.
139
+
123
140
  ---
124
141
 
125
142
  ## Uso en React (Métodos Imperativos)
@@ -161,9 +178,9 @@ Botón de acción principal con múltiples variantes de tipo, apariencia, tamañ
161
178
 
162
179
  **Eventos**
163
180
 
164
- | Evento | `e.detail` | Cuándo |
181
+ | Evento React | `e.detail` | Cuándo |
165
182
  |---|---|---|
166
- | `dropiClick` | `MouseEvent` | Al hacer click (no se emite si `state` es `disabled` o `loading`) |
183
+ | `onOnClick` | `MouseEvent` | Al hacer click (no se emite si `state` es `disabled` o `loading`) |
167
184
 
168
185
  **Ejemplo React**
169
186
  ```tsx
@@ -171,13 +188,13 @@ Botón de acción principal con múltiples variantes de tipo, apariencia, tamañ
171
188
  text="Guardar"
172
189
  severity="primary"
173
190
  size="normal"
174
- onDropiClick={(e) => console.log(e.detail)}
191
+ onOnClick={(e) => console.log(e.detail)}
175
192
  />
176
193
  ```
177
194
 
178
195
  **Ejemplo Angular**
179
196
  ```html
180
- <dropi-button text="Guardar" severity="primary" (dropiClick)="onSave($event)"></dropi-button>
197
+ <dropi-button text="Guardar" severity="primary" (onClick)="onSave($event)"></dropi-button>
181
198
  ```
182
199
 
183
200
  ---
@@ -195,9 +212,9 @@ Checkbox estilizado con soporte para formularios nativos.
195
212
 
196
213
  **Eventos**
197
214
 
198
- | Evento | `e.detail` | Cuándo |
215
+ | Evento React | `e.detail` | Cuándo |
199
216
  |---|---|---|
200
- | `dropiChange` | `boolean` | Al cambiar el estado (`true` = marcado, `false` = desmarcado) |
217
+ | `onOnChange` | `boolean` | Al cambiar el estado (`true` = marcado, `false` = desmarcado) |
201
218
 
202
219
  > `e.detail` es el boolean directamente. Si ves "el objeto completo" es porque estás leyendo `e` en vez de `e.detail`.
203
220
 
@@ -207,13 +224,13 @@ const [checked, setChecked] = useState(false)
207
224
 
208
225
  <DropiCheckbox
209
226
  checked={checked}
210
- onDropiChange={(e) => setChecked(e.detail)}
227
+ onOnChange={(e) => setChecked(e.detail)}
211
228
  />
212
229
  ```
213
230
 
214
231
  **Ejemplo Angular**
215
232
  ```html
216
- <dropi-checkbox [checked]="checked" (dropiChange)="checked = $event.detail"></dropi-checkbox>
233
+ <dropi-checkbox [checked]="checked" (onChange)="checked = $event.detail"></dropi-checkbox>
217
234
  ```
218
235
 
219
236
  ---
@@ -231,15 +248,15 @@ Toggle switch on/off.
231
248
 
232
249
  **Eventos**
233
250
 
234
- | Evento | `e.detail` | Cuándo |
251
+ | Evento React | `e.detail` | Cuándo |
235
252
  |---|---|---|
236
- | `dropiChange` | `boolean` | Al togglear (`true` = encendido, `false` = apagado) |
253
+ | `onOnChange` | `boolean` | Al togglear (`true` = encendido, `false` = apagado) |
237
254
 
238
255
  **Ejemplo React**
239
256
  ```tsx
240
257
  const [on, setOn] = useState(false)
241
258
 
242
- <DropiSwitch isChecked={on} onDropiChange={(e) => setOn(e.detail)} />
259
+ <DropiSwitch isChecked={on} onOnChange={(e) => setOn(e.detail)} />
243
260
  ```
244
261
 
245
262
  ---
@@ -277,12 +294,12 @@ Campo de texto con label flotante, validación, ícono, toggle de contraseña, f
277
294
 
278
295
  **Eventos**
279
296
 
280
- | Evento | `e.detail` | Cuándo |
297
+ | Evento React | `e.detail` | Cuándo |
281
298
  |---|---|---|
282
- | `dropiInput` | `string` | En cada tecla (keystroke) |
283
- | `dropiChange` | `string` | Al perder el foco (blur) |
284
- | `dropiFocus` | `void` | Al enfocar el campo |
285
- | `dropiBlur` | `void` | Al desenfocar el campo |
299
+ | `onOnInput` | `string` | En cada tecla (keystroke) |
300
+ | `onOnChange` | `string` | Al perder el foco (blur) |
301
+ | `onOnFocus` | `void` | Al enfocar el campo |
302
+ | `onOnBlur` | `void` | Al desenfocar el campo |
286
303
 
287
304
  **Ejemplo React**
288
305
  ```tsx
@@ -291,8 +308,8 @@ const [value, setValue] = useState('')
291
308
  <DropiInput
292
309
  label="Nombre"
293
310
  value={value}
294
- onDropiInput={(e) => setValue(e.detail)}
295
- onDropiChange={(e) => console.log('blur:', e.detail)}
311
+ onOnInput={(e) => setValue(e.detail)}
312
+ onOnChange={(e) => console.log('blur:', e.detail)}
296
313
  required
297
314
  invalid={value.length < 3}
298
315
  helperText="Mínimo 3 caracteres"
@@ -326,12 +343,12 @@ const [value, setValue] = useState('')
326
343
 
327
344
  **Eventos**
328
345
 
329
- | Evento | `e.detail` | Cuándo |
346
+ | Evento React | `e.detail` | Cuándo |
330
347
  |---|---|---|
331
- | `dropiInput` | `string` | En cada tecla (keystroke) |
332
- | `dropiChange` | `string` | Al perder el foco (blur) |
333
- | `dropiFocus` | `void` | Al enfocar el campo |
334
- | `dropiBlur` | `void` | Al desenfocar el campo |
348
+ | `onDropiInput` | `string` | En cada tecla (keystroke) |
349
+ | `onDropiChange` | `string` | Al perder el foco (blur) |
350
+ | `onDropiFocus` | `void` | Al enfocar el campo |
351
+ | `onDropiBlur` | `void` | Al desenfocar el campo |
335
352
 
336
353
  **Ejemplo React**
337
354
  ```tsx
@@ -407,13 +424,13 @@ interface SelectOptionGroup {
407
424
 
408
425
  **Eventos**
409
426
 
410
- | Evento | `e.detail` | Cuándo |
427
+ | Evento React | `e.detail` | Cuándo |
411
428
  |---|---|---|
412
- | `dropiChange` | `SelectOption` (single) o `SelectOption[]` (multi) | Al seleccionar una opción |
413
- | `dropiClear` | `void` | Al limpiar la selección |
414
- | `dropiSearch` | `string` | Al escribir en el buscador |
415
- | `dropiScrollEnd` | `void` | Al llegar al final del scroll (paginación) |
416
- | `dropiKeyEnter` | `KeyboardEvent` | Al presionar Enter en el buscador |
429
+ | `onOnChangeSelect` | `SelectOption` (single) o `SelectOption[]` (multi) | Al seleccionar una opción |
430
+ | `onOnClear` | `void` | Al limpiar la selección |
431
+ | `onOnSearch` | `string` | Al escribir en el buscador |
432
+ | `onScrolledToEnd` | `void` | Al llegar al final del scroll (paginación) |
433
+ | `onOnKeyEnter` | `KeyboardEvent` | Al presionar Enter en el buscador |
417
434
 
418
435
  **Ejemplo React**
419
436
  ```tsx
@@ -428,7 +445,7 @@ const options = [
428
445
  label="País"
429
446
  options={options}
430
447
  searchEnabled
431
- onDropiChange={(e) => setSelected(e.detail)}
448
+ onOnChangeSelect={(e) => setSelected(e.detail)}
432
449
  />
433
450
  ```
434
451
 
@@ -450,9 +467,9 @@ Radio button estilizado con label y soporte para grupos.
450
467
 
451
468
  **Eventos**
452
469
 
453
- | Evento | `e.detail` | Cuándo |
470
+ | Evento React | `e.detail` | Cuándo |
454
471
  |---|---|---|
455
- | `dropiChange` | `Event` (evento nativo) | Al seleccionar el radio |
472
+ | `onOnChange` | `Event` (evento nativo) | Al seleccionar el radio |
456
473
 
457
474
  > A diferencia del checkbox, emite el `Event` nativo. Para controlar el estado, maneja la prop `checked` desde el padre.
458
475
 
@@ -460,8 +477,8 @@ Radio button estilizado con label y soporte para grupos.
460
477
  ```tsx
461
478
  const [selected, setSelected] = useState('a')
462
479
 
463
- <DropiRadioButton label="Opción A" name="grupo" inputId="opt-a" checked={selected === 'a'} onDropiChange={() => setSelected('a')} />
464
- <DropiRadioButton label="Opción B" name="grupo" inputId="opt-b" checked={selected === 'b'} onDropiChange={() => setSelected('b')} />
480
+ <DropiRadioButton label="Opción A" name="grupo" inputId="opt-a" checked={selected === 'a'} onOnChange={() => setSelected('a')} />
481
+ <DropiRadioButton label="Opción B" name="grupo" inputId="opt-b" checked={selected === 'b'} onOnChange={() => setSelected('b')} />
465
482
  ```
466
483
 
467
484
  ---
@@ -549,11 +566,17 @@ Sistema de pestañas con contadores y estados.
549
566
  | `tabs` | `TabItem[]` | `[]` | Lista de tabs `{ id, label, counter, active, disabled, completed }` |
550
567
  | `showIcon` | `boolean` | `false` | Mostrar check si `completed` |
551
568
 
569
+ **Eventos**
570
+
571
+ | Evento React | `e.detail` | Cuándo |
572
+ |---|---|---|
573
+ | `onOnIndexChanged` | `TabItem` | Al cambiar de tab |
574
+
552
575
  **Ejemplo React**
553
576
  ```tsx
554
577
  <DropiTabs
555
578
  tabs={[{ id: 1, label: 'Activos', counter: 5 }]}
556
- onDropiTabChange={(e) => console.log(e.detail)}
579
+ onOnIndexChanged={(e) => console.log(e.detail)}
557
580
  />
558
581
  ```
559
582
 
@@ -606,11 +629,17 @@ Control de paginación.
606
629
  | `rows` | `number` | `10` | Registros por página |
607
630
  | `showPageSizeSelector` | `boolean` | `false` | Selector de cantidad por página |
608
631
 
632
+ **Eventos**
633
+
634
+ | Evento React | `e.detail` | Cuándo |
635
+ |---|---|---|
636
+ | `onPageChange` | `number` | Al cambiar de página |
637
+
609
638
  **Ejemplo React**
610
639
  ```tsx
611
640
  <DropiPaginator
612
641
  total={100}
613
- onDropiPageChange={(e) => console.log(e.detail.page)}
642
+ onPageChange={(e) => console.log(e.detail)}
614
643
  />
615
644
  ```
616
645
 
@@ -629,6 +658,12 @@ Pantalla de "no hay datos".
629
658
  | `actionLabel` | `string` | `''` | Texto botón principal |
630
659
  | `secondaryLabel` | `string` | `''` | Texto botón secundario |
631
660
 
661
+ **Eventos**
662
+
663
+ | Evento React | `e.detail` | Cuándo |
664
+ |---|---|---|
665
+ | `onButtonClickEvent` | `void` | Al hacer click en el botón principal |
666
+
632
667
  ---
633
668
 
634
669
  ### `<dropi-tooltip>` (V2)
@@ -669,12 +704,14 @@ Tabla de datos con paginación local/backend, ordenación, búsqueda y checkbox
669
704
 
670
705
  **Eventos**
671
706
 
672
- | Evento | `e.detail` | Cuándo |
707
+ | Evento React | `e.detail` | Cuándo |
673
708
  |---|---|---|
674
- | `rowsSelected` | `DropiTableRow[]` | Checkbox cambia selección |
675
- | `onSortChange` | `{ column, asc }` | Click en columna ordenable |
676
- | `onPageChange` | `number` | Cambio de página (backend) |
677
- | `actionClicked` | `{ row, action }` | Click en acción de fila |
709
+ | `onDropiSelection` | `number[]` | Checkbox cambia selección |
710
+ | `onDropiSort` | `{ key: string; dir: SortDir }` | Click en columna ordenable |
711
+ | `onDropiPageChange` | `number` | Cambio de página (backend) |
712
+ | `onDropiAction` | `{ row: TableRow; action: any }` | Click en acción de fila |
713
+ | `onDropiRowClick` | `{ row: TableRow; index: number }` | Click en una fila |
714
+ | `onDropiSearch` | `string` | Al buscar |
678
715
 
679
716
  **Ejemplo Angular**
680
717
  ```html
@@ -683,8 +720,8 @@ Tabla de datos con paginación local/backend, ordenación, búsqueda y checkbox
683
720
  [data]="data"
684
721
  [dropiTableConfiguration]="{ backendPagination: false, showPaginator: true, pageSizeConfiguration: [5, 10, 25] }"
685
722
  [loading]="loading"
686
- (onSortChange)="onSort($event)"
687
- (rowsSelected)="onSelect($event)"
723
+ (dropiSort)="onSort($event)"
724
+ (dropiSelection)="onSelect($event)"
688
725
  />
689
726
  ```
690
727
 
@@ -702,19 +739,36 @@ Ventana de diálogo con overlays.
702
739
  | `size` | `'s' \| 'm' \| 'l' \| 'full' ...` | `'m'` | Tamaño |
703
740
  | `visible` | `boolean` | `false` | Controlar visibilidad vía prop |
704
741
 
742
+ **Eventos**
743
+
744
+ | Evento React | `e.detail` | Cuándo |
745
+ |---|---|---|
746
+ | `onOnShow` | `void` | Al abrir el modal |
747
+ | `onOnHide` | `void` | Al cerrar el modal |
748
+ | `onVisibleChange` | `boolean` | Al cambiar `visible` |
749
+
705
750
  **Ejemplo React (Imperativo)**
706
751
  ```tsx
707
752
  const modalRef = useRef<any>(null);
708
753
  const Modal = DropiModal as any;
709
754
 
710
- <Modal ref={modalRef} header="Mi Modal">
755
+ <Modal ref={modalRef} header="Mi Modal" onOnHide={() => console.log('cerrado')}>
711
756
  <p>Contenido</p>
712
757
  <div slot="footer">
713
- <DropiButton text="Cerrar" onDropiClick={() => modalRef.current.hide()} />
758
+ <DropiButton text="Cerrar" onOnClick={() => modalRef.current.hide()} />
714
759
  </div>
715
760
  </Modal>
716
761
  ```
717
762
 
763
+ **Ejemplo React (Declarativo con `visible`)**
764
+ ```tsx
765
+ const [open, setOpen] = useState(false);
766
+
767
+ <DropiModal visible={open} header="Confirmar" onOnHide={() => setOpen(false)}>
768
+ <p>¿Estás seguro?</p>
769
+ </DropiModal>
770
+ ```
771
+
718
772
  ---
719
773
 
720
774
  ### `<dropi-toast>`