tide-design-system 2.4.5 → 2.4.7
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/.storybook/main.ts +1 -0
- package/dist/css/reset.css +1 -1
- package/dist/css/utilities-responsive.css +0 -546
- package/dist/style.css +1 -1
- package/dist/tide-design-system.cjs +2 -2
- package/dist/tide-design-system.esm.d.ts +62 -6
- package/dist/tide-design-system.esm.js +1821 -1720
- package/dist/utilities/storybook.ts +6 -2
- package/dist/utilities/validation.ts +1 -1
- package/index.ts +8 -5
- package/package.json +1 -1
- package/src/assets/css/reset.css +1 -1
- package/src/assets/css/utilities-responsive.css +0 -546
- package/src/components/InternalBaseLink.vue +11 -0
- package/src/components/TideBreadCrumbs.vue +3 -2
- package/src/components/TideButton.vue +17 -4
- package/src/components/TideButtonIcon.vue +15 -2
- package/src/components/TideButtonPagination.vue +16 -16
- package/src/components/TideButtonSegmented.vue +1 -0
- package/src/components/TideCard.vue +12 -2
- package/src/components/TideCarousel.vue +10 -5
- package/src/components/TideChipAction.vue +7 -1
- package/src/components/TideChipFilter.vue +1 -0
- package/src/components/TideChipInput.vue +1 -0
- package/src/components/TideIcon.vue +8 -9
- package/src/components/TideImage.vue +9 -9
- package/src/components/TideInputText.vue +2 -0
- package/src/components/TideInputTextDeprecated.vue +2 -0
- package/src/components/TideInputTextarea.vue +2 -2
- package/src/components/TideLink.vue +7 -1
- package/src/components/TideMenuItem.vue +83 -0
- package/src/components/TideModal.vue +91 -85
- package/src/components/TideSeoLinks.vue +3 -2
- package/src/components/TideSheet.vue +5 -3
- package/src/components/TideSwitch.vue +1 -0
- package/src/composables/useTideConfig.ts +23 -0
- package/src/stories/TideButtonPagination.stories.ts +6 -6
- package/src/stories/TideCarousel.stories.ts +0 -1
- package/src/stories/TideInputCheckbox.stories.ts +58 -23
- package/src/stories/TideInputRadio.stories.ts +39 -30
- package/src/stories/TideInputSelect.stories.ts +51 -27
- package/src/stories/TideInputText.stories.ts +83 -23
- package/src/stories/TideInputTextarea.stories.ts +66 -17
- package/src/stories/TideLink.stories.ts +1 -14
- package/src/stories/TideMenuItem.stories.ts +117 -0
- package/src/stories/TidePagination.stories.ts +2 -2
- package/src/stories/TidePopover.stories.ts +1 -1
- package/src/types/Badge.ts +4 -0
- package/src/types/Element.ts +2 -2
- package/src/types/Formatted.ts +1 -0
- package/src/types/Storybook.ts +4 -6
- package/src/types/Type.ts +6 -0
- package/src/types/Validation.ts +1 -0
- package/src/utilities/storybook.ts +6 -2
- package/src/utilities/validation.ts +1 -1
- package/tests/InternalBaseLink.spec.ts +61 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
|
-
import { nextTick, onMounted, ref, watch } from 'vue';
|
|
2
|
+
import { nextTick, onBeforeMount, onMounted, ref, watch } from 'vue';
|
|
3
3
|
|
|
4
4
|
import TideButtonIcon from '@/components/TideButtonIcon.vue';
|
|
5
5
|
import { BREAKPOINT } from '@/types/Breakpoint';
|
|
6
6
|
import { ICON } from '@/types/Icon';
|
|
7
7
|
import { PRIORITY } from '@/types/Priority';
|
|
8
8
|
import { CSS } from '@/types/Styles';
|
|
9
|
-
import { setScrollLock } from '@/utilities/viewport';
|
|
9
|
+
import { TOP_LAYER_ID, initFauxTopLayer, setScrollLock } from '@/utilities/viewport';
|
|
10
10
|
|
|
11
11
|
import type { Ref } from 'vue';
|
|
12
12
|
|
|
@@ -73,6 +73,10 @@
|
|
|
73
73
|
}
|
|
74
74
|
);
|
|
75
75
|
|
|
76
|
+
onBeforeMount(() => {
|
|
77
|
+
initFauxTopLayer();
|
|
78
|
+
});
|
|
79
|
+
|
|
76
80
|
onMounted(() => {
|
|
77
81
|
if (props.isOpen) {
|
|
78
82
|
triggerNativeDialogOpen();
|
|
@@ -81,97 +85,99 @@
|
|
|
81
85
|
</script>
|
|
82
86
|
|
|
83
87
|
<template>
|
|
84
|
-
<
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
<div
|
|
93
|
-
:class="[
|
|
94
|
-
'tide-modal-body',
|
|
95
|
-
CSS.BG.SURFACE.DEFAULT,
|
|
96
|
-
CSS.BORDER.RADIUS.ONE,
|
|
97
|
-
CSS.DISPLAY.FLEX,
|
|
98
|
-
CSS.FLEX.DIRECTION.COLUMN,
|
|
99
|
-
CSS.OVERFLOW.XY.HIDDEN,
|
|
100
|
-
CSS.POSITION.ABSOLUTE,
|
|
101
|
-
CSS.POSITIONING.BOTTOM,
|
|
102
|
-
CSS.SHADOW.TOP,
|
|
103
|
-
CSS.WIDTH.FULL,
|
|
104
|
-
CSS.WIDTH.MAX_FULL,
|
|
105
|
-
CSS.withBreakpoint([CSS.SHADOW.BOTTOM], BREAKPOINT.SM),
|
|
106
|
-
]"
|
|
88
|
+
<Teleport :to="`#${TOP_LAYER_ID}`">
|
|
89
|
+
<dialog
|
|
90
|
+
:class="['tide-modal', CSS.BG.INITIAL, CSS.HEIGHT.FULL, CSS.WIDTH.FULL, CSS.OVERFLOW.XY.HIDDEN]"
|
|
91
|
+
ref="modalDialog"
|
|
92
|
+
:style="{ '--modal-width': props.width }"
|
|
93
|
+
@click.self="handleBackdropClick"
|
|
94
|
+
@close.prevent
|
|
95
|
+
@keydown.escape="handleEscapeKeydown"
|
|
107
96
|
>
|
|
108
|
-
<
|
|
97
|
+
<div
|
|
109
98
|
:class="[
|
|
110
|
-
'tide-modal-
|
|
111
|
-
CSS.
|
|
112
|
-
CSS.BORDER.
|
|
113
|
-
CSS.BORDER.COLOR.LOW,
|
|
99
|
+
'tide-modal-body',
|
|
100
|
+
CSS.BG.SURFACE.DEFAULT,
|
|
101
|
+
CSS.BORDER.RADIUS.ONE,
|
|
114
102
|
CSS.DISPLAY.FLEX,
|
|
115
|
-
CSS.
|
|
116
|
-
CSS.
|
|
117
|
-
CSS.
|
|
118
|
-
CSS.
|
|
119
|
-
CSS.
|
|
103
|
+
CSS.FLEX.DIRECTION.COLUMN,
|
|
104
|
+
CSS.OVERFLOW.XY.HIDDEN,
|
|
105
|
+
CSS.POSITION.ABSOLUTE,
|
|
106
|
+
CSS.POSITIONING.BOTTOM,
|
|
107
|
+
CSS.SHADOW.TOP,
|
|
108
|
+
CSS.WIDTH.FULL,
|
|
109
|
+
CSS.WIDTH.MAX_FULL,
|
|
110
|
+
CSS.withBreakpoint([CSS.SHADOW.BOTTOM], BREAKPOINT.SM),
|
|
120
111
|
]"
|
|
121
112
|
>
|
|
122
|
-
<
|
|
123
|
-
:
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
113
|
+
<header
|
|
114
|
+
:class="[
|
|
115
|
+
'tide-modal-header',
|
|
116
|
+
CSS.AXIS2.CENTER,
|
|
117
|
+
CSS.BORDER.BOTTOM.ONE,
|
|
118
|
+
CSS.BORDER.COLOR.LOW,
|
|
119
|
+
CSS.DISPLAY.FLEX,
|
|
120
|
+
CSS.GAP.HALF,
|
|
121
|
+
CSS.ISOLATION.ISOLATE,
|
|
122
|
+
CSS.PADDING.Y.ONE,
|
|
123
|
+
CSS.POSITION.RELATIVE,
|
|
124
|
+
CSS.Z_INDEX.ONE,
|
|
125
|
+
]"
|
|
126
|
+
>
|
|
127
|
+
<TideButtonIcon
|
|
128
|
+
:icon="ICON.CHEVRON_LEFT"
|
|
129
|
+
:priority="PRIORITY.QUATERNARY"
|
|
130
|
+
@click="emit('back')"
|
|
131
|
+
title="Back"
|
|
132
|
+
v-if="isBackButton"
|
|
133
|
+
/>
|
|
134
|
+
|
|
135
|
+
<div
|
|
136
|
+
:class="[CSS.FONT.ROLE.HEADLINE_2]"
|
|
137
|
+
v-text="title"
|
|
138
|
+
/>
|
|
139
|
+
|
|
140
|
+
<TideButtonIcon
|
|
141
|
+
:class="[CSS.FLEX.GROW.OFF, CSS.FLEX.SHRINK.OFF, CSS.MARGIN.LEFT.AUTO]"
|
|
142
|
+
:icon="ICON.CLOSE"
|
|
143
|
+
:priority="PRIORITY.QUATERNARY"
|
|
144
|
+
@click="emit('close')"
|
|
145
|
+
v-if="isDismissible"
|
|
146
|
+
/>
|
|
147
|
+
</header>
|
|
129
148
|
|
|
130
149
|
<div
|
|
131
|
-
:class="[
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
150
|
+
:class="[
|
|
151
|
+
'tide-modal-content',
|
|
152
|
+
CSS.DISPLAY.GRID,
|
|
153
|
+
CSS.ISOLATION.ISOLATE,
|
|
154
|
+
CSS.OVERFLOW.X.HIDDEN,
|
|
155
|
+
CSS.OVERFLOW.Y.AUTO,
|
|
156
|
+
CSS.PADDING.Y.TWO,
|
|
157
|
+
CSS.WIDTH.FULL,
|
|
158
|
+
]"
|
|
159
|
+
ref="modalContent"
|
|
160
|
+
>
|
|
161
|
+
<slot />
|
|
162
|
+
</div>
|
|
163
|
+
|
|
164
|
+
<footer
|
|
165
|
+
:class="[
|
|
166
|
+
'tide-modal-footer',
|
|
167
|
+
CSS.AXIS1.END,
|
|
168
|
+
CSS.DISPLAY.FLEX,
|
|
169
|
+
CSS.GAP.TWO,
|
|
170
|
+
CSS.ISOLATION.ISOLATE,
|
|
171
|
+
CSS.PADDING.Y.ONE,
|
|
172
|
+
CSS.SHADOW.TOP,
|
|
173
|
+
]"
|
|
174
|
+
v-if="$slots.footer"
|
|
175
|
+
>
|
|
176
|
+
<slot name="footer" />
|
|
177
|
+
</footer>
|
|
157
178
|
</div>
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
:class="[
|
|
161
|
-
'tide-modal-footer',
|
|
162
|
-
CSS.AXIS1.END,
|
|
163
|
-
CSS.DISPLAY.FLEX,
|
|
164
|
-
CSS.GAP.TWO,
|
|
165
|
-
CSS.ISOLATION.ISOLATE,
|
|
166
|
-
CSS.PADDING.Y.ONE,
|
|
167
|
-
CSS.SHADOW.TOP,
|
|
168
|
-
]"
|
|
169
|
-
v-if="$slots.footer"
|
|
170
|
-
>
|
|
171
|
-
<slot name="footer" />
|
|
172
|
-
</footer>
|
|
173
|
-
</div>
|
|
174
|
-
</dialog>
|
|
179
|
+
</dialog>
|
|
180
|
+
</Teleport>
|
|
175
181
|
</template>
|
|
176
182
|
|
|
177
183
|
<style scoped>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
|
+
import InternalBaseLink from '@/components/InternalBaseLink.vue';
|
|
2
3
|
import { CSS } from '@/types/Styles';
|
|
3
4
|
import { TARGET } from '@/types/Target';
|
|
4
5
|
|
|
@@ -26,13 +27,13 @@
|
|
|
26
27
|
:key="link.label"
|
|
27
28
|
v-for="link in props.links"
|
|
28
29
|
>
|
|
29
|
-
<
|
|
30
|
+
<InternalBaseLink
|
|
30
31
|
:class="[CSS.UNDERLINE.REST.OFF]"
|
|
31
32
|
:href="link.url"
|
|
32
33
|
:target="link.isNewTab ? TARGET.BLANK : TARGET.SELF"
|
|
33
34
|
>
|
|
34
35
|
{{ link.label }}
|
|
35
|
-
</
|
|
36
|
+
</InternalBaseLink>
|
|
36
37
|
</li>
|
|
37
38
|
</ul>
|
|
38
39
|
</section>
|
|
@@ -119,11 +119,13 @@
|
|
|
119
119
|
:class="[
|
|
120
120
|
'tide-sheet-content',
|
|
121
121
|
CSS.DISPLAY.GRID,
|
|
122
|
-
CSS.
|
|
122
|
+
CSS.HEIGHT.FULL,
|
|
123
|
+
CSS.ISOLATION.ISOLATE,
|
|
123
124
|
CSS.OVERFLOW.X.HIDDEN,
|
|
124
|
-
CSS.
|
|
125
|
+
CSS.OVERFLOW.Y.AUTO,
|
|
125
126
|
CSS.PADDING.BOTTOM.ONE,
|
|
126
|
-
CSS.
|
|
127
|
+
CSS.POSITION.RELATIVE,
|
|
128
|
+
CSS.WIDTH.FULL,
|
|
127
129
|
]"
|
|
128
130
|
>
|
|
129
131
|
<slot />
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { inject, provide } from 'vue';
|
|
2
|
+
|
|
3
|
+
import { ELEMENT } from '@/types/Element';
|
|
4
|
+
|
|
5
|
+
import type { Component } from 'vue';
|
|
6
|
+
|
|
7
|
+
type TideConfig = {
|
|
8
|
+
linkComponent: Component | typeof ELEMENT.LINK;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const tideConfigDefaults: TideConfig = { linkComponent: ELEMENT.LINK };
|
|
12
|
+
|
|
13
|
+
const CONFIG_KEY = Symbol('tide-config');
|
|
14
|
+
|
|
15
|
+
export const provideTideConfig = (config: Partial<TideConfig> = {}) => {
|
|
16
|
+
const configWithDefaults: TideConfig = { ...tideConfigDefaults, ...config };
|
|
17
|
+
|
|
18
|
+
provide<TideConfig>(CONFIG_KEY, configWithDefaults);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const useTideConfig = () => {
|
|
22
|
+
return inject<TideConfig>(CONFIG_KEY, tideConfigDefaults);
|
|
23
|
+
};
|
|
@@ -16,7 +16,7 @@ type Args = InstanceType<typeof TideButtonPagination>['$props'] & {
|
|
|
16
16
|
click: string;
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
-
const
|
|
19
|
+
const ELEMENT_BROAD = prependNoneAsUndefined(STANDARD_ELEMENT.ELEMENT_BROAD);
|
|
20
20
|
|
|
21
21
|
const render = (args: Args) => ({
|
|
22
22
|
components: { TideButtonPagination },
|
|
@@ -44,7 +44,7 @@ export default {
|
|
|
44
44
|
argTypes: {
|
|
45
45
|
click: {
|
|
46
46
|
...click,
|
|
47
|
-
if: { arg: 'element', neq:
|
|
47
|
+
if: { arg: 'element', neq: ELEMENT_BROAD.LINK },
|
|
48
48
|
},
|
|
49
49
|
dataTrack,
|
|
50
50
|
disabled: {
|
|
@@ -52,11 +52,11 @@ export default {
|
|
|
52
52
|
description: 'Indicates whether Pagination Button is associated with the displayed page',
|
|
53
53
|
if: {
|
|
54
54
|
arg: 'element',
|
|
55
|
-
eq:
|
|
55
|
+
eq: ELEMENT_BROAD.BUTTON,
|
|
56
56
|
},
|
|
57
57
|
},
|
|
58
58
|
element: {
|
|
59
|
-
...formatArgType({
|
|
59
|
+
...formatArgType({ ELEMENT_BROAD }),
|
|
60
60
|
description: 'HTML tag type',
|
|
61
61
|
table: {
|
|
62
62
|
defaultValue: { summary: 'BUTTON' },
|
|
@@ -64,7 +64,7 @@ export default {
|
|
|
64
64
|
},
|
|
65
65
|
href: {
|
|
66
66
|
description: 'URL to open<br />(Link only)',
|
|
67
|
-
if: { arg: 'element', eq:
|
|
67
|
+
if: { arg: 'element', eq: ELEMENT_BROAD.LINK },
|
|
68
68
|
table: {
|
|
69
69
|
defaultValue: { summary: 'None' },
|
|
70
70
|
type: { summary: 'string' },
|
|
@@ -73,7 +73,7 @@ export default {
|
|
|
73
73
|
isNewTab: {
|
|
74
74
|
...argTypeBooleanUnrequired,
|
|
75
75
|
description: 'Determines whether to target a new browser tab<br />(Link only)',
|
|
76
|
-
if: { arg: 'element', eq:
|
|
76
|
+
if: { arg: 'element', eq: ELEMENT_BROAD.LINK },
|
|
77
77
|
},
|
|
78
78
|
label: {
|
|
79
79
|
control: 'text',
|
|
@@ -1,53 +1,72 @@
|
|
|
1
1
|
import { action } from '@storybook/addon-actions';
|
|
2
|
+
import { ref } from 'vue';
|
|
2
3
|
|
|
3
4
|
import TideInputCheckbox from '@/components/TideInputCheckbox.vue';
|
|
4
|
-
import { argTypeBooleanUnrequired,
|
|
5
|
-
|
|
6
|
-
import type { StoryContext } from '@storybook/vue3';
|
|
5
|
+
import { argTypeBooleanUnrequired, dataTrack, disabledArgType, doSomething, parameters } from '@/utilities/storybook';
|
|
7
6
|
|
|
8
7
|
type Args = InstanceType<typeof TideInputCheckbox>['$props'] & {
|
|
9
|
-
|
|
8
|
+
handleValid: string;
|
|
9
|
+
vModel: string;
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
-
const render = (args: Args
|
|
12
|
+
const render = (args: Args) => ({
|
|
13
13
|
components: { TideInputCheckbox },
|
|
14
14
|
methods: {
|
|
15
15
|
doSomething,
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
action('TideInputCheckbox clicked')({});
|
|
20
|
-
context.updateArgs({ ...args, checked: !input?.checked === true, indeterminate: undefined });
|
|
16
|
+
handleValid: () => {
|
|
17
|
+
action('TideInputText valid was emitted')({});
|
|
21
18
|
|
|
22
19
|
try {
|
|
23
|
-
const callback = eval(args.
|
|
20
|
+
const callback = eval(args.handleValid);
|
|
24
21
|
|
|
25
22
|
if (callback) {
|
|
26
23
|
callback();
|
|
27
24
|
}
|
|
28
25
|
} catch {
|
|
29
|
-
alert('Please specify a valid handler in the "
|
|
26
|
+
alert('Please specify a valid handler in the "valid" control.');
|
|
30
27
|
}
|
|
31
28
|
},
|
|
32
29
|
},
|
|
33
|
-
setup
|
|
34
|
-
|
|
30
|
+
setup() {
|
|
31
|
+
const model = ref<boolean>(false);
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
args: {
|
|
35
|
+
...args,
|
|
36
|
+
inputId: undefined, // Do not allow empty ID attribute to break the demo.
|
|
37
|
+
},
|
|
38
|
+
model,
|
|
39
|
+
};
|
|
40
|
+
},
|
|
41
|
+
template: `<TideInputCheckbox @valid="handleValid" v-bind="args" v-model="model" />`,
|
|
35
42
|
});
|
|
36
43
|
|
|
37
44
|
export default {
|
|
38
45
|
argTypes: {
|
|
39
|
-
checked: {
|
|
40
|
-
...argTypeBooleanUnrequired,
|
|
41
|
-
description: 'Determines whether Checkbox is checked or unchecked',
|
|
42
|
-
},
|
|
43
|
-
click: {
|
|
44
|
-
...click,
|
|
45
|
-
},
|
|
46
46
|
dataTrack,
|
|
47
47
|
disabled: {
|
|
48
48
|
...argTypeBooleanUnrequired,
|
|
49
49
|
description: 'Determines whether Checkbox state is interactable',
|
|
50
50
|
},
|
|
51
|
+
error: {
|
|
52
|
+
control: 'text',
|
|
53
|
+
description: 'Overrides the default error message and valid state',
|
|
54
|
+
table: {
|
|
55
|
+
defaultValue: { summary: 'None' },
|
|
56
|
+
type: { summary: 'string' },
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
handleValid: {
|
|
60
|
+
control: 'text',
|
|
61
|
+
description: 'JS code or function to execute on valid event',
|
|
62
|
+
isEmit: true,
|
|
63
|
+
name: 'valid',
|
|
64
|
+
table: {
|
|
65
|
+
category: 'Events',
|
|
66
|
+
defaultValue: { summary: 'None' },
|
|
67
|
+
type: { summary: '(isValid: boolean) => void' },
|
|
68
|
+
},
|
|
69
|
+
},
|
|
51
70
|
indeterminate: {
|
|
52
71
|
...argTypeBooleanUnrequired,
|
|
53
72
|
description: 'Determines whether Checkbox is indeterminate',
|
|
@@ -85,17 +104,33 @@ export default {
|
|
|
85
104
|
type: { summary: 'number' },
|
|
86
105
|
},
|
|
87
106
|
},
|
|
107
|
+
required: {
|
|
108
|
+
...argTypeBooleanUnrequired,
|
|
109
|
+
description: 'Determines whether input is required',
|
|
110
|
+
},
|
|
111
|
+
vModel: {
|
|
112
|
+
control: 'text',
|
|
113
|
+
description: 'Data binding to Vue ref',
|
|
114
|
+
table: {
|
|
115
|
+
category: 'Native',
|
|
116
|
+
defaultValue: { summary: 'None' },
|
|
117
|
+
type: { summary: 'Ref' },
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
valid: disabledArgType,
|
|
88
121
|
},
|
|
89
122
|
args: {
|
|
90
|
-
checked: undefined,
|
|
91
|
-
click: 'doSomething',
|
|
92
123
|
dataTrack: '',
|
|
93
124
|
disabled: undefined,
|
|
125
|
+
error: '',
|
|
126
|
+
handleValid: 'doSomething',
|
|
94
127
|
indeterminate: undefined,
|
|
95
128
|
inputId: '',
|
|
96
129
|
label: 'Input label',
|
|
97
130
|
name: '',
|
|
98
131
|
number: '',
|
|
132
|
+
required: undefined,
|
|
133
|
+
vModel: '',
|
|
99
134
|
},
|
|
100
135
|
component: TideInputCheckbox,
|
|
101
136
|
parameters,
|
|
@@ -1,46 +1,38 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ref, watch } from 'vue';
|
|
2
2
|
|
|
3
3
|
import TideInputRadio from '@/components/TideInputRadio.vue';
|
|
4
|
-
import { argTypeBooleanUnrequired,
|
|
4
|
+
import { argTypeBooleanUnrequired, dataTrack, parameters } from '@/utilities/storybook';
|
|
5
5
|
|
|
6
6
|
import type { StoryContext } from '@storybook/vue3';
|
|
7
7
|
|
|
8
|
-
type Args = InstanceType<typeof TideInputRadio>['$props']
|
|
9
|
-
click: string;
|
|
10
|
-
};
|
|
8
|
+
type Args = InstanceType<typeof TideInputRadio>['$props'];
|
|
11
9
|
|
|
12
10
|
const render = (args: Args, context: StoryContext) => ({
|
|
13
11
|
components: { TideInputRadio },
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
handleClick: () => {
|
|
17
|
-
const input = context.canvasElement.querySelector('input');
|
|
18
|
-
|
|
19
|
-
action('TideInputRadio changed')({});
|
|
20
|
-
context.updateArgs({ ...args, checked: !input?.checked });
|
|
21
|
-
|
|
22
|
-
try {
|
|
23
|
-
const callback = eval(args.click);
|
|
12
|
+
setup() {
|
|
13
|
+
const model = ref<string | undefined>(undefined);
|
|
24
14
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
15
|
+
watch(
|
|
16
|
+
() => ({ ...args }),
|
|
17
|
+
(newArgs) => {
|
|
18
|
+
// Reset v-model when arg table is reset.
|
|
19
|
+
if (JSON.stringify(newArgs) === JSON.stringify(context.allArgs)) model.value = undefined;
|
|
30
20
|
}
|
|
31
|
-
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
return {
|
|
24
|
+
args: {
|
|
25
|
+
...args,
|
|
26
|
+
inputId: undefined,
|
|
27
|
+
},
|
|
28
|
+
model,
|
|
29
|
+
};
|
|
32
30
|
},
|
|
33
|
-
|
|
34
|
-
template: `<TideInputRadio @click="handleClick" v-bind="args" />`,
|
|
31
|
+
template: `<TideInputRadio v-bind="args" v-model="model" />`,
|
|
35
32
|
});
|
|
36
33
|
|
|
37
34
|
export default {
|
|
38
35
|
argTypes: {
|
|
39
|
-
checked: {
|
|
40
|
-
...argTypeBooleanUnrequired,
|
|
41
|
-
description: 'Determines whether input is selected',
|
|
42
|
-
},
|
|
43
|
-
click,
|
|
44
36
|
dataTrack,
|
|
45
37
|
disabled: {
|
|
46
38
|
...argTypeBooleanUnrequired,
|
|
@@ -78,16 +70,33 @@ export default {
|
|
|
78
70
|
type: { summary: 'number' },
|
|
79
71
|
},
|
|
80
72
|
},
|
|
73
|
+
vModel: {
|
|
74
|
+
control: 'text',
|
|
75
|
+
description: 'Data binding to Vue ref',
|
|
76
|
+
table: {
|
|
77
|
+
category: 'Native',
|
|
78
|
+
defaultValue: { summary: 'None' },
|
|
79
|
+
type: { summary: 'Ref' },
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
value: {
|
|
83
|
+
control: 'text',
|
|
84
|
+
description: 'Value attribute',
|
|
85
|
+
table: {
|
|
86
|
+
defaultValue: { summary: 'None' },
|
|
87
|
+
type: { summary: 'string' },
|
|
88
|
+
},
|
|
89
|
+
},
|
|
81
90
|
},
|
|
82
91
|
args: {
|
|
83
|
-
checked: undefined,
|
|
84
|
-
click: 'doSomething',
|
|
85
92
|
dataTrack: '',
|
|
86
93
|
disabled: undefined,
|
|
87
94
|
inputId: '',
|
|
88
95
|
label: 'Input label',
|
|
89
96
|
name: '',
|
|
90
97
|
number: '',
|
|
98
|
+
vModel: '',
|
|
99
|
+
value: '',
|
|
91
100
|
},
|
|
92
101
|
component: TideInputRadio,
|
|
93
102
|
parameters,
|