basecoat-cli 0.1.1 → 0.2.0
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/assets/jinja/dialog.html.jinja +1 -1
- package/dist/assets/jinja/dropdown-menu.html.jinja +3 -3
- package/dist/assets/jinja/select.html.jinja +61 -49
- package/dist/assets/jinja/toast.html.jinja +2 -2
- package/dist/assets/js/all.js +796 -0
- package/dist/assets/js/all.min.js +1 -0
- package/dist/assets/js/dark-mode.js +10 -0
- package/dist/assets/js/dark-mode.min.js +1 -0
- package/dist/assets/js/dropdown-menu.js +128 -83
- package/dist/assets/js/dropdown-menu.min.js +1 -0
- package/dist/assets/js/popover.js +69 -26
- package/dist/assets/js/popover.min.js +1 -0
- package/dist/assets/js/select.js +195 -136
- package/dist/assets/js/select.min.js +1 -0
- package/dist/assets/js/sidebar.js +109 -24
- package/dist/assets/js/sidebar.min.js +1 -0
- package/dist/assets/js/tabs.js +68 -57
- package/dist/assets/js/tabs.min.js +1 -0
- package/dist/assets/js/toast.js +183 -62
- package/dist/assets/js/toast.min.js +1 -0
- package/dist/assets/nunjucks/dialog.njk +63 -79
- package/dist/assets/nunjucks/dropdown-menu.njk +29 -27
- package/dist/assets/nunjucks/popover.njk +11 -19
- package/dist/assets/nunjucks/select.njk +57 -37
- package/dist/assets/nunjucks/sidebar.njk +2 -5
- package/dist/assets/nunjucks/tabs.njk +7 -8
- package/dist/assets/nunjucks/toast.njk +45 -134
- package/dist/index.js +7 -7
- package/package.json +1 -1
- package/dist/assets/js/dialog.js +0 -54
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
@param name {string} [optional] - The name attribute for the hidden input storing the selected value.
|
|
7
7
|
@param main_attrs {object} [optional] - Additional HTML attributes for the main container div.
|
|
8
8
|
@param trigger_attrs {object} [optional] - Additional HTML attributes for the trigger button.
|
|
9
|
-
@param
|
|
9
|
+
@param popover_attrs {object} [optional] - Additional HTML attributes for the popover content div.
|
|
10
10
|
@param listbox_attrs {object} [optional] - Additional HTML attributes for the listbox div.
|
|
11
11
|
@param input_attrs {object} [optional] - Additional HTML attributes for the hidden input.
|
|
12
12
|
@param search_placeholder {string} [optional] [default="Search entries..."] - Placeholder text for the search input (combobox only).
|
|
@@ -19,37 +19,59 @@
|
|
|
19
19
|
items=None,
|
|
20
20
|
main_attrs={},
|
|
21
21
|
trigger_attrs={},
|
|
22
|
-
|
|
22
|
+
popover_attrs={},
|
|
23
23
|
listbox_attrs={},
|
|
24
24
|
input_attrs={},
|
|
25
25
|
search_placeholder="Search entries...",
|
|
26
26
|
is_combobox=false
|
|
27
27
|
) %}
|
|
28
|
+
{% set id = id or ("select-" + (range(100000, 999999) | random | string)) %}
|
|
29
|
+
|
|
30
|
+
{% set first_option = [] %}
|
|
31
|
+
{% set selected_option = [] %}
|
|
32
|
+
|
|
33
|
+
{% if items %}
|
|
34
|
+
{% for item in items %}
|
|
35
|
+
{% if item.type == "group" %}
|
|
36
|
+
{% for sub_item in item.items %}
|
|
37
|
+
{% if not first_option[0] %}
|
|
38
|
+
{% set first_option = (first_option.push(sub_item), first_option) %}
|
|
39
|
+
{% endif %}
|
|
40
|
+
{% if selected and sub_item.value == selected and not selected_option[0] %}
|
|
41
|
+
{% set selected_option = (selected_option.push(sub_item), selected_option) %}
|
|
42
|
+
{% endif %}
|
|
43
|
+
{% endfor %}
|
|
44
|
+
{% else %}
|
|
45
|
+
{% if not first_option[0] %}
|
|
46
|
+
{% set first_option = (first_option.push(item), first_option) %}
|
|
47
|
+
{% endif %}
|
|
48
|
+
{% if selected and item.value == selected and not selected_option[0] %}
|
|
49
|
+
{% set selected_option = (selected_option.push(item), selected_option) %}
|
|
50
|
+
{% endif %}
|
|
51
|
+
{% endif %}
|
|
52
|
+
{% endfor %}
|
|
53
|
+
{% endif %}
|
|
54
|
+
|
|
55
|
+
{% set default_option = selected_option[0] or first_option[0] or None %}
|
|
56
|
+
|
|
28
57
|
<div
|
|
29
|
-
class="
|
|
30
|
-
x-data="select('{{ name }}', '{{ selected or '' }}')"
|
|
31
|
-
@click.away="open = false"
|
|
32
|
-
{% if id %}id="{{ id }}"{% endif %}
|
|
58
|
+
class="select {{ main_attrs.class }}"
|
|
33
59
|
{% for key, value in main_attrs %}
|
|
34
60
|
{% if key != 'class' %}{{ key }}="{{ value }}"{% endif %}
|
|
35
61
|
{% endfor %}
|
|
36
62
|
>
|
|
37
63
|
<button
|
|
38
64
|
type="button"
|
|
65
|
+
class="btn-outline justify-between font-normal {{ trigger_attrs.class }}"
|
|
66
|
+
id="{{ id }}-trigger"
|
|
39
67
|
aria-haspopup="listbox"
|
|
40
68
|
aria-expanded="false"
|
|
41
|
-
|
|
42
|
-
{% if id %}
|
|
43
|
-
id="{{ id }}-trigger"
|
|
44
|
-
aria-controls="{{ id }}-content"
|
|
45
|
-
{% endif %}
|
|
46
|
-
class="btn-outline justify-between font-normal {{ trigger_attrs.class }}"
|
|
69
|
+
aria-controls="{{ id }}-listbox"
|
|
47
70
|
{% for key, value in trigger_attrs %}
|
|
48
71
|
{% if key != 'class' %}{{ key }}="{{ value }}"{% endif %}
|
|
49
72
|
{% endfor %}
|
|
50
73
|
>
|
|
51
|
-
<
|
|
52
|
-
></div>
|
|
74
|
+
<span class="truncate">{{ default_option.label }}</span>
|
|
53
75
|
{% if is_combobox %}
|
|
54
76
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevrons-up-down-icon lucide-chevrons-up-down text-muted-foreground opacity-50 shrink-0"><path d="m7 15 5 5 5-5"/><path d="m7 9 5-5 5 5"/></svg>
|
|
55
77
|
{% else %}
|
|
@@ -57,11 +79,10 @@
|
|
|
57
79
|
{% endif %}
|
|
58
80
|
</button>
|
|
59
81
|
<div
|
|
82
|
+
id="{{ id }}"
|
|
60
83
|
data-popover
|
|
61
84
|
aria-hidden="true"
|
|
62
|
-
|
|
63
|
-
{% if id %}id="{{ id }}-content"{% endif %}
|
|
64
|
-
{% for key, value in content_attrs %}
|
|
85
|
+
{% for key, value in popover_attrs %}
|
|
65
86
|
{{ key }}="{{ value }}"
|
|
66
87
|
{% endfor %}
|
|
67
88
|
>
|
|
@@ -77,38 +98,36 @@
|
|
|
77
98
|
spellcheck="false"
|
|
78
99
|
aria-autocomplete="list"
|
|
79
100
|
role="combobox"
|
|
80
|
-
aria-expanded="
|
|
81
|
-
aria-controls="{{ id }}-
|
|
101
|
+
aria-expanded="false"
|
|
102
|
+
aria-controls="{{ id }}-listbox"
|
|
82
103
|
aria-labelledby="{{ id }}-trigger"
|
|
83
|
-
x-model="query"
|
|
84
|
-
x-bind="$filter"
|
|
85
104
|
>
|
|
86
105
|
</header>
|
|
87
106
|
{% endif %}
|
|
88
107
|
<div
|
|
89
108
|
role="listbox"
|
|
109
|
+
id="{{ id }}-listbox"
|
|
90
110
|
aria-orientation="vertical"
|
|
111
|
+
aria-labelledby="{{ id }}-trigger"
|
|
91
112
|
{% for key, value in listbox_attrs %}
|
|
92
113
|
{{ key }}="{{ value }}"
|
|
93
114
|
{% endfor %}
|
|
94
115
|
>
|
|
95
|
-
{% if items %}
|
|
96
|
-
{{ render_select_items(items, id ~ "-items" if id else "items") }}
|
|
116
|
+
{% if items and items.length > 0 %}
|
|
117
|
+
{{ render_select_items(items, default_option.value, id ~ "-items" if id else "items") }}
|
|
97
118
|
{% else %}
|
|
98
119
|
{{ caller() if caller }}
|
|
99
120
|
{% endif %}
|
|
100
121
|
</div>
|
|
101
122
|
</div>
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
{%
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
>
|
|
111
|
-
{% endif %}
|
|
123
|
+
<input
|
|
124
|
+
type="hidden"
|
|
125
|
+
name="{{ name or id ~ '-value' }}"
|
|
126
|
+
value="{{ (default_option.value if default_option) or '' }}"
|
|
127
|
+
{% for key, value in input_attrs %}
|
|
128
|
+
{% if key != 'name' and key != 'value' %}{{ key }}="{{ value }}"{% endif %}
|
|
129
|
+
{% endfor %}
|
|
130
|
+
>
|
|
112
131
|
</div>
|
|
113
132
|
{% endmacro %}
|
|
114
133
|
|
|
@@ -118,10 +137,9 @@
|
|
|
118
137
|
@param items {array} - The array of items to render.
|
|
119
138
|
@param parent_id_prefix {string} [optional] - The prefix for the item id.
|
|
120
139
|
#}
|
|
121
|
-
{% macro render_select_items(items, parent_id_prefix="items") %}
|
|
140
|
+
{% macro render_select_items(items, selected, parent_id_prefix="items") %}
|
|
122
141
|
{% for item in items %}
|
|
123
142
|
{% set item_id = parent_id_prefix ~ "-" ~ loop.index %}
|
|
124
|
-
|
|
125
143
|
{% if item.type == "group" %}
|
|
126
144
|
{% set group_label_id = item.id if item.id else "group-label-" + item_id %}
|
|
127
145
|
<div
|
|
@@ -131,15 +149,17 @@
|
|
|
131
149
|
{{ key }}="{{ value }}"
|
|
132
150
|
{% endfor %}
|
|
133
151
|
>
|
|
134
|
-
<div role="
|
|
135
|
-
{{ render_select_items(item.items, item_id) if item.items }}
|
|
152
|
+
<div role="presentation" id="{{ group_label_id }}">{{ item.label }}</div>
|
|
153
|
+
{{ render_select_items(item.items, selected, item_id) if item.items }}
|
|
136
154
|
</div>
|
|
137
155
|
{% elif item.type == "separator" %}
|
|
138
156
|
<hr role="separator" />
|
|
139
157
|
{% elif item.type == "item" or not item.type %}
|
|
140
158
|
<div
|
|
159
|
+
id="{{ item_id }}"
|
|
141
160
|
role="option"
|
|
142
161
|
data-value="{{ item.value }}"
|
|
162
|
+
{% if selected == item.value %}aria-selected="true"{% endif %}
|
|
143
163
|
{% for key, value in item.attrs %}
|
|
144
164
|
{{ key }}="{{ value }}"
|
|
145
165
|
{% endfor %}
|
|
@@ -23,18 +23,15 @@
|
|
|
23
23
|
footer_attrs={},
|
|
24
24
|
content_wrapper_attrs=None
|
|
25
25
|
) %}
|
|
26
|
-
<
|
|
26
|
+
<aside
|
|
27
27
|
{% if id %}id="{{ id }}"{% endif %}
|
|
28
28
|
class="sidebar {{ main_attrs.class }}"
|
|
29
|
-
data-uninitialized
|
|
30
29
|
data-side="{{ side if side else "left" }}"
|
|
31
30
|
aria-hidden="{{ "true" if not open else "false" }}"
|
|
32
31
|
{{ "inert" if not open }}
|
|
33
32
|
{% for key, value in main_attrs %}
|
|
34
33
|
{% if key != "class" %}{{ key }}="{{ value }}"{% endif %}
|
|
35
34
|
{% endfor %}
|
|
36
|
-
x-data="sidebar({{ "true" if open else "false" }})"
|
|
37
|
-
x-bind="$main"
|
|
38
35
|
>
|
|
39
36
|
<nav
|
|
40
37
|
aria-label="{{ label }}"
|
|
@@ -71,7 +68,7 @@
|
|
|
71
68
|
</footer>
|
|
72
69
|
{% endif %}
|
|
73
70
|
</nav>
|
|
74
|
-
</
|
|
71
|
+
</aside>
|
|
75
72
|
{% endmacro %}
|
|
76
73
|
|
|
77
74
|
{#
|
|
@@ -14,17 +14,17 @@
|
|
|
14
14
|
@param default_tab_index {number} [optional] [default=1] - The 1-based index of the tab to be active initially.
|
|
15
15
|
#}
|
|
16
16
|
{% macro tabs(
|
|
17
|
-
id,
|
|
17
|
+
id=None,
|
|
18
18
|
tabsets=[],
|
|
19
19
|
main_attrs=None,
|
|
20
20
|
tablist_attrs=None,
|
|
21
21
|
default_tab_index=1
|
|
22
22
|
)
|
|
23
23
|
%}
|
|
24
|
+
{% set id = id or ("tabs-" + (range(100000, 999999) | random | string)) %}
|
|
24
25
|
<div
|
|
25
26
|
class="tabs {{ main_attrs.class }}"
|
|
26
|
-
|
|
27
|
-
{% if id %}id="{{ id }}"{% endif %}
|
|
27
|
+
id="{{ id }}"
|
|
28
28
|
{% for key, value in main_attrs %}
|
|
29
29
|
{% if key != 'class' %}{{ key }}="{{ value }}"{% endif %}
|
|
30
30
|
{% endfor %}
|
|
@@ -32,7 +32,6 @@
|
|
|
32
32
|
<nav
|
|
33
33
|
role="tablist"
|
|
34
34
|
aria-orientation="horizontal"
|
|
35
|
-
x-bind="$tablist"
|
|
36
35
|
{% for key, value in tablist_attrs %}
|
|
37
36
|
{{ key }}="{{ value }}"
|
|
38
37
|
{% endfor %}
|
|
@@ -41,8 +40,8 @@
|
|
|
41
40
|
<button
|
|
42
41
|
type="button"
|
|
43
42
|
role="tab"
|
|
44
|
-
id="{{
|
|
45
|
-
aria-controls="{{
|
|
43
|
+
id="{{ id }}-tab-{{ loop.index }}"
|
|
44
|
+
aria-controls="{{ id }}-panel-{{ loop.index }}"
|
|
46
45
|
aria-selected="{{ 'true' if loop.index == default_tab_index else 'false' }}"
|
|
47
46
|
tabindex="0"
|
|
48
47
|
{% for key, value in tabset.tab_attrs %}
|
|
@@ -58,8 +57,8 @@
|
|
|
58
57
|
{% if tabset.panel %}
|
|
59
58
|
<div
|
|
60
59
|
role="tabpanel"
|
|
61
|
-
id="{{
|
|
62
|
-
aria-labelledby="{{
|
|
60
|
+
id="{{ id }}-panel-{{ loop.index }}"
|
|
61
|
+
aria-labelledby="{{ id }}-tab-{{ loop.index }}"
|
|
63
62
|
tabindex="-1"
|
|
64
63
|
aria-selected="{{ 'true' if loop.index == default_tab_index else 'false' }}"
|
|
65
64
|
{% if loop.index != default_tab_index %}hidden{% endif %}
|
|
@@ -10,16 +10,14 @@
|
|
|
10
10
|
{% macro toaster(
|
|
11
11
|
id="toaster",
|
|
12
12
|
toasts=[],
|
|
13
|
-
|
|
14
|
-
is_fragment=false
|
|
13
|
+
attrs=None
|
|
15
14
|
) %}
|
|
16
15
|
<div
|
|
17
16
|
id="{{ id }}"
|
|
18
|
-
class="toaster"
|
|
19
|
-
{% for key, value in
|
|
20
|
-
{{ key }}="{{ value }}"
|
|
17
|
+
class="toaster {{ attrs.class }}"
|
|
18
|
+
{% for key, value in attrs %}
|
|
19
|
+
{% if key != 'class' %}{{ key }}="{{ value }}"{% endif %}
|
|
21
20
|
{% endfor %}
|
|
22
|
-
{% if is_fragment %}hx-swap-oob="beforeend"{% endif %}
|
|
23
21
|
>
|
|
24
22
|
{% for item in toasts %}
|
|
25
23
|
{{ toast(
|
|
@@ -31,79 +29,6 @@
|
|
|
31
29
|
) }}
|
|
32
30
|
{% endfor %}
|
|
33
31
|
</div>
|
|
34
|
-
|
|
35
|
-
{% if not is_fragment %}
|
|
36
|
-
<template id="toast-template">
|
|
37
|
-
<div
|
|
38
|
-
class="toast"
|
|
39
|
-
role="status"
|
|
40
|
-
aria-atomic="true"
|
|
41
|
-
x-bind="$toastBindings"
|
|
42
|
-
>
|
|
43
|
-
<div class="toast-content">
|
|
44
|
-
<div class="flex items-center justify-between gap-x-3 p-4 [&>svg]:size-4 [&>svg]:shrink-0 [&>[role=img]]:size-4 [&>[role=img]]:shrink-0 [&>[role=img]>svg]:size-4">
|
|
45
|
-
<template x-if="config.icon">
|
|
46
|
-
<span aria-hidden="true" role="img" x-html="config.icon"></span>
|
|
47
|
-
</template>
|
|
48
|
-
<template x-if="!config.icon && config.category === 'success'">
|
|
49
|
-
{{ toast_icons.success | safe }}
|
|
50
|
-
</template>
|
|
51
|
-
<template x-if="!config.icon && config.category === 'error'">
|
|
52
|
-
{{ toast_icons.error | safe }}
|
|
53
|
-
</template>
|
|
54
|
-
<template x-if="!config.icon && config.category === 'info'">
|
|
55
|
-
{{ toast_icons.info | safe }}
|
|
56
|
-
</template>
|
|
57
|
-
<template x-if="!config.icon && config.category === 'warning'">
|
|
58
|
-
{{ toast_icons.warning | safe }}
|
|
59
|
-
</template>
|
|
60
|
-
<section class="flex-1 flex flex-col gap-0.5 items-start">
|
|
61
|
-
<template x-if="config.title">
|
|
62
|
-
<h2 class="font-medium" x-text="config.title"></h2>
|
|
63
|
-
</template>
|
|
64
|
-
<template x-if="config.description">
|
|
65
|
-
<p class="text-muted-foreground" x-text="config.description"></p>
|
|
66
|
-
</template>
|
|
67
|
-
</section>
|
|
68
|
-
<template x-if="config.action || config.cancel">
|
|
69
|
-
<footer class="flex flex-col gap-1 self-start">
|
|
70
|
-
<template x-if="config.action?.click">
|
|
71
|
-
<button
|
|
72
|
-
type="button"
|
|
73
|
-
class="btn h-6 text-xs px-2.5 rounded-sm"
|
|
74
|
-
@click="executeAction(config.action.click)"
|
|
75
|
-
x-text="config.action.label"
|
|
76
|
-
></button>
|
|
77
|
-
</template>
|
|
78
|
-
<template x-if="config.action?.url">
|
|
79
|
-
<a
|
|
80
|
-
:href="config.action.url"
|
|
81
|
-
class="btn h-6 text-xs px-2.5 rounded-sm"
|
|
82
|
-
x-text="config.action.label"
|
|
83
|
-
></a>
|
|
84
|
-
</template>
|
|
85
|
-
<template x-if="config.cancel?.click">
|
|
86
|
-
<button
|
|
87
|
-
type="button"
|
|
88
|
-
class="btn-outline h-6 text-xs px-2.5 rounded-sm"
|
|
89
|
-
@click="executeAction(config.cancel.click)"
|
|
90
|
-
x-text="config.cancel.label"
|
|
91
|
-
></button>
|
|
92
|
-
</template>
|
|
93
|
-
<template x-if="config.cancel?.url">
|
|
94
|
-
<a
|
|
95
|
-
:href="config.cancel.url"
|
|
96
|
-
class="btn-outline h-6 text-xs px-2.5 rounded-sm"
|
|
97
|
-
x-text="config.cancel.label"
|
|
98
|
-
></a>
|
|
99
|
-
</template>
|
|
100
|
-
</footer>
|
|
101
|
-
</template>
|
|
102
|
-
</div>
|
|
103
|
-
</div>
|
|
104
|
-
</div>
|
|
105
|
-
</template>
|
|
106
|
-
{% endif %}
|
|
107
32
|
{% endmacro %}
|
|
108
33
|
|
|
109
34
|
{#
|
|
@@ -134,65 +59,51 @@
|
|
|
134
59
|
aria-atomic="true"
|
|
135
60
|
aria-hidden="false"
|
|
136
61
|
{% if category %}data-category="{{ category }}"{% endif %}
|
|
137
|
-
x-data="toast({
|
|
138
|
-
category: '{{ category }}',
|
|
139
|
-
duration: {{ duration or 'null' }}
|
|
140
|
-
})"
|
|
141
|
-
x-bind="$toastBindings"
|
|
142
62
|
>
|
|
143
63
|
<div class="toast-content">
|
|
144
|
-
|
|
145
|
-
{% if category
|
|
146
|
-
{
|
|
64
|
+
{% if category in ["error", "success", "info", "warning"] %}
|
|
65
|
+
{% if category == "success" %}
|
|
66
|
+
{% lucide "circle-check" %}
|
|
67
|
+
{% elif category == "error" %}
|
|
68
|
+
{% lucide "circle-x" %}
|
|
69
|
+
{% elif category == "info" %}
|
|
70
|
+
{% lucide "info" %}
|
|
71
|
+
{% elif category == "warning" %}
|
|
72
|
+
{% lucide "triangle-alert" %}
|
|
147
73
|
{% endif %}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
74
|
+
{% endif %}
|
|
75
|
+
<section>
|
|
76
|
+
{% if title %}<h2>{{ title }}</h2>{% endif %}
|
|
77
|
+
{% if description %}<p>{{ description }}</p>{% endif %}
|
|
78
|
+
</section>
|
|
79
|
+
{% if action or cancel %}
|
|
80
|
+
<footer>
|
|
81
|
+
{% if action %}
|
|
82
|
+
{% if action.href %}
|
|
83
|
+
<a
|
|
84
|
+
href="{{ action.href }}"
|
|
85
|
+
class="btn-sm"
|
|
86
|
+
data-toast-action
|
|
87
|
+
>{{ action.label }}</a>
|
|
88
|
+
{% else %}
|
|
89
|
+
<button
|
|
90
|
+
type="button"
|
|
91
|
+
class="btn"
|
|
92
|
+
data-toast-action
|
|
93
|
+
{% if action.onclick %}onclick="{{ action.onclick }}"{% endif %}
|
|
94
|
+
>{{ action.label }}</button>
|
|
95
|
+
{% endif %}
|
|
151
96
|
{% endif %}
|
|
152
|
-
{% if
|
|
153
|
-
<
|
|
97
|
+
{% if cancel %}
|
|
98
|
+
<button
|
|
99
|
+
type="button"
|
|
100
|
+
class="btn-sm-outline"
|
|
101
|
+
data-toast-cancel
|
|
102
|
+
{% if cancel.onclick %}onclick="{{ cancel.onclick }}"{% endif %}
|
|
103
|
+
>{{ cancel.label }}</button>
|
|
154
104
|
{% endif %}
|
|
155
|
-
</
|
|
156
|
-
|
|
157
|
-
<footer class="flex flex-col gap-1 self-start">
|
|
158
|
-
{% if action %}
|
|
159
|
-
{% if action.click %}
|
|
160
|
-
<button
|
|
161
|
-
type="button"
|
|
162
|
-
class="btn h-6 text-xs px-2.5 rounded-sm"
|
|
163
|
-
@click="{{ action.click }}"
|
|
164
|
-
>{{ action.label }}</button>
|
|
165
|
-
{% elif action.url %}
|
|
166
|
-
<a
|
|
167
|
-
href="{{ action.url }}"
|
|
168
|
-
class="btn h-6 text-xs px-2.5 rounded-sm"
|
|
169
|
-
>{{ action.label }}</a>
|
|
170
|
-
{% endif %}
|
|
171
|
-
{% endif %}
|
|
172
|
-
{% if cancel %}
|
|
173
|
-
{% if cancel.click %}
|
|
174
|
-
<button
|
|
175
|
-
type="button"
|
|
176
|
-
class="btn-outline h-6 text-xs px-2.5 rounded-sm"
|
|
177
|
-
@click="{{ cancel.click }}"
|
|
178
|
-
>{{ cancel.label }}</button>
|
|
179
|
-
{% elif cancel.url %}
|
|
180
|
-
<a
|
|
181
|
-
href="{{ cancel.url }}"
|
|
182
|
-
class="btn-outline h-6 text-xs px-2.5 rounded-sm"
|
|
183
|
-
>{{ toast.cancel.label }}</a>
|
|
184
|
-
{% endif %}
|
|
185
|
-
{% endif %}
|
|
186
|
-
</footer>
|
|
187
|
-
{% endif %}
|
|
188
|
-
</div>
|
|
105
|
+
</footer>
|
|
106
|
+
{% endif %}
|
|
189
107
|
</div>
|
|
190
108
|
</div>
|
|
191
|
-
{% endmacro %}
|
|
192
|
-
|
|
193
|
-
{% set toast_icons = {
|
|
194
|
-
'success': '<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-circle-check-icon lucide-circle-check"><circle cx="12" cy="12" r="10"/><path d="m9 12 2 2 4-4"/></svg>',
|
|
195
|
-
'error': '<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-circle-x-icon lucide-circle-x"><circle cx="12" cy="12" r="10"/><path d="m15 9-6 6"/><path d="m9 9 6 6"/></svg>',
|
|
196
|
-
'info': '<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-info-icon lucide-info"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>',
|
|
197
|
-
'warning': '<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-triangle-alert-icon lucide-triangle-alert"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/></svg>'
|
|
198
|
-
} %}
|
|
109
|
+
{% endmacro %}
|
package/dist/index.js
CHANGED
|
@@ -62,17 +62,17 @@ async function ensureConfiguration() {
|
|
|
62
62
|
const pathPrompts = [];
|
|
63
63
|
if (!config.templateDest || config.templateDest === DEFAULT_CONFIG.templateDest) {
|
|
64
64
|
pathPrompts.push({
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
type: 'input',
|
|
66
|
+
name: 'templateDest',
|
|
67
|
+
message: 'Where should template files be placed?',
|
|
68
68
|
default: DEFAULT_CONFIG.templateDest,
|
|
69
69
|
});
|
|
70
70
|
}
|
|
71
71
|
if (!config.scriptDest || config.scriptDest === DEFAULT_CONFIG.scriptDest) {
|
|
72
72
|
pathPrompts.push({
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
type: 'input',
|
|
74
|
+
name: 'scriptDest',
|
|
75
|
+
message: 'Where should script files be placed?',
|
|
76
76
|
default: DEFAULT_CONFIG.scriptDest,
|
|
77
77
|
});
|
|
78
78
|
}
|
|
@@ -108,7 +108,7 @@ async function addComponent(componentName) {
|
|
|
108
108
|
}
|
|
109
109
|
if (!scriptExists) {
|
|
110
110
|
console.error(` Error: Script file for component '${componentName}' not found in CLI assets. Searched: ${scriptSource}`);
|
|
111
|
-
|
|
111
|
+
}
|
|
112
112
|
if (!templateExists || !scriptExists) return; // Skip this component if sources are missing
|
|
113
113
|
|
|
114
114
|
await fs.ensureDir(path.dirname(templateDestPath));
|
package/package.json
CHANGED
package/dist/assets/js/dialog.js
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
window.basecoat = window.basecoat || {};
|
|
2
|
-
window.basecoat.registerDialog = function(Alpine) {
|
|
3
|
-
if (Alpine.components && Alpine.components.dialog) return;
|
|
4
|
-
|
|
5
|
-
Alpine.data('dialog', (initialOpen = false, initialCloseOnOverlayClick = true) => ({
|
|
6
|
-
id: null,
|
|
7
|
-
open: false,
|
|
8
|
-
closeOnOverlayClick: true,
|
|
9
|
-
|
|
10
|
-
init() {
|
|
11
|
-
this.id = this.$el.id;
|
|
12
|
-
if (!this.id) {
|
|
13
|
-
console.warn('Dialog component initialized without an `id`. This may cause issues with event targeting and accessibility.');
|
|
14
|
-
}
|
|
15
|
-
this.open = initialOpen;
|
|
16
|
-
this.closeOnOverlayClick = initialCloseOnOverlayClick;
|
|
17
|
-
},
|
|
18
|
-
show() {
|
|
19
|
-
if (!this.open) {
|
|
20
|
-
this.open = true;
|
|
21
|
-
this.$nextTick(() => {
|
|
22
|
-
this.$el.dispatchEvent(new CustomEvent('dialog:opened', { bubbles: true, detail: { id: this.id } }));
|
|
23
|
-
setTimeout(() => {
|
|
24
|
-
const focusTarget = this.$refs.focusOnOpen || this.$el.querySelector('[role="dialog"]');
|
|
25
|
-
if (focusTarget) focusTarget.focus();
|
|
26
|
-
}, 50);
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
},
|
|
30
|
-
hide() {
|
|
31
|
-
if (this.open) {
|
|
32
|
-
this.open = false;
|
|
33
|
-
this.$nextTick(() => {
|
|
34
|
-
this.$el.dispatchEvent(new CustomEvent('dialog:closed', { bubbles: true, detail: { id: this.id } }));
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
|
-
|
|
39
|
-
$main: {
|
|
40
|
-
'@dialog:open.window'(e) { if (e.detail && e.detail.id === this.id) this.show() },
|
|
41
|
-
'@dialog:close.window'(e) { if (e.detail && e.detail.id === this.id) this.hide() },
|
|
42
|
-
'@keydown.escape.window'() { this.open && this.hide() },
|
|
43
|
-
},
|
|
44
|
-
$trigger: {
|
|
45
|
-
'@click'() { this.show() },
|
|
46
|
-
':aria-expanded'() { return this.open }
|
|
47
|
-
},
|
|
48
|
-
$content: {
|
|
49
|
-
':inert'() { return !this.open },
|
|
50
|
-
'@click.self'() { if (this.closeOnOverlayClick) this.hide() },
|
|
51
|
-
'x-cloak': ''
|
|
52
|
-
}
|
|
53
|
-
}));
|
|
54
|
-
};
|