@erplora/outfitkit 0.1.18 → 0.1.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/components/ok-hero/ok-hero.d.ts +11 -0
- package/dist/components/ok-hero/ok-hero.test.d.ts +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +8 -1
- package/dist/ok-hero.js +204 -12
- package/dist/outfitkit.bundle.js +1474 -1300
- package/dist/tabbar/tabbar.d.ts +69 -0
- package/dist/tabbar/tabbar.test.d.ts +1 -0
- package/dist/tabbar.css +72 -0
- package/dist/tabbar.js +76 -0
- package/package.json +6 -1
package/README.md
CHANGED
|
@@ -89,7 +89,7 @@ El bundle `outfitkit.js` deja `lit` external, así que necesitas un **import-map
|
|
|
89
89
|
|
|
90
90
|
## Inventario de componentes
|
|
91
91
|
|
|
92
|
-
|
|
92
|
+
97 web components rellena-huecos (todos registran su tag `ok-*` vía `define()`). Abajo el qué-hace y
|
|
93
93
|
los **eventos `ok-*`** que emite cada uno (`—` = presentacional, sin eventos). La **referencia viva
|
|
94
94
|
de props/slots** es el [showcase](https://erplora.github.io/outfitkit/).
|
|
95
95
|
|
|
@@ -167,6 +167,7 @@ de props/slots** es el [showcase](https://erplora.github.io/outfitkit/).
|
|
|
167
167
|
| `ok-time-picker` | Pastilla HH:MM + popover de listas (horas/minutos/AM-PM), canónico 24h. | `ok-change` |
|
|
168
168
|
| `ok-range-dual` | Slider min-max de doble thumb con readout. | `ok-change` |
|
|
169
169
|
| `ok-color-picker` | Selector de color (SV + hue + hex + presets). | `ok-change`, `ok-open` |
|
|
170
|
+
| `ok-theme-picker` | Selector de tema compartido Cloud↔Hub: paleta de marca (swatches) + modo claro/oscuro/sistema. | `ok-change` |
|
|
170
171
|
| `ok-rich-text` | Editor WYSIWYG con toolbar y contador de palabras. | `ok-input` |
|
|
171
172
|
| `ok-signature` | Pad de firma sobre canvas con limpiar/exportar. | `ok-change`, `ok-clear` |
|
|
172
173
|
| `ok-calculator` | Calculadora con teclado 4×4 y máquina de estados. | `ok-input`, `ok-change` |
|
|
@@ -182,6 +183,7 @@ de props/slots** es el [showcase](https://erplora.github.io/outfitkit/).
|
|
|
182
183
|
| `ok-menu` | Menú desplegable/contextual con submenús, checkbox/radio, divisores. | `ok-select`, `ok-open` |
|
|
183
184
|
| `ok-menubar` | Barra de menús de app (Archivo/Editar/Ver) con dropdowns. | `ok-select`, `ok-open` |
|
|
184
185
|
| `ok-drawer` | Panel lateral deslizante (slide-over) modal con focus-trap y cierre por ESC/scrim. | `ok-open`, `ok-close` |
|
|
186
|
+
| `ok-spotlight-search` | Buscador overlay estilo Spotlight (macOS): `<dialog>` top-layer translúcido, chrome solo (input+✕+panel); resultados los pone el consumidor por slot. | `ok-input`, `ok-open` |
|
|
185
187
|
|
|
186
188
|
### Media y archivos
|
|
187
189
|
|
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
import { LitElement } from 'lit';
|
|
2
|
+
export type OkHeroAlign = 'center' | 'split';
|
|
3
|
+
export type OkHeroTone = 'neutral' | 'soft' | 'gradient';
|
|
2
4
|
export declare class OkHero extends LitElement {
|
|
5
|
+
align: OkHeroAlign;
|
|
6
|
+
tone: OkHeroTone;
|
|
7
|
+
compact: boolean;
|
|
8
|
+
private hasEyebrow;
|
|
9
|
+
private hasActions;
|
|
10
|
+
private hasMedia;
|
|
3
11
|
static styles: import("lit").CSSResult;
|
|
12
|
+
connectedCallback(): void;
|
|
13
|
+
private refreshSlotState;
|
|
14
|
+
private onSlotChange;
|
|
4
15
|
render(): unknown;
|
|
5
16
|
}
|
|
6
17
|
declare global {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import './ok-hero.js';
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,8 @@ export { createStore, store } from './store/store.js';
|
|
|
2
2
|
export type { Store, StoreOptions, StoreSubscriber } from './store/store.js';
|
|
3
3
|
export { StoreController } from './store/controller.js';
|
|
4
4
|
export { OkStore } from './components/ok-store/ok-store.js';
|
|
5
|
+
export { bindTabbar, tabbarOverflow, syncTabbarOverflow, scrollActiveTabIntoView, shouldHintScroll, hintScroll } from './tabbar/tabbar.js';
|
|
6
|
+
export type { TabbarOverflow } from './tabbar/tabbar.js';
|
|
5
7
|
export { OkDataTable } from './components/ok-data-table/ok-data-table.js';
|
|
6
8
|
export type { DataTableColumn, DataTableAction, DataTableView, DataTablePrimaryAction, DataTableRowKey, } from './components/ok-data-table/ok-data-table.js';
|
|
7
9
|
export { OkMail } from './components/ok-mail/ok-mail.js';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createStore, store } from "./store.js";
|
|
2
2
|
import { StoreController } from "./store-controller.js";
|
|
3
3
|
import { OkStore } from "./ok-store.js";
|
|
4
|
+
import { bindTabbar, hintScroll, scrollActiveTabIntoView, shouldHintScroll, syncTabbarOverflow, tabbarOverflow } from "./tabbar.js";
|
|
4
5
|
import { OkDataTable } from "./ok-data-table.js";
|
|
5
6
|
import { OkMail } from "./ok-mail.js";
|
|
6
7
|
import { OkTree } from "./ok-tree.js";
|
|
@@ -198,6 +199,12 @@ export {
|
|
|
198
199
|
OkWizard,
|
|
199
200
|
StoreController,
|
|
200
201
|
applyPalette,
|
|
202
|
+
bindTabbar,
|
|
201
203
|
createStore,
|
|
202
|
-
|
|
204
|
+
hintScroll,
|
|
205
|
+
scrollActiveTabIntoView,
|
|
206
|
+
shouldHintScroll,
|
|
207
|
+
store,
|
|
208
|
+
syncTabbarOverflow,
|
|
209
|
+
tabbarOverflow
|
|
203
210
|
};
|
package/dist/ok-hero.js
CHANGED
|
@@ -1,42 +1,234 @@
|
|
|
1
1
|
import { LitElement, css, html } from "lit";
|
|
2
|
+
import { property, state } from "lit/decorators.js";
|
|
2
3
|
import { define } from "./define.js";
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
6
|
+
var result = void 0;
|
|
7
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
8
|
+
if (decorator = decorators[i])
|
|
9
|
+
result = decorator(target, key, result) || result;
|
|
10
|
+
if (result) __defProp(target, key, result);
|
|
11
|
+
return result;
|
|
12
|
+
};
|
|
3
13
|
class OkHero extends LitElement {
|
|
14
|
+
constructor() {
|
|
15
|
+
super(...arguments);
|
|
16
|
+
this.align = "center";
|
|
17
|
+
this.tone = "soft";
|
|
18
|
+
this.compact = false;
|
|
19
|
+
this.hasEyebrow = false;
|
|
20
|
+
this.hasActions = false;
|
|
21
|
+
this.hasMedia = false;
|
|
22
|
+
this.onSlotChange = () => this.refreshSlotState();
|
|
23
|
+
}
|
|
4
24
|
static {
|
|
5
25
|
this.styles = css`
|
|
6
26
|
:host {
|
|
7
27
|
--color: var(--ok-text, var(--ion-text-color, #1c1b17));
|
|
8
|
-
--color-muted: var(--ok-muted, rgba(var(--ion-text-color-rgb, 24, 24, 27), 0.
|
|
28
|
+
--color-muted: var(--ok-muted, rgba(var(--ion-text-color-rgb, 24, 24, 27), 0.68));
|
|
29
|
+
--surface: var(--ok-surface, var(--ion-background-color, #fff));
|
|
30
|
+
--surface-soft: var(--ok-surface-soft, var(--ion-color-light, #f4f5f8));
|
|
31
|
+
--primary: var(--ok-primary, var(--ion-color-primary, #3880ff));
|
|
9
32
|
--max-width: var(--ok-container-max, 1140px);
|
|
10
33
|
--padding: var(--ok-spacing, var(--ion-padding, 16px));
|
|
11
34
|
--font: var(--ok-font, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif);
|
|
35
|
+
--font-display: var(--ok-font-display, var(--font));
|
|
12
36
|
|
|
13
37
|
display: block;
|
|
14
38
|
color: var(--color);
|
|
15
39
|
font-family: var(--font);
|
|
40
|
+
overflow: hidden;
|
|
41
|
+
border-bottom: 1px solid color-mix(in oklab, var(--color) 8%, transparent);
|
|
42
|
+
}
|
|
43
|
+
:host([tone='neutral']) { background: var(--surface); }
|
|
44
|
+
:host([tone='soft']) {
|
|
45
|
+
background: color-mix(in oklab, var(--surface-soft) 54%, var(--surface));
|
|
16
46
|
}
|
|
17
|
-
|
|
47
|
+
:host([tone='gradient']) {
|
|
48
|
+
background:
|
|
49
|
+
radial-gradient(circle at 20% 0%, color-mix(in oklab, var(--primary) 14%, transparent), transparent 42%),
|
|
50
|
+
color-mix(in oklab, var(--surface-soft) 42%, var(--surface));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.layout {
|
|
18
54
|
max-width: var(--max-width);
|
|
19
55
|
margin-inline: auto;
|
|
20
|
-
padding: clamp(
|
|
56
|
+
padding: clamp(3.5rem, 7vw, 6rem) var(--padding);
|
|
21
57
|
display: grid;
|
|
22
|
-
|
|
58
|
+
align-items: center;
|
|
59
|
+
}
|
|
60
|
+
:host([compact]) .layout {
|
|
61
|
+
padding-block: clamp(2.5rem, 5vw, 4rem);
|
|
62
|
+
}
|
|
63
|
+
.copy {
|
|
64
|
+
min-width: 0;
|
|
65
|
+
max-width: 52rem;
|
|
66
|
+
display: flex;
|
|
67
|
+
flex-direction: column;
|
|
68
|
+
align-items: flex-start;
|
|
69
|
+
}
|
|
70
|
+
:host([align='center']) .copy {
|
|
71
|
+
align-items: center;
|
|
72
|
+
text-align: center;
|
|
73
|
+
margin-inline: auto;
|
|
74
|
+
}
|
|
75
|
+
:host([align='split']) .layout {
|
|
76
|
+
grid-template-columns: minmax(0, 1fr) minmax(18rem, 0.8fr);
|
|
77
|
+
gap: clamp(2rem, 6vw, 5rem);
|
|
78
|
+
}
|
|
79
|
+
.eyebrow {
|
|
80
|
+
display: inline-flex;
|
|
81
|
+
align-items: center;
|
|
82
|
+
align-self: flex-start;
|
|
83
|
+
margin: 0 0 1.25rem;
|
|
84
|
+
padding: 0.28rem 0.7rem;
|
|
85
|
+
border: 1px solid color-mix(in oklab, var(--primary) 22%, transparent);
|
|
86
|
+
border-radius: 999px;
|
|
87
|
+
color: var(--primary);
|
|
88
|
+
background: color-mix(in oklab, var(--primary) 12%, transparent);
|
|
89
|
+
font-size: 0.72rem;
|
|
90
|
+
font-weight: 600;
|
|
91
|
+
line-height: 1.2;
|
|
92
|
+
letter-spacing: 0.04em;
|
|
93
|
+
text-transform: uppercase;
|
|
94
|
+
}
|
|
95
|
+
.eyebrow.empty { display: none; }
|
|
96
|
+
:host([align='center']) .eyebrow {
|
|
97
|
+
align-self: center;
|
|
98
|
+
}
|
|
99
|
+
.eyebrow ::slotted([slot='eyebrow']) {
|
|
100
|
+
margin: 0 !important;
|
|
101
|
+
padding: 0 !important;
|
|
102
|
+
border: 0 !important;
|
|
103
|
+
color: inherit !important;
|
|
104
|
+
background: transparent !important;
|
|
105
|
+
font: inherit !important;
|
|
106
|
+
letter-spacing: inherit !important;
|
|
107
|
+
line-height: inherit !important;
|
|
108
|
+
text-transform: inherit !important;
|
|
109
|
+
}
|
|
110
|
+
.title {
|
|
111
|
+
max-width: 52rem;
|
|
112
|
+
margin: 0;
|
|
113
|
+
font-family: var(--font-display);
|
|
114
|
+
font-size: clamp(2.35rem, 1.75rem + 2.6vw, 4rem);
|
|
115
|
+
font-weight: 650;
|
|
116
|
+
line-height: 1.04;
|
|
117
|
+
letter-spacing: -0.045em;
|
|
118
|
+
text-wrap: balance;
|
|
119
|
+
}
|
|
120
|
+
:host([compact]) .title {
|
|
121
|
+
font-size: clamp(2rem, 1.55rem + 2vw, 3.25rem);
|
|
122
|
+
}
|
|
123
|
+
.title ::slotted([slot='title']) {
|
|
124
|
+
margin: 0 !important;
|
|
125
|
+
padding: 0 !important;
|
|
126
|
+
border: 0 !important;
|
|
127
|
+
color: inherit !important;
|
|
128
|
+
background: transparent !important;
|
|
129
|
+
font: inherit !important;
|
|
130
|
+
letter-spacing: inherit !important;
|
|
131
|
+
line-height: inherit !important;
|
|
132
|
+
text-wrap: inherit !important;
|
|
133
|
+
}
|
|
134
|
+
.subtitle {
|
|
135
|
+
max-width: 46rem;
|
|
136
|
+
margin: 1.5rem 0 0;
|
|
137
|
+
color: var(--color-muted);
|
|
138
|
+
font-size: clamp(1rem, 0.95rem + 0.25vw, 1.125rem);
|
|
139
|
+
line-height: 1.6;
|
|
140
|
+
text-wrap: pretty;
|
|
141
|
+
}
|
|
142
|
+
.subtitle ::slotted([slot='subtitle']) {
|
|
143
|
+
margin: 0 !important;
|
|
144
|
+
padding: 0 !important;
|
|
145
|
+
border: 0 !important;
|
|
146
|
+
color: inherit !important;
|
|
147
|
+
background: transparent !important;
|
|
148
|
+
font: inherit !important;
|
|
149
|
+
letter-spacing: inherit !important;
|
|
150
|
+
line-height: inherit !important;
|
|
151
|
+
text-wrap: inherit !important;
|
|
152
|
+
}
|
|
153
|
+
.actions {
|
|
154
|
+
display: flex;
|
|
155
|
+
flex-wrap: wrap;
|
|
156
|
+
gap: 0.5rem;
|
|
157
|
+
margin-top: 1.5rem;
|
|
158
|
+
}
|
|
159
|
+
:host([align='center']) .actions { justify-content: center; }
|
|
160
|
+
.actions.empty,
|
|
161
|
+
.media.empty { display: none; }
|
|
162
|
+
.media {
|
|
163
|
+
min-width: 0;
|
|
164
|
+
width: 100%;
|
|
165
|
+
margin-top: 2rem;
|
|
166
|
+
}
|
|
167
|
+
:host([align='split']) .media { margin-top: 0; }
|
|
168
|
+
|
|
169
|
+
@media (max-width: 767px) {
|
|
170
|
+
.layout { padding-block: 2.75rem 3rem; }
|
|
171
|
+
:host([compact]) .layout { padding-block: 2.25rem 2.5rem; }
|
|
172
|
+
:host([align='split']) .layout {
|
|
173
|
+
grid-template-columns: 1fr;
|
|
174
|
+
gap: 2rem;
|
|
175
|
+
}
|
|
176
|
+
.eyebrow { margin-bottom: 1rem; }
|
|
177
|
+
.subtitle { margin-top: 1.25rem; line-height: 1.5; }
|
|
178
|
+
.actions { width: 100%; }
|
|
23
179
|
}
|
|
24
|
-
::slotted([slot='title']) { font-size: clamp(1.8rem, 4vw, 3rem); line-height: 1.1; margin: 0; }
|
|
25
|
-
::slotted([slot='subtitle']) { font-size: clamp(1rem, 2vw, 1.25rem); color: var(--color-muted); margin: 0; max-width: 42ch; }
|
|
26
|
-
.actions { display: flex; gap: 0.75rem; flex-wrap: wrap; margin-top: 0.5rem; }
|
|
27
180
|
`;
|
|
28
181
|
}
|
|
182
|
+
connectedCallback() {
|
|
183
|
+
super.connectedCallback();
|
|
184
|
+
this.refreshSlotState();
|
|
185
|
+
}
|
|
186
|
+
refreshSlotState() {
|
|
187
|
+
this.hasEyebrow = this.querySelector('[slot="eyebrow"]') !== null;
|
|
188
|
+
this.hasActions = this.querySelector('[slot="actions"]') !== null;
|
|
189
|
+
this.hasMedia = [...this.childNodes].some((node) => {
|
|
190
|
+
if (node.nodeType === Node.TEXT_NODE) return (node.textContent ?? "").trim().length > 0;
|
|
191
|
+
return node.nodeType === Node.ELEMENT_NODE && !node.hasAttribute("slot");
|
|
192
|
+
});
|
|
193
|
+
}
|
|
29
194
|
render() {
|
|
30
195
|
return html`
|
|
31
|
-
<section class="
|
|
32
|
-
<
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
196
|
+
<section class="layout">
|
|
197
|
+
<header class="copy">
|
|
198
|
+
<div class=${this.hasEyebrow ? "eyebrow" : "eyebrow empty"}>
|
|
199
|
+
<slot name="eyebrow" @slotchange=${this.onSlotChange}></slot>
|
|
200
|
+
</div>
|
|
201
|
+
<div class="title"><slot name="title" @slotchange=${this.onSlotChange}></slot></div>
|
|
202
|
+
<div class="subtitle"><slot name="subtitle" @slotchange=${this.onSlotChange}></slot></div>
|
|
203
|
+
<div class=${this.hasActions ? "actions" : "actions empty"}>
|
|
204
|
+
<slot name="actions" @slotchange=${this.onSlotChange}></slot>
|
|
205
|
+
</div>
|
|
206
|
+
</header>
|
|
207
|
+
<div class=${this.hasMedia ? "media" : "media empty"}>
|
|
208
|
+
<slot @slotchange=${this.onSlotChange}></slot>
|
|
209
|
+
</div>
|
|
36
210
|
</section>
|
|
37
211
|
`;
|
|
38
212
|
}
|
|
39
213
|
}
|
|
214
|
+
__decorateClass([
|
|
215
|
+
property({ reflect: true })
|
|
216
|
+
], OkHero.prototype, "align");
|
|
217
|
+
__decorateClass([
|
|
218
|
+
property({ reflect: true })
|
|
219
|
+
], OkHero.prototype, "tone");
|
|
220
|
+
__decorateClass([
|
|
221
|
+
property({ type: Boolean, reflect: true })
|
|
222
|
+
], OkHero.prototype, "compact");
|
|
223
|
+
__decorateClass([
|
|
224
|
+
state()
|
|
225
|
+
], OkHero.prototype, "hasEyebrow");
|
|
226
|
+
__decorateClass([
|
|
227
|
+
state()
|
|
228
|
+
], OkHero.prototype, "hasActions");
|
|
229
|
+
__decorateClass([
|
|
230
|
+
state()
|
|
231
|
+
], OkHero.prototype, "hasMedia");
|
|
40
232
|
define("ok-hero", OkHero);
|
|
41
233
|
export {
|
|
42
234
|
OkHero
|