srcdev-nuxt-components 3.0.0 → 4.0.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.
Files changed (87) hide show
  1. package/assets/styles/a11y/_utils.css +20 -0
  2. package/assets/styles/a11y/_variables.css +8 -0
  3. package/assets/styles/a11y/index.css +2 -0
  4. package/assets/styles/forms/index.css +2 -0
  5. package/assets/styles/forms/themes/_error.css +77 -0
  6. package/assets/styles/forms/themes/_ghost.css +77 -0
  7. package/assets/styles/forms/themes/_input-action.css +20 -0
  8. package/assets/styles/forms/themes/_primary.css +82 -0
  9. package/assets/styles/forms/themes/_secondary.css +77 -0
  10. package/assets/styles/forms/themes/_success.css +77 -0
  11. package/assets/styles/forms/themes/_tertiary.css +77 -0
  12. package/assets/styles/forms/themes/_warning.css +77 -0
  13. package/assets/styles/forms/themes/index.css +8 -0
  14. package/assets/styles/forms/variables/_sizes.css +82 -0
  15. package/assets/styles/forms/variables/_theme.css +11 -0
  16. package/assets/styles/forms/variables/index.css +2 -0
  17. package/assets/styles/main.css +5 -0
  18. package/assets/styles/typography/index.css +2 -0
  19. package/assets/styles/typography/utils/_font-classes.css +160 -0
  20. package/assets/styles/typography/utils/_weights.css +69 -0
  21. package/assets/styles/typography/utils/index.css +2 -0
  22. package/assets/styles/typography/variables/_colors.css +14 -0
  23. package/assets/styles/typography/variables/_reponsive-font-size.css +10 -0
  24. package/assets/styles/typography/variables/index.css +2 -0
  25. package/assets/styles/utils/_animations.css +42 -0
  26. package/assets/styles/utils/_canvasWidths.css +18 -0
  27. package/assets/styles/utils/_display.css +7 -0
  28. package/assets/styles/utils/_margin-helpers.css +334 -0
  29. package/assets/styles/utils/_padding-helpers.css +308 -0
  30. package/assets/styles/utils/_page.css +24 -0
  31. package/assets/styles/utils/_placement.css +73 -0
  32. package/assets/styles/utils/index.css +7 -0
  33. package/assets/styles/variables/colors/_blue.css +15 -0
  34. package/assets/styles/variables/colors/_gray.css +16 -0
  35. package/assets/styles/variables/colors/_green.css +15 -0
  36. package/assets/styles/variables/colors/_orange.css +15 -0
  37. package/assets/styles/variables/colors/_red.css +15 -0
  38. package/assets/styles/variables/colors/_yellow.css +15 -0
  39. package/assets/styles/variables/colors/colors.css +6 -0
  40. package/assets/styles/variables/components/_accordian.css +7 -0
  41. package/assets/styles/variables/components/_container-glow-core.css +16 -0
  42. package/assets/styles/variables/components/_display-dialog-core.css +35 -0
  43. package/assets/styles/variables/components/_tabs.css +18 -0
  44. package/assets/styles/variables/components/display-prompt-core/_scaffolding.css +57 -0
  45. package/assets/styles/variables/components/display-prompt-core/index.css +2 -0
  46. package/assets/styles/variables/components/display-prompt-core/themes/_error.css +39 -0
  47. package/assets/styles/variables/components/display-prompt-core/themes/_info.css +39 -0
  48. package/assets/styles/variables/components/display-prompt-core/themes/_success.css +39 -0
  49. package/assets/styles/variables/components/display-prompt-core/themes/_warning.css +39 -0
  50. package/assets/styles/variables/components/display-prompt-core/themes/index.css +4 -0
  51. package/assets/styles/variables/components/index.css +5 -0
  52. package/assets/styles/variables/index.css +2 -0
  53. package/components/animated-svg-text/AnimatedSvgText.vue +87 -0
  54. package/components/canvas-switcher/CanvasSwitcher.vue +77 -0
  55. package/components/clip-element/ClipElement.vue +73 -0
  56. package/components/clipped-panels/ClippedPanel.vue +73 -0
  57. package/components/deep-expanding-menu/DeepExpandingMenu.vue +214 -0
  58. package/components/deep-expanding-menu/DeepExpandingMenuOld.vue +218 -0
  59. package/components/display-banner/DisplayBanner.vue +63 -0
  60. package/components/display-details/DisplayDetailsCore.vue +312 -0
  61. package/components/functional/accordian/AccordianCore.vue +138 -0
  62. package/components/functional/display-dialog/DisplayDialogCore.vue +244 -0
  63. package/components/functional/display-dialog/variants/DisplayDialogConfirm.vue +45 -0
  64. package/components/functional/display-dialog/variants/DisplayDialogScrollableContent.vue +49 -0
  65. package/components/functional/pop-over/PopOver.vue +88 -0
  66. package/components/image-galleries/SliderGallery.vue +784 -0
  67. package/components/masonry-grid-ordered/MasonryGridOrdered.vue +158 -0
  68. package/components/presentation/container-glow/ContainerGlowCore.vue +211 -0
  69. package/components/presentation/display-grid/DisplayGridCore.vue +22 -0
  70. package/components/presentation/display-prompt/DisplayPromptCore.vue +150 -0
  71. package/components/presentation/display-prompt/variants/DisplayPromptError.vue +53 -0
  72. package/components/presentation/layout-grids/LayoutGridA.vue +103 -0
  73. package/components/presentation/layout-grids/LayoutGridB.vue +132 -0
  74. package/components/presentation/layout-row/LayoutRow.vue +157 -0
  75. package/components/presentation/masonry-grid/MasonryGrid.vue +62 -0
  76. package/components/presentation/masonry-grid-sorted/MasonryGridSorted.vue +115 -0
  77. package/components/presentation/tabs/TabsCore.vue +308 -0
  78. package/components/responsive-header/NavigationItems.vue +164 -0
  79. package/components/responsive-header/ResponsiveHeader.vue +586 -0
  80. package/components/rotating-carousel/RotatingCarouselImage.vue +200 -0
  81. package/composables/useDialogControls.ts +23 -0
  82. package/composables/useStyleClassPassthrough.ts +35 -0
  83. package/composables/useTabs.ts +201 -0
  84. package/nuxt.config.ts +0 -3
  85. package/package.json +2 -2
  86. package/types/gallery-data.ts +13 -0
  87. package/types/responsiveHeader.ts +38 -0
@@ -0,0 +1,312 @@
1
+ <template>
2
+ <details @click.prevent="handleClick()" :name="name" class="display-details" :class="[elementClasses]" ref="detailsRef">
3
+ <summary class="display-details-summary" :id="triggerId" :aria-controls="contentId" ref="summaryRef">
4
+ <span class="label">
5
+ <slot name="summary"></slot>
6
+ </span>
7
+ <slot name="summaryIcon">
8
+ <Icon name="bi:caret-down-fill" class="icon mi-12" :class="iconSize" />
9
+ </slot>
10
+ </summary>
11
+ <div class="display-details-content" :aria-labelledby="triggerId" :id="contentId" role="region" ref="contentRef">
12
+ <slot name="content"></slot>
13
+ </div>
14
+ </details>
15
+ </template>
16
+
17
+ <script lang="ts">
18
+ // Create a global store to track open details elements by name
19
+ const openDetailsByName = reactive(new Map<string, HTMLDetailsElement>());
20
+
21
+ export const useDetailsTransition = (detailsRef: Ref<HTMLDetailsElement | null>, summaryRef: Ref<HTMLElement | null>, contentRef: Ref<HTMLDivElement | null>, name: string, animationDuration: number) => {
22
+ // State
23
+ const animation = ref<Animation | null>(null);
24
+ const isClosing = ref(false);
25
+ const isExpanding = ref(false);
26
+
27
+ // Check if refs are available
28
+ if (!detailsRef.value || !summaryRef.value || !contentRef.value) {
29
+ console.warn('Details, summary, or content ref is null');
30
+ return {
31
+ clickAction: () => console.warn('Component not fully initialized'),
32
+ };
33
+ }
34
+
35
+ const closeOtherDetailsWithSameName = () => {
36
+ const currentDetails = detailsRef.value;
37
+ if (!currentDetails || !name) return;
38
+
39
+ // Get the currently open details with the same name
40
+ const openDetails = openDetailsByName.get(name);
41
+
42
+ // If there's an open details with the same name and it's not the current one, close it
43
+ if (openDetails && openDetails !== currentDetails && openDetails.open) {
44
+ // Simulate a click on the other details to close it with animation
45
+ const otherSummary = openDetails.querySelector('summary');
46
+ if (otherSummary) {
47
+ otherSummary.click();
48
+ } else {
49
+ // Fallback: close directly without animation
50
+ openDetails.open = false;
51
+ }
52
+ }
53
+
54
+ // Update the map with the current details if it's open
55
+ if (currentDetails.open) {
56
+ openDetailsByName.set(name, currentDetails);
57
+ } else {
58
+ // If it's closed and was the one in the map, remove it
59
+ if (openDetailsByName.get(name) === currentDetails) {
60
+ openDetailsByName.delete(name);
61
+ }
62
+ }
63
+ };
64
+
65
+ const clickAction = () => {
66
+ const details = detailsRef.value;
67
+ const summary = summaryRef.value;
68
+ const content = contentRef.value;
69
+
70
+ if (!details || !summary || !content) return;
71
+
72
+ // Add overflow hidden to avoid content jumping
73
+ details.style.overflow = 'hidden';
74
+
75
+ if (isClosing.value || !details.open) {
76
+ // Close other details with the same name first
77
+ closeOtherDetailsWithSameName();
78
+
79
+ // Open the details
80
+ details.open = true;
81
+ isExpanding.value = true;
82
+ isClosing.value = false;
83
+
84
+ // Get the height of the content
85
+ const detailsHeight = details.offsetHeight;
86
+ const contentHeight = content.offsetHeight;
87
+ const summaryHeight = summary.offsetHeight;
88
+
89
+ const startHeight = `${detailsHeight - contentHeight}px`;
90
+ const endHeight = `${summaryHeight + contentHeight}px`;
91
+
92
+ // If there's an animation running, cancel it
93
+ if (animation.value) {
94
+ animation.value.cancel();
95
+ }
96
+
97
+ // Start animation
98
+ animation.value = details.animate(
99
+ {
100
+ height: [startHeight, endHeight],
101
+ },
102
+ {
103
+ duration: animationDuration,
104
+ easing: 'ease-out',
105
+ }
106
+ );
107
+
108
+ animation.value.onfinish = () => {
109
+ // Animation finished - reset everything
110
+ details.style.height = 'auto';
111
+ details.style.overflow = '';
112
+ isExpanding.value = false;
113
+ animation.value = null;
114
+
115
+ // Register this as the open details for this name
116
+ openDetailsByName.set(name, details);
117
+ };
118
+
119
+ animation.value.oncancel = () => {
120
+ isExpanding.value = false;
121
+ };
122
+ } else if (isExpanding.value || details.open) {
123
+ // Close the details
124
+ isClosing.value = true;
125
+ isExpanding.value = false;
126
+
127
+ // Get the height of the content
128
+ const startHeight = `${details.offsetHeight}px`;
129
+ const endHeight = `${details.offsetHeight - content.offsetHeight}px`;
130
+
131
+ // If there's an animation running, cancel it
132
+ if (animation.value) {
133
+ animation.value.cancel();
134
+ }
135
+
136
+ // Start animation
137
+ animation.value = details.animate(
138
+ {
139
+ height: [startHeight, endHeight],
140
+ },
141
+ {
142
+ duration: animationDuration,
143
+ easing: 'ease-out',
144
+ }
145
+ );
146
+
147
+ animation.value.onfinish = () => {
148
+ // Animation finished - reset everything
149
+ details.open = false;
150
+ details.style.height = 'auto';
151
+ details.style.overflow = '';
152
+ isClosing.value = false;
153
+ animation.value = null;
154
+
155
+ // Remove this from the open details map if it's there
156
+ if (openDetailsByName.get(name) === details) {
157
+ openDetailsByName.delete(name);
158
+ }
159
+ };
160
+
161
+ animation.value.oncancel = () => {
162
+ isClosing.value = false;
163
+ };
164
+ }
165
+ };
166
+
167
+ return {
168
+ clickAction,
169
+ isClosing,
170
+ isExpanding,
171
+ };
172
+ };
173
+ </script>
174
+
175
+ <script setup lang="ts">
176
+ const props = defineProps({
177
+ name: {
178
+ type: String,
179
+ required: true,
180
+ },
181
+ id: {
182
+ type: String,
183
+ required: true,
184
+ },
185
+ animationDuration: {
186
+ type: Number,
187
+ default: 400,
188
+ },
189
+ iconSize: {
190
+ type: String,
191
+ default: 'small',
192
+ validator(value: string) {
193
+ return ['small', 'medium', 'large'].includes(value);
194
+ },
195
+ },
196
+ styleClassPassthrough: {
197
+ type: Array as PropType<string[]>,
198
+ default: () => [],
199
+ },
200
+ });
201
+
202
+ const triggerId = computed(() => `${props.id}-trigger`);
203
+ const contentId = computed(() => `${props.id}-content`);
204
+
205
+ const { elementClasses, resetElementClasses, updateElementClasses } = useStyleClassPassthrough(props.styleClassPassthrough);
206
+
207
+ updateElementClasses([props.iconSize]);
208
+
209
+ const detailsRef = ref<HTMLDetailsElement | null>(null);
210
+ const summaryRef = ref<HTMLElement | null>(null);
211
+ const contentRef = ref<HTMLDivElement | null>(null);
212
+
213
+ // Initialize with dummy function that will be replaced when refs are available
214
+ let clickAction = () => console.warn('Component not fully initialized');
215
+
216
+ // Handle click with the current clickAction function
217
+ const handleClick = () => {
218
+ clickAction();
219
+ };
220
+
221
+ watch(
222
+ () => props.styleClassPassthrough,
223
+ () => {
224
+ resetElementClasses(props.styleClassPassthrough);
225
+ }
226
+ );
227
+
228
+ onMounted(() => {
229
+ // Initialize the composable once the component is mounted and refs are available
230
+ if (detailsRef.value && contentRef.value && summaryRef.value) {
231
+ const details = useDetailsTransition(detailsRef, summaryRef, contentRef, props.name, props.animationDuration);
232
+ clickAction = details.clickAction; // Assign the real click handler
233
+ } else {
234
+ console.error('Refs not available after mounting');
235
+ }
236
+ });
237
+ </script>
238
+
239
+ <style lang="css">
240
+ .display-details {
241
+ /* Component setup */
242
+ --_display-details-icon-transform: scaleY(1);
243
+ --_display-details-icon-size: 1.2rem;
244
+
245
+ /* Configurable properties */
246
+ --_display-details-border: none;
247
+ --_display-details-outline: none;
248
+ --_display-details-box-shadow: none;
249
+ --_display-details-border-radius: 0;
250
+ --_display-details-mbe: 1em;
251
+
252
+ --_display-details-summary-gap: 12px;
253
+ --_display-details-summary-flex-direction: row;
254
+
255
+ --_display-details-content-padding: 0;
256
+
257
+ &.medium {
258
+ --_display-details-icon-size: 1.8rem;
259
+ }
260
+ &.large {
261
+ --_display-details-icon-size: 2.4rem;
262
+ }
263
+
264
+ &[open] {
265
+ --_display-details-icon-transform: scaleY(-1);
266
+ }
267
+
268
+ border: var(--_display-details-border);
269
+ outline: var(--_display-details-outline);
270
+ box-shadow: var(--_display-details-box-shadow);
271
+ border-radius: var(--_display-details-border-radius);
272
+ margin-block-end: var(--_display-details-mbe);
273
+
274
+ .display-details-summary {
275
+
276
+ display: flex;
277
+ align-items: center;
278
+ justify-content: space-between;
279
+
280
+ list-style: none;
281
+
282
+ &::-webkit-details-marker,
283
+ &::marker {
284
+ display: none;
285
+ }
286
+
287
+ display: flex !important;
288
+ flex-direction: var(--_display-details-summary-flex-direction);
289
+ align-items: center;
290
+ gap: var(--_display-details-summary-gap);
291
+ overflow: clip;
292
+
293
+ .label {
294
+ display: block;
295
+ flex-grow: 1;
296
+ }
297
+
298
+ .icon {
299
+ display: block;
300
+
301
+ font-size: var(--_display-details-icon-size);
302
+ transform: var(--_display-details-icon-transform);
303
+ transition: transform 200ms;
304
+ }
305
+ }
306
+
307
+ .display-details-content {
308
+ padding: var(--_display-details-content-padding);
309
+ }
310
+ }
311
+
312
+ </style>
@@ -0,0 +1,138 @@
1
+ <template>
2
+ <div class="display-accordian" :class="[elementClasses]" ref="accordianRef">
3
+ <details v-for="(item, key) in data" :key="key" class="accordion-panel" :name="accordianName">
4
+ <summary class="accordion-trigger" :id="`accordian-${key}-trigger`" :aria-controls="`accordian-${key}-content`">
5
+ <span class="label">
6
+ <slot :name="`accordian-${key}-trigger`"></slot>
7
+ </span>
8
+ <Icon name="bi:caret-down-fill" class="icon mi-12" />
9
+ </summary>
10
+ <div class="accordion-content" :aria-labelledby="`accordian-${key}-trigger`" :id="`accordian-${key}-content`" role="region">
11
+ <div class="accordion-content-inner">
12
+ <slot :name="`accordian-${key}-content`"></slot>
13
+ </div>
14
+ </div>
15
+ </details>
16
+ </div>
17
+ </template>
18
+
19
+ <script setup lang="ts">
20
+ interface IAccordianData {
21
+ title: string;
22
+ content: string;
23
+ }
24
+
25
+ const props = defineProps({
26
+ data: {
27
+ type: Array as PropType<IAccordianData[]>,
28
+ default: () => [],
29
+ },
30
+ styleClassPassthrough: {
31
+ type: Array as PropType<string[]>,
32
+ default: () => [],
33
+ },
34
+ });
35
+
36
+ const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough);
37
+ const accordianName = useId();
38
+ </script>
39
+
40
+ <style lang="css">
41
+ .display-accordian {
42
+ max-width: 600px;
43
+ margin: 0 auto;
44
+ }
45
+
46
+ .accordion-panel {
47
+ @property --_grid-template-rows {
48
+ syntax: '<length-percentage> | auto | min-content | max-content | minmax( <length-percentage> , <length-percentage> ) | fit-content( <length-percentage> ) | <flex>';
49
+ inherits: true;
50
+ initial-value: 0fr;
51
+ }
52
+
53
+ @property --_accordian-content-transform {
54
+ syntax: '<transform-list>';
55
+ inherits: true;
56
+ initial-value: scaleY(0);
57
+ }
58
+
59
+ --_grid-template-rows: 0fr;
60
+ --_details-content-height: 0px;
61
+ --_icon-transform: scaleY(1);
62
+ --_accordian-content-transform: scaleY(0);
63
+
64
+ border: var(--accordian-panel-border);
65
+ border-radius: var(--accordian-panel-border-radius);
66
+ margin-block-end: var(--accordian-panel-mbe);
67
+
68
+ summary::-webkit-details-marker,
69
+ summary::marker {
70
+ display: none;
71
+ }
72
+
73
+ .accordion-trigger {
74
+ display: flex !important;
75
+ align-items: center;
76
+ gap: 12px;
77
+ list-style: none;
78
+ padding: 1rem;
79
+
80
+ .label {
81
+ display: block;
82
+ flex-grow: 1;
83
+ }
84
+
85
+ .icon {
86
+ display: block;
87
+ font-size: 1.2rem;
88
+
89
+ transform: var(--_icon-transform);
90
+ transition: transform 200ms;
91
+ }
92
+ }
93
+
94
+ .accordion-content {
95
+ /* display: block; */
96
+ /* display: grid; */
97
+ /* grid-template-rows: 0fr; */
98
+ /* grid-template-rows: var(--_grid-template-rows); */
99
+
100
+ /* transform: var(--_accordian-content-transform); */
101
+ /* transform: scaleY(0); */
102
+ /* transform-origin: top; */
103
+ /* transition: all 2000ms; */
104
+
105
+ .accordion-content-inner {
106
+ background-color: red;
107
+
108
+ overflow: clip;
109
+ height: var(--_details-content-height);
110
+ transition: all 2000ms;
111
+ transition-behavior: allow-discrete;
112
+
113
+ @starting-style {
114
+ height: 0;
115
+ }
116
+ }
117
+ }
118
+
119
+ &[open] {
120
+ --_grid-template-rows: 1fr;
121
+ --_details-content-height: calc-size(auto, size);
122
+
123
+ --_icon-transform: scaleY(-1);
124
+ --_accordian-content-transform: scaleY(1);
125
+
126
+ .accordion-content {
127
+ /* transform: scaleY(1); */
128
+ /* grid-template-rows: unset; */
129
+ grid-template-rows: 1fr;
130
+
131
+ .accordion-content-inner {
132
+ /* grid-template-rows: 1fr; */
133
+ /* transform: scaleY(1); */
134
+ }
135
+ }
136
+ }
137
+ }
138
+ </style>
@@ -0,0 +1,244 @@
1
+ <template>
2
+ <dialog class="display-dialog-core" :class="[variant, elementClasses]" role="dialog" :align-dialog :open :data-dialog-id="dataDialogId" ref="dialogRef">
3
+ <focus-trap v-model:active="open" :clickOutsideDeactivates="true" @deactivate="closeDialog()">
4
+ <div class="inner">
5
+ <div class="header">
6
+ <div v-if="hasDialogTitle" class="col-left">
7
+ <slot name="dialogTitle"></slot>
8
+ </div>
9
+
10
+ <div class="col-center">
11
+ <p class="text-normal wght-700">Center col</p>
12
+ </div>
13
+ <div class="col-right">
14
+ <button @click.prevent="closeDialog()" data-test-id="display-dialog-header-close" class="display-prompt-action">
15
+ <Icon name="bitcoin-icons:cross-filled" class="icon" />
16
+ <span class="sr-only">Really Close</span>
17
+ </button>
18
+ </div>
19
+ </div>
20
+ <div v-if="hasDialogContent" class="dialog-content" :class="[{ 'allow-content-scroll': allowContentScroll }]">
21
+ <slot name="dialogContent"></slot>
22
+ </div>
23
+ <div v-if="hasActionButtons" class="footer">
24
+ <slot name="actionButtons"></slot>
25
+ </div>
26
+ </div>
27
+ </focus-trap>
28
+ </dialog>
29
+ </template>
30
+
31
+ <script setup lang="ts">
32
+ import { FocusTrap } from 'focus-trap-vue';
33
+ const props = defineProps({
34
+ styleClassPassthrough: {
35
+ type: Array as PropType<string[]>,
36
+ default: () => [],
37
+ },
38
+ variant: {
39
+ type: String,
40
+ default: 'dialog',
41
+ validator: (val) => ['dialog', 'modal', 'confirm'].includes(val as string),
42
+ },
43
+ positionX: {
44
+ type: String,
45
+ default: 'center',
46
+ validator: (val) => ['left', 'center', 'right'].includes(val as string),
47
+ },
48
+ positionY: {
49
+ type: String,
50
+ default: 'center',
51
+ validator: (val) => ['top', 'center', 'bottom'].includes(val as string),
52
+ },
53
+ lockViewport: {
54
+ type: Boolean,
55
+ default: true,
56
+ },
57
+ allowContentScroll: {
58
+ type: Boolean,
59
+ default: false,
60
+ },
61
+ dataDialogId: {
62
+ type: String,
63
+ required: true,
64
+ },
65
+ });
66
+
67
+ const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough);
68
+
69
+ const open = defineModel<boolean>();
70
+ const bodyTag = ref<HTMLBodyElement | null>(null);
71
+ const lockViewport = toRef<boolean>(props.lockViewport);
72
+
73
+ const closeDialog = () => {
74
+ open.value = false;
75
+
76
+ if (lockViewport.value && bodyTag.value !== null) {
77
+ bodyTag.value.classList.remove('lock');
78
+ }
79
+ };
80
+
81
+ const slots = useSlots();
82
+ const hasDialogTitle = computed(() => slots.dialogTitle !== undefined);
83
+ const hasDialogContent = computed(() => slots.dialogContent !== undefined);
84
+ const hasActionButtons = computed(() => slots.actionButtons !== undefined);
85
+
86
+ const alignDialog = computed(() => `${props.positionY}-${props.positionX}`);
87
+
88
+ onMounted(() => {
89
+ bodyTag.value = document.querySelector('body');
90
+ if (lockViewport.value && bodyTag.value !== null) {
91
+ bodyTag.value.classList.add('lock');
92
+ }
93
+ });
94
+ </script>
95
+
96
+ <style lang="css">
97
+ .display-dialog-core {
98
+ --_dialog-inner-height: initial;
99
+ --_dialog-inner-width: 100vw;
100
+
101
+ display: flex;
102
+ position: fixed;
103
+ left: 0;
104
+ top: 0;
105
+ width: 100%;
106
+ height: 100%;
107
+ backdrop-filter: blur(5px);
108
+ background-color: rgba(0, 0, 0, 0.5);
109
+ z-index: 13;
110
+ opacity: 0;
111
+ border: none;
112
+ padding: 0;
113
+
114
+ display: none;
115
+ transition: opacity 200ms, display 200ms, overlay 200ms;
116
+ transition-behavior: allow-discrete;
117
+
118
+ &[open] {
119
+ display: flex;
120
+ opacity: 1;
121
+
122
+ @starting-style {
123
+ display: flex;
124
+ opacity: 0;
125
+ }
126
+ }
127
+
128
+ &[align-dialog$='center'] {
129
+ justify-content: center;
130
+ }
131
+ &[align-dialog^='center'] {
132
+ align-items: center;
133
+ }
134
+
135
+ &.confirm {
136
+ --_dialog-inner-width: initial;
137
+ }
138
+
139
+ &.dialog {
140
+ --_dialog-inner-height: 70dvh;
141
+ --_dialog-inner-width: min(75%, 720px);
142
+ }
143
+
144
+ &.form {
145
+ --_dialog-inner-width: initial;
146
+ }
147
+
148
+ &.fullscreen {
149
+ --_dialog-inner-width: initial;
150
+ }
151
+
152
+ &.modal {
153
+ --_dialog-inner-width: initial;
154
+ }
155
+
156
+ .inner {
157
+ display: grid;
158
+ grid-template-rows: auto 1fr auto;
159
+
160
+ border-radius: var(--dialog-border-radius);
161
+ border: var(--dialog-border);
162
+ outline: var(--dialog-outline);
163
+
164
+ background-color: var(--dialog-inner-background);
165
+ height: var(--_dialog-inner-height);
166
+ width: var(--_dialog-inner-width);
167
+
168
+ overflow: hidden;
169
+
170
+ .header {
171
+ display: grid;
172
+ grid-template-columns: auto 1fr auto;
173
+ align-items: center;
174
+
175
+ padding: var(--dialog-header-padding);
176
+
177
+ .col-left {
178
+ /* grid-column: 1; */
179
+ /* display: none; */
180
+ }
181
+
182
+ .col-center {
183
+ /* grid-column: 2; */
184
+ text-align: center;
185
+
186
+ color: var(--color-red-1);
187
+ display: none;
188
+ }
189
+
190
+ .col-right {
191
+ grid-column: 3;
192
+
193
+ .display-prompt-action {
194
+ background-color: transparent;
195
+ display: block flex;
196
+ align-items: center;
197
+ justify-content: center;
198
+ margin: var(--dialog-header-button-margin);
199
+ padding: var(--dialog-header-button-padding);
200
+ border: var(--dialog-header-button-border);
201
+ border-radius: var(--dialog-header-button-border-radius);
202
+ outline: var(--dialog-header-button-outline);
203
+
204
+ transition: border-color 0.2s, outline-color 0.2s;
205
+
206
+ &:hover,
207
+ &:focus-visible {
208
+ cursor: pointer;
209
+ border: var(--dialog-header-button-border-hover);
210
+ outline: var(--dialog-header-button-outline-hover);
211
+ }
212
+
213
+ .icon {
214
+ color: var(--dialog-header-button-icon-color);
215
+ display: block;
216
+ font-size: var(--dialog-header-button-icon-font-size);
217
+ border: 1px solid green;
218
+ padding: 1rem;
219
+ }
220
+ }
221
+ }
222
+ }
223
+
224
+ .dialog-content {
225
+ overflow: hidden;
226
+ padding: var(--dialog-content-padding);
227
+
228
+ &.allow-content-scroll {
229
+ overflow-y: auto;
230
+ &::-webkit-scrollbar {
231
+ display: none;
232
+ }
233
+ }
234
+ }
235
+
236
+ .footer {
237
+ display: flex;
238
+ gap: 1.2rem;
239
+ justify-content: flex-end;
240
+ padding: var(--dialog-footer-padding);
241
+ }
242
+ }
243
+ }
244
+ </style>