rook-cli 1.3.2 → 1.3.5

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.
Files changed (92) hide show
  1. package/package.json +3 -2
  2. package/rook-framework/PRD-INSTALL-COMMAND.md +379 -0
  3. package/rook-framework/PRD.md +1214 -0
  4. package/rook-framework/README.md +143 -0
  5. package/rook-framework/assets/rk-accordion.js +99 -0
  6. package/rook-framework/assets/rk-alert-dialog.js +132 -0
  7. package/rook-framework/assets/rk-bottom-app-bar.js +88 -0
  8. package/rook-framework/assets/rk-carousel.js +145 -0
  9. package/rook-framework/assets/rk-collapsible.js +151 -0
  10. package/rook-framework/assets/rk-dialog.js +161 -0
  11. package/rook-framework/assets/rk-drawer.js +214 -0
  12. package/rook-framework/assets/rk-framework-core.css +2554 -0
  13. package/rook-framework/assets/rk-framework-tokens.css +101 -0
  14. package/rook-framework/assets/rk-modal.js +91 -0
  15. package/rook-framework/assets/rk-popover.js +264 -0
  16. package/rook-framework/assets/rk-progress.js +81 -0
  17. package/rook-framework/assets/rk-quantity.js +91 -0
  18. package/rook-framework/assets/rk-scroll-area.js +286 -0
  19. package/rook-framework/assets/rk-sheet.js +157 -0
  20. package/rook-framework/assets/rk-tabs.js +179 -0
  21. package/rook-framework/assets/rk-toggle.js +153 -0
  22. package/rook-framework/blocks/rk-accordion.liquid +97 -0
  23. package/rook-framework/blocks/rk-badge.liquid +103 -0
  24. package/rook-framework/blocks/rk-button.liquid +166 -0
  25. package/rook-framework/blocks/rk-divider.liquid +100 -0
  26. package/rook-framework/blocks/rk-form-field.liquid +120 -0
  27. package/rook-framework/blocks/rk-icon.liquid +134 -0
  28. package/rook-framework/blocks/rk-image.liquid +198 -0
  29. package/rook-framework/blocks/rk-installments.liquid +99 -0
  30. package/rook-framework/blocks/rk-pix-discount.liquid +99 -0
  31. package/rook-framework/blocks/rk-price.liquid +128 -0
  32. package/rook-framework/blocks/rk-quantity.liquid +108 -0
  33. package/rook-framework/blocks/rk-quick-add.liquid +137 -0
  34. package/rook-framework/blocks/rk-skeleton.liquid +104 -0
  35. package/rook-framework/blocks/rk-typography.liquid +183 -0
  36. package/rook-framework/config/rk-color-scheme-group.json +138 -0
  37. package/rook-framework/config/rk-settings_schema.json +259 -0
  38. package/rook-framework/snippets/rk-accordion.liquid +31 -0
  39. package/rook-framework/snippets/rk-alert-dialog.liquid +83 -0
  40. package/rook-framework/snippets/rk-aspect-ratio.liquid +23 -0
  41. package/rook-framework/snippets/rk-badge.liquid +17 -0
  42. package/rook-framework/snippets/rk-bottom-app-bar.liquid +51 -0
  43. package/rook-framework/snippets/rk-button.liquid +49 -0
  44. package/rook-framework/snippets/rk-card.liquid +64 -0
  45. package/rook-framework/snippets/rk-carousel.liquid +74 -0
  46. package/rook-framework/snippets/rk-checkbox.liquid +34 -0
  47. package/rook-framework/snippets/rk-collapsible.liquid +52 -0
  48. package/rook-framework/snippets/rk-color-schemes-standalone.liquid +61 -0
  49. package/rook-framework/snippets/rk-color-schemes.liquid +43 -0
  50. package/rook-framework/snippets/rk-dialog.liquid +85 -0
  51. package/rook-framework/snippets/rk-divider.liquid +25 -0
  52. package/rook-framework/snippets/rk-drawer.liquid +81 -0
  53. package/rook-framework/snippets/rk-external-assets copy.liquid +33 -0
  54. package/rook-framework/snippets/rk-external-assets.liquid +68 -0
  55. package/rook-framework/snippets/rk-form-field.liquid +83 -0
  56. package/rook-framework/snippets/rk-gap-style.liquid +32 -0
  57. package/rook-framework/snippets/rk-icon.liquid +28 -0
  58. package/rook-framework/snippets/rk-image.liquid +60 -0
  59. package/rook-framework/snippets/rk-input.liquid +35 -0
  60. package/rook-framework/snippets/rk-installments.liquid +54 -0
  61. package/rook-framework/snippets/rk-item.liquid +69 -0
  62. package/rook-framework/snippets/rk-layout-style.liquid +37 -0
  63. package/rook-framework/snippets/rk-modal.liquid +31 -0
  64. package/rook-framework/snippets/rk-pix-discount.liquid +34 -0
  65. package/rook-framework/snippets/rk-popover.liquid +77 -0
  66. package/rook-framework/snippets/rk-price.liquid +48 -0
  67. package/rook-framework/snippets/rk-progress.liquid +38 -0
  68. package/rook-framework/snippets/rk-quantity.liquid +56 -0
  69. package/rook-framework/snippets/rk-quick-add.liquid +67 -0
  70. package/rook-framework/snippets/rk-scripts.liquid +17 -0
  71. package/rook-framework/snippets/rk-scroll-area.liquid +60 -0
  72. package/rook-framework/snippets/rk-sheet.liquid +86 -0
  73. package/rook-framework/snippets/rk-size-style.liquid +48 -0
  74. package/rook-framework/snippets/rk-skeleton.liquid +25 -0
  75. package/rook-framework/snippets/rk-spacing-padding.liquid +18 -0
  76. package/rook-framework/snippets/rk-spacing-style.liquid +54 -0
  77. package/rook-framework/snippets/rk-spinner.liquid +43 -0
  78. package/rook-framework/snippets/rk-swatch.liquid +33 -0
  79. package/rook-framework/snippets/rk-table.liquid +44 -0
  80. package/rook-framework/snippets/rk-tabs.liquid +52 -0
  81. package/rook-framework/snippets/rk-textarea.liquid +42 -0
  82. package/rook-framework/snippets/rk-toggle-group.liquid +27 -0
  83. package/rook-framework/snippets/rk-toggle.liquid +58 -0
  84. package/rook-framework/snippets/rk-typography.liquid +27 -0
  85. package/rook-framework/snippets/rk-variables.liquid +76 -0
  86. package/src/app.js +24 -0
  87. package/src/commands/InstallCommand.js +133 -0
  88. package/src/mcp/server.js +111 -1
  89. package/src/services/FrameworkInstaller.js +485 -0
  90. package/src/templates/block.liquid.txt +0 -15
  91. package/src/ui/PromptUI.js +15 -1
  92. package/src/utils/logger.js +1 -1
@@ -0,0 +1,83 @@
1
+ {% doc %}
2
+ Snippet: RkFormField
3
+ Componente estrutural para agrupar campos de formulário (Label + Input + Descrição + Mensagem de Erro).
4
+ Gerencia automaticamente as associações WAI-ARIA com base no ID fornecido.
5
+
6
+ @param {string} id - O ID único base para o controle (Ex: 'customer_email'). O input dentro deve usar esse ID.
7
+ @param {string} label - O texto do label.
8
+ @param {string} control - Elemento transcluído de marcação (ex: `<input>`, `<select>`, `<textarea>`).
9
+ @param {string} [description] - Texto descritivo/ajuda opcional para guiar o preenchimento.
10
+ @param {string} [error] - Se presente, o campo entra em estado de erro e exibe esta mensagem.
11
+ @param {boolean} [required] - Se true, exibe o indicador (asterisco) de campo obrigatório.
12
+ @param {string} [layout] - 'vertical' (padrão) ou 'horizontal'.
13
+
14
+ @example
15
+ {% capture control_input %}
16
+ <input type="email" id="email" name="customer[email]" class="rk-input" required>
17
+ {% endcapture %}
18
+
19
+ {% render 'rk-form-field',
20
+ id: 'email',
21
+ label: 'Endereço de E-mail',
22
+ control: control_input,
23
+ description: 'Nós nunca compartilharemos o seu e-mail.',
24
+ required: true
25
+ %}
26
+ {% enddoc %}
27
+
28
+ {%- liquid
29
+ assign t_layout = layout | default: 'vertical'
30
+ assign has_error = false
31
+ if error != blank
32
+ assign has_error = true
33
+ endif
34
+
35
+ assign description_id = id | append: '-description'
36
+ assign error_id = id | append: '-error'
37
+ -%}
38
+
39
+ <div class="rk-form-field rk-form-field--{{ t_layout }}{% if has_error %} rk-form-field--error{% endif %}">
40
+
41
+ {%- comment -%} ==========================================
42
+ 1. LABEL AREA
43
+ ========================================== {%- endcomment -%}
44
+ <label for="{{ id }}" class="rk-form-field__label">
45
+ {{ label }}
46
+ {%- if required -%}
47
+ <span class="rk-form-field__required" aria-hidden="true">*</span>
48
+ {%- endif -%}
49
+ </label>
50
+
51
+ {%- comment -%} ==========================================
52
+ 2. CONTROL WRAPPER (Adicionando ARIA associations ao filho)
53
+ ========================================== {%- endcomment -%}
54
+ <div
55
+ class="rk-form-field__control"
56
+ {%- comment -%}
57
+ Como Liquid não parseia o conteúdo de `control` para injetar ATRIBUTOS facilmente
58
+ nós deixamos como wrapper. Recomendado que no arquivo que chamou adicione navativamente
59
+ se o WAI ARIA total for crítico. Mas o wrapper abraça.
60
+ {%- endcomment -%}
61
+ >
62
+ {{ control }}
63
+ </div>
64
+
65
+ {%- comment -%} ==========================================
66
+ 3. DESCRIPTION AREA
67
+ ========================================== {%- endcomment -%}
68
+ {%- if description != blank and has_error == false -%}
69
+ <p id="{{ description_id }}" class="rk-form-field__description">
70
+ {{ description }}
71
+ </p>
72
+ {%- endif -%}
73
+
74
+ {%- comment -%} ==========================================
75
+ 4. ERROR MESSAGE
76
+ ========================================== {%- endcomment -%}
77
+ {%- if has_error -%}
78
+ <p id="{{ error_id }}" class="rk-form-field__error" role="alert">
79
+ {{ error }}
80
+ </p>
81
+ {%- endif -%}
82
+
83
+ </div>
@@ -0,0 +1,32 @@
1
+ {%- doc -%}
2
+ Renders the CSS variable for the `gap` style with responsive scaling support.
3
+ Portable equivalent of Horizon's `gap-style.liquid` with `rk-` prefixed variables.
4
+
5
+ Values above `scale_min` (default: 24px) are wrapped in a responsive `max()` function
6
+ that scales down proportionally on smaller viewports using `--rk-gap-scale`.
7
+
8
+ @param {number} value - The base or desktop gap value to use, in pixels.
9
+ @param {string} [name] - The name of the CSS variable suffix. Default: 'gap'
10
+ @param {number} [scale_min] - Value above which gap scaling will be applied. Default: 24
11
+ @param {boolean} [disable_scaling] - If true, disables scaling and outputs the original value.
12
+
13
+ @example
14
+ <div class="rk-gap-style" style="{% render 'rk-gap-style', value: block.settings.gap %}">
15
+
16
+ @example Custom name
17
+ <div style="{% render 'rk-gap-style', value: 28, name: 'card-gap' %}">
18
+ → outputs: --rk-card-gap: max(24px, calc(var(--rk-gap-scale, 1) * 28px));
19
+ {%- enddoc -%}
20
+
21
+ {%- liquid
22
+ assign rk_min = scale_min | default: 24
23
+ assign rk_name = name | default: 'gap'
24
+ -%}
25
+
26
+ {%- if value != blank -%}
27
+ {%- if disable_scaling != true and value > rk_min -%}
28
+ --rk-{{ rk_name }}: max({{ rk_min }}px, calc(var(--rk-gap-scale, 1) * {{ value }}px));
29
+ {%- else -%}
30
+ --rk-{{ rk_name }}: {{ value }}px;
31
+ {%- endif -%}
32
+ {%- endif -%}
@@ -0,0 +1,28 @@
1
+ {% doc %}
2
+ Snippet: RkIcon
3
+ Renders an SVG icon wrapper.
4
+
5
+ @param {string} icon - Icon name to render (passes through to theme's icon.liquid)
6
+ @param {string} [size] - 'sm' | 'md' | 'lg' | 'xl' (default: 'md')
7
+ @param {string} [custom_class] - Extra CSS classes
8
+ @param {string} [color] - CSS color value
9
+ @param {string} [label] - Accessibility label
10
+
11
+ @example
12
+ {% render 'rk-icon', icon: 'heart', size: 'lg' %}
13
+ {% enddoc %}
14
+
15
+ {%- liquid
16
+ assign icon_size = size | default: 'md'
17
+ -%}
18
+
19
+ <span
20
+ class="rk-icon rk-icon--{{ icon_size }}{% if custom_class %} {{ custom_class }}{% endif %}"
21
+ {% if color %}style="color: {{ color }}"{% endif %}
22
+ {% if label %}aria-label="{{ label }}"{% else %}aria-hidden="true"{% endif %}
23
+ role="{% if label %}img{% else %}presentation{% endif %}"
24
+ >
25
+ <svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
26
+ {% render 'icon', icon: icon %}
27
+ </svg>
28
+ </span>
@@ -0,0 +1,60 @@
1
+ {% doc %}
2
+ Snippet: RkImage
3
+ Renders a responsive <img> with srcset, aspect-ratio, lazyload, and CLS prevention.
4
+
5
+ @param {object} image - Shopify image object
6
+ @param {number} [width] - Custom width (default: image.width)
7
+ @param {number} [height] - Custom height
8
+ @param {string} [sizes] - Responsive sizes attribute
9
+ @param {string} [loading] - 'lazy' | 'eager' (default: 'lazy')
10
+ @param {string} [class] - Extra CSS classes
11
+ @param {string} [style] - Additional inline styles
12
+ @param {string} [alt] - Alt text override
13
+ @param {string} [shape] - 'rounded' | 'circle'
14
+ @param {string} [placeholder_text] - Text fallback if image is blank
15
+
16
+ @example
17
+ {% render 'rk-image', image: product.featured_image, loading: 'eager' %}
18
+ {% enddoc %}
19
+
20
+ {%- liquid
21
+ assign img_loading = loading | default: 'lazy'
22
+ assign img_alt = alt | default: image.alt | escape
23
+ assign img_width = width | default: image.width
24
+ assign img_height = height | default: image.height
25
+ assign img_sizes = sizes | default: '100vw'
26
+
27
+ assign shape_class = ''
28
+ if shape == 'rounded'
29
+ assign shape_class = ' rk-image--rounded'
30
+ elsif shape == 'circle'
31
+ assign shape_class = ' rk-image--circle'
32
+ endif
33
+ -%}
34
+
35
+ {% if image != blank %}
36
+ {%- assign height_1x = img_height -%}
37
+ {%- assign height_2x = img_height | times: 2 -%}
38
+ {%- assign height_3x = img_height | times: 3 -%}
39
+
40
+ {%- capture srcset_value -%}
41
+ {{ image | image_url: height: height_1x }} 1x, {{ image | image_url: height: height_2x }} 2x, {{ image | image_url: height: height_3x }} 3x
42
+ {%- endcapture -%}
43
+
44
+ <div
45
+ class="rk-image{{ shape_class }}{% if class %} {{ class }}{% endif %}"
46
+ style="aspect-ratio: {{ img_width }} / {{ img_height }};{% if style %} {{ style }}{% endif %}"
47
+ >
48
+ {{ image | image_url: height: height_1x | image_tag:
49
+ class: 'rk-image__img',
50
+ srcset: srcset_value,
51
+ sizes: img_sizes,
52
+ loading: img_loading,
53
+ alt: img_alt
54
+ }}
55
+ </div>
56
+ {% elsif placeholder_text != blank %}
57
+ <div class="rk-image__placeholder{% if class %} {{ class }}{% endif %}" style="{% if style %}{{ style }}{% endif %}">
58
+ {{ placeholder_text }}
59
+ </div>
60
+ {% endif %}
@@ -0,0 +1,35 @@
1
+ {% doc %}
2
+ Snippet: RkInput
3
+ Renders a text input field.
4
+
5
+ @param {string} name - Input name attribute
6
+ @param {string} [id] - Input id attribute
7
+ @param {string} [type] - Input type (default: 'text')
8
+ @param {string} [value] - Initial value
9
+ @param {string} [placeholder] - Placeholder text
10
+ @param {boolean} [required] - Makes input required
11
+ @param {boolean} [disabled] - Disables input
12
+ @param {boolean} [error] - Shows error state
13
+ @param {string} [custom_class] - Extra CSS classes
14
+ @param {string} [attr] - Additional HTML attributes
15
+
16
+ @example
17
+ {% render 'rk-input', name: 'email', type: 'email', placeholder: 'seu@email.com' %}
18
+ {% enddoc %}
19
+
20
+ {%- liquid
21
+ assign input_type = type | default: 'text'
22
+ assign input_id = id | default: name
23
+ -%}
24
+
25
+ <input
26
+ type="{{ input_type }}"
27
+ id="{{ input_id }}"
28
+ name="{{ name }}"
29
+ {% if value %}value="{{ value }}"{% endif %}
30
+ {% if placeholder %}placeholder="{{ placeholder }}"{% endif %}
31
+ {% if required %}required aria-required="true"{% endif %}
32
+ {% if disabled %}disabled{% endif %}
33
+ class="rk-input{% if error %} rk-input--error{% endif %}{% if custom_class %} {{ custom_class }}{% endif %}"
34
+ {{ attr }}
35
+ >
@@ -0,0 +1,54 @@
1
+ {% doc %}
2
+ Snippet: RkInstallments
3
+ Renders the installment price information reading global settings.
4
+
5
+ @param {number} price - Price in cents to calculate installments from
6
+ @param {string} [custom_class] - Extra CSS classes
7
+
8
+ @example
9
+ {% render 'rk-installments', price: product.selected_or_first_available_variant.price %}
10
+ {% enddoc %}
11
+
12
+ {%- liquid
13
+ unless settings.rk_installments_enabled
14
+ break
15
+ endunless
16
+
17
+ assign inst_max = settings.rk_installments_max | default: 12
18
+ assign inst_no_interest = settings.rk_installments_without_interest | default: 3
19
+ assign inst_min_value = settings.rk_installments_min_value | default: '500' | plus: 0
20
+ assign interest_rate_raw = settings.rk_installments_interest_rate | default: '2.99'
21
+
22
+ assign best_installments = 1
23
+ assign best_value = price
24
+
25
+ for i in (1..inst_max)
26
+ assign value = price | divided_by: i
27
+ if value >= inst_min_value
28
+ assign best_installments = i
29
+ assign best_value = value
30
+ else
31
+ break
32
+ endif
33
+ endfor
34
+
35
+ assign has_interest = false
36
+ if best_installments > inst_no_interest
37
+ assign has_interest = true
38
+ endif
39
+
40
+ assign formatted_value = best_value | money
41
+ -%}
42
+
43
+ {% if best_installments > 1 %}
44
+ <span class="rk-installments{% if custom_class %} {{ custom_class }}{% endif %}">
45
+ <span class="rk-installments__value">{{ best_installments }}x</span>
46
+ de
47
+ <span class="rk-installments__value">{{ formatted_value }}</span>
48
+ {% if has_interest %}
49
+ <span class="rk-installments__interest">(com juros de {{ interest_rate_raw }}%)</span>
50
+ {% else %}
51
+ <span class="rk-installments__interest">sem juros</span>
52
+ {% endif %}
53
+ </span>
54
+ {% endif %}
@@ -0,0 +1,69 @@
1
+ {% doc %}
2
+ Snippet: RkItem
3
+ Componente base de lista/menu (List Item / Menu Item) com suporte a ícones, atalhos, e estados interativos.
4
+
5
+ @param {string} [as] - Tag HTML (ex: 'div', 'li', 'a', 'button'). Padrão: 'div'
6
+ @param {string} [href] - URL caso `as: 'a'`.
7
+ @param {string} [role] - Papel ARIA (ex: 'menuitem', 'option', 'listitem').
8
+ @param {boolean} [interactive] - Se true, aplica estilos de hover/focus. Automático se for link/button.
9
+ @param {boolean} [selected] - Se true, marca como visualmente ativo/selecionado (aria-selected="true").
10
+ @param {boolean} [disabled] - Se true, desativa a interação (aria-disabled="true").
11
+ @param {string} [leading] - Ícone ou elemento injetado à esquerda.
12
+ @param {string} [content] - Texto principal do item.
13
+ @param {string} [description] - Texto secundário menor exibido abaixo do content.
14
+ @param {string} [trailing] - Elemento injetado à direita (atalhos de teclado, chevron, check).
15
+ @param {string} [custom_class] - Classes CSS extras.
16
+
17
+ @example
18
+ {% render 'rk-item',
19
+ as: 'button',
20
+ leading: '<svg>...</svg>',
21
+ content: 'Configurações',
22
+ trailing: '<span class="text-sm text-muted">⌘S</span>',
23
+ interactive: true
24
+ %}
25
+ {% enddoc %}
26
+
27
+ {%- liquid
28
+ assign t_as = as | default: 'div'
29
+
30
+ assign is_link = false
31
+ if t_as == 'a' and href != blank
32
+ assign is_link = true
33
+ endif
34
+
35
+ assign is_interactive = false
36
+ if interactive == true or interactive == 'true' or is_link or t_as == 'button'
37
+ assign is_interactive = true
38
+ endif
39
+ -%}
40
+
41
+ <{{ t_as }}
42
+ class="rk-item{% if is_interactive %} rk-item--interactive{% endif %}{% if selected %} rk-item--selected{% endif %}{% if disabled %} rk-item--disabled{% endif %}{% if custom_class %} {{ custom_class }}{% endif %}"
43
+ {% if role %}role="{{ role }}"{% endif %}
44
+ {% if is_link %}href="{{ href }}"{% endif %}
45
+ {% if selected %}aria-selected="true"{% endif %}
46
+ {% if disabled %}aria-disabled="true" tabindex="-1"{% endif %}
47
+ {% if t_as == 'button' and disabled %}disabled{% endif %}
48
+ >
49
+ {%- if leading != blank -%}
50
+ <span class="rk-item__leading">
51
+ {{ leading }}
52
+ </span>
53
+ {%- endif -%}
54
+
55
+ <span class="rk-item__main">
56
+ {%- if content != blank -%}
57
+ <span class="rk-item__content">{{ content }}</span>
58
+ {%- endif -%}
59
+ {%- if description != blank -%}
60
+ <span class="rk-item__description">{{ description }}</span>
61
+ {%- endif -%}
62
+ </span>
63
+
64
+ {%- if trailing != blank -%}
65
+ <span class="rk-item__trailing">
66
+ {{ trailing }}
67
+ </span>
68
+ {%- endif -%}
69
+ </{{ t_as }}>
@@ -0,0 +1,37 @@
1
+ {%- doc -%}
2
+ Renders CSS variables for layout/panel styles including flex direction, alignment, gap and wrapping.
3
+ Portable equivalent of Horizon's `layout-panel-style.liquid` with `rk-` prefixed variables.
4
+
5
+ @param {object} settings - The block or section settings object containing layout values
6
+
7
+ Settings keys used:
8
+ - settings.content_direction: 'row' | 'column' (default: 'column')
9
+ - settings.horizontal_alignment: CSS justify-content value
10
+ - settings.vertical_alignment: CSS align-items value
11
+ - settings.gap: number (px)
12
+
13
+ @example
14
+ <div class="rk-layout-style" style="{% render 'rk-layout-style', settings: block.settings %}">
15
+ {%- enddoc -%}
16
+
17
+ {%- liquid
18
+ assign rk_h_align = settings.horizontal_alignment
19
+ assign rk_v_align = settings.vertical_alignment
20
+
21
+ unless settings.content_direction == 'row'
22
+ if settings.horizontal_alignment_flex_direction_column != blank
23
+ assign rk_h_align = settings.horizontal_alignment_flex_direction_column
24
+ endif
25
+ if settings.vertical_alignment_flex_direction_column != blank
26
+ assign rk_v_align = settings.vertical_alignment_flex_direction_column
27
+ endif
28
+ endunless
29
+ -%}
30
+
31
+ --rk-flex-direction: {{ settings.content_direction | default: 'column' }};
32
+ --rk-flex-wrap: nowrap;
33
+ --rk-flex-wrap-mobile: wrap;
34
+ --rk-h-align: {{ rk_h_align }};
35
+ --rk-v-align: {{ rk_v_align }};
36
+
37
+ {% render 'rk-gap-style', value: settings.gap %}
@@ -0,0 +1,31 @@
1
+ {% doc %}
2
+ Snippet: RkModal
3
+ Renders a modal/dialog wrapper using a Web Component.
4
+
5
+ @param {string} id - Unique modal id
6
+ @param {string} content - HTML content of the modal
7
+ @param {string} [title] - Optional title
8
+ @param {string} [custom_class] - Extra CSS classes
9
+
10
+ @example
11
+ {% render 'rk-modal', id: 'my-modal', title: 'Quick View', content: some_html %}
12
+ {% enddoc %}
13
+
14
+ <rk-modal-element data-modal-id="{{ id }}">
15
+ <div id="{{ id }}" class="rk-modal{% if custom_class %} {{ custom_class }}{% endif %}">
16
+ <div class="rk-modal__overlay" data-action="close"></div>
17
+ <div class="rk-modal__content" role="dialog" aria-modal="true" {% if title %}aria-label="{{ title }}"{% endif %}>
18
+ <button type="button" class="rk-modal__close" data-action="close" aria-label="Fechar">
19
+ <svg width="20" height="20" viewBox="0 0 20 20" fill="none">
20
+ <path d="M15 5L5 15M5 5l10 10" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
21
+ </svg>
22
+ </button>
23
+
24
+ {% if title %}
25
+ <h2 class="rk-typography rk-typography--lg rk-typography--bold" style="margin-bottom: var(--rk-space-md);">{{ title }}</h2>
26
+ {% endif %}
27
+
28
+ {{ content }}
29
+ </div>
30
+ </div>
31
+ </rk-modal-element>
@@ -0,0 +1,34 @@
1
+ {% doc %}
2
+ Snippet: RkPixDiscount
3
+ Renders the Pix discount price reading global settings.
4
+
5
+ @param {number} price - Price in cents to apply discount
6
+ @param {string} [custom_class] - Extra CSS classes
7
+
8
+ @example
9
+ {% render 'rk-pix-discount', price: product.selected_or_first_available_variant.price %}
10
+ {% enddoc %}
11
+
12
+ {%- liquid
13
+ unless settings.rk_pix_enabled
14
+ break
15
+ endunless
16
+
17
+ assign pix_discount_pct = settings.rk_pix_discount | default: 5
18
+ assign pix_label = settings.rk_pix_label | default: 'no Pix'
19
+
20
+ assign discount_multiplier = 100 | minus: pix_discount_pct
21
+ assign pix_price = price | times: discount_multiplier | divided_by: 100
22
+ assign formatted_pix = pix_price | money
23
+ -%}
24
+
25
+ {% if pix_discount_pct > 0 %}
26
+ <span class="rk-pix{% if custom_class %} {{ custom_class }}{% endif %}">
27
+ <svg class="rk-pix__icon" viewBox="0 0 512 512" fill="currentColor" aria-hidden="true">
28
+ <path d="M393.8 254.3l-79.3-79.3c-14.7-14.7-38.5-14.7-53.2 0L182 254.3c-14.7 14.7-14.7 38.5 0 53.2l79.3 79.3c14.7 14.7 38.5 14.7 53.2 0l79.3-79.3c14.7-14.7 14.7-38.5 0-53.2zM239.7 346.5L165.9 272.7c-3.9-3.9-3.9-10.2 0-14.1l73.8-73.8c3.9-3.9 10.2-3.9 14.1 0l73.8 73.8c3.9 3.9 3.9 10.2 0 14.1l-73.8 73.8c-3.9 3.9-10.2 3.9-14.1 0z"/>
29
+ </svg>
30
+ <span>{{ formatted_pix }}</span>
31
+ <span>{{ pix_label }}</span>
32
+ <span class="rk-pix__badge">-{{ pix_discount_pct }}%</span>
33
+ </span>
34
+ {% endif %}
@@ -0,0 +1,77 @@
1
+ {% doc %}
2
+ Snippet: RkPopover
3
+ Renders a Popover component (floating overlay triggered by click).
4
+ Uses Web Component <rk-popover-element> for behaviour.
5
+
6
+ @param {string} id - Unique popover id
7
+ @param {string} [side] - Preferred side: 'top' | 'bottom' | 'left' | 'right' (default: 'bottom')
8
+ @param {string} [align] - Alignment: 'start' | 'center' | 'end' (default: 'center')
9
+ @param {number} [side_offset] - Distance from trigger in px (default: 8)
10
+ @param {number} [align_offset] - Lateral shift in px (default: 0)
11
+ @param {boolean} [show_arrow] - Show pointing arrow (default: true)
12
+ @param {string} [title] - Optional header title
13
+ @param {string} [description] - Optional header description
14
+ @param {string} [trigger_content] - HTML for the trigger element
15
+ @param {string} [body] - HTML for the body content
16
+ @param {string} [custom_class] - Extra CSS classes for the content container
17
+ @param {string} [width] - Content container width (e.g. '320px')
18
+
19
+ @example
20
+ {% capture popover_trigger %}
21
+ {% render 'rk-button', text: 'Open Popover', style: 'outline', size: 'sm' %}
22
+ {% endcapture %}
23
+ {% capture popover_body %}
24
+ <p>Any rich content here</p>
25
+ {% endcapture %}
26
+ {% render 'rk-popover', id: 'my-pop', trigger_content: popover_trigger, body: popover_body, title: 'Settings' %}
27
+ {% enddoc %}
28
+
29
+ {%- liquid
30
+ assign pop_side = side | default: 'bottom'
31
+ assign pop_align = align | default: 'center'
32
+ assign pop_side_offset = side_offset | default: 8
33
+ assign pop_align_offset = align_offset | default: 0
34
+ assign pop_show_arrow = show_arrow | default: true
35
+ -%}
36
+
37
+ <rk-popover-element
38
+ data-side="{{ pop_side }}"
39
+ data-align="{{ pop_align }}"
40
+ data-side-offset="{{ pop_side_offset }}"
41
+ data-align-offset="{{ pop_align_offset }}"
42
+ class="rk-popover"
43
+ >
44
+ {%- comment -%} Trigger Area {%- endcomment -%}
45
+ <div data-rk-popover-trigger class="rk-popover__trigger">
46
+ {{ trigger_content }}
47
+ </div>
48
+
49
+ {%- comment -%} Content Container {%- endcomment -%}
50
+ <div
51
+ id="{{ id }}"
52
+ class="rk-popover__content{% if custom_class %} {{ custom_class }}{% endif %}"
53
+ role="dialog"
54
+ aria-modal="false"
55
+ {% if title %}aria-label="{{ title }}"{% endif %}
56
+ {% if width %}style="--rk-popover-width: {{ width }};"{% endif %}
57
+ >
58
+ {%- if pop_show_arrow -%}
59
+ <div class="rk-popover__arrow"></div>
60
+ {%- endif -%}
61
+
62
+ {%- if title or description -%}
63
+ <div class="rk-popover__header">
64
+ {%- if title -%}
65
+ <h3 class="rk-popover__title">{{ title }}</h3>
66
+ {%- endif -%}
67
+ {%- if description -%}
68
+ <p class="rk-popover__description">{{ description }}</p>
69
+ {%- endif -%}
70
+ </div>
71
+ {%- endif -%}
72
+
73
+ <div class="rk-popover__body">
74
+ {{ body }}
75
+ </div>
76
+ </div>
77
+ </rk-popover-element>
@@ -0,0 +1,48 @@
1
+ {% doc %}
2
+ Snippet: RkPrice
3
+ Renders a configurable price display with optional promotional/compare pricing.
4
+
5
+ @param {object} product - The product object
6
+ @param {boolean} [from] - Show "A partir de" prefix
7
+ @param {boolean} [show_compare] - Force show compare-at price
8
+ @param {string} [compare_position] - 'before' | 'after' (default: 'before')
9
+ @param {string} [custom_class] - Extra CSS classes
10
+
11
+ @example
12
+ {% render 'rk-price', product: product, from: true %}
13
+ {% enddoc %}
14
+
15
+ {%- liquid
16
+ assign selected_variant = product.selected_or_first_available_variant
17
+ assign current_price = selected_variant.price
18
+ assign compare_price = selected_variant.compare_at_price
19
+ assign cmp_position = compare_position | default: 'before'
20
+
21
+ assign is_on_sale = false
22
+ if compare_price > current_price
23
+ assign is_on_sale = true
24
+ endif
25
+
26
+ if product == blank
27
+ assign current_price = 1999
28
+ endif
29
+
30
+ assign formatted_price = current_price | money
31
+ assign formatted_compare = compare_price | money
32
+ -%}
33
+
34
+ <div class="rk-price{% if is_on_sale %} rk-price--sale{% endif %}{% if custom_class %} {{ custom_class }}{% endif %}">
35
+ {%- if from -%}
36
+ <span class="rk-price__from">A partir de</span>
37
+ {%- endif -%}
38
+
39
+ {%- if is_on_sale and cmp_position == 'before' -%}
40
+ <span class="rk-price__compare">{{ formatted_compare }}</span>
41
+ {%- endif -%}
42
+
43
+ <span class="rk-price__current">{{ formatted_price }}</span>
44
+
45
+ {%- if is_on_sale and cmp_position == 'after' -%}
46
+ <span class="rk-price__compare">{{ formatted_compare }}</span>
47
+ {%- endif -%}
48
+ </div>
@@ -0,0 +1,38 @@
1
+ {% doc %}
2
+ Snippet: RkProgress
3
+ Renders a visual Progress Bar (Shadcn/UI pattern).
4
+ The Web Component `<rk-progress-element>` animates changes using CSS transform.
5
+
6
+ @param {number} value - Current progress value
7
+ @param {number} [max] - Maximum progress value (default: 100)
8
+ @param {string} [id] - Unique id for accessibility linking
9
+ @param {string} [aria_label] - Describe the context for screen readers
10
+ @param {string} [custom_class] - Extra CSS classes for sizing or coloring
11
+
12
+ @example
13
+ {% render 'rk-progress', value: 45, aria_label: 'Progresso do Frete Grátis' %}
14
+ {% enddoc %}
15
+
16
+ {%- liquid
17
+ assign t_value = value | default: 0
18
+ assign t_max = max | default: 100
19
+ -%}
20
+
21
+ <rk-progress-element
22
+ data-value="{{ t_value }}"
23
+ data-max="{{ t_max }}"
24
+ {% if id %}id="{{ id }}"{% endif %}
25
+ class="rk-progress{% if custom_class %} {{ custom_class }}{% endif %}"
26
+ >
27
+ <div
28
+ class="rk-progress__track"
29
+ role="progressbar"
30
+ aria-valuenow="{{ t_value }}"
31
+ aria-valuemin="0"
32
+ aria-valuemax="{{ t_max }}"
33
+ aria-valuetext="{{ t_value }} de {{ t_max }}"
34
+ {% if aria_label %}aria-label="{{ aria_label }}"{% endif %}
35
+ >
36
+ <div class="rk-progress__indicator"></div>
37
+ </div>
38
+ </rk-progress-element>