rook-cli 1.3.7 → 1.3.9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rook-cli",
3
- "version": "1.3.7",
3
+ "version": "1.3.9",
4
4
  "description": "CLI para instalar componentes Shopify",
5
5
  "repository": {
6
6
  "type": "git",
@@ -72,14 +72,15 @@ O framework inteiro vive em `/rook-framework/` como pasta isolada. Para portar p
72
72
  ├── config/
73
73
  │ └── rk-settings_schema.json ← Seção de settings para injetar no tema
74
74
  ├── assets/
75
- │ ├── rk-framework-tokens.css ← Design Tokens (CSS Variables + Liquid)
75
+ │ ├── rk-framework-tokens.css ← Design Tokens (CSS Variables estáticas)
76
76
  │ ├── rk-framework-core.css ← Estilos BEM de todos os componentes
77
77
  │ ├── rk-quantity.js ← Controller: <rk-quantity-selector>
78
- │ ├── rk-modal.js ← Controller: <rk-modal-element>
78
+ │ ├── rk-modal.js ← Controller: <rk-modal-element> (Media Lightbox)
79
79
  │ ├── rk-popover.js ← Controller: <rk-popover-element>
80
80
  │ ├── rk-scroll-area.js ← Controller: <rk-scroll-area>
81
81
  │ ├── rk-drawer.js ← Controller: <rk-drawer-element>
82
82
  │ ├── rk-dialog.js ← Controller: <rk-dialog-element>
83
+ │ ├── rk-alert-dialog.js ← Controller: <rk-alert-dialog-element>
83
84
  │ ├── rk-sheet.js ← Controller: <rk-sheet-element>
84
85
  │ ├── rk-tabs.js ← Controller: <rk-tabs-element>
85
86
  │ ├── rk-toggle.js ← Controller: <rk-toggle-element> & <rk-toggle-group>
@@ -87,7 +88,8 @@ O framework inteiro vive em `/rook-framework/` como pasta isolada. Para portar p
87
88
  │ ├── rk-collapsible.js ← Controller: <rk-collapsible-element>
88
89
  │ ├── rk-carousel.js ← Controller: <rk-carousel-element>
89
90
  │ ├── rk-bottom-app-bar.js ← Controller: <rk-bottom-app-bar-element>
90
- └── rk-accordion.js ← Controller: <rk-accordion-element>
91
+ ├── rk-accordion.js ← Controller: <rk-accordion-element>
92
+ │ └── rk-reveal.js ← Controller: <rk-reveal-element>
91
93
  ├── snippets/
92
94
  │ ├── rk-size-style.liquid ← Style: CSS vars de width/height (portável)
93
95
  │ ├── rk-spacing-style.liquid ← Style: CSS vars de padding com scaling (portável)
@@ -96,7 +98,9 @@ O framework inteiro vive em `/rook-framework/` como pasta isolada. Para portar p
96
98
  │ ├── rk-layout-style.liquid ← Style: CSS vars de layout/flex (portável)
97
99
  │ ├── rk-button.liquid ← Átomo: Botão/Link com variantes
98
100
  │ ├── rk-image.liquid ← Átomo: Imagem responsiva com CLS
99
- │ ├── rk-icon.liquid ← Átomo: Wrapper SVG para ícones
101
+ │ ├── rk-icon.liquid ← Átomo: Wrapper SVG para ícones (usa rk-icon-list)
102
+ │ ├── rk-icon-list.liquid ← Átomo: Biblioteca SVG self-contained (90+ ícones)
103
+ │ ├── rk-icon-or-image.liquid ← Átomo: Ícone SVG ou imagem com fallback
100
104
  │ ├── rk-input.liquid ← Átomo: Campo de texto
101
105
  │ ├── rk-textarea.liquid ← Átomo: Campo de texto multilinhas
102
106
  │ ├── rk-checkbox.liquid ← Átomo: Checkbox acessível
@@ -108,6 +112,7 @@ O framework inteiro vive em `/rook-framework/` como pasta isolada. Para portar p
108
112
  │ ├── rk-aspect-ratio.liquid ← Átomo: Container utilitário 16:9, 4:3, etc.
109
113
  │ ├── rk-item.liquid ← Átomo: Item de Lista/Menu
110
114
  │ ├── rk-spinner.liquid ← Átomo: Indicador de carregamento animado (Loading)
115
+ │ ├── rk-reveal.liquid ← Átomo: Revelação progressiva por scroll (fade-in/slide-up)
111
116
  │ ├── rk-card.liquid ← Molécula: Container flexível (Header/Body/Footer)
112
117
  │ ├── rk-price.liquid ← Molécula: Display de preço
113
118
  │ ├── rk-installments.liquid ← Molécula: Parcelamento (global)
@@ -115,11 +120,12 @@ O framework inteiro vive em `/rook-framework/` como pasta isolada. Para portar p
115
120
  │ ├── rk-quantity.liquid ← Molécula: Seletor de quantidade
116
121
  │ ├── rk-accordion.liquid ← Molécula: Accordion/Disclosure
117
122
  │ ├── rk-form-field.liquid ← Molécula: Label + Input + Error
118
- │ ├── rk-modal.liquid ← Molécula: Dialog/Modal base
123
+ │ ├── rk-modal.liquid ← Molécula: Lightbox de mídia (imagem/vídeo/embed)
119
124
  │ ├── rk-popover.liquid ← Molécula: Popover flutuante
120
125
  │ ├── rk-scroll-area.liquid ← Molécula: Área de scroll customizada
121
126
  │ ├── rk-drawer.liquid ← Molécula: Painel deslizante
122
127
  │ ├── rk-dialog.liquid ← Molécula: Dialog/Modal (Shadcn/UI)
128
+ │ ├── rk-alert-dialog.liquid ← Molécula: Alert Dialog para confirmações críticas
123
129
  │ ├── rk-sheet.liquid ← Molécula: Painel lateral full-viewport
124
130
  │ ├── rk-tabs.liquid ← Molécula: Guias (Tabs) alternáveis
125
131
  │ ├── rk-table.liquid ← Molécula: Tabela semântica e responsiva
@@ -140,7 +146,7 @@ O framework inteiro vive em `/rook-framework/` como pasta isolada. Para portar p
140
146
  ├── rk-divider.liquid ← Block: Divisor com customizer
141
147
  ├── rk-accordion.liquid ← Block: Accordion com customizer
142
148
  ├── rk-badge.liquid ← Block: Badge com customizer
143
- ├── rk-icon.liquid ← Block: Ícone com customizer
149
+ ├── rk-icon-or-image.liquid ← Block: Ícone ou Imagem com customizer
144
150
  ├── rk-form-field.liquid ← Block: Campo formulário com customizer
145
151
  ├── rk-installments.liquid ← Block: Parcelamento com customizer
146
152
  ├── rk-pix-discount.liquid ← Block: Desconto Pix com customizer
@@ -244,14 +250,74 @@ O arquivo `rk-settings_schema.json` define uma seção **"⚡ Rook UI Core Frame
244
250
 
245
251
  #### `rk-icon`
246
252
  **Arquivo:** `snippets/rk-icon.liquid`
247
- **Descrição:** Wrapper SVG para ícones com sizes e acessibilidade.
253
+ **Descrição:** Wrapper SVG para ícones com sizes e acessibilidade. Utiliza a biblioteca `rk-icon-list` com 90+ ícones SVG self-contained.
248
254
 
249
- | Prop | Tipo | Default |
250
- |---|---|---|
251
- | `icon` | string | — |
252
- | `size` | string | `md` |
253
- | `color` | string | `inherit` |
254
- | `label` | string | — |
255
+ | Prop | Tipo | Default | Descrição |
256
+ |---|---|---|---|
257
+ | `icon` | string | — | Nome do ícone (da biblioteca `rk-icon-list`) |
258
+ | `size` | string | `md` | `sm` \| `md` \| `lg` \| `xl` |
259
+ | `color` | string | `inherit` | Cor CSS do ícone (via `currentColor`) |
260
+ | `custom_class` | string | — | Classes CSS extras |
261
+ | `label` | string | — | Label acessível (se vazio, `aria-hidden="true"`) |
262
+
263
+ **Exemplo:**
264
+ ```liquid
265
+ {% render 'rk-icon', icon: 'heart', size: 'lg' %}
266
+ {% render 'rk-icon', icon: 'star', size: 'md', color: '#FF0000', label: 'Destaque' %}
267
+ ```
268
+
269
+ ---
270
+
271
+ #### `rk-icon-list`
272
+ **Arquivo:** `snippets/rk-icon-list.liquid`
273
+ **Descrição:** Biblioteca SVG self-contained com 90+ ícones organizados por categoria. Renderiza paths SVG inline via `{% render 'rk-icon-list', icon: 'nome' %}`.
274
+
275
+ | Prop | Tipo | Default | Descrição |
276
+ |---|---|---|---|
277
+ | `icon` | string | — | Nome do ícone a renderizar |
278
+
279
+ **Categorias de Ícones Disponíveis:**
280
+
281
+ | Categoria | Ícones |
282
+ |---|---|
283
+ | **Navegação** | `menu`, `search`, `user`, `cart`, `wishlist`, `heart`, `globe`, `home`, `trash`, `arrow`, `arrow-right`, `chevron-down`, `chevron-up`, `chevron-left`, `chevron-right`, `close`, `check` |
284
+ | **Produto** | `plus`, `minus`, `share`, `star`, `star-outline`, `zoom`, `play`, `info`, `filter`, `eye`, `compare`, `sort` |
285
+ | **Medidas/Técnico** | `ruler`, `scissors`, `expand`, `layers`, `iron`, `hanger`, `tape-measure`, `size-guide` |
286
+ | **Benefícios** | `leaf`, `plant`, `sparkles`, `zap`, `lightning_bolt`, `shield-check`, `gem`, `hand-heart`, `recycle`, `fire`, `crown`, `medal`, `thumbs-up`, `verified`, `eco`, `organic` |
287
+ | **Logística** | `truck`, `lock`, `return`, `package`, `gift`, `credit-card`, `percent`, `coupon`, `wallet`, `receipt`, `barcode`, `price_tag`, `store`, `delivery`, `exchange`, `warranty`, `plane` |
288
+ | **Comunicação** | `chat_bubble`, `phone`, `email`, `bell` |
289
+ | **Informação** | `question_mark`, `error`, `check_box`, `clipboard`, `clock`, `stopwatch`, `calendar`, `map_pin`, `download`, `upload`, `link`, `silhouette`, `qr-code`, `snowflake`, `scan`, `refresh`, `sun`, `moon`, `cookie` |
290
+ | **Moda/Vestuário** | `shirt`, `shoe`, `pants`, `dress`, `glasses`, `watch`, `lipstick`, `perfume`, `diamond`, `paw-print`, `leather` |
291
+ | **Alimentação** | `apple`, `banana`, `carrot`, `serving-dish`, `dairy`, `dairy-free`, `gluten-free`, `nut-free`, `pepper`, `bottle` |
292
+ | **Cuidados/Lavagem** | `washing`, `dryer`, `hand-wash` |
293
+ | **Redes Sociais** | `instagram`, `tiktok`, `facebook`, `x`, `youtube`, `whatsapp`, `telegram`, `spotify`, `pinterest`, `linkedin`, `bluesky`, `snapchat`, `threads`, `tumblr`, `vimeo` |
294
+
295
+ **Especificações Técnicas:**
296
+ - Todos os ícones usam `viewBox="0 0 20 20"`
297
+ - Paths utilizam `fill="currentColor"` (herda cor do elemento pai)
298
+
299
+ ---
300
+
301
+ #### `rk-icon-or-image`
302
+ **Arquivo:** `snippets/rk-icon-or-image.liquid`
303
+ **Descrição:** Renderiza um ícone SVG (via `rk-icon`) ou uma imagem uploadada, com lógica de fallback. Se `image` for fornecido, tem prioridade sobre `icon`.
304
+
305
+ | Prop | Tipo | Default | Descrição |
306
+ |---|---|---|---|
307
+ | `icon` | string | — | Nome do ícone (ignorado se `image` for fornecido) |
308
+ | `image` | object | — | Objeto imagem do Shopify (prioridade sobre `icon`) |
309
+ | `size` | string | `md` | `sm` (16px) \| `md` (20px) \| `lg` (24px) \| `xl` (32px) \| `custom` |
310
+ | `custom_width` | number | — | Largura em px quando size é `custom` |
311
+ | `color` | string | — | Cor CSS (apenas para ícones SVG) |
312
+ | `custom_class` | string | — | Classes CSS extras |
313
+ | `label` | string | — | Label acessível |
314
+ | `loading` | string | `lazy` | `lazy` \| `eager` (apenas para imagens) |
315
+
316
+ **Exemplo:**
317
+ ```liquid
318
+ {% render 'rk-icon-or-image', icon: 'heart', size: 'lg' %}
319
+ {% render 'rk-icon-or-image', image: block.settings.image_upload, size: 'custom', custom_width: 48 %}
320
+ ```
255
321
 
256
322
  ---
257
323
 
@@ -330,6 +396,48 @@ Shapes: `text` \| `circle` \| `rect`
330
396
 
331
397
  ---
332
398
 
399
+ #### `rk-reveal`
400
+ **Arquivo:** `snippets/rk-reveal.liquid`
401
+ **Controller:** `assets/rk-reveal.js` → `<rk-reveal-element>`
402
+ **Descrição:** Wrapper de revelação progressiva por scroll. Aplica animações de fade-in com slide direcional usando IntersectionObserver. Suporta stagger (cascata) entre filhos para efeito sequencial.
403
+
404
+ | Prop | Tipo | Default | Descrição |
405
+ |---|---|---|---|
406
+ | `animation` | string | `fade-up` | `fade-up` \| `fade-down` \| `fade-left` \| `fade-right` \| `fade` \| `zoom` |
407
+ | `duration` | number | `600` | Duração da animação em ms |
408
+ | `delay` | number | `0` | Atraso antes de iniciar em ms |
409
+ | `stagger` | number | `0` | Atraso incremental entre filhos diretos em ms (0 = desativado) |
410
+ | `threshold` | number | `0.1` | Percentual visível para disparar (0.0 a 1.0) |
411
+ | `easing` | string | `cubic-bezier(0.16, 1, 0.3, 1)` | CSS easing function |
412
+ | `once` | boolean | `true` | Anima apenas uma vez |
413
+ | `content` | string | — | HTML do conteúdo interno |
414
+ | `custom_class` | string | — | Classes extras |
415
+ | `tag` | string | `div` | Tag HTML do wrapper interno |
416
+
417
+ **Exemplo simples:**
418
+ ```liquid
419
+ {% capture banner %}
420
+ <h2>Bem-vindo</h2>
421
+ {% endcapture %}
422
+ {% render 'rk-reveal', content: banner, animation: 'fade-up' %}
423
+ ```
424
+
425
+ **Exemplo com stagger (cascata):**
426
+ ```liquid
427
+ {% capture cards %}
428
+ <div>Card 1</div>
429
+ <div>Card 2</div>
430
+ <div>Card 3</div>
431
+ {% endcapture %}
432
+ {% render 'rk-reveal', content: cards, animation: 'fade-up', stagger: 100, delay: 100 %}
433
+ ```
434
+
435
+ **Acessibilidade:** Respeita `prefers-reduced-motion: reduce` — se ativo, o conteúdo é exibido imediatamente sem animação.
436
+
437
+ **Custom Event:** `rk:reveal:visible` → `{ animation }`
438
+
439
+ ---
440
+
333
441
  ### 5.2 Moléculas
334
442
 
335
443
  #### `rk-price`
@@ -421,22 +529,52 @@ Shapes: `text` \| `circle` \| `rect`
421
529
 
422
530
  ---
423
531
 
424
- #### `rk-modal`
532
+ #### `rk-modal` (Media Lightbox)
425
533
  **Arquivo:** `snippets/rk-modal.liquid`
426
534
  **Controller:** `assets/rk-modal.js` → `<rk-modal-element>`
427
- **Descrição:** Dialog base com overlay, trap focus, ESC key e scroll lock.
535
+ **Descrição:** Lightbox de mídia especializado para imagens, vídeos hospedados, YouTube, Vimeo e HTML customizado. Suporta lazy-loading de iframes, autoplay, overlay escuro (85% opacidade), ESC key e scroll lock.
428
536
 
429
- | Prop | Tipo | Default |
430
- |---|---|---|
431
- | `id` | string | — |
432
- | `content` | string | |
433
- | `title` | string | — |
537
+ | Prop | Tipo | Default | Descrição |
538
+ |---|---|---|---|
539
+ | `id` | string | — | ID único do modal (obrigatório) |
540
+ | `type` | string | `image` | `image` \| `video` \| `youtube` \| `vimeo` \| `html` |
541
+ | `image` | object | — | Objeto imagem Shopify (para type: `image`) |
542
+ | `video_url` | string | — | URL do arquivo .mp4 (para type: `video`) |
543
+ | `youtube_id` | string | — | ID do vídeo YouTube (para type: `youtube`) |
544
+ | `vimeo_id` | string | — | ID do vídeo Vimeo (para type: `vimeo`) |
545
+ | `content` | string | — | HTML customizado (para type: `html`) |
546
+ | `alt` | string | — | Texto alternativo / aria-label |
547
+ | `aspect_ratio` | string | `16/9` | Aspect ratio para vídeos |
548
+ | `autoplay` | boolean | `true` | Autoplay ao abrir |
549
+ | `custom_class` | string | — | Classes CSS extras |
434
550
 
435
551
  **Para abrir externamente:** Usar `data-modal-open="ID_DO_MODAL"` em qualquer botão.
436
552
 
553
+ **Exemplo:**
554
+ ```liquid
555
+ {%- comment -%} Lightbox de imagem {%- endcomment -%}
556
+ {% render 'rk-modal', id: 'product-zoom', type: 'image', image: product.featured_image, alt: product.title %}
557
+
558
+ {%- comment -%} Vídeo YouTube {%- endcomment -%}
559
+ {% render 'rk-modal', id: 'brand-video', type: 'youtube', youtube_id: 'dQw4w9WgXcQ' %}
560
+
561
+ {%- comment -%} Vídeo hospedado {%- endcomment -%}
562
+ {% render 'rk-modal', id: 'story', type: 'video', video_url: video_source, autoplay: true %}
563
+
564
+ {%- comment -%} HTML customizado {%- endcomment -%}
565
+ {% render 'rk-modal', id: 'custom', type: 'html', content: '<p>Conteúdo aqui</p>' %}
566
+ ```
567
+
568
+ **Comportamento Técnico:**
569
+ - Iframes (YouTube/Vimeo) usam `data-src` para lazy-loading (carregam apenas ao abrir)
570
+ - YouTube: `https://www.youtube.com/embed/{ID}?rel=0&enablejsapi=1`
571
+ - Vimeo: `https://player.vimeo.com/video/{ID}?title=0&byline=0&portrait=0`
572
+ - Vídeos hospedados usam `<video>` com `preload="metadata"`
573
+ - Ao fechar: pausa vídeos e limpa src de iframes para prevenir reprodução em background
574
+
437
575
  **Custom Events:**
438
- - `rk:modal:open` → `{ id }`
439
- - `rk:modal:close` → `{ id }`
576
+ - `rk:modal:open` → `{ id, type }`
577
+ - `rk:modal:close` → `{ id, type }`
440
578
 
441
579
  ---
442
580
 
@@ -608,6 +746,49 @@ Shapes: `text` \| `circle` \| `rect`
608
746
 
609
747
  ---
610
748
 
749
+ #### `rk-alert-dialog`
750
+ **Arquivo:** `snippets/rk-alert-dialog.liquid`
751
+ **Controller:** `assets/rk-alert-dialog.js` → `<rk-alert-dialog-element>`
752
+ **Descrição:** Dialog de confirmação crítica (estilo Shadcn/UI AlertDialog). Diferente do Dialog padrão: **não fecha ao clicar no overlay**, foca o botão Cancelar por padrão (segurança) e usa `role="alertdialog"` para tecnologias assistivas.
753
+
754
+ | Prop | Tipo | Default | Descrição |
755
+ |---|---|---|---|
756
+ | `id` | string | — | ID único do alert dialog |
757
+ | `title` | string | — | Título do alerta (obrigatório) |
758
+ | `description` | string | — | Texto explicativo sobre consequências |
759
+ | `cancel_text` | string | `Cancelar` | Texto do botão cancelar |
760
+ | `confirm_text` | string | `Confirmar` | Texto do botão confirmar |
761
+ | `confirm_style` | string | `primary` | Estilo rk-button do botão confirmar |
762
+ | `esc_close` | boolean | `true` | Permite ESC para fechar |
763
+ | `custom_class` | string | — | Classes CSS extras |
764
+
765
+ **Para abrir externamente:** Usar `data-alert-dialog-open="ID"` em qualquer botão.
766
+
767
+ **Exemplo:**
768
+ ```liquid
769
+ {% render 'rk-alert-dialog',
770
+ id: 'delete-account',
771
+ title: 'Você tem certeza absoluta?',
772
+ description: 'Esta ação não pode ser desfeita. Isso excluirá permanentemente sua conta.',
773
+ cancel_text: 'Cancelar',
774
+ confirm_text: 'Excluir Conta',
775
+ confirm_style: 'danger'
776
+ %}
777
+ ```
778
+
779
+ **Diferenças do `rk-dialog`:**
780
+ - Overlay **não é clicável** (não fecha ao clicar fora)
781
+ - Foca o botão **Cancelar** por padrão (segurança contra confirmações acidentais)
782
+ - Usa `role="alertdialog"` em vez de `role="dialog"`
783
+ - Botão confirmar **não auto-fecha** — emite evento `rk:alert-dialog:confirm` para que o consumidor decida (ex: estado de loading)
784
+
785
+ **Custom Events:**
786
+ - `rk:alert-dialog:open` → `{ id }`
787
+ - `rk:alert-dialog:close` → `{ id, reason }` (reason: `'cancel'`)
788
+ - `rk:alert-dialog:confirm` → `{ id }` (emitido ao clicar confirmar, sem auto-close)
789
+
790
+ ---
791
+
611
792
  #### `rk-sheet`
612
793
  **Arquivo:** `snippets/rk-sheet.liquid`
613
794
  **Controller:** `assets/rk-sheet.js` → `<rk-sheet-element>`
@@ -902,13 +1083,17 @@ Shapes: `text` \| `circle` \| `rect`
902
1083
  | `updateButtons()` | Habilita/desabilita botões nos limites |
903
1084
  | `dispatchChange()` | Emite `rk:quantity:change` com o novo valor |
904
1085
 
905
- ### 6.2 `rk-modal.js` → `<rk-modal-element>`
1086
+ ### 6.2 `rk-modal.js` → `<rk-modal-element>` (Media Lightbox)
906
1087
 
907
1088
  | Método | Descrição |
908
1089
  |---|---|
909
- | `open()` | Abre o modal, trava scroll e foca |
910
- | `close()` | Fecha o modal, restaura scroll e focus |
911
- | `isOpen()` | Verifica se o modal está ativo |
1090
+ | `open()` | Abre o lightbox, carrega mídia (lazy iframes), trava scroll e foca |
1091
+ | `close()` | Fecha o lightbox, para mídia, limpa iframes, restaura scroll e focus |
1092
+ | `isOpen()` | Verifica se o lightbox está ativo |
1093
+ | `_loadIframes()` | Lazy-load de iframes YouTube/Vimeo via `data-src` com autoplay |
1094
+ | `_playMedia()` | Play de vídeo hospedado se autoplay ativo |
1095
+ | `_stopMedia()` | Pausa vídeos e limpa src de iframes ao fechar |
1096
+ | `_setupOpenTriggers()` | Vincula triggers `[data-modal-open="ID"]` da página |
912
1097
 
913
1098
  ### 6.3 `rk-accordion.js` → `<rk-accordion-element>`
914
1099
 
@@ -963,7 +1148,16 @@ Shapes: `text` \| `circle` \| `rect`
963
1148
  | `_trapFocus(e)` | Tab trap: wraps entre first/last focusable |
964
1149
  | `_onKeyDown(e)` | ESC dismiss + Tab trap handler |
965
1150
 
966
- ### 6.8 `rk-sheet.js` → `<rk-sheet-element>`
1151
+ ### 6.8 `rk-alert-dialog.js` → `<rk-alert-dialog-element>`
1152
+
1153
+ | Método | Descrição |
1154
+ |---|---|
1155
+ | `open()` | Abre o alert dialog, trava scroll e foca o botão Cancelar |
1156
+ | `close(reason)` | Fecha o alert dialog, restaura scroll e focus (reason: `'cancel'`) |
1157
+ | `isOpen()` | Verifica se o alert dialog está ativo |
1158
+ | `_setupOpenTriggers()` | Vincula triggers `[data-alert-dialog-open="ID"]` |
1159
+
1160
+ ### 6.9 `rk-sheet.js` → `<rk-sheet-element>`
967
1161
 
968
1162
  | Método | Descrição |
969
1163
  |---|---|
@@ -973,14 +1167,14 @@ Shapes: `text` \| `circle` \| `rect`
973
1167
  | `_trapFocus(e)` | Tab trap: wraps entre first/last focusable |
974
1168
  | `_onKeyDown(e)` | ESC dismiss + Tab trap handler |
975
1169
 
976
- ### 6.9 `rk-tabs.js` → `<rk-tabs-element>`
1170
+ ### 6.10 `rk-tabs.js` → `<rk-tabs-element>`
977
1171
 
978
1172
  | Método | Descrição |
979
1173
  |---|---|
980
1174
  | `activateTab(id, focus)` | Ativa a tab correspondente e oculta demais painéis |
981
1175
  | `_onKeyDown()` | Gerencia navegação de teclado (Setas, Home, End) |
982
1176
 
983
- ### 6.10 `rk-toggle.js` → `<rk-toggle-element>` e `<rk-toggle-group>`
1177
+ ### 6.11 `rk-toggle.js` → `<rk-toggle-element>` e `<rk-toggle-group>`
984
1178
 
985
1179
  | Método (Toggle) | Descrição |
986
1180
  |---|---|
@@ -993,7 +1187,7 @@ Shapes: `text` \| `circle` \| `rect`
993
1187
  | `_handleMultiple()` | Lógica de checkbox |
994
1188
  | `_emitChange()` | Dispara o valor final atualizado do grupo |
995
1189
 
996
- ### 6.11 `rk-progress.js` → `<rk-progress-element>`
1190
+ ### 6.12 `rk-progress.js` → `<rk-progress-element>`
997
1191
 
998
1192
  | Método / Getter | Descrição |
999
1193
  |---|---|
@@ -1001,7 +1195,7 @@ Shapes: `text` \| `circle` \| `rect`
1001
1195
  | `max` (getter/setter) | Define teto via dataset |
1002
1196
  | `_updateIndicator()` | Calcula `(value/max)*100` e converte em `transform: translateX()` |
1003
1197
 
1004
- ### 6.12 `rk-collapsible.js` → `<rk-collapsible-element>`
1198
+ ### 6.13 `rk-collapsible.js` → `<rk-collapsible-element>`
1005
1199
 
1006
1200
  | Método | Descrição |
1007
1201
  |---|---|
@@ -1010,7 +1204,7 @@ Shapes: `text` \| `circle` \| `rect`
1010
1204
  | `toggle()` | Alterna estado atual |
1011
1205
  | `_syncState()` | Gerencia `<rk-collapsible__content--expanded>`, foca/desfoca tabindex |
1012
1206
 
1013
- ### 6.13 `rk-carousel.js` → `<rk-carousel-element>`
1207
+ ### 6.14 `rk-carousel.js` → `<rk-carousel-element>`
1014
1208
 
1015
1209
  | Método / Feature | Descrição |
1016
1210
  |---|---|
@@ -1018,13 +1212,25 @@ Shapes: `text` \| `circle` \| `rect`
1018
1212
  | `_initSwiper()` | Combina opções em dataset com o object `this.options` do Swiper |
1019
1213
  | `ResizeObserver` | Garante que se o Carousel for redimensionado (ex. em tabs) ele ajuste `swiper.update()` |
1020
1214
 
1021
- ### 6.14 `rk-bottom-app-bar.js` → `<rk-bottom-app-bar-element>`
1215
+ ### 6.15 `rk-bottom-app-bar.js` → `<rk-bottom-app-bar-element>`
1022
1216
 
1023
1217
  | Método / Feature | Descrição |
1024
1218
  |---|---|
1025
1219
  | `_onKeyDown(e)` | Ouve Setas Direita/Esquerda para mover Foco entre itens `[role="menuitem"]` |
1026
1220
  | `Tabindex Manager` | Troca dinamicamente tabindex="-1" e "0" mantendo padrão Roving Tabindex A11y |
1027
1221
 
1222
+ ### 6.16 `rk-reveal.js` → `<rk-reveal-element>`
1223
+
1224
+ | Método / Feature | Descrição |
1225
+ |---|---|
1226
+ | `_applyInitialState()` | Define opacity: 0 e transform inicial baseado no tipo de animação |
1227
+ | `_reveal()` | Dispara a animação de revelação (single ou stagger) |
1228
+ | `_revealSingle()` | Anima o content wrapper como bloco único |
1229
+ | `_revealWithStagger()` | Anima cada filho direto com delay incremental (cascata) |
1230
+ | `_hide()` | Reseta o estado (quando `once: false`) para re-animação |
1231
+ | `_revealImmediate()` | Exibe sem animação (prefers-reduced-motion) |
1232
+ | `IntersectionObserver` | Detecta quando o elemento entra na viewport para disparar a revelação |
1233
+
1028
1234
  ---
1029
1235
 
1030
1236
  ## 7. Guia de Integração com o Tema
@@ -1211,4 +1417,4 @@ O sistema de scaling é definido em `rk-framework-tokens.css`:
1211
1417
 
1212
1418
  ---
1213
1419
 
1214
- *Versão: 1.1.0 — Última atualização: 05/03/2026*
1420
+ *Versão: 1.2.0 — Última atualização: 15/03/2026*
@@ -276,6 +276,19 @@
276
276
  --rk-icon-size: 32px;
277
277
  }
278
278
 
279
+ .rk-icon__img {
280
+ display: block;
281
+ width: 100%;
282
+ height: 100%;
283
+ object-fit: contain;
284
+ }
285
+
286
+ .rk-icon-block__link {
287
+ display: inline-flex;
288
+ color: inherit;
289
+ text-decoration: none;
290
+ }
291
+
279
292
  /* --------------------------------------------------------------------------
280
293
  rk-input (Input)
281
294
  -------------------------------------------------------------------------- */
@@ -705,7 +718,7 @@
705
718
  }
706
719
 
707
720
  /* --------------------------------------------------------------------------
708
- rk-modal (Modal)
721
+ rk-modal (Media Lightbox)
709
722
  -------------------------------------------------------------------------- */
710
723
  .rk-modal {
711
724
  position: fixed;
@@ -729,42 +742,105 @@
729
742
  .rk-modal__overlay {
730
743
  position: absolute;
731
744
  inset: 0;
732
- background: rgba(0, 0, 0, 0.5);
745
+ background: rgba(0, 0, 0, 0.85);
733
746
  backdrop-filter: blur(4px);
734
747
  }
735
748
 
736
749
  .rk-modal__content {
737
750
  position: relative;
738
751
  z-index: 1;
739
- background: #fff;
740
- border-radius: var(--rk-radius);
752
+ display: flex;
753
+ align-items: center;
754
+ justify-content: center;
741
755
  max-width: 90vw;
742
756
  max-height: 90vh;
743
- overflow-y: auto;
744
- padding: var(--rk-space-lg);
745
- transform: translateY(16px);
757
+ transform: scale(0.95);
746
758
  transition: transform var(--rk-transition);
747
759
  }
748
760
 
749
761
  .rk-modal--active .rk-modal__content {
750
- transform: translateY(0);
762
+ transform: scale(1);
751
763
  }
752
764
 
753
765
  .rk-modal__close {
754
- position: absolute;
755
- top: var(--rk-space-sm);
756
- right: var(--rk-space-sm);
757
- background: none;
766
+ position: fixed;
767
+ top: var(--rk-space-md);
768
+ right: var(--rk-space-md);
769
+ z-index: 2;
770
+ background: rgba(0, 0, 0, 0.5);
758
771
  border: none;
759
772
  cursor: pointer;
760
- color: var(--rk-color-text-muted);
761
- padding: var(--rk-space-2xs);
773
+ color: #fff;
774
+ padding: var(--rk-space-xs);
762
775
  border-radius: 50%;
763
776
  transition: background-color var(--rk-transition);
777
+ line-height: 0;
764
778
  }
765
779
 
766
780
  .rk-modal__close:hover {
767
- background-color: var(--rk-color-secondary-hover);
781
+ background-color: rgba(255, 255, 255, 0.2);
782
+ }
783
+
784
+ /* Media containers */
785
+ .rk-modal__media {
786
+ display: flex;
787
+ align-items: center;
788
+ justify-content: center;
789
+ }
790
+
791
+ .rk-modal__media--image {
792
+ max-width: 90vw;
793
+ max-height: 90vh;
794
+ }
795
+
796
+ .rk-modal__img {
797
+ display: block;
798
+ max-width: 90vw;
799
+ max-height: 90vh;
800
+ width: auto;
801
+ height: auto;
802
+ object-fit: contain;
803
+ border-radius: var(--rk-radius-sm, 4px);
804
+ }
805
+
806
+ .rk-modal__media--video,
807
+ .rk-modal__media--embed {
808
+ width: min(90vw, 1200px);
809
+ max-height: 90vh;
810
+ border-radius: var(--rk-radius-sm, 4px);
811
+ overflow: hidden;
812
+ background: #000;
813
+ }
814
+
815
+ .rk-modal__video {
816
+ display: block;
817
+ width: 100%;
818
+ height: 100%;
819
+ object-fit: contain;
820
+ }
821
+
822
+ .rk-modal__iframe {
823
+ display: block;
824
+ width: 100%;
825
+ height: 100%;
826
+ border: none;
827
+ }
828
+
829
+ .rk-modal__media--html {
830
+ background: #fff;
831
+ border-radius: var(--rk-radius);
832
+ padding: var(--rk-space-lg);
833
+ max-width: min(90vw, 800px);
834
+ max-height: 90vh;
835
+ overflow-y: auto;
836
+ }
837
+
838
+ @media (max-width: 749px) {
839
+ .rk-modal__media--video,
840
+ .rk-modal__media--embed {
841
+ width: 100vw;
842
+ border-radius: 0;
843
+ }
768
844
  }
769
845
 
770
846
  /* --------------------------------------------------------------------------
@@ -2538,6 +2614,17 @@ a.rk-card {
2538
2614
  height: 32px;
2539
2615
  }
2540
2616
 
2617
+ /* --------------------------------------------------------------------------
2618
+ rk-reveal (Scroll Reveal Animation)
2619
+ -------------------------------------------------------------------------- */
2620
+ .rk-reveal {
2621
+ display: block;
2622
+ }
2623
+
2624
+ .rk-reveal__content {
2625
+ will-change: opacity, transform;
2626
+ }
2627
+
2541
2628
  /* --------------------------------------------------------------------------
2542
2629
  rk-sr-only (Screen Reader Only utility)
2543
2630
  -------------------------------------------------------------------------- */