@keenmate/pure-admin-core 1.0.0-rc01

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 (167) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +172 -0
  3. package/dist/css/main.css +11542 -0
  4. package/dist/fonts/Delivery/Delivery_W_Bd.woff2 +0 -0
  5. package/dist/fonts/Delivery/Delivery_W_BdIt.woff2 +0 -0
  6. package/dist/fonts/Delivery/Delivery_W_CdBlk.woff2 +0 -0
  7. package/dist/fonts/Delivery/Delivery_W_CdLt.woff2 +0 -0
  8. package/dist/fonts/Delivery/Delivery_W_It.woff2 +0 -0
  9. package/dist/fonts/Delivery/Delivery_W_Lt.woff2 +0 -0
  10. package/dist/fonts/Delivery/Delivery_W_LtIt.woff2 +0 -0
  11. package/dist/fonts/Delivery/Delivery_W_Rg.woff2 +0 -0
  12. package/dist/fonts/google/3y976aknfjLm_3lMKjiMgmUUYBs04Y8UH-qVHQ.woff2 +0 -0
  13. package/dist/fonts/google/3y976aknfjLm_3lMKjiMgmUUYBs04Y8UH-qVHQ.woff2.1 +0 -0
  14. package/dist/fonts/google/3y976aknfjLm_3lMKjiMgmUUYBs04Y8UH-qVHQ.woff2.2 +0 -0
  15. package/dist/fonts/google/3y976aknfjLm_3lMKjiMgmUUYBs04Y8VH-qVHQ.woff2 +0 -0
  16. package/dist/fonts/google/3y976aknfjLm_3lMKjiMgmUUYBs04Y8VH-qVHQ.woff2.1 +0 -0
  17. package/dist/fonts/google/3y976aknfjLm_3lMKjiMgmUUYBs04Y8VH-qVHQ.woff2.2 +0 -0
  18. package/dist/fonts/google/3y976aknfjLm_3lMKjiMgmUUYBs04Y8bH-o.woff2 +0 -0
  19. package/dist/fonts/google/3y976aknfjLm_3lMKjiMgmUUYBs04Y8bH-o.woff2.1 +0 -0
  20. package/dist/fonts/google/3y976aknfjLm_3lMKjiMgmUUYBs04Y8fH-qVHQ.woff2 +0 -0
  21. package/dist/fonts/google/3y976aknfjLm_3lMKjiMgmUUYBs04Y8fH-qVHQ.woff2.1 +0 -0
  22. package/dist/fonts/google/3y976aknfjLm_3lMKjiMgmUUYBs04Y8fH-qVHQ.woff2.2 +0 -0
  23. package/dist/fonts/google/6aez4K2oVqwIvtE2H68T.woff2 +0 -0
  24. package/dist/fonts/google/6aez4K2oVqwIvtU2Hw.woff2 +0 -0
  25. package/dist/fonts/google/6aez4K2oVqwIvtY2H68T.woff2 +0 -0
  26. package/dist/fonts/google/6aez4K2oVqwIvtg2H68T.woff2 +0 -0
  27. package/dist/fonts/google/6aez4K2oVqwIvto2H68T.woff2 +0 -0
  28. package/dist/fonts/google/6aez4K2oVqwIvts2H68T.woff2 +0 -0
  29. package/dist/fonts/google/7Auup_AqnyWWAxW2Wk3swUz56MS91Eww8SX21nejog.woff2 +0 -0
  30. package/dist/fonts/google/7Auup_AqnyWWAxW2Wk3swUz56MS91Eww8SX21nijogp5.woff2 +0 -0
  31. package/dist/fonts/google/7Auup_AqnyWWAxW2Wk3swUz56MS91Eww8SX21nmjogp5.woff2 +0 -0
  32. package/dist/fonts/google/PN_xRfK9oXHga0XdZ8g_vT0.woff2 +0 -0
  33. package/dist/fonts/google/PN_xRfK9oXHga0XdZsg_.woff2 +0 -0
  34. package/dist/fonts/google/PN_xRfK9oXHga0XdaMg_vT0.woff2 +0 -0
  35. package/dist/fonts/google/TK3tWkYFABsmjsphPho.woff2 +0 -0
  36. package/dist/fonts/google/TK3tWkYFABsmjspuPho7vA.woff2 +0 -0
  37. package/dist/fonts/google/TK3tWkYFABsmjspvPho7vA.woff2 +0 -0
  38. package/dist/fonts/google/dg45_pLmvrkcOkBnKsOzXyGWTBcmg-X6VjTYJwQj.woff2 +0 -0
  39. package/dist/fonts/google/dg45_pLmvrkcOkBnKsOzXyGWTBcmg-X6VjXYJwQj.woff2 +0 -0
  40. package/dist/fonts/google/dg45_pLmvrkcOkBnKsOzXyGWTBcmg-X6Vj_YJwQj.woff2 +0 -0
  41. package/dist/fonts/google/dg45_pLmvrkcOkBnKsOzXyGWTBcmg-X6VjbYJwQj.woff2 +0 -0
  42. package/dist/fonts/google/dg45_pLmvrkcOkBnKsOzXyGWTBcmg-X6VjvYJw.woff2 +0 -0
  43. package/dist/fonts/google/fonts-tracklist.txt +48 -0
  44. package/dist/fonts/google/vEFO2_JTCgwQ5ejvMV0O96D01E8J0tJXHKbBjM4.woff2 +0 -0
  45. package/dist/fonts/google/vEFO2_JTCgwQ5ejvMV0O96D01E8J0tJXHKbOjM7sfA.woff2 +0 -0
  46. package/dist/fonts/google/vEFO2_JTCgwQ5ejvMV0O96D01E8J0tJXHKbPjM7sfA.woff2 +0 -0
  47. package/dist/fonts/google/wEOhEADFm8hSaQTFG18FErVhsC9x-tarUfLtrftV.woff2 +0 -0
  48. package/dist/fonts/google/wEOhEADFm8hSaQTFG18FErVhsC9x-tarUfXtrftV.woff2 +0 -0
  49. package/dist/fonts/google/wEOhEADFm8hSaQTFG18FErVhsC9x-tarUfbtrQ.woff2 +0 -0
  50. package/dist/fonts/google/wEOhEADFm8hSaQTFG18FErVhsC9x-tarUfjtrftV.woff2 +0 -0
  51. package/dist/fonts/google/wEOhEADFm8hSaQTFG18FErVhsC9x-tarUfntrftV.woff2 +0 -0
  52. package/dist/fonts/google/wEOhEADFm8hSaQTFG18FErVhsC9x-tarUfrtrftV.woff2 +0 -0
  53. package/dist/fonts/google/wEOhEADFm8hSaQTFG18FErVhsC9x-tarUfvtrftV.woff2 +0 -0
  54. package/dist/fonts/google/xn7_YHE41ni1AdIRqAuZuw1Bx9mbZk79FN_B-bnBeA.woff2 +0 -0
  55. package/dist/fonts/google/xn7_YHE41ni1AdIRqAuZuw1Bx9mbZk79FN_C-bk.woff2 +0 -0
  56. package/dist/fonts/google/xn7_YHE41ni1AdIRqAuZuw1Bx9mbZk79FN_G-bnBeA.woff2 +0 -0
  57. package/dist/fonts/google/xn7_YHE41ni1AdIRqAuZuw1Bx9mbZk79FN_M-bnBeA.woff2 +0 -0
  58. package/dist/fonts/google/xn7_YHE41ni1AdIRqAuZuw1Bx9mbZk79FN_N-bnBeA.woff2 +0 -0
  59. package/dist/fonts/google/xn7_YHE41ni1AdIRqAuZuw1Bx9mbZk79FN_P-bnBeA.woff2 +0 -0
  60. package/package.json +60 -0
  61. package/snippets/alerts.html +281 -0
  62. package/snippets/badges.html +212 -0
  63. package/snippets/buttons.html +287 -0
  64. package/snippets/cards.html +393 -0
  65. package/snippets/checkbox-lists.html +490 -0
  66. package/snippets/code.html +225 -0
  67. package/snippets/command-palette.html +210 -0
  68. package/snippets/comparison.html +428 -0
  69. package/snippets/customization.html +142 -0
  70. package/snippets/forms.html +477 -0
  71. package/snippets/grid.html +338 -0
  72. package/snippets/layout.html +598 -0
  73. package/snippets/lists.html +232 -0
  74. package/snippets/loaders.html +183 -0
  75. package/snippets/manifest.json +388 -0
  76. package/snippets/modal-dialogs.html +411 -0
  77. package/snippets/modals.html +310 -0
  78. package/snippets/popconfirm.html +253 -0
  79. package/snippets/profile.html +264 -0
  80. package/snippets/tables.html +317 -0
  81. package/snippets/tabs.html +930 -0
  82. package/snippets/timeline.html +364 -0
  83. package/snippets/toasts.html +154 -0
  84. package/snippets/tooltips.html +411 -0
  85. package/snippets/typography.html +101 -0
  86. package/snippets/utilities.html +595 -0
  87. package/snippets/virtual-scroll.html +322 -0
  88. package/snippets/web-daterangepicker.html +634 -0
  89. package/snippets/web-multiselect.html +362 -0
  90. package/src/scss/.claude/settings.local.json +11 -0
  91. package/src/scss/_base-css-variables.scss +348 -0
  92. package/src/scss/_core.scss +99 -0
  93. package/src/scss/_fonts.scss +67 -0
  94. package/src/scss/_purecss-grid-responsive.scss +138 -0
  95. package/src/scss/_purecss-grid.scss +58 -0
  96. package/src/scss/_variables.scss +14 -0
  97. package/src/scss/core-components/_alerts.scss +212 -0
  98. package/src/scss/core-components/_badges.scss +16 -0
  99. package/src/scss/core-components/_base.scss +124 -0
  100. package/src/scss/core-components/_buttons.scss +473 -0
  101. package/src/scss/core-components/_cards.scss +285 -0
  102. package/src/scss/core-components/_checkbox-lists.scss +289 -0
  103. package/src/scss/core-components/_code.scss +141 -0
  104. package/src/scss/core-components/_command-palette.scss +518 -0
  105. package/src/scss/core-components/_comparison.scss +172 -0
  106. package/src/scss/core-components/_file-selector.scss +780 -0
  107. package/src/scss/core-components/_forms.scss +16 -0
  108. package/src/scss/core-components/_grid.scss +264 -0
  109. package/src/scss/core-components/_layout.scss +15 -0
  110. package/src/scss/core-components/_lists.scss +211 -0
  111. package/src/scss/core-components/_loaders.scss +277 -0
  112. package/src/scss/core-components/_logic-tree.scss +280 -0
  113. package/src/scss/core-components/_modals.scss +209 -0
  114. package/src/scss/core-components/_notifications.scss +253 -0
  115. package/src/scss/core-components/_pagers.scss +141 -0
  116. package/src/scss/core-components/_popconfirm.scss +170 -0
  117. package/src/scss/core-components/_profile.scss +281 -0
  118. package/src/scss/core-components/_settings-panel.scss +128 -0
  119. package/src/scss/core-components/_statistics.scss +200 -0
  120. package/src/scss/core-components/_tables.scss +555 -0
  121. package/src/scss/core-components/_tabs.scss +438 -0
  122. package/src/scss/core-components/_timeline.scss +589 -0
  123. package/src/scss/core-components/_toasts.scss +281 -0
  124. package/src/scss/core-components/_tooltips.scss +503 -0
  125. package/src/scss/core-components/_utilities.scss +241 -0
  126. package/src/scss/core-components/_web-components-theme.scss +294 -0
  127. package/src/scss/core-components/badges/_badge-base.scss +131 -0
  128. package/src/scss/core-components/badges/_badge-group.scss +25 -0
  129. package/src/scss/core-components/badges/_composite-badge-variants.scss +396 -0
  130. package/src/scss/core-components/badges/_composite-badge.scss +70 -0
  131. package/src/scss/core-components/badges/_index.scss +10 -0
  132. package/src/scss/core-components/badges/_labels.scss +155 -0
  133. package/src/scss/core-components/forms/_checkboxes-radios.scss +205 -0
  134. package/src/scss/core-components/forms/_form-inputs.scss +100 -0
  135. package/src/scss/core-components/forms/_form-layout.scss +66 -0
  136. package/src/scss/core-components/forms/_form-states.scss +89 -0
  137. package/src/scss/core-components/forms/_index.scss +12 -0
  138. package/src/scss/core-components/forms/_input-groups.scss +149 -0
  139. package/src/scss/core-components/forms/_input-wrapper.scss +89 -0
  140. package/src/scss/core-components/forms/_query-editor.scss +313 -0
  141. package/src/scss/core-components/layout/_index.scss +11 -0
  142. package/src/scss/core-components/layout/_layout-container.scss +105 -0
  143. package/src/scss/core-components/layout/_layout-responsive.scss +100 -0
  144. package/src/scss/core-components/layout/_navbar-elements.scss +238 -0
  145. package/src/scss/core-components/layout/_navbar.scss +71 -0
  146. package/src/scss/core-components/layout/_sidebar-states.scss +228 -0
  147. package/src/scss/core-components/layout/_sidebar.scss +177 -0
  148. package/src/scss/main.scss +7 -0
  149. package/src/scss/themes/_dark-base.scss +207 -0
  150. package/src/scss/themes/audi-light.scss +311 -0
  151. package/src/scss/themes/audi.scss +288 -0
  152. package/src/scss/themes/corporate.scss +203 -0
  153. package/src/scss/themes/dark-blue.scss +152 -0
  154. package/src/scss/themes/dark-green.scss +156 -0
  155. package/src/scss/themes/dark-red.scss +160 -0
  156. package/src/scss/themes/dark.scss +145 -0
  157. package/src/scss/themes/express.scss +281 -0
  158. package/src/scss/themes/minimal.scss +121 -0
  159. package/src/scss/utilities.scss +481 -0
  160. package/src/scss/variables/_base.scss +81 -0
  161. package/src/scss/variables/_colors.scss +148 -0
  162. package/src/scss/variables/_components.scss +509 -0
  163. package/src/scss/variables/_index.scss +13 -0
  164. package/src/scss/variables/_layout.scss +65 -0
  165. package/src/scss/variables/_spacing.scss +66 -0
  166. package/src/scss/variables/_system.scss +80 -0
  167. package/src/scss/variables/_typography.scss +37 -0
@@ -0,0 +1,310 @@
1
+ <!-- ================================
2
+ MODAL SNIPPETS
3
+ Pure Admin Visual Framework
4
+ ================================ -->
5
+
6
+ <!--
7
+ MODAL WRAPPER CLASSES:
8
+ - pa-modal: Base modal wrapper
9
+ - pa-modal--show: Show the modal (add/remove via JavaScript)
10
+ - pa-modal--top: Position modal near top instead of center (useful for search/command interfaces)
11
+ - pa-modal--primary: Primary themed modal (blue header)
12
+ - pa-modal--success: Success themed modal (green header)
13
+ - pa-modal--warning: Warning themed modal (orange header)
14
+ - pa-modal--danger: Danger themed modal (red header)
15
+ - pa-modal--info: Info themed modal (cyan header)
16
+
17
+ CONTAINER SIZE CLASSES:
18
+ - pa-modal__container--sm: Small (20rem / 320px)
19
+ - pa-modal__container: Medium/default (30rem / 480px)
20
+ - pa-modal__container--lg: Large (50rem / 800px)
21
+ - pa-modal__container--xl: Extra large (70rem / 1120px)
22
+ - pa-modal__container--xxl: Extra extra large (90rem / 1440px)
23
+ - pa-modal__container--fw: Full width (constrained by viewport margins)
24
+
25
+ BODY CLASSES:
26
+ - pa-modal__body: Base body class
27
+ - pa-modal__body--scrollable: Scrollable body with max-height (header/footer fixed)
28
+
29
+ HEADER THEME CLASSES (alternative to modal-level themes):
30
+ - pa-modal__header--primary: Blue themed header
31
+ - pa-modal__header--success: Green themed header
32
+ - pa-modal__header--warning: Orange themed header
33
+ - pa-modal__header--danger: Red themed header
34
+ -->
35
+
36
+ <!-- BASIC MODAL (Centered) -->
37
+
38
+ <!-- Modal Structure -->
39
+ <div class="pa-modal pa-modal--show" id="basicModal">
40
+ <div class="pa-modal__backdrop"></div>
41
+ <div class="pa-modal__container">
42
+ <div class="pa-modal__header">
43
+ <h3 class="pa-modal__title">Modal Title</h3>
44
+ <button class="pa-btn pa-btn--primary pa-btn--icon-only pa-btn--sm" onclick="closeModal('basicModal')">✕</button>
45
+ </div>
46
+ <div class="pa-modal__body">
47
+ <p>Modal body content goes here.</p>
48
+ </div>
49
+ <div class="pa-modal__footer">
50
+ <button class="pa-btn pa-btn--secondary" onclick="closeModal('basicModal')">Close</button>
51
+ <button class="pa-btn pa-btn--primary">Save changes</button>
52
+ </div>
53
+ </div>
54
+ </div>
55
+
56
+ <!-- TOP-ALIGNED MODAL -->
57
+
58
+ <!-- Modal positioned near top (5vh from top) -->
59
+ <div class="pa-modal pa-modal--top pa-modal--show" id="topModal">
60
+ <div class="pa-modal__backdrop"></div>
61
+ <div class="pa-modal__container">
62
+ <div class="pa-modal__header">
63
+ <h3 class="pa-modal__title">Top-Aligned Modal</h3>
64
+ <button class="pa-btn pa-btn--primary pa-btn--icon-only pa-btn--sm" onclick="closeModal('topModal')">✕</button>
65
+ </div>
66
+ <div class="pa-modal__body">
67
+ <p>This modal appears near the top of the viewport.</p>
68
+ <p>Useful for search interfaces, quick actions, or command palettes.</p>
69
+ </div>
70
+ <div class="pa-modal__footer">
71
+ <button class="pa-btn pa-btn--secondary" onclick="closeModal('topModal')">Close</button>
72
+ <button class="pa-btn pa-btn--primary">Confirm</button>
73
+ </div>
74
+ </div>
75
+ </div>
76
+
77
+
78
+ <!-- MODAL SIZES -->
79
+
80
+ <!-- Small Modal -->
81
+ <div class="pa-modal" id="smallModal">
82
+ <div class="pa-modal__backdrop"></div>
83
+ <div class="pa-modal__container pa-modal__container--sm">
84
+ <!-- content -->
85
+ </div>
86
+ </div>
87
+
88
+ <!-- Medium Modal (Default) -->
89
+ <div class="pa-modal" id="mediumModal">
90
+ <div class="pa-modal__backdrop"></div>
91
+ <div class="pa-modal__container">
92
+ <!-- content -->
93
+ </div>
94
+ </div>
95
+
96
+ <!-- Large Modal -->
97
+ <div class="pa-modal" id="largeModal">
98
+ <div class="pa-modal__backdrop"></div>
99
+ <div class="pa-modal__container pa-modal__container--lg">
100
+ <!-- content -->
101
+ </div>
102
+ </div>
103
+
104
+ <!-- Extra Large Modal -->
105
+ <div class="pa-modal" id="xlModal">
106
+ <div class="pa-modal__backdrop"></div>
107
+ <div class="pa-modal__container pa-modal__container--xl">
108
+ <!-- content -->
109
+ </div>
110
+ </div>
111
+
112
+ <!-- 2XL Modal -->
113
+ <div class="pa-modal" id="xxlModal">
114
+ <div class="pa-modal__backdrop"></div>
115
+ <div class="pa-modal__container pa-modal__container--xxl">
116
+ <!-- content -->
117
+ </div>
118
+ </div>
119
+
120
+ <!-- Full Width Modal -->
121
+ <div class="pa-modal" id="fwModal">
122
+ <div class="pa-modal__backdrop"></div>
123
+ <div class="pa-modal__container pa-modal__container--fw">
124
+ <!-- content -->
125
+ </div>
126
+ </div>
127
+
128
+
129
+ <!-- THEMED MODALS -->
130
+
131
+ <!-- Primary Modal -->
132
+ <div class="pa-modal pa-modal--primary" id="primaryModal">
133
+ <div class="pa-modal__backdrop"></div>
134
+ <div class="pa-modal__container">
135
+ <div class="pa-modal__header">
136
+ <h3 class="pa-modal__title">Primary Modal</h3>
137
+ <button class="pa-btn pa-btn--primary pa-btn--icon-only pa-btn--sm">✕</button>
138
+ </div>
139
+ <div class="pa-modal__body">
140
+ Content here.
141
+ </div>
142
+ </div>
143
+ </div>
144
+
145
+ <!-- Success Modal -->
146
+ <div class="pa-modal pa-modal--success" id="successModal">
147
+ <div class="pa-modal__backdrop"></div>
148
+ <div class="pa-modal__container">
149
+ <div class="pa-modal__header">
150
+ <h3 class="pa-modal__title">Success Modal</h3>
151
+ <button class="pa-btn pa-btn--primary pa-btn--icon-only pa-btn--sm">✕</button>
152
+ </div>
153
+ <div class="pa-modal__body">
154
+ Content here.
155
+ </div>
156
+ </div>
157
+ </div>
158
+
159
+ <!-- Warning Modal -->
160
+ <div class="pa-modal pa-modal--warning" id="warningModal">
161
+ <div class="pa-modal__backdrop"></div>
162
+ <div class="pa-modal__container">
163
+ <div class="pa-modal__header">
164
+ <h3 class="pa-modal__title">Warning Modal</h3>
165
+ <button class="pa-btn pa-btn--primary pa-btn--icon-only pa-btn--sm">✕</button>
166
+ </div>
167
+ <div class="pa-modal__body">
168
+ Content here.
169
+ </div>
170
+ </div>
171
+ </div>
172
+
173
+ <!-- Danger Modal -->
174
+ <div class="pa-modal pa-modal--danger" id="dangerModal">
175
+ <div class="pa-modal__backdrop"></div>
176
+ <div class="pa-modal__container">
177
+ <div class="pa-modal__header">
178
+ <h3 class="pa-modal__title">Danger Modal</h3>
179
+ <button class="pa-btn pa-btn--primary pa-btn--icon-only pa-btn--sm">✕</button>
180
+ </div>
181
+ <div class="pa-modal__body">
182
+ Content here.
183
+ </div>
184
+ </div>
185
+ </div>
186
+
187
+
188
+ <!-- SCROLLABLE MODAL BODY -->
189
+
190
+ <!-- Modal with Scrollable Content -->
191
+ <div class="pa-modal" id="scrollableModal">
192
+ <div class="pa-modal__backdrop"></div>
193
+ <div class="pa-modal__container pa-modal__container--lg">
194
+ <div class="pa-modal__header">
195
+ <h3 class="pa-modal__title">Terms and Conditions</h3>
196
+ <button class="pa-btn pa-btn--primary pa-btn--icon-only pa-btn--sm">✕</button>
197
+ </div>
198
+ <div class="pa-modal__body pa-modal__body--scrollable">
199
+ <!-- Long content that requires scrolling -->
200
+ <h4>1. Introduction</h4>
201
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
202
+ <h4>2. Terms of Service</h4>
203
+ <p>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
204
+ <h4>3. Privacy Policy</h4>
205
+ <p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p>
206
+ <h4>4. User Responsibilities</h4>
207
+ <p>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
208
+ <h4>5. Disclaimer</h4>
209
+ <p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium.</p>
210
+ <!-- More content... -->
211
+ </div>
212
+ <div class="pa-modal__footer">
213
+ <button class="pa-btn pa-btn--secondary">Decline</button>
214
+ <button class="pa-btn pa-btn--primary">Accept</button>
215
+ </div>
216
+ </div>
217
+ </div>
218
+
219
+ <!--
220
+ SCROLLABLE BODY NOTES:
221
+ - Use pa-modal__body--scrollable for content that may exceed viewport height
222
+ - Body gets max-height and overflow-y: auto
223
+ - Header and footer remain fixed, only body scrolls
224
+ - Recommended for: Terms of service, long forms, data tables, file lists
225
+ -->
226
+
227
+
228
+ <!-- MODAL WITH FORM -->
229
+
230
+ <!-- Form Modal -->
231
+ <div class="pa-modal" id="formModal">
232
+ <div class="pa-modal__backdrop"></div>
233
+ <div class="pa-modal__container">
234
+ <div class="pa-modal__header">
235
+ <h3 class="pa-modal__title">User Information</h3>
236
+ <button class="pa-btn pa-btn--primary pa-btn--icon-only pa-btn--sm">✕</button>
237
+ </div>
238
+ <div class="pa-modal__body">
239
+ <form>
240
+ <div class="pa-form-group">
241
+ <label class="pa-form-label">Name</label>
242
+ <input type="text" class="pa-input">
243
+ </div>
244
+ <div class="pa-form-group">
245
+ <label class="pa-form-label">Email</label>
246
+ <input type="email" class="pa-input">
247
+ </div>
248
+ </form>
249
+ </div>
250
+ <div class="pa-modal__footer">
251
+ <button class="pa-btn pa-btn--secondary">Cancel</button>
252
+ <button class="pa-btn pa-btn--primary">Submit</button>
253
+ </div>
254
+ </div>
255
+ </div>
256
+
257
+
258
+ <!-- JAVASCRIPT -->
259
+ <script>
260
+ function openModal(modalId) {
261
+ const modal = document.getElementById(modalId);
262
+ if (modal) {
263
+ // Calculate scrollbar width to prevent layout shift
264
+ const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
265
+
266
+ modal.classList.add('pa-modal--show');
267
+ document.body.style.overflow = 'hidden'; // Prevent background scrolling
268
+ document.body.style.paddingRight = scrollbarWidth + 'px'; // Compensate for scrollbar
269
+ }
270
+ }
271
+
272
+ function closeModal(modalId) {
273
+ const modal = document.getElementById(modalId);
274
+ if (modal) {
275
+ modal.classList.remove('pa-modal--show');
276
+ document.body.style.overflow = ''; // Restore scrolling
277
+ document.body.style.paddingRight = ''; // Remove compensation
278
+ }
279
+ }
280
+
281
+ // Close modal with Escape key
282
+ document.addEventListener('keydown', function(e) {
283
+ if (e.key === 'Escape') {
284
+ const openModal = document.querySelector('.pa-modal--show');
285
+ if (openModal) {
286
+ closeModal(openModal.id);
287
+ }
288
+ }
289
+ });
290
+
291
+ // Close modal when clicking backdrop
292
+ document.querySelectorAll('.pa-modal__backdrop').forEach(backdrop => {
293
+ backdrop.addEventListener('click', function() {
294
+ const modal = this.closest('.pa-modal');
295
+ if (modal) {
296
+ closeModal(modal.id);
297
+ }
298
+ });
299
+ });
300
+
301
+ // Close modal when clicking close button
302
+ document.querySelectorAll('.pa-modal .pa-btn--icon-only').forEach(btn => {
303
+ btn.addEventListener('click', function() {
304
+ const modal = this.closest('.pa-modal');
305
+ if (modal) {
306
+ closeModal(modal.id);
307
+ }
308
+ });
309
+ });
310
+ </script>
@@ -0,0 +1,253 @@
1
+ <!-- ================================
2
+ POPCONFIRM SNIPPETS
3
+ Pure Admin Visual Framework
4
+ ================================ -->
5
+
6
+ <!--
7
+ POPCONFIRM COMPONENT:
8
+ Small confirmation dialogs anchored to trigger buttons.
9
+ Perfect for delete confirmations and quick yes/no decisions.
10
+
11
+ BENEFITS OVER MODALS:
12
+ - Appears directly below/above the trigger button
13
+ - More contextual (stays near the action)
14
+ - Lighter weight (no backdrop)
15
+ - Better for quick decisions
16
+ - Ideal for table row actions
17
+
18
+ POSITION CLASSES:
19
+ - pa-popconfirm--bottom: Arrow on top, popconfirm below button (default)
20
+ - pa-popconfirm--top: Arrow on bottom, popconfirm above button
21
+ - pa-popconfirm--right: Arrow on left, popconfirm to the right
22
+ - pa-popconfirm--left: Arrow on right, popconfirm to the left
23
+
24
+ SIZE VARIANTS:
25
+ - pa-popconfirm--compact: Smaller padding and dimensions
26
+
27
+ ICON VARIANTS (for message):
28
+ - pa-popconfirm__icon--danger: Shows delete icon (🗑️)
29
+ - pa-popconfirm__icon--warning: Shows warning icon (⚠️)
30
+ - pa-popconfirm__icon--info: Shows info icon (ℹ️)
31
+
32
+ JAVASCRIPT REQUIRED:
33
+ - Floating UI library for positioning (loaded globally)
34
+ - Automatic collision detection via flip() middleware
35
+ - Edge detection via shift() middleware
36
+ - Click outside to close
37
+ - Reposition on scroll/resize
38
+ -->
39
+
40
+ <!-- BASIC POPCONFIRM -->
41
+
42
+ <!-- HTML Structure -->
43
+ <button
44
+ class="pa-btn pa-btn--danger"
45
+ onclick="togglePopconfirm(event, 'popconfirm-delete')"
46
+ >
47
+ Delete Item
48
+ </button>
49
+
50
+ <div id="popconfirm-delete" class="pa-popconfirm pa-popconfirm--bottom">
51
+ <div class="pa-popconfirm__arrow"></div>
52
+ <div class="pa-popconfirm__content">
53
+ <div class="pa-popconfirm__message pa-popconfirm__icon pa-popconfirm__icon--danger">
54
+ <p>Are you sure you want to delete this item? This action cannot be undone.</p>
55
+ </div>
56
+ <div class="pa-popconfirm__actions">
57
+ <button class="pa-btn pa-btn--secondary" onclick="closePopconfirm('popconfirm-delete')">Cancel</button>
58
+ <button class="pa-btn pa-btn--danger" onclick="confirmAction('popconfirm-delete')">Delete</button>
59
+ </div>
60
+ </div>
61
+ </div>
62
+
63
+
64
+ <!-- COMPACT POPCONFIRM -->
65
+
66
+ <!-- Smaller variant for table actions -->
67
+ <button
68
+ class="pa-btn pa-btn--xs pa-btn--danger"
69
+ onclick="togglePopconfirm(event, 'popconfirm-compact')"
70
+ >
71
+ Delete
72
+ </button>
73
+
74
+ <div id="popconfirm-compact" class="pa-popconfirm pa-popconfirm--bottom pa-popconfirm--compact">
75
+ <div class="pa-popconfirm__arrow"></div>
76
+ <div class="pa-popconfirm__content">
77
+ <div class="pa-popconfirm__message">
78
+ <p>Delete this item?</p>
79
+ </div>
80
+ <div class="pa-popconfirm__actions">
81
+ <button class="pa-btn pa-btn--secondary" onclick="closePopconfirm('popconfirm-compact')">No</button>
82
+ <button class="pa-btn pa-btn--danger" onclick="confirmAction('popconfirm-compact')">Yes</button>
83
+ </div>
84
+ </div>
85
+ </div>
86
+
87
+
88
+ <!-- WITHOUT ICON -->
89
+
90
+ <!-- Simple message without icon -->
91
+ <div id="popconfirm-simple" class="pa-popconfirm pa-popconfirm--bottom">
92
+ <div class="pa-popconfirm__arrow"></div>
93
+ <div class="pa-popconfirm__content">
94
+ <div class="pa-popconfirm__message">
95
+ <p>Are you sure you want to proceed with this action?</p>
96
+ </div>
97
+ <div class="pa-popconfirm__actions">
98
+ <button class="pa-btn pa-btn--secondary" onclick="closePopconfirm('popconfirm-simple')">Cancel</button>
99
+ <button class="pa-btn pa-btn--primary" onclick="confirmAction('popconfirm-simple')">Confirm</button>
100
+ </div>
101
+ </div>
102
+ </div>
103
+
104
+
105
+ <!-- TABLE USAGE EXAMPLE -->
106
+
107
+ <!-- Common pattern: Delete action in table -->
108
+ <table class="pa-table pa-table--striped">
109
+ <thead>
110
+ <tr>
111
+ <th>Name</th>
112
+ <th>Status</th>
113
+ <th class="col-auto">Actions</th>
114
+ </tr>
115
+ </thead>
116
+ <tbody>
117
+ <tr>
118
+ <td>John Doe</td>
119
+ <td><span class="pa-badge pa-badge--success">Active</span></td>
120
+ <td class="col-auto">
121
+ <div class="pa-btn-group">
122
+ <button class="pa-btn pa-btn--xs pa-btn--primary">Edit</button>
123
+ <button
124
+ class="pa-btn pa-btn--xs pa-btn--danger"
125
+ onclick="togglePopconfirm(event, 'popconfirm-user-1')"
126
+ >
127
+ Delete
128
+ </button>
129
+ </div>
130
+ </td>
131
+ </tr>
132
+ </tbody>
133
+ </table>
134
+
135
+ <!-- Popconfirm for table row -->
136
+ <div id="popconfirm-user-1" class="pa-popconfirm pa-popconfirm--bottom pa-popconfirm--compact">
137
+ <div class="pa-popconfirm__arrow"></div>
138
+ <div class="pa-popconfirm__content">
139
+ <div class="pa-popconfirm__message">
140
+ <p>Delete John Doe?</p>
141
+ </div>
142
+ <div class="pa-popconfirm__actions">
143
+ <button class="pa-btn pa-btn--secondary" onclick="closePopconfirm('popconfirm-user-1')">No</button>
144
+ <button class="pa-btn pa-btn--danger" onclick="confirmAction('popconfirm-user-1')">Yes</button>
145
+ </div>
146
+ </div>
147
+ </div>
148
+
149
+
150
+ <!-- JAVASCRIPT FUNCTIONS -->
151
+
152
+ <script>
153
+ // Popconfirm positioning and interaction
154
+ let currentPopconfirm = null;
155
+ let currentTrigger = null;
156
+
157
+ function togglePopconfirm(event, popconfirmId) {
158
+ event.stopPropagation();
159
+
160
+ const trigger = event.currentTarget;
161
+ const popconfirm = document.getElementById(popconfirmId);
162
+
163
+ // Close current if different
164
+ if (currentPopconfirm && currentPopconfirm !== popconfirm) {
165
+ currentPopconfirm.classList.remove('is-open');
166
+ }
167
+
168
+ // Toggle this popconfirm
169
+ const isOpen = popconfirm.classList.contains('is-open');
170
+
171
+ if (isOpen) {
172
+ popconfirm.classList.remove('is-open');
173
+ currentPopconfirm = null;
174
+ currentTrigger = null;
175
+ } else {
176
+ // Position and show
177
+ positionPopconfirm(trigger, popconfirm);
178
+ popconfirm.classList.add('is-open');
179
+ currentPopconfirm = popconfirm;
180
+ currentTrigger = trigger;
181
+ }
182
+ }
183
+
184
+ function closePopconfirm(popconfirmId) {
185
+ const popconfirm = document.getElementById(popconfirmId);
186
+ popconfirm.classList.remove('is-open');
187
+
188
+ if (currentPopconfirm === popconfirm) {
189
+ currentPopconfirm = null;
190
+ currentTrigger = null;
191
+ }
192
+ }
193
+
194
+ function confirmAction(popconfirmId) {
195
+ console.log('Confirmed:', popconfirmId);
196
+ closePopconfirm(popconfirmId);
197
+
198
+ // Perform your action here (e.g., delete API call)
199
+ }
200
+
201
+ async function positionPopconfirm(trigger, popconfirm) {
202
+ // Get the initial position class (or default to bottom)
203
+ const classMatch = popconfirm.className.match(/pa-popconfirm--(top|bottom|left|right)/);
204
+ const placement = classMatch ? classMatch[1] : 'bottom';
205
+
206
+ // Use Floating UI for automatic positioning with collision detection
207
+ const { computePosition, flip, shift, offset } = window.FloatingUIDOM;
208
+
209
+ const { x, y, placement: finalPlacement } = await computePosition(trigger, popconfirm, {
210
+ placement: placement,
211
+ middleware: [
212
+ offset(8), // 8px gap from trigger
213
+ flip(), // Flip to opposite side if not enough space
214
+ shift({ padding: 10 }) // Keep 10px from viewport edges
215
+ ]
216
+ });
217
+
218
+ // Update position class to match actual placement
219
+ popconfirm.className = popconfirm.className
220
+ .replace(/pa-popconfirm--(top|bottom|left|right)/g, '')
221
+ .trim() + ' pa-popconfirm--' + finalPlacement;
222
+
223
+ // Apply positioning
224
+ Object.assign(popconfirm.style, {
225
+ left: `${x}px`,
226
+ top: `${y}px`
227
+ });
228
+ }
229
+
230
+ // Close popconfirm when clicking outside
231
+ document.addEventListener('click', (e) => {
232
+ if (currentPopconfirm &&
233
+ !currentPopconfirm.contains(e.target) &&
234
+ currentTrigger !== e.target) {
235
+ currentPopconfirm.classList.remove('is-open');
236
+ currentPopconfirm = null;
237
+ currentTrigger = null;
238
+ }
239
+ });
240
+
241
+ // Reposition on scroll/resize
242
+ window.addEventListener('scroll', () => {
243
+ if (currentPopconfirm && currentTrigger) {
244
+ positionPopconfirm(currentTrigger, currentPopconfirm);
245
+ }
246
+ });
247
+
248
+ window.addEventListener('resize', () => {
249
+ if (currentPopconfirm && currentTrigger) {
250
+ positionPopconfirm(currentTrigger, currentPopconfirm);
251
+ }
252
+ });
253
+ </script>