@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.
- package/dist/dropi-ui/dropi-button.entry.js +6 -6
- package/dist/dropi-ui/dropi-button.entry.js.map +1 -1
- package/hydrate/index.js +6 -6
- package/hydrate/index.mjs +6 -6
- package/package.json +1 -1
- package/readme.md +112 -58
|
@@ -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: '
|
|
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: '
|
|
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":"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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 ?? '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: '
|
|
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: '
|
|
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: '
|
|
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: '
|
|
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
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.
|
|
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/
|
|
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.
|
|
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
|
-
###
|
|
72
|
-
En
|
|
73
|
-
|
|
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
|
-
|
|
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
|
-
|
|
132
|
+
onOnInput={(e) => console.log(e)}
|
|
118
133
|
|
|
119
134
|
// ✅ Correcto — e.detail tiene el valor real
|
|
120
|
-
|
|
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
|
-
| `
|
|
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
|
-
|
|
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" (
|
|
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
|
-
| `
|
|
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
|
-
|
|
227
|
+
onOnChange={(e) => setChecked(e.detail)}
|
|
211
228
|
/>
|
|
212
229
|
```
|
|
213
230
|
|
|
214
231
|
**Ejemplo Angular**
|
|
215
232
|
```html
|
|
216
|
-
<dropi-checkbox [checked]="checked" (
|
|
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
|
-
| `
|
|
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}
|
|
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
|
-
| `
|
|
283
|
-
| `
|
|
284
|
-
| `
|
|
285
|
-
| `
|
|
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
|
-
|
|
295
|
-
|
|
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
|
-
| `
|
|
332
|
-
| `
|
|
333
|
-
| `
|
|
334
|
-
| `
|
|
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
|
-
| `
|
|
413
|
-
| `
|
|
414
|
-
| `
|
|
415
|
-
| `
|
|
416
|
-
| `
|
|
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
|
-
|
|
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
|
-
| `
|
|
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'}
|
|
464
|
-
<DropiRadioButton label="Opción B" name="grupo" inputId="opt-b" checked={selected === '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
|
-
|
|
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
|
-
|
|
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
|
-
| `
|
|
675
|
-
| `
|
|
676
|
-
| `
|
|
677
|
-
| `
|
|
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
|
-
(
|
|
687
|
-
(
|
|
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"
|
|
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>`
|