@citizenplane/pimp 11.0.2 → 11.0.4
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/pimp.es.js +774 -770
- package/dist/pimp.umd.js +23 -23
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/components/CpDialog.vue +19 -8
- package/src/components/CpInput.vue +4 -0
- package/src/stories/CpDialog.stories.ts +24 -2
package/package.json
CHANGED
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
<div aria-hidden="true" class="cpDialog__overlay" />
|
|
12
12
|
<main ref="dialogContainer" class="cpDialog__container" :style="dynamicStyle" @keydown.tab="trapFocus">
|
|
13
13
|
<header class="cpDialog__header">
|
|
14
|
-
<div class="
|
|
15
|
-
<div class="cpDialog__title">
|
|
14
|
+
<div v-if="hasTitleOrSubtitle" class="cpDialog__headerTexts">
|
|
15
|
+
<div v-if="hasTitle" class="cpDialog__title">
|
|
16
16
|
<slot name="title">
|
|
17
17
|
<h2 :id="titleId">{{ title }}</h2>
|
|
18
18
|
</slot>
|
|
@@ -46,7 +46,7 @@ import { getKeyboardFocusableElements, handleTrapFocus } from '@/helpers/dom'
|
|
|
46
46
|
interface Props {
|
|
47
47
|
maxWidth?: number
|
|
48
48
|
subtitle?: string
|
|
49
|
-
title
|
|
49
|
+
title?: string
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
interface Emits {
|
|
@@ -55,6 +55,7 @@ interface Emits {
|
|
|
55
55
|
|
|
56
56
|
const props = withDefaults(defineProps<Props>(), {
|
|
57
57
|
maxWidth: 600,
|
|
58
|
+
title: '',
|
|
58
59
|
subtitle: '',
|
|
59
60
|
})
|
|
60
61
|
|
|
@@ -73,8 +74,12 @@ const dialogContainer = ref<HTMLElement | null>(null)
|
|
|
73
74
|
|
|
74
75
|
const dynamicStyle = computed(() => ({ maxWidth: `${props.maxWidth}px` }))
|
|
75
76
|
|
|
77
|
+
const hasTitleSlot = computed(() => !!slots.title)
|
|
78
|
+
const hasTitle = computed(() => !!props.title || hasTitleSlot.value)
|
|
76
79
|
const hasSubtitleSlot = computed(() => !!slots.subtitle)
|
|
77
80
|
const hasSubtitle = computed(() => !!props.subtitle || hasSubtitleSlot.value)
|
|
81
|
+
const hasTitleOrSubtitle = computed(() => hasTitle.value || hasSubtitle.value)
|
|
82
|
+
|
|
78
83
|
const hasFooterSlot = computed(() => !!slots.footer)
|
|
79
84
|
|
|
80
85
|
const handleClose = () => emit('close')
|
|
@@ -96,9 +101,7 @@ onMounted(() => {
|
|
|
96
101
|
nextTick(() => focusOnFirstFocusableElement())
|
|
97
102
|
})
|
|
98
103
|
|
|
99
|
-
onBeforeUnmount(() =>
|
|
100
|
-
closeDialog()
|
|
101
|
-
})
|
|
104
|
+
onBeforeUnmount(() => closeDialog())
|
|
102
105
|
</script>
|
|
103
106
|
|
|
104
107
|
<style lang="scss">
|
|
@@ -184,10 +187,17 @@ $dialog-breakpoint: 550px;
|
|
|
184
187
|
align-items: flex-start;
|
|
185
188
|
justify-content: space-between;
|
|
186
189
|
gap: var(--cp-spacing-md);
|
|
187
|
-
|
|
190
|
+
|
|
191
|
+
&:not(:has(.cpDialog__headerTexts)) {
|
|
192
|
+
padding-bottom: 0;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
&:has(.cpDialog__headerTexts) {
|
|
196
|
+
border-bottom: 1px solid var(--cp-border-soft);
|
|
197
|
+
}
|
|
188
198
|
}
|
|
189
199
|
|
|
190
|
-
&
|
|
200
|
+
&__headerText {
|
|
191
201
|
display: flex;
|
|
192
202
|
flex-direction: column;
|
|
193
203
|
min-width: 0;
|
|
@@ -214,6 +224,7 @@ $dialog-breakpoint: 550px;
|
|
|
214
224
|
|
|
215
225
|
&__close {
|
|
216
226
|
display: flex;
|
|
227
|
+
margin-left: auto;
|
|
217
228
|
align-items: center;
|
|
218
229
|
justify-content: center;
|
|
219
230
|
padding: var(--cp-spacing-sm);
|
|
@@ -268,6 +268,10 @@ onMounted(async () => {
|
|
|
268
268
|
box-shadow: 0 0 0 var(--cp-dimensions-0_25) var(--cp-border-disabled);
|
|
269
269
|
}
|
|
270
270
|
|
|
271
|
+
.cpInput__icon {
|
|
272
|
+
color: var(--cp-foreground-disabled);
|
|
273
|
+
}
|
|
274
|
+
|
|
271
275
|
.cpInput__icon:hover ~ .cpInput__inner {
|
|
272
276
|
box-shadow: 0 0 0 var(--cp-dimensions-0_25) var(--cp-border-disabled);
|
|
273
277
|
}
|
|
@@ -51,6 +51,7 @@ export const TitleSubtitleWithProps: Story = {
|
|
|
51
51
|
args: {
|
|
52
52
|
maxWidth: 600,
|
|
53
53
|
title: 'Dialog title',
|
|
54
|
+
subtitle: 'Dialog subtitle',
|
|
54
55
|
},
|
|
55
56
|
render: (args) => ({
|
|
56
57
|
setup() {
|
|
@@ -72,11 +73,32 @@ export const TitleSubtitleWithProps: Story = {
|
|
|
72
73
|
}),
|
|
73
74
|
}
|
|
74
75
|
|
|
76
|
+
export const ContentOnly: Story = {
|
|
77
|
+
args: {
|
|
78
|
+
maxWidth: 600,
|
|
79
|
+
},
|
|
80
|
+
render: (args) => ({
|
|
81
|
+
setup() {
|
|
82
|
+
const isOpen = ref(false)
|
|
83
|
+
return { args, isOpen }
|
|
84
|
+
},
|
|
85
|
+
template: `
|
|
86
|
+
<CpButton @click="isOpen = true">Open Dialog (content only)</CpButton>
|
|
87
|
+
<CpTransitionDialog>
|
|
88
|
+
<CpDialog v-bind="args" v-if="isOpen" @close="isOpen = false">
|
|
89
|
+
<p>This is the default slot content with no title or subtitle.</p>
|
|
90
|
+
<template #footer>
|
|
91
|
+
<CpButton @click="isOpen = false">Close</CpButton>
|
|
92
|
+
</template>
|
|
93
|
+
</CpDialog>
|
|
94
|
+
</CpTransitionDialog>
|
|
95
|
+
`,
|
|
96
|
+
}),
|
|
97
|
+
}
|
|
98
|
+
|
|
75
99
|
export const TitleSubtitleWithSlots: Story = {
|
|
76
100
|
args: {
|
|
77
101
|
maxWidth: 560,
|
|
78
|
-
titleTag: 'div',
|
|
79
|
-
subtitleTag: 'div',
|
|
80
102
|
},
|
|
81
103
|
render: (args) => ({
|
|
82
104
|
setup() {
|