@citizenplane/pimp 18.0.6 → 18.1.1
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/components/CpButtonToggle.vue.d.ts +30 -0
- package/dist/components/CpButtonToggle.vue.d.ts.map +1 -0
- package/dist/components/CpDate.vue.d.ts.map +1 -1
- package/dist/components/CpSwitch.vue.d.ts +2 -0
- package/dist/components/CpSwitch.vue.d.ts.map +1 -1
- package/dist/components/index.d.ts +2 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/pimp.es.js +2294 -2228
- package/dist/pimp.umd.js +51 -51
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/components/CpButtonToggle.vue +137 -0
- package/src/components/CpDate.vue +52 -25
- package/src/components/CpSwitch.vue +13 -1
- package/src/components/index.ts +3 -0
- package/src/stories/CpButtonToggle.stories.ts +137 -0
- package/src/stories/CpDate.stories.ts +27 -0
package/package.json
CHANGED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<button
|
|
3
|
+
:aria-disabled="disabled"
|
|
4
|
+
:aria-pressed="isSelected"
|
|
5
|
+
class="cpToggleButton"
|
|
6
|
+
:class="dynamicClasses"
|
|
7
|
+
:disabled="disabled"
|
|
8
|
+
type="button"
|
|
9
|
+
@click="handleClick"
|
|
10
|
+
>
|
|
11
|
+
<span class="cpToggleButton__leading">
|
|
12
|
+
<slot name="leading">
|
|
13
|
+
<cp-icon size="16" :type="leadingIcon" />
|
|
14
|
+
</slot>
|
|
15
|
+
</span>
|
|
16
|
+
<span v-if="showLabel" class="cpToggleButton__label">
|
|
17
|
+
<slot>
|
|
18
|
+
{{ label }}
|
|
19
|
+
</slot>
|
|
20
|
+
</span>
|
|
21
|
+
</button>
|
|
22
|
+
</template>
|
|
23
|
+
|
|
24
|
+
<script setup lang="ts">
|
|
25
|
+
import { computed, useSlots } from 'vue'
|
|
26
|
+
|
|
27
|
+
interface Props {
|
|
28
|
+
disabled?: boolean
|
|
29
|
+
isSelected?: boolean
|
|
30
|
+
label?: string
|
|
31
|
+
leadingIcon?: string
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
35
|
+
isSelected: false,
|
|
36
|
+
disabled: false,
|
|
37
|
+
label: '',
|
|
38
|
+
leadingIcon: 'dashed-circle',
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
const emit = defineEmits<{
|
|
42
|
+
click: [event: MouseEvent]
|
|
43
|
+
}>()
|
|
44
|
+
|
|
45
|
+
const slots = useSlots()
|
|
46
|
+
|
|
47
|
+
const showLabel = computed(() => !!props.label || !!slots.default)
|
|
48
|
+
|
|
49
|
+
const dynamicClasses = computed(() => ({
|
|
50
|
+
'cpToggleButton--isSelected': props.isSelected,
|
|
51
|
+
}))
|
|
52
|
+
|
|
53
|
+
const handleClick = (event: MouseEvent) => {
|
|
54
|
+
emit('click', event)
|
|
55
|
+
}
|
|
56
|
+
</script>
|
|
57
|
+
|
|
58
|
+
<style lang="scss">
|
|
59
|
+
.cpToggleButton {
|
|
60
|
+
display: inline-flex;
|
|
61
|
+
align-items: center;
|
|
62
|
+
justify-content: center;
|
|
63
|
+
gap: var(--cp-spacing-md);
|
|
64
|
+
padding: var(--cp-spacing-lg);
|
|
65
|
+
border-radius: var(--cp-radius-md);
|
|
66
|
+
box-shadow:
|
|
67
|
+
var(--cp-shadows-3xs-inset),
|
|
68
|
+
0 0 0 var(--cp-dimensions-0_25) var(--cp-border-soft);
|
|
69
|
+
background-color: var(--cp-background-primary);
|
|
70
|
+
color: var(--cp-text-secondary);
|
|
71
|
+
transition:
|
|
72
|
+
background-color 100ms ease-out,
|
|
73
|
+
box-shadow 100ms ease-out,
|
|
74
|
+
color 100ms ease-out;
|
|
75
|
+
|
|
76
|
+
&:hover:not(:disabled) {
|
|
77
|
+
background-color: var(--cp-background-primary-hover);
|
|
78
|
+
color: var(--cp-text-secondary-hover);
|
|
79
|
+
box-shadow:
|
|
80
|
+
var(--cp-shadows-3xs-inset),
|
|
81
|
+
0 0 0 var(--cp-dimensions-0_25) var(--cp-border-soft-hover);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
&:focus-visible {
|
|
85
|
+
box-shadow:
|
|
86
|
+
0 0 0 var(--cp-dimensions-0_25) var(--cp-border-soft-hover),
|
|
87
|
+
var(--cp-shadow-focus-ring-accent);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
&__leading {
|
|
91
|
+
display: flex;
|
|
92
|
+
align-items: center;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
&__label {
|
|
96
|
+
font-size: var(--cp-text-size-sm);
|
|
97
|
+
line-height: var(--cp-line-height-sm);
|
|
98
|
+
font-weight: 500;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
&__defaultLeading,
|
|
102
|
+
&__defaultLeading * {
|
|
103
|
+
pointer-events: none;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
&:disabled {
|
|
107
|
+
cursor: not-allowed;
|
|
108
|
+
background-color: var(--cp-background-disabled);
|
|
109
|
+
color: var(--cp-text-disabled);
|
|
110
|
+
box-shadow:
|
|
111
|
+
var(--cp-shadows-3xs-inset),
|
|
112
|
+
0 0 0 var(--cp-dimensions-0_25) var(--cp-border-disabled);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
&--isSelected:not(:disabled) {
|
|
116
|
+
background-color: var(--cp-background-accent-secondary);
|
|
117
|
+
color: var(--cp-text-accent-primary);
|
|
118
|
+
box-shadow:
|
|
119
|
+
var(--cp-shadows-3xs-inset),
|
|
120
|
+
0 0 0 var(--cp-dimensions-0_25) var(--cp-border-accent-solid);
|
|
121
|
+
|
|
122
|
+
&:hover {
|
|
123
|
+
background-color: var(--cp-background-accent-secondary-hover);
|
|
124
|
+
color: var(--cp-text-accent-primary-hover);
|
|
125
|
+
box-shadow:
|
|
126
|
+
var(--cp-shadows-3xs-inset),
|
|
127
|
+
0 0 0 var(--cp-dimensions-0_25) var(--cp-border-accent-solid);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
&:focus-visible {
|
|
131
|
+
box-shadow:
|
|
132
|
+
0 0 0 var(--cp-dimensions-0_25) var(--cp-border-accent-solid),
|
|
133
|
+
var(--cp-shadow-focus-ring-accent);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
</style>
|
|
@@ -4,33 +4,36 @@
|
|
|
4
4
|
{{ capitalizedLabel }}
|
|
5
5
|
</base-input-label>
|
|
6
6
|
<div class="cpDate__inputs">
|
|
7
|
-
<
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
maxlength="2"
|
|
16
|
-
:placeholder="dayInputPlaceholder"
|
|
17
|
-
:required="required"
|
|
18
|
-
/>
|
|
19
|
-
<div class="cpDate__divider" />
|
|
20
|
-
<div class="cpDate__month" :class="selectDynamicClass">
|
|
21
|
-
<select
|
|
22
|
-
:id="cpDateId"
|
|
23
|
-
v-model="month"
|
|
24
|
-
:autocomplete="autocompleteFields.month"
|
|
7
|
+
<template v-for="(field, index) in orderedDateFields" :key="field">
|
|
8
|
+
<input
|
|
9
|
+
v-if="isDayField(field)"
|
|
10
|
+
v-model="day"
|
|
11
|
+
v-maska
|
|
12
|
+
:autocomplete="autocompleteFields.day"
|
|
13
|
+
class="cpDate__day"
|
|
14
|
+
data-maska="##"
|
|
25
15
|
:disabled="disabled"
|
|
16
|
+
inputmode="numeric"
|
|
17
|
+
maxlength="2"
|
|
18
|
+
:placeholder="dayInputPlaceholder"
|
|
26
19
|
:required="required"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
<
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
20
|
+
/>
|
|
21
|
+
<div v-else class="cpDate__month" :class="selectDynamicClass">
|
|
22
|
+
<select
|
|
23
|
+
:id="cpDateId"
|
|
24
|
+
v-model="month"
|
|
25
|
+
:autocomplete="autocompleteFields.month"
|
|
26
|
+
:disabled="disabled"
|
|
27
|
+
:required="required"
|
|
28
|
+
>
|
|
29
|
+
<option value>{{ monthInputPlaceholder }}</option>
|
|
30
|
+
<option v-for="(monthItem, monthIndex) in months" :key="monthIndex" :value="monthItem.value">
|
|
31
|
+
{{ monthItem.label }}
|
|
32
|
+
</option>
|
|
33
|
+
</select>
|
|
34
|
+
</div>
|
|
35
|
+
<div v-if="shouldShowDivider(index)" class="cpDate__divider" />
|
|
36
|
+
</template>
|
|
34
37
|
<div class="cpDate__divider" />
|
|
35
38
|
<input
|
|
36
39
|
v-model="year"
|
|
@@ -71,6 +74,7 @@ interface InputsOptions {
|
|
|
71
74
|
monthInputPlaceholder?: string
|
|
72
75
|
yearInputPlaceholder?: string
|
|
73
76
|
}
|
|
77
|
+
type DateField = 'day' | 'month'
|
|
74
78
|
|
|
75
79
|
interface Props {
|
|
76
80
|
autocompleteBirthday?: boolean
|
|
@@ -265,6 +269,24 @@ const monthInputPlaceholder = computed(() => {
|
|
|
265
269
|
return props.inputsOptions?.monthInputPlaceholder || 'Months'
|
|
266
270
|
})
|
|
267
271
|
|
|
272
|
+
const isDayFirst = computed(() => {
|
|
273
|
+
const parts = new Intl.DateTimeFormat(props.locale, {
|
|
274
|
+
day: '2-digit',
|
|
275
|
+
month: '2-digit',
|
|
276
|
+
}).formatToParts(new Date(2024, 0, 31))
|
|
277
|
+
|
|
278
|
+
const dayIndex = parts.findIndex((part) => part.type === 'day')
|
|
279
|
+
const monthIndex = parts.findIndex((part) => part.type === 'month')
|
|
280
|
+
|
|
281
|
+
if (dayIndex === -1 || monthIndex === -1) return false
|
|
282
|
+
|
|
283
|
+
return dayIndex < monthIndex
|
|
284
|
+
})
|
|
285
|
+
|
|
286
|
+
const orderedDateFields = computed<DateField[]>(() => {
|
|
287
|
+
return isDayFirst.value ? ['day', 'month'] : ['month', 'day']
|
|
288
|
+
})
|
|
289
|
+
|
|
268
290
|
const yearInputPlaceholder = computed(() => {
|
|
269
291
|
return props.inputsOptions?.yearInputPlaceholder || 'YYYY'
|
|
270
292
|
})
|
|
@@ -274,6 +296,10 @@ const handleUpdate = (): void => {
|
|
|
274
296
|
emit('onValidation', isDateValid.value)
|
|
275
297
|
}
|
|
276
298
|
|
|
299
|
+
const isDayField = (field: DateField): boolean => field === 'day'
|
|
300
|
+
|
|
301
|
+
const shouldShowDivider = (index: number): boolean => index < orderedDateFields.value.length - 1
|
|
302
|
+
|
|
277
303
|
watch(day, handleUpdate)
|
|
278
304
|
watch(month, handleUpdate)
|
|
279
305
|
watch(year, handleUpdate)
|
|
@@ -296,6 +322,7 @@ watch(year, handleUpdate)
|
|
|
296
322
|
}
|
|
297
323
|
|
|
298
324
|
input[type='number'] {
|
|
325
|
+
appearance: textfield;
|
|
299
326
|
-moz-appearance: textfield;
|
|
300
327
|
}
|
|
301
328
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<label class="cpSwitch" :class="computedClasses" :for="switchUniqueId">
|
|
2
|
+
<label class="cpSwitch" :class="computedClasses" :for="switchUniqueId" v-bind="inertProps">
|
|
3
3
|
<span class="cpSwitch__switch">
|
|
4
4
|
<input
|
|
5
5
|
:id="switchUniqueId"
|
|
@@ -46,6 +46,7 @@ interface Props {
|
|
|
46
46
|
enableHaptics?: boolean
|
|
47
47
|
groupName?: string
|
|
48
48
|
helper?: string
|
|
49
|
+
inert?: boolean
|
|
49
50
|
isRequired?: boolean
|
|
50
51
|
label?: string
|
|
51
52
|
modelValue?: boolean
|
|
@@ -68,6 +69,7 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
68
69
|
autofocus: false,
|
|
69
70
|
isRequired: false,
|
|
70
71
|
tooltip: '',
|
|
72
|
+
inert: false,
|
|
71
73
|
})
|
|
72
74
|
|
|
73
75
|
const emit = defineEmits<Emits>()
|
|
@@ -80,6 +82,16 @@ const capitalizedColor = computed(() => {
|
|
|
80
82
|
return capitalizeFirstLetter(props.color)
|
|
81
83
|
})
|
|
82
84
|
|
|
85
|
+
const inertProps = computed(() => {
|
|
86
|
+
if (!props.inert) return
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
'aria-hidden': true,
|
|
90
|
+
tabindex: -1,
|
|
91
|
+
inert: true,
|
|
92
|
+
}
|
|
93
|
+
})
|
|
94
|
+
|
|
83
95
|
const computedClasses = computed(() => {
|
|
84
96
|
return [
|
|
85
97
|
{
|
package/src/components/index.ts
CHANGED
|
@@ -22,6 +22,7 @@ import CpAlert from './CpAlert.vue'
|
|
|
22
22
|
import CpBadge from './CpBadge.vue'
|
|
23
23
|
import CpButton from './CpButton.vue'
|
|
24
24
|
import CpButtonGroup from './CpButtonGroup.vue'
|
|
25
|
+
import CpButtonToggle from './CpButtonToggle.vue'
|
|
25
26
|
import CpCalendar from './CpCalendar.vue'
|
|
26
27
|
import CpCheckbox from './CpCheckbox.vue'
|
|
27
28
|
import CpContextualMenu from './CpContextualMenu.vue'
|
|
@@ -73,6 +74,7 @@ const Components = {
|
|
|
73
74
|
CpAccordion,
|
|
74
75
|
CpAccordionGroup,
|
|
75
76
|
CpToast,
|
|
77
|
+
CpButtonToggle,
|
|
76
78
|
CpBadge,
|
|
77
79
|
CpTabs,
|
|
78
80
|
CpHeading,
|
|
@@ -148,6 +150,7 @@ export {
|
|
|
148
150
|
CpAccordion,
|
|
149
151
|
CpAccordionGroup,
|
|
150
152
|
CpToast,
|
|
153
|
+
CpButtonToggle,
|
|
151
154
|
CpBadge,
|
|
152
155
|
CpTabs,
|
|
153
156
|
CpHeading,
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { ref } from 'vue'
|
|
2
|
+
|
|
3
|
+
import type { Args, Meta, StoryObj } from '@storybook/vue3-vite'
|
|
4
|
+
|
|
5
|
+
import CpButtonToggle from '@/components/CpButtonToggle.vue'
|
|
6
|
+
import CpSwitch from '@/components/CpSwitch.vue'
|
|
7
|
+
|
|
8
|
+
import { docCellStyle, docLabelStyle, docRowWrapStyle } from '@/stories/documentationStyles'
|
|
9
|
+
|
|
10
|
+
const meta = {
|
|
11
|
+
title: 'Atoms/CpButtonToggle',
|
|
12
|
+
component: CpButtonToggle,
|
|
13
|
+
argTypes: {
|
|
14
|
+
isSelected: {
|
|
15
|
+
control: 'boolean',
|
|
16
|
+
description: 'Whether the toggle button is selected.',
|
|
17
|
+
},
|
|
18
|
+
disabled: {
|
|
19
|
+
control: 'boolean',
|
|
20
|
+
description: 'Whether interactions are disabled.',
|
|
21
|
+
},
|
|
22
|
+
label: {
|
|
23
|
+
control: 'text',
|
|
24
|
+
description: 'Text displayed in the button.',
|
|
25
|
+
},
|
|
26
|
+
leadingIcon: {
|
|
27
|
+
control: 'text',
|
|
28
|
+
description: 'Icon displayed in the button.',
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
} satisfies Meta<typeof CpButtonToggle>
|
|
32
|
+
|
|
33
|
+
export default meta
|
|
34
|
+
type Story = StoryObj<typeof meta>
|
|
35
|
+
|
|
36
|
+
const defaultRender = (args: Args) => ({
|
|
37
|
+
components: { CpButtonToggle },
|
|
38
|
+
setup() {
|
|
39
|
+
return { args }
|
|
40
|
+
},
|
|
41
|
+
template: `
|
|
42
|
+
<CpButtonToggle v-bind="args" />
|
|
43
|
+
`,
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
export const Default: Story = {
|
|
47
|
+
args: {
|
|
48
|
+
label: 'Title',
|
|
49
|
+
isSelected: false,
|
|
50
|
+
disabled: false,
|
|
51
|
+
leadingIcon: 'dashed-circle',
|
|
52
|
+
},
|
|
53
|
+
render: defaultRender,
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export const States: Story = {
|
|
57
|
+
parameters: { controls: { disable: true } },
|
|
58
|
+
render: () => ({
|
|
59
|
+
components: { CpButtonToggle },
|
|
60
|
+
setup() {
|
|
61
|
+
return { docCellStyle, docLabelStyle, docRowWrapStyle }
|
|
62
|
+
},
|
|
63
|
+
template: `
|
|
64
|
+
<div :style="docRowWrapStyle">
|
|
65
|
+
<div :style="docCellStyle">
|
|
66
|
+
<span :style="docLabelStyle">Default</span>
|
|
67
|
+
<CpButtonToggle label="Title" />
|
|
68
|
+
</div>
|
|
69
|
+
<div :style="docCellStyle">
|
|
70
|
+
<span :style="docLabelStyle">Selected</span>
|
|
71
|
+
<CpButtonToggle label="Title" :is-selected="true" />
|
|
72
|
+
</div>
|
|
73
|
+
<div :style="docCellStyle">
|
|
74
|
+
<span :style="docLabelStyle">Disabled</span>
|
|
75
|
+
<CpButtonToggle label="Title" :disabled="true" />
|
|
76
|
+
</div>
|
|
77
|
+
<div :style="docCellStyle">
|
|
78
|
+
<span :style="docLabelStyle">Disabled selected</span>
|
|
79
|
+
<CpButtonToggle label="Title" :is-selected="true" :disabled="true" />
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
`,
|
|
83
|
+
}),
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export const withInertSwitch: Story = {
|
|
87
|
+
args: {
|
|
88
|
+
...Default.args,
|
|
89
|
+
isSelected: undefined,
|
|
90
|
+
},
|
|
91
|
+
render: (args: Args) => ({
|
|
92
|
+
components: { CpButtonToggle, CpSwitch },
|
|
93
|
+
setup() {
|
|
94
|
+
const isSelected = ref(false)
|
|
95
|
+
return { docCellStyle, docLabelStyle, docRowWrapStyle, isSelected, args }
|
|
96
|
+
},
|
|
97
|
+
template: `
|
|
98
|
+
<div :style="docRowWrapStyle">
|
|
99
|
+
<div :style="docCellStyle">
|
|
100
|
+
<span :style="docLabelStyle">Selected</span>
|
|
101
|
+
<CpButtonToggle v-bind="args" :is-selected="isSelected" @click="isSelected = !isSelected">
|
|
102
|
+
<template #leading>
|
|
103
|
+
<CpSwitch v-model="isSelected" inert :disabled="args.disabled" />
|
|
104
|
+
</template>
|
|
105
|
+
</CpButtonToggle>
|
|
106
|
+
</div>
|
|
107
|
+
</div>
|
|
108
|
+
`,
|
|
109
|
+
}),
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export const CustomLeadingSlot: Story = {
|
|
113
|
+
parameters: { controls: { disable: true } },
|
|
114
|
+
render: () => ({
|
|
115
|
+
components: { CpButtonToggle },
|
|
116
|
+
template: `
|
|
117
|
+
<div>
|
|
118
|
+
<CpButtonToggle label="Title" :is-selected="true">
|
|
119
|
+
<template #leading>
|
|
120
|
+
<span style="
|
|
121
|
+
width: 16px;
|
|
122
|
+
height: 16px;
|
|
123
|
+
display: inline-flex;
|
|
124
|
+
align-items: center;
|
|
125
|
+
justify-content: center;
|
|
126
|
+
border-radius: 4px;
|
|
127
|
+
background: var(--cp-background-accent-solid);
|
|
128
|
+
color: var(--cp-foreground-white);
|
|
129
|
+
font-size: 11px;
|
|
130
|
+
line-height: 1;
|
|
131
|
+
">✓</span>
|
|
132
|
+
</template>
|
|
133
|
+
</CpButtonToggle>
|
|
134
|
+
</div>
|
|
135
|
+
`,
|
|
136
|
+
}),
|
|
137
|
+
}
|
|
@@ -140,6 +140,33 @@ export const States: Story = {
|
|
|
140
140
|
}),
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
+
/**
|
|
144
|
+
* Compares input ordering by locale (day/month in French, month/day in US English).
|
|
145
|
+
*/
|
|
146
|
+
export const LocaleOrdering: Story = {
|
|
147
|
+
parameters: { controls: { disable: true } },
|
|
148
|
+
render: () => ({
|
|
149
|
+
components: { CpDate },
|
|
150
|
+
setup() {
|
|
151
|
+
const frenchDate = ref('')
|
|
152
|
+
const usDate = ref('')
|
|
153
|
+
return { frenchDate, usDate, docRowColumnStyle, dateStackStyle, docLabelStyle }
|
|
154
|
+
},
|
|
155
|
+
template: `
|
|
156
|
+
<div :style="docRowColumnStyle">
|
|
157
|
+
<div :style="dateStackStyle">
|
|
158
|
+
<span :style="docLabelStyle">fr-FR (day / month / year)</span>
|
|
159
|
+
<CpDate v-model="frenchDate" label="Date" locale="fr-FR" />
|
|
160
|
+
</div>
|
|
161
|
+
<div :style="dateStackStyle">
|
|
162
|
+
<span :style="docLabelStyle">en-US (month / day / year)</span>
|
|
163
|
+
<CpDate v-model="usDate" label="Date" locale="en-US" />
|
|
164
|
+
</div>
|
|
165
|
+
</div>
|
|
166
|
+
`,
|
|
167
|
+
}),
|
|
168
|
+
}
|
|
169
|
+
|
|
143
170
|
/**
|
|
144
171
|
* Combines a date input with a text input on the same line.
|
|
145
172
|
*/
|