@nexxtmove/ui 0.1.30 → 0.1.32

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 (56) hide show
  1. package/dist/index.d.ts +113 -17
  2. package/dist/index.js +146 -111
  3. package/dist/nuxt.js +26 -25
  4. package/package.json +1 -1
  5. package/src/components/Avatar/Avatar.vue +49 -0
  6. package/src/components/Calendar/_CalendarDayView.vue +1 -1
  7. package/src/components/Chip/Chip.vue +9 -4
  8. package/src/components/Table/Table.vue +2 -2
  9. package/src/components.json +1 -0
  10. package/src/index.ts +1 -0
  11. package/src/components/AnimatedNumber/AnimatedNumber.stories.ts +0 -15
  12. package/src/components/AnimatedNumber/AnimatedNumber.test.ts +0 -56
  13. package/src/components/Button/Button.stories.ts +0 -212
  14. package/src/components/Button/Button.test.ts +0 -318
  15. package/src/components/Calendar/Calendar.stories.ts +0 -91
  16. package/src/components/Calendar/Calendar.test.ts +0 -279
  17. package/src/components/Calendar/_CalendarDayView.test.ts +0 -104
  18. package/src/components/Calendar/_CalendarHeader.test.ts +0 -86
  19. package/src/components/Calendar/_CalendarMonthView.test.ts +0 -52
  20. package/src/components/Calendar/_CalendarYearView.test.ts +0 -56
  21. package/src/components/Checkbox/Checkbox.stories.ts +0 -35
  22. package/src/components/Checkbox/Checkbox.test.ts +0 -55
  23. package/src/components/Chip/Chip.stories.ts +0 -42
  24. package/src/components/Chip/Chip.test.ts +0 -51
  25. package/src/components/CustomerJourneyTile/CustomerJourneyTile.stories.ts +0 -86
  26. package/src/components/CustomerJourneyTile/CustomerJourneyTile.test.ts +0 -178
  27. package/src/components/DatePicker/DatePicker.stories.ts +0 -149
  28. package/src/components/DatePicker/DatePicker.test.ts +0 -191
  29. package/src/components/DropdownButton/DropdownButton.stories.ts +0 -68
  30. package/src/components/DropdownButton/DropdownButton.test.ts +0 -124
  31. package/src/components/Header/Header.stories.ts +0 -54
  32. package/src/components/Header/Header.test.ts +0 -183
  33. package/src/components/Icon/Icon.stories.ts +0 -50
  34. package/src/components/Icon/Icon.test.ts +0 -73
  35. package/src/components/InfoBlock/InfoBlock.stories.ts +0 -90
  36. package/src/components/InfoBlock/InfoBlock.test.ts +0 -101
  37. package/src/components/ProgressBar/ProgressBar.stories.ts +0 -30
  38. package/src/components/ProgressBar/ProgressBar.test.ts +0 -314
  39. package/src/components/SocialIcons/SocialIcons.stories.ts +0 -34
  40. package/src/components/SocialIcons/SocialIcons.test.ts +0 -58
  41. package/src/components/SocialMediaCustomTemplate/SocialMediaCustomTemplate.stories.ts +0 -11
  42. package/src/components/SocialMediaCustomTemplate/SocialMediaCustomTemplate.test.ts +0 -131
  43. package/src/components/SocialMediaTemplate/SocialMediaTemplate.stories.ts +0 -71
  44. package/src/components/SocialMediaTemplate/SocialMediaTemplate.test.ts +0 -466
  45. package/src/components/SocialMediaType/SocialMediaType.stories.ts +0 -43
  46. package/src/components/SocialMediaType/SocialMediaType.test.ts +0 -126
  47. package/src/components/StepperHeader/StepperHeader.stories.ts +0 -47
  48. package/src/components/StepperHeader/StepperHeader.test.ts +0 -244
  49. package/src/components/Table/Table.stories.ts +0 -283
  50. package/src/components/Table/Table.test.ts +0 -220
  51. package/src/components/TimelineEvent/TimelineEvent.stories.ts +0 -291
  52. package/src/components/TimelineEvent/TimelineEvent.test.ts +0 -166
  53. package/src/components/TimelinePhaseblock/TimelinePhaseblock.stories.ts +0 -198
  54. package/src/components/TimelinePhaseblock/TimelinePhaseblock.test.ts +0 -283
  55. package/src/components/Tooltip/Tooltip.stories.ts +0 -146
  56. package/src/components/Tooltip/Tooltip.test.ts +0 -122
@@ -1,198 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/vue3-vite'
2
- import TimelinePhaseblock from './TimelinePhaseblock.vue'
3
- import type { TimelinePhase } from '../TimelineEvent/TimelineTypes'
4
-
5
- export default {
6
- title: 'Components/Molecules/Timeline Phaseblock',
7
- component: TimelinePhaseblock,
8
- } satisfies Meta<typeof TimelinePhaseblock>
9
-
10
- type Story = StoryObj<typeof TimelinePhaseblock>
11
-
12
- const makePhase = (
13
- value: number,
14
- entered_at: string | null = '2024-06-01T09:00:00.000Z',
15
- exited_at: string | null = '2024-07-01T09:00:00.000Z',
16
- events: TimelinePhase['events'] = [],
17
- ): TimelinePhase => ({
18
- phase: { value },
19
- entered_at,
20
- exited_at,
21
- events,
22
- })
23
-
24
- const sampleEvent = {
25
- id: 1,
26
- type: 'contact_created',
27
- happened_at: '2024-06-10T10:30:00.000Z',
28
- medium_type: null,
29
- url: null,
30
- page_title: null,
31
- request_reason: null,
32
- agenda_item_type: null,
33
- source: 'system',
34
- direction: 'outbound',
35
- description: null,
36
- }
37
-
38
- // Single phase at the end of the timeline (no separator shown)
39
- export const SinglePhase: Story = {
40
- args: {
41
- phase: makePhase(1),
42
- index: 0,
43
- phases: [makePhase(1)],
44
- isSplitView: true,
45
- isLast: true,
46
- },
47
- }
48
-
49
- // First phase (index 0) in split view — shows the Outbound/Inbound header
50
- export const FirstPhaseWithHeader: Story = {
51
- args: {
52
- phase: makePhase(4),
53
- index: 0,
54
- phases: [makePhase(4), makePhase(2)],
55
- isSplitView: true,
56
- isLast: false,
57
- },
58
- }
59
-
60
- // Phase separator visible — phase progressed upward (arrow up)
61
- export const PhaseProgressedUp: Story = {
62
- args: {
63
- phase: makePhase(4),
64
- index: 0,
65
- phases: [makePhase(4), makePhase(2)],
66
- isSplitView: true,
67
- isLast: false,
68
- },
69
- }
70
-
71
- // Phase separator visible — phase regressed downward (arrow down)
72
- export const PhaseRegressedDown: Story = {
73
- args: {
74
- phase: makePhase(2),
75
- index: 0,
76
- phases: [makePhase(2), makePhase(4)],
77
- isSplitView: true,
78
- isLast: false,
79
- },
80
- }
81
-
82
- // Last item in a multi-phase list — no separator shown
83
- export const LastInList: Story = {
84
- args: {
85
- phase: makePhase(1),
86
- index: 1,
87
- phases: [makePhase(4), makePhase(1)],
88
- isSplitView: true,
89
- isLast: true,
90
- },
91
- }
92
-
93
- // Non-split view — with phase separator
94
- export const NonSplitView: Story = {
95
- args: {
96
- phase: makePhase(3),
97
- index: 0,
98
- phases: [makePhase(3), makePhase(1)],
99
- isSplitView: false,
100
- isLast: false,
101
- },
102
- }
103
-
104
- // Non-split view — single/last phase (no separator)
105
- export const NonSplitViewLast: Story = {
106
- args: {
107
- phase: makePhase(3),
108
- index: 0,
109
- phases: [makePhase(3)],
110
- isSplitView: false,
111
- isLast: true,
112
- },
113
- }
114
-
115
- // Non-split view — with events
116
- export const NonSplitViewWithEvents: Story = {
117
- args: {
118
- phase: makePhase(4, '2024-06-01T09:00:00.000Z', '2024-07-01T09:00:00.000Z', [
119
- sampleEvent,
120
- { ...sampleEvent, id: 2, type: 'page_viewed', happened_at: '2024-06-12T14:00:00.000Z' },
121
- ]),
122
- index: 0,
123
- phases: [makePhase(4), makePhase(2)],
124
- isSplitView: false,
125
- isLast: false,
126
- },
127
- }
128
-
129
- // Phase with events
130
- export const WithEvents: Story = {
131
- args: {
132
- phase: makePhase(4, '2024-06-01T09:00:00.000Z', '2024-07-01T09:00:00.000Z', [
133
- sampleEvent,
134
- { ...sampleEvent, id: 2, type: 'page_viewed', happened_at: '2024-06-12T14:00:00.000Z' },
135
- {
136
- ...sampleEvent,
137
- id: 3,
138
- type: 'whatsapp_message_received',
139
- direction: 'inbound',
140
- happened_at: '2024-06-15T11:00:00.000Z',
141
- },
142
- ]),
143
- index: 0,
144
- phases: [makePhase(4), makePhase(2)],
145
- isSplitView: true,
146
- isLast: false,
147
- },
148
- }
149
-
150
- // All phases shown together (newest first)
151
- export const FullTimeline: Story = {
152
- args: {
153
- phase: makePhase(5, '2024-08-01T09:00:00.000Z', null, [
154
- { ...sampleEvent, id: 4, type: 'proposal_accepted', happened_at: '2024-08-05T10:00:00.000Z' },
155
- ]),
156
- index: 0,
157
- phases: [
158
- makePhase(5, '2024-08-01T09:00:00.000Z', null),
159
- makePhase(4, '2024-06-01T09:00:00.000Z', '2024-08-01T09:00:00.000Z'),
160
- makePhase(1, '2024-01-01T09:00:00.000Z', '2024-06-01T09:00:00.000Z'),
161
- ],
162
- isSplitView: true,
163
- isLast: false,
164
- },
165
- }
166
-
167
- // Phase with no entered_at or exited_at dates
168
- export const NoDates: Story = {
169
- args: {
170
- phase: makePhase(2, null, null),
171
- index: 0,
172
- phases: [makePhase(2, null, null), makePhase(1, null, null)],
173
- isSplitView: true,
174
- isLast: false,
175
- },
176
- }
177
-
178
- // Inactive phase (value 0)
179
- export const InactivePhase: Story = {
180
- args: {
181
- phase: makePhase(0),
182
- index: 0,
183
- phases: [makePhase(0)],
184
- isSplitView: true,
185
- isLast: true,
186
- },
187
- }
188
-
189
- // Wonen phase (value 6 — highest)
190
- export const WonenPhase: Story = {
191
- args: {
192
- phase: makePhase(6),
193
- index: 0,
194
- phases: [makePhase(6), makePhase(5)],
195
- isSplitView: true,
196
- isLast: false,
197
- },
198
- }
@@ -1,283 +0,0 @@
1
- import { describe, it, expect } from 'vitest'
2
- import { mount } from '@vue/test-utils'
3
- import { defineComponent } from 'vue'
4
- import TimelinePhaseblock from './TimelinePhaseblock.vue'
5
- import type { TimelinePhase } from '../TimelineEvent/TimelineTypes'
6
-
7
- const TimelineEventStub = defineComponent({
8
- name: 'NexxtTimelineEvent',
9
- props: ['event', 'splitView'],
10
- template: '<div class="timeline-event-stub" />',
11
- })
12
-
13
- const makePhase = (
14
- value: number,
15
- entered_at: string | null = '2024-06-01T09:00:00.000Z',
16
- exited_at: string | null = '2024-07-01T09:00:00.000Z',
17
- events: TimelinePhase['events'] = [],
18
- ): TimelinePhase => ({
19
- phase: { value },
20
- entered_at,
21
- exited_at,
22
- events,
23
- })
24
-
25
- const baseEvent = {
26
- id: 1,
27
- type: 'contact_created',
28
- happened_at: '2024-06-10T10:30:00.000Z',
29
- medium_type: null,
30
- url: null,
31
- page_title: null,
32
- request_reason: null,
33
- agenda_item_type: null,
34
- source: 'system',
35
- direction: 'outbound',
36
- description: null,
37
- }
38
-
39
- const stubs = {
40
- NexxtIcon: true,
41
- NexxtTimelineEvent: TimelineEventStub,
42
- }
43
-
44
- const mountBlock = (overrides: Partial<InstanceType<typeof TimelinePhaseblock>['$props']> = {}) => {
45
- const phases = [makePhase(4), makePhase(2)]
46
- return mount(TimelinePhaseblock, {
47
- props: {
48
- phase: phases[0],
49
- index: 0,
50
- phases,
51
- isSplitView: true,
52
- isLast: false,
53
- ...overrides,
54
- },
55
- global: { stubs },
56
- })
57
- }
58
-
59
- describe('TimelinePhaseblock', () => {
60
- describe('data attribute', () => {
61
- it('sets data-phase to the phase value', () => {
62
- const wrapper = mountBlock()
63
- expect(wrapper.attributes('data-phase')).toBe('4')
64
- })
65
- })
66
-
67
- describe('outbound/inbound header', () => {
68
- it('shows the header when index is 0 and isSplitView is true', () => {
69
- const wrapper = mountBlock({ index: 0, isSplitView: true })
70
- expect(wrapper.text()).toContain('Outbound')
71
- expect(wrapper.text()).toContain('Inbound')
72
- })
73
-
74
- it('does not show the header when index is not 0', () => {
75
- const phases = [makePhase(4), makePhase(2)]
76
- const wrapper = mountBlock({ phase: phases[1], index: 1, phases, isSplitView: true })
77
- expect(wrapper.text()).not.toContain('Outbound')
78
- })
79
-
80
- it('does not show the header when isSplitView is false', () => {
81
- const wrapper = mountBlock({ index: 0, isSplitView: false })
82
- expect(wrapper.text()).not.toContain('Outbound')
83
- })
84
- })
85
-
86
- describe('timeline lines', () => {
87
- it('always renders the left timeline line', () => {
88
- const wrapper = mountBlock({ isSplitView: false })
89
- expect(wrapper.find('.border-l.left-5').exists()).toBe(true)
90
- })
91
-
92
- it('renders the right timeline line when isSplitView is true', () => {
93
- const wrapper = mountBlock({ isSplitView: true })
94
- expect(wrapper.find('.border-l.right-5').exists()).toBe(true)
95
- })
96
-
97
- it('does not render the right timeline line when isSplitView is false', () => {
98
- const wrapper = mountBlock({ isSplitView: false })
99
- expect(wrapper.find('.border-l.right-5').exists()).toBe(false)
100
- })
101
-
102
- it('applies the phase color to the left timeline line', () => {
103
- // phase value 4 → border-blue-500
104
- const wrapper = mountBlock()
105
- expect(wrapper.find('.border-l.left-5').classes()).toContain('border-blue-500')
106
- })
107
- })
108
-
109
- describe('events', () => {
110
- it('renders a NexxtTimelineEvent for each event in the phase', () => {
111
- const phases = [
112
- makePhase(4, '2024-06-01T09:00:00.000Z', '2024-07-01T09:00:00.000Z', [
113
- baseEvent,
114
- { ...baseEvent, id: 2 },
115
- ]),
116
- ]
117
- const wrapper = mount(TimelinePhaseblock, {
118
- props: { phase: phases[0], index: 0, phases, isSplitView: true, isLast: true },
119
- global: { stubs },
120
- })
121
- expect(wrapper.findAllComponents(TimelineEventStub).length).toBe(2)
122
- })
123
-
124
- it('renders no events when the phase has an empty events array', () => {
125
- const wrapper = mountBlock()
126
- expect(wrapper.findAllComponents(TimelineEventStub).length).toBe(0)
127
- })
128
-
129
- it('passes isSplitView to each event', () => {
130
- const phases = [
131
- makePhase(4, '2024-06-01T09:00:00.000Z', '2024-07-01T09:00:00.000Z', [baseEvent]),
132
- ]
133
- const wrapper = mount(TimelinePhaseblock, {
134
- props: { phase: phases[0], index: 0, phases, isSplitView: false, isLast: true },
135
- global: { stubs },
136
- })
137
- expect(wrapper.findComponent(TimelineEventStub).props('splitView')).toBe(false)
138
- })
139
- })
140
-
141
- describe('phase separator badge', () => {
142
- it('shows the separator when index is not the last in the phases array', () => {
143
- // phases has 2 items, index 0 → 0 !== 1 → shows separator
144
- const wrapper = mountBlock({ index: 0 })
145
- expect(wrapper.find('.rounded-full').exists()).toBe(true)
146
- })
147
-
148
- it('does not show the separator when index equals phases.length - 1', () => {
149
- const phases = [makePhase(4), makePhase(2)]
150
- const wrapper = mountBlock({ phase: phases[1], index: 1, phases })
151
- expect(wrapper.find('.rounded-full').exists()).toBe(false)
152
- })
153
-
154
- it('displays the phase label in the separator', () => {
155
- // phase value 4 → 'Selectie'
156
- const wrapper = mountBlock()
157
- expect(wrapper.find('.rounded-full').text()).toContain('Selectie')
158
- })
159
-
160
- it('applies the correct background color class to the separator badge', () => {
161
- // phase value 4 → bg-blue-500
162
- const wrapper = mountBlock()
163
- expect(wrapper.find('.rounded-full').classes()).toContain('bg-blue-500')
164
- })
165
-
166
- it('applies the correct text color class to the separator badge', () => {
167
- // phase value 4 → text-white
168
- const wrapper = mountBlock()
169
- expect(wrapper.find('.rounded-full').classes()).toContain('text-white')
170
- })
171
-
172
- it('shows an up arrow when the current phase value is higher than the previous phase', () => {
173
- // index 0 = value 4, index 1 = value 2 → 4 > 2 → up
174
- const wrapper = mountBlock()
175
- const arrowStub = wrapper.find('nexxt-icon-stub[name="arrow-up"]')
176
- expect(arrowStub.exists()).toBe(true)
177
- })
178
-
179
- it('shows a down arrow when the current phase value is lower than the previous phase', () => {
180
- // index 0 = value 2, index 1 = value 4 → 2 < 4 → down
181
- const phases = [makePhase(2), makePhase(4)]
182
- const wrapper = mountBlock({ phase: phases[0], index: 0, phases })
183
- const arrowStub = wrapper.find('nexxt-icon-stub[name="arrow-down"]')
184
- expect(arrowStub.exists()).toBe(true)
185
- })
186
-
187
- it('shows no direction arrow when there is no previous phase', () => {
188
- const phases = [makePhase(4)]
189
- // With only one phase, index 0 === phases.length - 1, so separator is hidden anyway.
190
- // Use a 2-item list but check the last item's arrow (no prevPhase for last)
191
- // Actually let's test: if index === phases.length -1, separator is hidden.
192
- // The arrow is inside the separator, so let's just check getPhaseDirection returns null
193
- // by having no phase at index+1. We can't show separator unless index !== phases.length-1,
194
- // so create a dummy scenario: index=0, phases=[phase0] would hide separator.
195
- // Instead verify: no arrow-up or arrow-down when phases only have one entry.
196
- const wrapper = mount(TimelinePhaseblock, {
197
- props: { phase: phases[0], index: 0, phases, isSplitView: true, isLast: true },
198
- global: { stubs },
199
- })
200
- expect(wrapper.find('nexxt-icon-stub[name="arrow-up"]').exists()).toBe(false)
201
- expect(wrapper.find('nexxt-icon-stub[name="arrow-down"]').exists()).toBe(false)
202
- })
203
-
204
- it('shows entered_at date when phase progressed upward', () => {
205
- // phase value 4 > prev value 2 → show entered_at
206
- const phase = makePhase(4, '2024-06-01T09:00:00.000Z', '2024-07-01T09:00:00.000Z')
207
- const phases = [phase, makePhase(2)]
208
- const wrapper = mountBlock({ phase, phases })
209
- // entered_at = 2024-06-01 → formatted in nl-NL → contains "jun"
210
- const dateEl = wrapper.find('.text-gray-500')
211
- expect(dateEl.text()).toContain('jun')
212
- })
213
-
214
- it('shows exited_at date when phase regressed downward', () => {
215
- // phase value 2 < prev value 4 → show exited_at
216
- const phase = makePhase(2, '2024-06-01T09:00:00.000Z', '2024-07-01T09:00:00.000Z')
217
- const phases = [phase, makePhase(4)]
218
- const wrapper = mountBlock({ phase, phases })
219
- // exited_at = 2024-07-01 → contains "jul"
220
- const dateEl = wrapper.find('.text-gray-500')
221
- expect(dateEl.text()).toContain('jul')
222
- })
223
-
224
- it('shows empty string when relevant date is null', () => {
225
- const phase = makePhase(4, null, null)
226
- const phases = [phase, makePhase(2)]
227
- const wrapper = mountBlock({ phase, phases })
228
- expect(wrapper.find('.text-gray-500').text()).toBe('')
229
- })
230
-
231
- it('renders the horizontal divider line in split view', () => {
232
- const wrapper = mountBlock({ isSplitView: true })
233
- expect(wrapper.find('.h-px.w-\\[75\\%\\]').exists()).toBe(true)
234
- })
235
-
236
- it('does not render the horizontal divider line outside split view', () => {
237
- const wrapper = mountBlock({ isSplitView: false })
238
- expect(wrapper.find('.h-px.w-\\[75\\%\\]').exists()).toBe(false)
239
- })
240
-
241
- it('applies pl-16 to the separator container when not in split view', () => {
242
- const wrapper = mountBlock({ isSplitView: false })
243
- const separator = wrapper.find('.relative.flex.flex-col.items-center')
244
- expect(separator.classes()).toContain('pl-16')
245
- })
246
-
247
- it('does not apply pl-16 to the separator container in split view', () => {
248
- const wrapper = mountBlock({ isSplitView: true })
249
- const separator = wrapper.find('.relative.flex.flex-col.items-center')
250
- expect(separator.classes()).not.toContain('pl-16')
251
- })
252
- })
253
-
254
- describe('gradient', () => {
255
- it('applies gradient classes to the vertical gradient bar when there is a previous phase', () => {
256
- // phase value 4 → fromColor: from-blue-500; prev phase value 2 → toColor: to-purple-500
257
- const wrapper = mountBlock()
258
- const gradientBar = wrapper.find('.bg-linear-to-b.left-5')
259
- expect(gradientBar.classes()).toContain('from-blue-500')
260
- expect(gradientBar.classes()).toContain('to-purple-500')
261
- })
262
-
263
- it('applies no gradient classes when there is no previous phase', () => {
264
- const phases = [makePhase(4)]
265
- const wrapper = mount(TimelinePhaseblock, {
266
- props: { phase: phases[0], index: 0, phases, isSplitView: true, isLast: true },
267
- global: { stubs },
268
- })
269
- // No separator rendered, so no gradient bar inside separator
270
- expect(wrapper.find('.bg-linear-to-b').exists()).toBe(false)
271
- })
272
-
273
- it('renders the right-side gradient bar in split view', () => {
274
- const wrapper = mountBlock({ isSplitView: true })
275
- expect(wrapper.find('.bg-linear-to-b.right-5').exists()).toBe(true)
276
- })
277
-
278
- it('does not render the right-side gradient bar outside split view', () => {
279
- const wrapper = mountBlock({ isSplitView: false })
280
- expect(wrapper.find('.bg-linear-to-b.right-5').exists()).toBe(false)
281
- })
282
- })
283
- })
@@ -1,146 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/vue3-vite'
2
- import Tooltip from './Tooltip.vue'
3
-
4
- export default {
5
- title: 'Components/Atoms/Tooltip',
6
- component: Tooltip,
7
- } satisfies Meta<typeof Tooltip>
8
-
9
- type Story = StoryObj<typeof Tooltip>
10
-
11
- const trigger = `<button class="rounded border border-gray-300 px-3 py-1 text-sm">Hover me</button>`
12
-
13
- export const Default: Story = {
14
- render: () => ({
15
- components: { Tooltip },
16
- template: `
17
- <Tooltip>
18
- ${trigger}
19
- <template #tooltip>This is a tooltip</template>
20
- </Tooltip>
21
- `,
22
- }),
23
- }
24
-
25
- export const WithDelay: Story = {
26
- render: () => ({
27
- components: { Tooltip },
28
- template: `
29
- <Tooltip :delay="500">
30
- <button class="rounded border border-gray-300 px-3 py-1 text-sm">Hover me (500ms delay)</button>
31
- <template #tooltip>Appears after a delay</template>
32
- </Tooltip>
33
- `,
34
- }),
35
- }
36
-
37
- export const SideBottom: Story = {
38
- render: () => ({
39
- components: { Tooltip },
40
- template: `
41
- <Tooltip side="bottom">
42
- ${trigger}
43
- <template #tooltip>Tooltip below</template>
44
- </Tooltip>
45
- `,
46
- }),
47
- }
48
-
49
- export const SideLeft: Story = {
50
- render: () => ({
51
- components: { Tooltip },
52
- template: `
53
- <Tooltip side="left">
54
- ${trigger}
55
- <template #tooltip>Tooltip on the left</template>
56
- </Tooltip>
57
- `,
58
- }),
59
- }
60
-
61
- export const SideRight: Story = {
62
- render: () => ({
63
- components: { Tooltip },
64
- template: `
65
- <Tooltip side="right">
66
- ${trigger}
67
- <template #tooltip>Tooltip on the right</template>
68
- </Tooltip>
69
- `,
70
- }),
71
- }
72
-
73
- export const AlignStart: Story = {
74
- render: () => ({
75
- components: { Tooltip },
76
- template: `
77
- <Tooltip align="start">
78
- ${trigger}
79
- <template #tooltip>Aligned to start</template>
80
- </Tooltip>
81
- `,
82
- }),
83
- }
84
-
85
- export const AlignEnd: Story = {
86
- render: () => ({
87
- components: { Tooltip },
88
- template: `
89
- <Tooltip align="end">
90
- ${trigger}
91
- <template #tooltip>Aligned to end</template>
92
- </Tooltip>
93
- `,
94
- }),
95
- }
96
-
97
- export const CustomOffset: Story = {
98
- render: () => ({
99
- components: { Tooltip },
100
- template: `
101
- <Tooltip :side-offset="20">
102
- ${trigger}
103
- <template #tooltip>Further away (20px offset)</template>
104
- </Tooltip>
105
- `,
106
- }),
107
- }
108
-
109
- export const DisableHoverableContent: Story = {
110
- render: () => ({
111
- components: { Tooltip },
112
- template: `
113
- <Tooltip :disable-hoverable-content="true">
114
- ${trigger}
115
- <template #tooltip>Closes when you move to the tooltip</template>
116
- </Tooltip>
117
- `,
118
- }),
119
- }
120
-
121
- export const RichContent: Story = {
122
- render: () => ({
123
- components: { Tooltip },
124
- template: `
125
- <Tooltip>
126
- <button class="rounded border border-gray-300 px-3 py-1 text-sm">Hover for details</button>
127
- <template #tooltip>
128
- <strong>Title</strong>
129
- <p class="mt-1 text-gray-500">Additional description here</p>
130
- </template>
131
- </Tooltip>
132
- `,
133
- }),
134
- }
135
-
136
- export const OnIcon: Story = {
137
- render: () => ({
138
- components: { Tooltip },
139
- template: `
140
- <Tooltip>
141
- <span class="inline-flex h-5 w-5 cursor-pointer items-center justify-center rounded-full bg-gray-200 text-xs text-gray-600">?</span>
142
- <template #tooltip>Helpful information about this field</template>
143
- </Tooltip>
144
- `,
145
- }),
146
- }