@carbon/vue 3.0.6-alpha.0 → 3.0.8-alpha.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.
- package/README.md +7 -0
- package/dist/carbon-vue-3.common.js +16111 -9105
- package/dist/carbon-vue-3.common.js.map +1 -1
- package/dist/carbon-vue-3.umd.js +16111 -9105
- package/dist/carbon-vue-3.umd.js.map +1 -1
- package/dist/carbon-vue-3.umd.min.js +4 -4
- package/dist/carbon-vue-3.umd.min.js.map +1 -1
- package/package.json +9 -6
- package/src/components/CvAccordion/CvAccordion.stories.js +1 -0
- package/src/components/CvButton/CvButton.stories.js +3 -3
- package/src/components/CvButton/CvButtonSkeleton.stories.js +79 -0
- package/src/components/CvButton/CvButtonSkeleton.vue +19 -0
- package/src/components/CvButton/index.js +8 -1
- package/src/components/CvCheckbox/CvCheckbox.stories.js +18 -7
- package/src/components/CvCheckbox/CvCheckbox.vue +19 -3
- package/src/components/CvCheckbox/CvCheckboxSkeleton.vue +16 -0
- package/src/components/CvCheckbox/__tests__/__snapshots__/CvCheckboxSkeleton.spec.js.snap +3 -0
- package/src/components/CvCheckbox/index.js +2 -1
- package/src/components/CvDatePicker/CvDatePicker.vue +1 -1
- package/src/components/CvDropdown/CvDropdown.stories.mdx +407 -0
- package/src/components/CvDropdown/CvDropdown.vue +416 -0
- package/src/components/CvDropdown/CvDropdownItem.vue +86 -0
- package/src/components/CvDropdown/CvDropdownSkeleton.vue +17 -0
- package/src/components/CvDropdown/index.js +5 -0
- package/src/components/CvFileUploader/CvFileUploader.stories.mdx +333 -0
- package/src/components/CvFileUploader/CvFileUploader.vue +286 -0
- package/src/components/CvFileUploader/CvFileUploaderItem.vue +92 -0
- package/src/components/CvFileUploader/CvFileUploaderSkeleton.vue +16 -0
- package/src/components/CvFileUploader/const.js +10 -0
- package/src/components/CvFileUploader/index.js +5 -0
- package/src/components/CvForm/CvFormGroup.vue +1 -1
- package/src/components/CvInlineLoading/CvInlineLoading.stories.mdx +87 -0
- package/src/components/CvInlineLoading/CvInlineLoading.vue +144 -0
- package/src/components/CvInlineLoading/consts.js +9 -0
- package/src/components/CvInlineLoading/index.js +4 -0
- package/src/components/CvModal/CvModal.stories.mdx +4 -2
- package/src/components/CvModal/CvModal.vue +3 -5
- package/src/components/CvMultiSelect/CvMultiSelect.stories.mdx +333 -0
- package/src/components/CvMultiSelect/CvMultiSelect.vue +705 -0
- package/src/components/CvMultiSelect/consts.js +16 -0
- package/src/components/CvMultiSelect/index.js +3 -0
- package/src/components/CvNumberInput/CvNumberInput.stories.js +265 -0
- package/src/components/CvNumberInput/CvNumberInput.vue +227 -0
- package/src/components/CvNumberInput/CvNumberInputSkeleton.stories.js +30 -0
- package/src/components/CvNumberInput/CvNumberInputSkeleton.vue +10 -0
- package/src/components/CvNumberInput/StorybookGroupConst.js +1 -0
- package/src/components/CvNumberInput/__tests__/__snapshots__/CvNumberInput.spec.js.snap +21 -0
- package/src/components/CvNumberInput/index.js +5 -0
- package/src/components/CvProgress/CvProgress.stories.mdx +202 -0
- package/src/components/CvProgress/CvProgress.vue +78 -0
- package/src/components/CvProgress/CvProgressStep.vue +124 -0
- package/src/components/CvProgress/index.js +4 -0
- package/src/components/CvRadioButton/CvRadioButton.stories.js +166 -0
- package/src/components/CvRadioButton/CvRadioButton.vue +57 -0
- package/src/components/CvRadioButton/CvRadioGroup.vue +27 -0
- package/src/components/CvRadioButton/__tests__/__snapshots__/CvRadioButton.spec.js.snap +27 -0
- package/src/components/CvRadioButton/index.js +6 -0
- package/src/components/CvSearch/CvSearch.stories.mdx +168 -0
- package/src/components/CvSearch/CvSearch.vue +250 -0
- package/src/components/CvSearch/index.js +3 -0
- package/src/components/CvSelect/CvSelect.vue +27 -6
- package/src/components/CvSlider/CvSlider.stories.js +166 -0
- package/src/components/CvSlider/CvSlider.vue +324 -0
- package/src/components/CvSlider/CvSliderSkeleton.stories.js +26 -0
- package/src/components/CvSlider/CvSliderSkeleton.vue +18 -0
- package/src/components/CvSlider/__tests__/__snapshots__/CvSlider.spec.js.snap +13 -0
- package/src/components/CvSlider/__tests__/__snapshots__/CvSliderSkeleton.spec.js.snap +13 -0
- package/src/components/CvSlider/index.js +5 -0
- package/src/components/CvSlider/sbSliderPrefix.js +2 -0
- package/src/components/CvTabs/CvTab.vue +77 -0
- package/src/components/CvTabs/CvTabs.stories.mdx +175 -0
- package/src/components/CvTabs/CvTabs.vue +406 -0
- package/src/components/CvTabs/CvTabsSkeleton.vue +24 -0
- package/src/components/CvTabs/_SbContainer.vue +22 -0
- package/src/components/CvTabs/index.js +5 -0
- package/src/components/CvTextArea/CvTextArea.stories.js +2 -2
- package/src/components/CvTextArea/CvTextAreaSkeleton.stories.js +29 -0
- package/src/components/CvTextArea/CvTextAreaSkeleton.vue +10 -0
- package/src/components/CvTextArea/StorybookGroupConst.js +1 -0
- package/src/components/CvTextArea/__tests__/__snapshots__/CvTextAreaSkeleton.spec.js.snap +7 -0
- package/src/components/CvTextArea/index.js +2 -1
- package/src/components/CvTimePicker/CvTimePicker.stories.mdx +325 -0
- package/src/components/CvTimePicker/CvTimePicker.vue +217 -0
- package/src/components/CvTimePicker/index.js +21 -0
- package/src/components/CvToggle/CvToggle-Skeleton.vue +44 -0
- package/src/components/CvToggle/CvToggle.stories.js +249 -0
- package/src/components/CvToggle/CvToggle.vue +87 -0
- package/src/components/CvToggle/__tests__/__snapshots__/CvToggle.spec.js.snap +7 -0
- package/src/components/CvToggle/index.js +4 -0
- package/src/components/CvTooltip/CvDefinitionTooltip.stories.js +80 -0
- package/src/components/CvTooltip/CvDefinitionTooltip.vue +61 -0
- package/src/components/CvTooltip/CvInteractiveTooltip.stories.js +90 -0
- package/src/components/CvTooltip/CvInteractiveTooltip.vue +267 -0
- package/src/components/CvTooltip/CvTooltip.stories.js +128 -0
- package/src/components/CvTooltip/CvTooltip.vue +44 -0
- package/src/components/CvTooltip/__tests__/__snapshots__/CvTooltip.spec.js.snap +525 -0
- package/src/components/CvTooltip/consts.js +15 -0
- package/src/components/CvTooltip/index.js +6 -0
- package/src/components/CvTooltip/sbTooltipPrefix.js +2 -0
- package/src/components/CvUIShell/CvSideNav.vue +10 -1
- package/src/components/CvUIShell/CvUIShell.stories.mdx +116 -50
- package/src/global/storybook-utils/story-source-code.js +1 -0
- package/src/index.d.ts +6 -0
- package/src/index.js +11 -0
- package/src/use/cvCheck.js +3 -0
- package/src/use/cvInput.js +34 -0
- package/src/use/index.js +2 -0
- package/src/use/useMethods.js +18 -0
- package/src/use/useRadio.js +25 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { Canvas, Meta, Story } from '@storybook/addon-docs';
|
|
2
|
+
import CvSearch from './CvSearch.vue';
|
|
3
|
+
import { sbCompPrefix } from '../../global/storybook-utils';
|
|
4
|
+
import { SEARCH_SIZES } from './index';
|
|
5
|
+
import { action } from '@storybook/addon-actions';
|
|
6
|
+
import { ref } from 'vue';
|
|
7
|
+
const myValue = ref('searching galaxies');
|
|
8
|
+
|
|
9
|
+
<Meta title={`${sbCompPrefix}/CvSearch`} component={CvSearch} />
|
|
10
|
+
|
|
11
|
+
export const Template = args => ({
|
|
12
|
+
// Components used in your story `template` are defined in the `components` object
|
|
13
|
+
components: {
|
|
14
|
+
CvSearch,
|
|
15
|
+
},
|
|
16
|
+
// The story's `args` need to be mapped into the template through the `setup()` method
|
|
17
|
+
setup() {
|
|
18
|
+
return {
|
|
19
|
+
light: args.light,
|
|
20
|
+
label: args.label,
|
|
21
|
+
placeholder: args.placeholder,
|
|
22
|
+
disabled: args.disabled,
|
|
23
|
+
size: args.size,
|
|
24
|
+
ariaLabel: args.ariaLabel,
|
|
25
|
+
clearAriaLabel: args.clearAriaLabel,
|
|
26
|
+
formItem: args.formItem,
|
|
27
|
+
expandable: args.expandable,
|
|
28
|
+
value: args.value,
|
|
29
|
+
myValue: myValue,
|
|
30
|
+
onInput: action('input'),
|
|
31
|
+
};
|
|
32
|
+
},
|
|
33
|
+
template: args.template,
|
|
34
|
+
});
|
|
35
|
+
const defaultTemplate = `
|
|
36
|
+
<cv-search
|
|
37
|
+
:light="light"
|
|
38
|
+
:label="label"
|
|
39
|
+
:placeholder="placeholder"
|
|
40
|
+
:disabled="disabled"
|
|
41
|
+
:size="size"
|
|
42
|
+
:expandable="expandable"
|
|
43
|
+
:value="value"
|
|
44
|
+
:form-item="formItem"
|
|
45
|
+
:aria-label="ariaLabel"
|
|
46
|
+
:clear-aria-label="clearAriaLabel"
|
|
47
|
+
@input="onInput"
|
|
48
|
+
>
|
|
49
|
+
</cv-search>
|
|
50
|
+
`;
|
|
51
|
+
const vModelTemplate = `
|
|
52
|
+
<div>
|
|
53
|
+
<cv-search
|
|
54
|
+
v-model:value="myValue"
|
|
55
|
+
:light="light"
|
|
56
|
+
:label="label"
|
|
57
|
+
:placeholder="placeholder"
|
|
58
|
+
:disabled="disabled"
|
|
59
|
+
:size="size"
|
|
60
|
+
:expandable="expandable"
|
|
61
|
+
:form-item="formItem"
|
|
62
|
+
:aria-label="ariaLabel"
|
|
63
|
+
:clear-aria-label="clearAriaLabel"
|
|
64
|
+
>
|
|
65
|
+
</cv-search>
|
|
66
|
+
<div style="margin-top:1rem; background-color: #888888; padding:1rem">
|
|
67
|
+
<div style="padding:1rem">v-model value: {{ myValue }}</div>
|
|
68
|
+
<input type="search" v-model="myValue"/>
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
`;
|
|
72
|
+
|
|
73
|
+
# CvSearch
|
|
74
|
+
|
|
75
|
+
Migration notes:
|
|
76
|
+
|
|
77
|
+
- The `v-model` is different in Vue 3 than Vue 2. If you specify it you will see an error deprecation message in the log.
|
|
78
|
+
Please use `v-model:value=something` instead.
|
|
79
|
+
- The "toolbar" mode is removed in this version. Please use the `expandable` mode instead.
|
|
80
|
+
|
|
81
|
+
<Canvas>
|
|
82
|
+
<Story
|
|
83
|
+
name="Default"
|
|
84
|
+
parameters={{
|
|
85
|
+
controls: {
|
|
86
|
+
exclude: [
|
|
87
|
+
'input',
|
|
88
|
+
'modelValue',
|
|
89
|
+
'template',
|
|
90
|
+
'update:modelValue',
|
|
91
|
+
'update:value',
|
|
92
|
+
'large',
|
|
93
|
+
'small',
|
|
94
|
+
'toolbarAriaLabel',
|
|
95
|
+
'kind',
|
|
96
|
+
],
|
|
97
|
+
},
|
|
98
|
+
docs: { source: { code: defaultTemplate } },
|
|
99
|
+
}}
|
|
100
|
+
args={{
|
|
101
|
+
template: defaultTemplate,
|
|
102
|
+
light: false,
|
|
103
|
+
disabled: false,
|
|
104
|
+
placeholder: 'JWST: search for light from the first stars',
|
|
105
|
+
}}
|
|
106
|
+
argTypes={{
|
|
107
|
+
light: {
|
|
108
|
+
description: '`true` to use the light version.',
|
|
109
|
+
table: { category: 'props', defaultValue: { summary: false } },
|
|
110
|
+
},
|
|
111
|
+
size: {
|
|
112
|
+
control: 'select',
|
|
113
|
+
default: 'xl',
|
|
114
|
+
options: SEARCH_SIZES,
|
|
115
|
+
table: { defaultValue: { summary: 'xl' } },
|
|
116
|
+
},
|
|
117
|
+
}}
|
|
118
|
+
>
|
|
119
|
+
{Template.bind({})}
|
|
120
|
+
</Story>
|
|
121
|
+
</Canvas>
|
|
122
|
+
|
|
123
|
+
# v-model
|
|
124
|
+
|
|
125
|
+
- The `v-model` is different in Vue 3 than Vue 2.If you specify it you will see an error deprecation message in the log.
|
|
126
|
+
Please use `v-model:value=something` instead.
|
|
127
|
+
|
|
128
|
+
<Canvas>
|
|
129
|
+
<Story
|
|
130
|
+
name="v-model"
|
|
131
|
+
parameters={{
|
|
132
|
+
controls: {
|
|
133
|
+
exclude: [
|
|
134
|
+
'input',
|
|
135
|
+
'modelValue',
|
|
136
|
+
'template',
|
|
137
|
+
'update:modelValue',
|
|
138
|
+
'update:value',
|
|
139
|
+
'large',
|
|
140
|
+
'small',
|
|
141
|
+
'toolbarAriaLabel',
|
|
142
|
+
'kind',
|
|
143
|
+
],
|
|
144
|
+
},
|
|
145
|
+
docs: { source: { code: vModelTemplate } },
|
|
146
|
+
}}
|
|
147
|
+
args={{
|
|
148
|
+
template: vModelTemplate,
|
|
149
|
+
light: false,
|
|
150
|
+
disabled: false,
|
|
151
|
+
placeholder: 'JWST: search for light from the first stars',
|
|
152
|
+
}}
|
|
153
|
+
argTypes={{
|
|
154
|
+
light: {
|
|
155
|
+
description: '`true` to use the light version.',
|
|
156
|
+
table: { category: 'props', defaultValue: { summary: false } },
|
|
157
|
+
},
|
|
158
|
+
size: {
|
|
159
|
+
control: 'select',
|
|
160
|
+
default: 'xl',
|
|
161
|
+
options: SEARCH_SIZES,
|
|
162
|
+
table: { defaultValue: { summary: 'xl' } },
|
|
163
|
+
},
|
|
164
|
+
}}
|
|
165
|
+
>
|
|
166
|
+
{Template.bind({})}
|
|
167
|
+
</Story>
|
|
168
|
+
</Canvas>
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<component
|
|
3
|
+
:is="formItem ? 'div' : CvEmpty"
|
|
4
|
+
:class="`cv-search ${carbonPrefix}--form-item`"
|
|
5
|
+
>
|
|
6
|
+
<div
|
|
7
|
+
:aria-label="internalAriaLabel"
|
|
8
|
+
:aria-labelledby="internalAriaLabelBy"
|
|
9
|
+
:class="[
|
|
10
|
+
`${carbonPrefix}--search`,
|
|
11
|
+
`${carbonPrefix}--search--${size}`,
|
|
12
|
+
{
|
|
13
|
+
[`${carbonPrefix}--search--expandable`]: expandable,
|
|
14
|
+
[`${carbonPrefix}--search--expanded`]: isExpanded,
|
|
15
|
+
[`${carbonPrefix}--search--disabled`]: disabled,
|
|
16
|
+
[`${carbonPrefix}--search--light`]: isLight,
|
|
17
|
+
'cv-search': !formItem,
|
|
18
|
+
},
|
|
19
|
+
]"
|
|
20
|
+
role="search"
|
|
21
|
+
ref="elSearch"
|
|
22
|
+
>
|
|
23
|
+
<div
|
|
24
|
+
:class="`${carbonPrefix}--search-magnifier`"
|
|
25
|
+
@click="toggleActive(true)"
|
|
26
|
+
@blur="checkFocus"
|
|
27
|
+
>
|
|
28
|
+
<search-icon :class="`${carbonPrefix}--search-magnifier-icon`" />
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
<label v-show="label" :for="uid" :class="`${carbonPrefix}--label`">{{
|
|
32
|
+
label
|
|
33
|
+
}}</label>
|
|
34
|
+
|
|
35
|
+
<input
|
|
36
|
+
role="searchbox"
|
|
37
|
+
:id="uid"
|
|
38
|
+
:class="`${carbonPrefix}--search-input`"
|
|
39
|
+
v-bind="$attrs"
|
|
40
|
+
v-model="internalSearchText"
|
|
41
|
+
@input="onInput"
|
|
42
|
+
type="text"
|
|
43
|
+
ref="elInput"
|
|
44
|
+
:placeholder="placeholder"
|
|
45
|
+
:aria-labelledby="uid"
|
|
46
|
+
@blur="checkFocus"
|
|
47
|
+
@click="toggleActive"
|
|
48
|
+
@keydown.esc="onClearClick"
|
|
49
|
+
:disabled="disabled ? 'true' : undefined"
|
|
50
|
+
/>
|
|
51
|
+
|
|
52
|
+
<button
|
|
53
|
+
type="button"
|
|
54
|
+
:class="[
|
|
55
|
+
`${carbonPrefix}--search-close`,
|
|
56
|
+
{ [`${carbonPrefix}--search-close--hidden`]: !clearVisible },
|
|
57
|
+
]"
|
|
58
|
+
:title="clearAriaLabel"
|
|
59
|
+
:aria-label="clearAriaLabel"
|
|
60
|
+
@click="onClearClick"
|
|
61
|
+
>
|
|
62
|
+
<close-icon />
|
|
63
|
+
</button>
|
|
64
|
+
</div>
|
|
65
|
+
</component>
|
|
66
|
+
</template>
|
|
67
|
+
|
|
68
|
+
<script setup>
|
|
69
|
+
import { carbonPrefix } from '../../global/settings';
|
|
70
|
+
import { useIsLight, props as propsTheme } from '../../use/cvTheme';
|
|
71
|
+
import { useCvId, props as propsCvId } from '../../use/cvId';
|
|
72
|
+
import SearchIcon from '@carbon/icons-vue/es/search/16';
|
|
73
|
+
import CloseIcon from '@carbon/icons-vue/es/close/16';
|
|
74
|
+
import { computed, ref, watch } from 'vue';
|
|
75
|
+
import { SEARCH_SIZES } from '.';
|
|
76
|
+
import CvEmpty from '../CvEmpty/_CvEmpty.vue';
|
|
77
|
+
|
|
78
|
+
defineOptions({
|
|
79
|
+
inheritAttrs: false,
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
const props = defineProps({
|
|
83
|
+
ariaLabel: { type: String, default: 'search input' },
|
|
84
|
+
/**
|
|
85
|
+
* Specify a label to be read by screen readers on the "close" button
|
|
86
|
+
*/
|
|
87
|
+
clearAriaLabel: { type: String, default: 'Clear search input' },
|
|
88
|
+
/**
|
|
89
|
+
* Specify whether the `<input>` should be disabled
|
|
90
|
+
*/
|
|
91
|
+
disabled: { type: Boolean, default: false },
|
|
92
|
+
/**
|
|
93
|
+
* Do no show full control until it has focus. Similar to deprecated toolbar search.
|
|
94
|
+
*/
|
|
95
|
+
expandable: { type: Boolean, default: false },
|
|
96
|
+
/**
|
|
97
|
+
* Wrap search in `<div>` if part of a form
|
|
98
|
+
*/
|
|
99
|
+
formItem: { type: Boolean, default: true },
|
|
100
|
+
/**
|
|
101
|
+
* @deprecated use expandable
|
|
102
|
+
*/
|
|
103
|
+
kind: {
|
|
104
|
+
type: String,
|
|
105
|
+
default: undefined,
|
|
106
|
+
validator: () => {
|
|
107
|
+
console.warn('Deprecated: probably you want expandable=true');
|
|
108
|
+
return true;
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
/**
|
|
112
|
+
* Provide the label text for the Search icon
|
|
113
|
+
*/
|
|
114
|
+
label: String,
|
|
115
|
+
/**
|
|
116
|
+
* Specify the search size ('sm', 'md', 'lg', 'xl')
|
|
117
|
+
*/
|
|
118
|
+
size: {
|
|
119
|
+
type: String,
|
|
120
|
+
default: 'xl',
|
|
121
|
+
validator: val => SEARCH_SIZES.includes(val),
|
|
122
|
+
},
|
|
123
|
+
/**
|
|
124
|
+
* @deprecated use size
|
|
125
|
+
*/
|
|
126
|
+
small: {
|
|
127
|
+
type: Boolean,
|
|
128
|
+
default: undefined,
|
|
129
|
+
validator: val => {
|
|
130
|
+
if (val !== undefined) {
|
|
131
|
+
console.error('Error: Use size property: sm, lg or xl (default)');
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
return true;
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
/**
|
|
138
|
+
* @deprecated use size
|
|
139
|
+
*/
|
|
140
|
+
large: {
|
|
141
|
+
type: Boolean,
|
|
142
|
+
default: undefined,
|
|
143
|
+
validator: val => {
|
|
144
|
+
if (val !== undefined) {
|
|
145
|
+
console.error('Error: Use size property: sm, lg or xl (default)');
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
return true;
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
/**
|
|
152
|
+
* Optionally provide the default value of the `<input>`
|
|
153
|
+
*/
|
|
154
|
+
value: String,
|
|
155
|
+
/**
|
|
156
|
+
* @deprecated use value
|
|
157
|
+
*/
|
|
158
|
+
modelValue: {
|
|
159
|
+
type: String,
|
|
160
|
+
default: undefined,
|
|
161
|
+
validator: () => {
|
|
162
|
+
console.warn('Deprecated: use v-model:value instead');
|
|
163
|
+
return true;
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
/**
|
|
167
|
+
* Provide an optional placeholder text for the Search. Note: if the label and placeholder differ, VoiceOver on Mac will read both
|
|
168
|
+
*/
|
|
169
|
+
placeholder: { type: String, default: 'Search' },
|
|
170
|
+
/**
|
|
171
|
+
* @deprecated
|
|
172
|
+
*/
|
|
173
|
+
toolbarAriaLabel: {
|
|
174
|
+
type: String,
|
|
175
|
+
validator: () => {
|
|
176
|
+
console.warn('Deprecated: probably you want expandable=true');
|
|
177
|
+
return true;
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
...propsTheme,
|
|
181
|
+
...propsCvId,
|
|
182
|
+
});
|
|
183
|
+
const uid = useCvId(props, true);
|
|
184
|
+
const isLight = useIsLight(props);
|
|
185
|
+
|
|
186
|
+
const clearVisible = ref(props.value ? props.value.length : false);
|
|
187
|
+
const internalSearchText = ref(props.value || props.modelValue);
|
|
188
|
+
const searchActive = ref(false);
|
|
189
|
+
watch(
|
|
190
|
+
() => props.value,
|
|
191
|
+
() => {
|
|
192
|
+
clearVisible.value = props.value ? props.value.length : false;
|
|
193
|
+
internalSearchText.value = props.value;
|
|
194
|
+
}
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
const internalAriaLabel = computed(() => {
|
|
198
|
+
if (!props.label) return props.ariaLabel;
|
|
199
|
+
else return undefined;
|
|
200
|
+
});
|
|
201
|
+
const internalAriaLabelBy = computed(() => {
|
|
202
|
+
if (props.label) return uid.value;
|
|
203
|
+
else return undefined;
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
const emit = defineEmits(['input', 'update:value', 'update:modelValue']);
|
|
207
|
+
watch(internalSearchText, () => {
|
|
208
|
+
emit('input', internalSearchText.value);
|
|
209
|
+
emit('update:value', internalSearchText.value);
|
|
210
|
+
if (props.modelValue) {
|
|
211
|
+
console.warn('Deprecated: use v-model:value instead');
|
|
212
|
+
emit('update:modelValue', internalSearchText.value);
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
function onClearClick() {
|
|
216
|
+
internalSearchText.value = '';
|
|
217
|
+
clearVisible.value = false;
|
|
218
|
+
if (props.expandable) {
|
|
219
|
+
elInput.value?.focus();
|
|
220
|
+
}
|
|
221
|
+
checkFocus();
|
|
222
|
+
}
|
|
223
|
+
function onInput() {
|
|
224
|
+
clearVisible.value = internalSearchText.value.length > 0;
|
|
225
|
+
}
|
|
226
|
+
const elInput = ref(null);
|
|
227
|
+
const isExpanded = computed(() => {
|
|
228
|
+
return props.expandable && searchActive.value;
|
|
229
|
+
});
|
|
230
|
+
function toggleActive(force) {
|
|
231
|
+
if (props.disabled) return;
|
|
232
|
+
|
|
233
|
+
if (typeof force === 'boolean') searchActive.value = force;
|
|
234
|
+
else if (internalSearchText.value?.length > 0) searchActive.value = true;
|
|
235
|
+
else searchActive.value = !searchActive.value;
|
|
236
|
+
|
|
237
|
+
if (searchActive.value) {
|
|
238
|
+
elInput.value?.focus();
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
const elSearch = ref(null);
|
|
242
|
+
function checkFocus() {
|
|
243
|
+
if (props.disabled) return;
|
|
244
|
+
|
|
245
|
+
if (props.expandable) {
|
|
246
|
+
if (elInput.value !== document.activeElement)
|
|
247
|
+
searchActive.value = internalSearchText.value?.length > 0;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
</script>
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<cv-wrapper
|
|
3
|
+
ref="el"
|
|
3
4
|
:tag-type="formItem ? 'div' : ''"
|
|
4
5
|
:class="`cv-select ${carbonPrefix}--form-item`"
|
|
5
|
-
ref="el"
|
|
6
6
|
>
|
|
7
7
|
<div
|
|
8
8
|
:data-test="value"
|
|
9
9
|
:class="[
|
|
10
10
|
`${carbonPrefix}--select`,
|
|
11
|
+
`${carbonClasses}`,
|
|
11
12
|
{
|
|
12
13
|
'cv-select': !formItem,
|
|
13
14
|
[`${carbonPrefix}--select--inline`]: inline,
|
|
@@ -48,9 +49,8 @@
|
|
|
48
49
|
size || 'md',
|
|
49
50
|
},
|
|
50
51
|
]"
|
|
51
|
-
@change="onChange"
|
|
52
|
-
ref="select"
|
|
53
52
|
:value="internalValue"
|
|
53
|
+
@change="onChange"
|
|
54
54
|
>
|
|
55
55
|
<slot></slot>
|
|
56
56
|
</select>
|
|
@@ -77,7 +77,6 @@
|
|
|
77
77
|
>
|
|
78
78
|
<slot name="helper-text">{{ helperText }}</slot>
|
|
79
79
|
</div>
|
|
80
|
-
|
|
81
80
|
<!-- cv-wrapper div ${carbonPrefix}--select-input--inline__wrapper -->
|
|
82
81
|
</cv-wrapper>
|
|
83
82
|
</div>
|
|
@@ -87,7 +86,15 @@
|
|
|
87
86
|
|
|
88
87
|
<script setup>
|
|
89
88
|
import { carbonPrefix } from '../../global/settings';
|
|
90
|
-
import {
|
|
89
|
+
import {
|
|
90
|
+
computed,
|
|
91
|
+
onMounted,
|
|
92
|
+
onUpdated,
|
|
93
|
+
ref,
|
|
94
|
+
useAttrs,
|
|
95
|
+
useSlots,
|
|
96
|
+
watch,
|
|
97
|
+
} from 'vue';
|
|
91
98
|
import {
|
|
92
99
|
WarningFilled16 as WarningFilled,
|
|
93
100
|
ChevronDown16 as ChevronDown,
|
|
@@ -112,6 +119,7 @@ const props = defineProps({
|
|
|
112
119
|
// multiple does not work with styling from carbon-components 9.20
|
|
113
120
|
multiple: {
|
|
114
121
|
type: String,
|
|
122
|
+
default: undefined,
|
|
115
123
|
validator: () => {
|
|
116
124
|
console.warn('property multiple not supported in CvSelect');
|
|
117
125
|
return false;
|
|
@@ -123,7 +131,7 @@ const props = defineProps({
|
|
|
123
131
|
default: 'md',
|
|
124
132
|
validator: val => ['sm', 'md', 'lg'].includes(val),
|
|
125
133
|
},
|
|
126
|
-
modelValue: { type: String },
|
|
134
|
+
modelValue: { type: String, default: undefined },
|
|
127
135
|
...propsTheme,
|
|
128
136
|
...propsCvId,
|
|
129
137
|
});
|
|
@@ -221,4 +229,17 @@ function updateWarning() {
|
|
|
221
229
|
}
|
|
222
230
|
onMounted(updateWarning);
|
|
223
231
|
onUpdated(updateWarning);
|
|
232
|
+
|
|
233
|
+
// There is an oddity here with Vue2 vs Vue3. The Vue2 component uses CvWrapper to determine if this component
|
|
234
|
+
// is wrapped in a div or not. Either way the class attributes are applied in Vue2. In Vue3 the attributes are
|
|
235
|
+
// not applied. The CvTimePicker consumes this component and needs to apply styles in both the wrapped and
|
|
236
|
+
// unwrapped case. Here we apply any carbon styles to the outer div.
|
|
237
|
+
const attrs = useAttrs();
|
|
238
|
+
const carbonClasses = computed(() => {
|
|
239
|
+
if (props.formItem || !attrs.class) return '';
|
|
240
|
+
return attrs.class
|
|
241
|
+
?.split(' ')
|
|
242
|
+
.filter(c => c.startsWith(`${carbonPrefix}--`))
|
|
243
|
+
.join(' ');
|
|
244
|
+
});
|
|
224
245
|
</script>
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { ref } from 'vue';
|
|
2
|
+
import { action } from '@storybook/addon-actions';
|
|
3
|
+
import {
|
|
4
|
+
sbCompPrefix,
|
|
5
|
+
storyParametersObject,
|
|
6
|
+
} from '../../global/storybook-utils';
|
|
7
|
+
import { sbSliderPrefix } from './sbSliderPrefix';
|
|
8
|
+
import { CvSlider } from '.';
|
|
9
|
+
|
|
10
|
+
export default {
|
|
11
|
+
title: `${sbCompPrefix}/${sbSliderPrefix}/CvSlider`,
|
|
12
|
+
component: CvSlider,
|
|
13
|
+
argTypes: {
|
|
14
|
+
disabled: {
|
|
15
|
+
type: 'boolean',
|
|
16
|
+
table: {
|
|
17
|
+
type: { summary: 'boolean' },
|
|
18
|
+
category: 'attributes',
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
value: {
|
|
22
|
+
type: 'string',
|
|
23
|
+
table: {
|
|
24
|
+
type: { summary: 'string' },
|
|
25
|
+
category: 'props',
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
label: {
|
|
29
|
+
type: 'string',
|
|
30
|
+
table: {
|
|
31
|
+
type: { summary: 'string' },
|
|
32
|
+
category: 'props',
|
|
33
|
+
},
|
|
34
|
+
description: 'Slider top label',
|
|
35
|
+
},
|
|
36
|
+
light: {
|
|
37
|
+
type: 'boolean',
|
|
38
|
+
table: {
|
|
39
|
+
type: { summary: 'boolean' },
|
|
40
|
+
category: 'props',
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
min: {
|
|
44
|
+
type: 'string',
|
|
45
|
+
table: {
|
|
46
|
+
type: { summary: 'string' },
|
|
47
|
+
category: 'props',
|
|
48
|
+
},
|
|
49
|
+
description: 'Slider input min value',
|
|
50
|
+
},
|
|
51
|
+
max: {
|
|
52
|
+
type: 'string',
|
|
53
|
+
table: {
|
|
54
|
+
type: { summary: 'string' },
|
|
55
|
+
category: 'props',
|
|
56
|
+
},
|
|
57
|
+
description: 'Slider input max value',
|
|
58
|
+
},
|
|
59
|
+
minLabel: {
|
|
60
|
+
type: 'string',
|
|
61
|
+
table: {
|
|
62
|
+
type: { summary: 'string' },
|
|
63
|
+
category: 'props',
|
|
64
|
+
},
|
|
65
|
+
description: 'Label for min side of slider, otherwise min value used',
|
|
66
|
+
},
|
|
67
|
+
maxLabel: {
|
|
68
|
+
type: 'string',
|
|
69
|
+
table: {
|
|
70
|
+
type: { summary: 'string' },
|
|
71
|
+
category: 'props',
|
|
72
|
+
},
|
|
73
|
+
description: 'Label for max side of slider, otherwise max value used',
|
|
74
|
+
},
|
|
75
|
+
step: {
|
|
76
|
+
type: 'string',
|
|
77
|
+
table: {
|
|
78
|
+
type: { summary: 'string' },
|
|
79
|
+
category: 'props',
|
|
80
|
+
},
|
|
81
|
+
description: 'Slider input step value',
|
|
82
|
+
},
|
|
83
|
+
stepMultiplier: {
|
|
84
|
+
type: 'string',
|
|
85
|
+
table: {
|
|
86
|
+
type: { summary: 'string' },
|
|
87
|
+
category: 'props',
|
|
88
|
+
},
|
|
89
|
+
description: 'multiplier > 1',
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
// events
|
|
94
|
+
change: {
|
|
95
|
+
type: 'event',
|
|
96
|
+
table: {
|
|
97
|
+
type: { summary: 'event' },
|
|
98
|
+
category: 'events',
|
|
99
|
+
},
|
|
100
|
+
control: { type: null },
|
|
101
|
+
},
|
|
102
|
+
'update:modelValue': {
|
|
103
|
+
type: 'event',
|
|
104
|
+
table: {
|
|
105
|
+
type: { summary: 'event' },
|
|
106
|
+
category: 'events',
|
|
107
|
+
},
|
|
108
|
+
control: { type: null },
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const template = `<cv-slider v-bind="args" @change="onChange"/>`;
|
|
113
|
+
const Template = args => {
|
|
114
|
+
return {
|
|
115
|
+
components: { CvSlider },
|
|
116
|
+
setup: () => ({
|
|
117
|
+
args,
|
|
118
|
+
onChange: action('change'),
|
|
119
|
+
}),
|
|
120
|
+
template,
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
export const Default = Template.bind({});
|
|
125
|
+
Default.args = {};
|
|
126
|
+
Default.parameters = storyParametersObject(
|
|
127
|
+
Default.parameters,
|
|
128
|
+
template,
|
|
129
|
+
Default.args
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
const vModelTemplate = `
|
|
133
|
+
<cv-slider v-bind="args" v-model="modelValue" />
|
|
134
|
+
|
|
135
|
+
<div style="margin-top:1rem; background-color: #888888; padding:1rem">
|
|
136
|
+
<div style="font-size: 150%">
|
|
137
|
+
Sample interaction
|
|
138
|
+
</div>
|
|
139
|
+
|
|
140
|
+
<input v-model="modelValue" type="string" />
|
|
141
|
+
<div>
|
|
142
|
+
Entered value:
|
|
143
|
+
<span style="font-weight: bold;">{{modelValue}}</span>
|
|
144
|
+
</div>
|
|
145
|
+
</div>
|
|
146
|
+
`;
|
|
147
|
+
|
|
148
|
+
const VModelTemplate = args => {
|
|
149
|
+
return {
|
|
150
|
+
components: { CvSlider },
|
|
151
|
+
setup: () => ({
|
|
152
|
+
args,
|
|
153
|
+
onChange: action('change'),
|
|
154
|
+
modelValue: ref('15'),
|
|
155
|
+
}),
|
|
156
|
+
template: vModelTemplate,
|
|
157
|
+
};
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
export const vModel = VModelTemplate.bind({});
|
|
161
|
+
vModel.args = {};
|
|
162
|
+
vModel.parameters = storyParametersObject(
|
|
163
|
+
vModel.parameters,
|
|
164
|
+
vModelTemplate,
|
|
165
|
+
vModel.args
|
|
166
|
+
);
|