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.
@@ -75,7 +75,7 @@
75
75
  {% endfor %}
76
76
  >
77
77
  <h2 id="{{ id }}-title">{{ title | safe }}</h2>
78
- <p>{{ description | safe }}</p>
78
+ {% if description %}<p>{{ description | safe }}</p>{% endif %}
79
79
  </header>
80
80
  {% endif %}
81
81
  {% if caller %}
@@ -21,7 +21,7 @@
21
21
  x-data="dropdownMenu"
22
22
  @click.away="open = false"
23
23
  {% if id %}id="{{ id }}"{% endif %}
24
- {% for key, value in main_attrs %}
24
+ {% for key, value in main_attrs.items() %}
25
25
  {% if key != "class" %}{{ key }}="{{ value }}"{% endif %}
26
26
  {% endfor %}
27
27
  >
@@ -35,7 +35,7 @@
35
35
  id="{{ id }}-trigger"
36
36
  aria-controls="{{ id }}-menu"
37
37
  {% endif %}
38
- {% for key, value in trigger_attrs %}
38
+ {% for key, value in trigger_attrs.items() %}
39
39
  {{ key }}="{{ value }}"
40
40
  {% endfor %}
41
41
  >
@@ -47,7 +47,7 @@
47
47
  aria-hidden="true"
48
48
  x-bind="$content"
49
49
  {% if id %}id="{{ id }}-menu"{% endif %}
50
- {% for key, value in content_attrs %}
50
+ {% for key, value in content_attrs.items() %}
51
51
  {{ key }}="{{ value }}"
52
52
  {% endfor %}
53
53
  >
@@ -10,46 +10,60 @@
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).
13
- @param is_combobox {boolean} [optional] [default=False] - Renders a combobox with search functionality if True.
13
+ @param is_combobox {boolean} [optional] [default=false] - Renders a combobox with search functionality if true.
14
14
  #}
15
15
  {% macro select(
16
16
  id=None,
17
17
  selected=None,
18
18
  name=None,
19
19
  items=None,
20
- main_attrs={},
21
20
  trigger_attrs={},
22
- content_attrs={},
21
+ popover_attrs={},
23
22
  listbox_attrs={},
24
- input_attrs={},
25
23
  search_placeholder="Search entries...",
26
- is_combobox=False
24
+ is_combobox=false
27
25
  ) %}
28
- <div
29
- class="popover {{ main_attrs.class }}"
30
- x-data="select('{{ name }}', '{{ selected or '' }}')"
31
- @click.away="open = false"
32
- {% if id %}id="{{ id }}"{% endif %}
33
- {% for key, value in main_attrs.items() %}
34
- {% if key != 'class' %}{{ key }}="{{ value }}"{% endif %}
35
- {% endfor %}
36
- >
26
+ {% set id = id or ("select-" + (range(100000, 999999) | random | string)) %}
27
+
28
+ {% set first_option = [] %}
29
+ {% set selected_option = [] %}
30
+
31
+ {% for item in items.items() %}
32
+ {% if item.type == "group" %}
33
+ {% for sub_item in item.items.items() %}
34
+ {% if not first_option[0] %}
35
+ {% set first_option = (first_option.push(sub_item), first_option) %}
36
+ {% endif %}
37
+ {% if selected and sub_item.value == selected and not selected_option[0] %}
38
+ {% set selected_option = (selected_option.push(sub_item), selected_option) %}
39
+ {% endif %}
40
+ {% endfor %}
41
+ {% else %}
42
+ {% if not first_option[0] %}
43
+ {% set first_option = (first_option.push(item), first_option) %}
44
+ {% endif %}
45
+ {% if selected and item.value == selected and not selected_option[0] %}
46
+ {% set selected_option = (selected_option.push(item), selected_option) %}
47
+ {% endif %}
48
+ {% endif %}
49
+ {% endfor %}
50
+
51
+ {% set default_option = selected_option[0] or first_option[0] or None %}
52
+
53
+ <div class="select">
37
54
  <button
38
55
  type="button"
56
+ class="btn-outline justify-between font-normal {{ trigger_attrs.class }}"
57
+ id="{{ id }}-trigger"
58
+ popovertarget="{{ id }}"
39
59
  aria-haspopup="listbox"
40
60
  aria-expanded="false"
41
- x-bind="$trigger"
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 }}"
47
- {% for key, value in trigger_attrs.items() %}
61
+ aria-controls="{{ id }}-listbox"
62
+ {% for key, value in trigger_attrs %}
48
63
  {% if key != 'class' %}{{ key }}="{{ value }}"{% endif %}
49
64
  {% endfor %}
50
65
  >
51
- <div x-html="selectedLabel" class="flex items-center gap-x-2"
52
- ></div>
66
+ <span class="truncate">{{ default_option.label }}</span>
53
67
  {% if is_combobox %}
54
68
  <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
69
  {% else %}
@@ -57,12 +71,11 @@
57
71
  {% endif %}
58
72
  </button>
59
73
  <div
60
- data-popover
61
- aria-hidden="true"
62
- x-bind="$content"
63
- {% if id %}id="{{ id }}-content"{% endif %}
64
- {% for key, value in content_attrs.items() %}
65
- {{ key }}="{{ value }}"
74
+ popover
75
+ id="{{ id }}"
76
+ class="popover {{ popover_attrs.class }}"
77
+ {% for key, value in popover_attrs.items() %}
78
+ {% if key != 'class' %}{{ key }}="{{ value }}"{% endif %}
66
79
  {% endfor %}
67
80
  >
68
81
  {% if is_combobox %}
@@ -80,35 +93,33 @@
80
93
  aria-expanded="true"
81
94
  aria-controls="{{ id }}-content"
82
95
  aria-labelledby="{{ id }}-trigger"
83
- x-model="query"
84
- x-bind="$filter"
85
96
  >
86
97
  </header>
87
98
  {% endif %}
88
99
  <div
89
100
  role="listbox"
101
+ id="{{ id }}-listbox"
90
102
  aria-orientation="vertical"
91
- {% for key, value in listbox_attrs.items() %}
103
+ aria-labelledby="{{ id }}-trigger"
104
+ {% for key, value in listbox_attrs %}
92
105
  {{ key }}="{{ value }}"
93
106
  {% endfor %}
94
107
  >
95
- {% if items %}
96
- {{ render_select_items(items, id ~ "-items" if id else "items") }}
108
+ {% if items.length > 0 %}
109
+ {{ render_select_items(items, default_option.value, id ~ "-items" if id else "items") }}
97
110
  {% else %}
98
111
  {{ caller() if caller }}
99
112
  {% endif %}
100
113
  </div>
101
114
  </div>
102
- {% if name is defined %}
103
- <input
104
- type="hidden"
105
- name="{{ name }}"
106
- x-model="selectedValue"
107
- {% for key, value in input_attrs.items() %}
108
- {% if key != 'name' %}{{ key }}="{{ value }}"{% endif %}
109
- {% endfor %}
110
- >
111
- {% endif %}
115
+ <input
116
+ type="hidden"
117
+ name="{{ name or id ~ '-value' }}"
118
+ value="{{ selected or '' }}"
119
+ {% for key, value in input_attrs.items() %}
120
+ {% if key != 'name' and key != 'value' %}{{ key }}="{{ value }}"{% endif %}
121
+ {% endfor %}
122
+ >
112
123
  </div>
113
124
  {% endmacro %}
114
125
 
@@ -118,29 +129,30 @@
118
129
  @param items {array} - The array of items to render.
119
130
  @param parent_id_prefix {string} [optional] - The prefix for the item id.
120
131
  #}
121
- {% macro render_select_items(items, parent_id_prefix="items") %}
132
+ {% macro render_select_items(items, selected, parent_id_prefix="items") %}
122
133
  {% for item in items.items() %}
123
134
  {% set item_id = parent_id_prefix ~ "-" ~ loop.index %}
124
-
125
135
  {% if item.type == "group" %}
126
136
  {% set group_label_id = item.id if item.id else "group-label-" + item_id %}
127
137
  <div
128
138
  role="group"
129
139
  aria-labelledby="{{ group_label_id }}"
130
- {% for key, value in item.attrs.items() %}
140
+ {% for key, value in item.attrs %}
131
141
  {{ key }}="{{ value }}"
132
142
  {% endfor %}
133
143
  >
134
144
  <div role="heading" id="{{ group_label_id }}">{{ item.label }}</div>
135
- {{ render_select_items(item.items, item_id) if item.items }}
145
+ {{ render_select_items(item.items, selected, item_id) if item.items }}
136
146
  </div>
137
147
  {% elif item.type == "separator" %}
138
148
  <hr role="separator" />
139
149
  {% elif item.type == "item" or not item.type %}
140
150
  <div
151
+ id="{{ item_id }}"
141
152
  role="option"
142
153
  data-value="{{ item.value }}"
143
- {% for key, value in item.attrs.items() %}
154
+ {% if selected == item.value %}aria-selected="true"{% endif %}
155
+ {% for key, value in item.attrs %}
144
156
  {{ key }}="{{ value }}"
145
157
  {% endfor %}
146
158
  >
@@ -10,7 +10,7 @@
10
10
  {% macro toaster(
11
11
  id="toaster",
12
12
  toasts=[],
13
- main_attrs=None,
13
+ main_attrs={},
14
14
  is_fragment=False
15
15
  ) %}
16
16
  <div
@@ -21,7 +21,7 @@
21
21
  {% endfor %}
22
22
  {% if is_fragment %}hx-swap-oob="beforeend"{% endif %}
23
23
  >
24
- {% for item in toasts.items() %}
24
+ {% for item in toasts %}
25
25
  {{ toast(
26
26
  category=item.category,
27
27
  title=item.title,