@nationaldesignstudio/react 0.5.2 → 0.5.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/package.json +10 -2
- package/src/components/organisms/navbar/navbar.tsx +8 -8
- package/src/App.css +0 -0
- package/src/App.tsx +0 -7
- package/src/assets/fonts/PPNeueMontreal-Variable.woff2 +0 -0
- package/src/assets/react.svg +0 -1
- package/src/components/atoms/accordion/accordion.stories.tsx +0 -228
- package/src/components/atoms/accordion/accordion.test.tsx +0 -231
- package/src/components/atoms/accordion/index.ts +0 -6
- package/src/components/atoms/background/background.test.tsx +0 -213
- package/src/components/atoms/background/index.ts +0 -22
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-charcoal-chromium-darwin.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-charcoal-chromium-linux.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-charcoal-outline-chromium-darwin.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-charcoal-outline-chromium-linux.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-charcoal-outline-quiet-chromium-darwin.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-charcoal-outline-quiet-chromium-linux.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-disabled-chromium-darwin.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-disabled-chromium-linux.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-ivory-chromium-darwin.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-ivory-chromium-linux.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-ivory-outline-chromium-darwin.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-ivory-outline-chromium-linux.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-ivory-outline-quiet-chromium-darwin.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-ivory-outline-quiet-chromium-linux.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-size-large-chromium-darwin.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-size-large-chromium-linux.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-size-medium-chromium-darwin.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-size-medium-chromium-linux.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-size-small-chromium-darwin.png +0 -0
- package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-size-small-chromium-linux.png +0 -0
- package/src/components/atoms/button/button.stories.tsx +0 -289
- package/src/components/atoms/button/button.test.tsx +0 -419
- package/src/components/atoms/button/button.visual.test.tsx +0 -98
- package/src/components/atoms/button/icon-button.stories.tsx +0 -260
- package/src/components/atoms/button/icon-button.test.tsx +0 -186
- package/src/components/atoms/button/index.ts +0 -6
- package/src/components/atoms/input/index.ts +0 -17
- package/src/components/atoms/input/input-group.stories.tsx +0 -646
- package/src/components/atoms/input/input-group.test.tsx +0 -362
- package/src/components/atoms/input/input.stories.tsx +0 -228
- package/src/components/atoms/input/input.test.tsx +0 -167
- package/src/components/atoms/ndstudio-footer/index.ts +0 -1
- package/src/components/atoms/pager-control/index.ts +0 -5
- package/src/components/atoms/pager-control/pager-control.stories.tsx +0 -207
- package/src/components/atoms/pager-control/pager-control.test.tsx +0 -130
- package/src/components/atoms/popover/index.ts +0 -30
- package/src/components/atoms/popover/popover.stories.tsx +0 -531
- package/src/components/atoms/popover/popover.test.tsx +0 -486
- package/src/components/atoms/select/index.ts +0 -18
- package/src/components/atoms/select/select.stories.tsx +0 -455
- package/src/components/atoms/tooltip/index.ts +0 -24
- package/src/components/atoms/tooltip/tooltip.stories.tsx +0 -348
- package/src/components/atoms/tooltip/tooltip.test.tsx +0 -363
- package/src/components/dev-tools/dev-toolbar/dev-toolbar.stories.tsx +0 -73
- package/src/components/dev-tools/dev-toolbar/index.ts +0 -1
- package/src/components/dev-tools/grid-overlay/index.ts +0 -1
- package/src/components/dev-tools/index.ts +0 -2
- package/src/components/foundation/typography/typography.stories.tsx +0 -401
- package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-default-vertical-chromium-darwin.png +0 -0
- package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-default-vertical-chromium-linux.png +0 -0
- package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-horizontal-chromium-darwin.png +0 -0
- package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-horizontal-chromium-linux.png +0 -0
- package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-minimal-chromium-darwin.png +0 -0
- package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-minimal-chromium-linux.png +0 -0
- package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-without-actions-chromium-darwin.png +0 -0
- package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-without-actions-chromium-linux.png +0 -0
- package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-without-eyebrow-chromium-darwin.png +0 -0
- package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-without-eyebrow-chromium-linux.png +0 -0
- package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-without-image-chromium-darwin.png +0 -0
- package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-without-image-chromium-linux.png +0 -0
- package/src/components/organisms/card/card.stories.tsx +0 -293
- package/src/components/organisms/card/card.test.tsx +0 -247
- package/src/components/organisms/card/card.visual.test.tsx +0 -197
- package/src/components/organisms/card/index.ts +0 -26
- package/src/components/organisms/navbar/__screenshots__/navbar.visual.test.tsx/navbar-active-link-chromium-darwin.png +0 -0
- package/src/components/organisms/navbar/__screenshots__/navbar.visual.test.tsx/navbar-active-link-chromium-linux.png +0 -0
- package/src/components/organisms/navbar/__screenshots__/navbar.visual.test.tsx/navbar-brand-only-chromium-darwin.png +0 -0
- package/src/components/organisms/navbar/__screenshots__/navbar.visual.test.tsx/navbar-brand-only-chromium-linux.png +0 -0
- package/src/components/organisms/navbar/__screenshots__/navbar.visual.test.tsx/navbar-default-chromium-darwin.png +0 -0
- package/src/components/organisms/navbar/__screenshots__/navbar.visual.test.tsx/navbar-default-chromium-linux.png +0 -0
- package/src/components/organisms/navbar/index.ts +0 -18
- package/src/components/organisms/navbar/navbar.stories.tsx +0 -313
- package/src/components/organisms/navbar/navbar.test.tsx +0 -190
- package/src/components/organisms/navbar/navbar.visual.test.tsx +0 -85
- package/src/components/organisms/us-gov-banner/__screenshots__/us-gov-banner.visual.test.tsx/us-gov-banner-custom-icon-chromium-darwin.png +0 -0
- package/src/components/organisms/us-gov-banner/__screenshots__/us-gov-banner.visual.test.tsx/us-gov-banner-custom-icon-chromium-linux.png +0 -0
- package/src/components/organisms/us-gov-banner/__screenshots__/us-gov-banner.visual.test.tsx/us-gov-banner-custom-text-chromium-darwin.png +0 -0
- package/src/components/organisms/us-gov-banner/__screenshots__/us-gov-banner.visual.test.tsx/us-gov-banner-custom-text-chromium-linux.png +0 -0
- package/src/components/organisms/us-gov-banner/__screenshots__/us-gov-banner.visual.test.tsx/us-gov-banner-default-chromium-darwin.png +0 -0
- package/src/components/organisms/us-gov-banner/__screenshots__/us-gov-banner.visual.test.tsx/us-gov-banner-default-chromium-linux.png +0 -0
- package/src/components/organisms/us-gov-banner/index.ts +0 -5
- package/src/components/organisms/us-gov-banner/us-gov-banner.stories.tsx +0 -35
- package/src/components/organisms/us-gov-banner/us-gov-banner.test.tsx +0 -107
- package/src/components/organisms/us-gov-banner/us-gov-banner.visual.test.tsx +0 -46
- package/src/components/sections/banner/banner.stories.tsx +0 -150
- package/src/components/sections/banner/banner.test.tsx +0 -185
- package/src/components/sections/banner/index.ts +0 -2
- package/src/components/sections/card-grid/card-grid.stories.tsx +0 -351
- package/src/components/sections/card-grid/index.ts +0 -1
- package/src/components/sections/faq-section/faq-section.stories.tsx +0 -453
- package/src/components/sections/faq-section/index.ts +0 -2
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a1-desktop-chromium-darwin.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a1-desktop-chromium-linux.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a1-mobile-chromium-darwin.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a1-mobile-chromium-linux.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a1-tablet-chromium-darwin.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a1-tablet-chromium-linux.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a2-desktop-chromium-darwin.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a2-desktop-chromium-linux.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a2-mobile-chromium-darwin.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a2-mobile-chromium-linux.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a2-tablet-chromium-darwin.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a2-tablet-chromium-linux.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a3-desktop-chromium-darwin.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a3-desktop-chromium-linux.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a3-mobile-chromium-darwin.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a3-mobile-chromium-linux.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a3-tablet-chromium-darwin.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a3-tablet-chromium-linux.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-custom-class-chromium-darwin.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-custom-class-chromium-linux.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-default-chromium-linux.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-long-title-chromium-darwin.png +0 -0
- package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-long-title-chromium-linux.png +0 -0
- package/src/components/sections/hero/hero.stories.tsx +0 -397
- package/src/components/sections/hero/hero.test.tsx +0 -138
- package/src/components/sections/hero/hero.visual.test.tsx +0 -140
- package/src/components/sections/hero/index.ts +0 -23
- package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-h3-heading-chromium-darwin.png +0 -0
- package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-h3-heading-chromium-linux.png +0 -0
- package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-multiple-paragraphs-chromium-darwin.png +0 -0
- package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-multiple-paragraphs-chromium-linux.png +0 -0
- package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-multiple-sections-chromium-darwin.png +0 -0
- package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-multiple-sections-chromium-linux.png +0 -0
- package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-single-section-chromium-darwin.png +0 -0
- package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-single-section-chromium-linux.png +0 -0
- package/src/components/sections/prose/index.ts +0 -6
- package/src/components/sections/prose/prose.stories.tsx +0 -144
- package/src/components/sections/prose/prose.test.tsx +0 -178
- package/src/components/sections/prose/prose.visual.test.tsx +0 -105
- package/src/components/sections/quote-block/index.ts +0 -5
- package/src/components/sections/river/index.ts +0 -1
- package/src/components/sections/river/river.stories.tsx +0 -237
- package/src/components/sections/river/river.test.tsx +0 -268
- package/src/components/sections/tout/index.ts +0 -1
- package/src/components/sections/tout/tout.stories.tsx +0 -171
- package/src/components/sections/tout/tout.test.tsx +0 -242
- package/src/components/sections/two-column-section/index.ts +0 -5
- package/src/components/sections/two-column-section/two-column-section.stories.tsx +0 -285
- package/src/components/shared/index.ts +0 -5
- package/src/index.ts +0 -293
- package/src/main.tsx +0 -13
- package/src/stories/grid-system.stories.tsx +0 -309
- package/src/stories/introduction.mdx +0 -128
- package/src/stories/theme-provider.stories.tsx +0 -349
- package/src/stories/token-showcase.stories.tsx +0 -73
- package/src/stories/token-showcase.tsx +0 -777
- package/src/styles.css +0 -14
- package/src/tests/token-resolution.test.tsx +0 -298
- package/src/theme/theme-provider.test.tsx +0 -270
|
@@ -1,348 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
-
import { Button } from "../button";
|
|
3
|
-
import {
|
|
4
|
-
Tooltip,
|
|
5
|
-
TooltipArrow,
|
|
6
|
-
TooltipParts,
|
|
7
|
-
TooltipPopup,
|
|
8
|
-
TooltipPortal,
|
|
9
|
-
TooltipPositioner,
|
|
10
|
-
TooltipProvider,
|
|
11
|
-
TooltipTrigger,
|
|
12
|
-
} from ".";
|
|
13
|
-
|
|
14
|
-
const meta: Meta<typeof Tooltip> = {
|
|
15
|
-
title: "Atoms/Tooltip",
|
|
16
|
-
component: Tooltip,
|
|
17
|
-
argTypes: {
|
|
18
|
-
side: {
|
|
19
|
-
control: { type: "select" },
|
|
20
|
-
options: ["top", "bottom", "left", "right"],
|
|
21
|
-
},
|
|
22
|
-
align: {
|
|
23
|
-
control: { type: "select" },
|
|
24
|
-
options: ["start", "center", "end"],
|
|
25
|
-
},
|
|
26
|
-
sideOffset: {
|
|
27
|
-
control: { type: "number" },
|
|
28
|
-
},
|
|
29
|
-
delay: {
|
|
30
|
-
control: { type: "number" },
|
|
31
|
-
},
|
|
32
|
-
closeDelay: {
|
|
33
|
-
control: { type: "number" },
|
|
34
|
-
},
|
|
35
|
-
showArrow: {
|
|
36
|
-
control: { type: "boolean" },
|
|
37
|
-
},
|
|
38
|
-
},
|
|
39
|
-
args: {
|
|
40
|
-
side: "top",
|
|
41
|
-
align: "center",
|
|
42
|
-
sideOffset: 8,
|
|
43
|
-
showArrow: true,
|
|
44
|
-
},
|
|
45
|
-
decorators: [
|
|
46
|
-
(Story) => (
|
|
47
|
-
<div className="flex min-h-[200px] items-center justify-center p-48">
|
|
48
|
-
<Story />
|
|
49
|
-
</div>
|
|
50
|
-
),
|
|
51
|
-
],
|
|
52
|
-
} satisfies Meta<typeof Tooltip>;
|
|
53
|
-
|
|
54
|
-
export default meta;
|
|
55
|
-
type Story = StoryObj<typeof Tooltip>;
|
|
56
|
-
|
|
57
|
-
// =============================================================================
|
|
58
|
-
// Playground
|
|
59
|
-
// =============================================================================
|
|
60
|
-
|
|
61
|
-
export const Playground: Story = {
|
|
62
|
-
render: (args) => (
|
|
63
|
-
<Tooltip {...args} content="This is a tooltip">
|
|
64
|
-
<Button>Hover me</Button>
|
|
65
|
-
</Tooltip>
|
|
66
|
-
),
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
// =============================================================================
|
|
70
|
-
// Basic Examples
|
|
71
|
-
// =============================================================================
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Basic tooltip with default settings.
|
|
75
|
-
*/
|
|
76
|
-
export const Default: Story = {
|
|
77
|
-
render: () => (
|
|
78
|
-
<Tooltip content="Save your changes">
|
|
79
|
-
<Button>Save</Button>
|
|
80
|
-
</Tooltip>
|
|
81
|
-
),
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Tooltip without arrow.
|
|
86
|
-
*/
|
|
87
|
-
export const NoArrow: Story = {
|
|
88
|
-
render: () => (
|
|
89
|
-
<Tooltip content="No arrow here" showArrow={false}>
|
|
90
|
-
<Button>Hover me</Button>
|
|
91
|
-
</Tooltip>
|
|
92
|
-
),
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Tooltip with longer content.
|
|
97
|
-
*/
|
|
98
|
-
export const LongContent: Story = {
|
|
99
|
-
render: () => (
|
|
100
|
-
<Tooltip content="This is a longer tooltip that provides more detailed information about the element.">
|
|
101
|
-
<Button>Hover for details</Button>
|
|
102
|
-
</Tooltip>
|
|
103
|
-
),
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
// =============================================================================
|
|
107
|
-
// Positioning
|
|
108
|
-
// =============================================================================
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Tooltip positioned on all four sides.
|
|
112
|
-
*/
|
|
113
|
-
export const AllPositions: Story = {
|
|
114
|
-
render: () => (
|
|
115
|
-
<div className="flex flex-col items-center gap-48">
|
|
116
|
-
<Tooltip content="Top tooltip" side="top">
|
|
117
|
-
<Button variant="outline">Top</Button>
|
|
118
|
-
</Tooltip>
|
|
119
|
-
<div className="flex items-center gap-48">
|
|
120
|
-
<Tooltip content="Left tooltip" side="left">
|
|
121
|
-
<Button variant="outline">Left</Button>
|
|
122
|
-
</Tooltip>
|
|
123
|
-
<Tooltip content="Right tooltip" side="right">
|
|
124
|
-
<Button variant="outline">Right</Button>
|
|
125
|
-
</Tooltip>
|
|
126
|
-
</div>
|
|
127
|
-
<Tooltip content="Bottom tooltip" side="bottom">
|
|
128
|
-
<Button variant="outline">Bottom</Button>
|
|
129
|
-
</Tooltip>
|
|
130
|
-
</div>
|
|
131
|
-
),
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
export const Top: Story = {
|
|
135
|
-
render: () => (
|
|
136
|
-
<Tooltip content="Top position" side="top">
|
|
137
|
-
<Button>Top</Button>
|
|
138
|
-
</Tooltip>
|
|
139
|
-
),
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
export const Bottom: Story = {
|
|
143
|
-
render: () => (
|
|
144
|
-
<Tooltip content="Bottom position" side="bottom">
|
|
145
|
-
<Button>Bottom</Button>
|
|
146
|
-
</Tooltip>
|
|
147
|
-
),
|
|
148
|
-
};
|
|
149
|
-
|
|
150
|
-
export const Left: Story = {
|
|
151
|
-
render: () => (
|
|
152
|
-
<Tooltip content="Left position" side="left">
|
|
153
|
-
<Button>Left</Button>
|
|
154
|
-
</Tooltip>
|
|
155
|
-
),
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
export const Right: Story = {
|
|
159
|
-
render: () => (
|
|
160
|
-
<Tooltip content="Right position" side="right">
|
|
161
|
-
<Button>Right</Button>
|
|
162
|
-
</Tooltip>
|
|
163
|
-
),
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
// =============================================================================
|
|
167
|
-
// Alignment
|
|
168
|
-
// =============================================================================
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Tooltip alignment options.
|
|
172
|
-
*/
|
|
173
|
-
export const Alignment: Story = {
|
|
174
|
-
render: () => (
|
|
175
|
-
<div className="flex flex-col gap-24">
|
|
176
|
-
<div className="flex items-center gap-24">
|
|
177
|
-
<Tooltip content="Aligned to start" side="bottom" align="start">
|
|
178
|
-
<Button variant="secondary" className="w-144">
|
|
179
|
-
Start
|
|
180
|
-
</Button>
|
|
181
|
-
</Tooltip>
|
|
182
|
-
<Tooltip content="Aligned to center" side="bottom" align="center">
|
|
183
|
-
<Button variant="secondary" className="w-144">
|
|
184
|
-
Center
|
|
185
|
-
</Button>
|
|
186
|
-
</Tooltip>
|
|
187
|
-
<Tooltip content="Aligned to end" side="bottom" align="end">
|
|
188
|
-
<Button variant="secondary" className="w-144">
|
|
189
|
-
End
|
|
190
|
-
</Button>
|
|
191
|
-
</Tooltip>
|
|
192
|
-
</div>
|
|
193
|
-
</div>
|
|
194
|
-
),
|
|
195
|
-
};
|
|
196
|
-
|
|
197
|
-
// =============================================================================
|
|
198
|
-
// Delays
|
|
199
|
-
// =============================================================================
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* Tooltip with custom open delay.
|
|
203
|
-
*/
|
|
204
|
-
export const CustomDelay: Story = {
|
|
205
|
-
render: () => (
|
|
206
|
-
<Tooltip content="Appears after 1 second" delay={1000}>
|
|
207
|
-
<Button>1s delay</Button>
|
|
208
|
-
</Tooltip>
|
|
209
|
-
),
|
|
210
|
-
};
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* Tooltip with close delay.
|
|
214
|
-
*/
|
|
215
|
-
export const CloseDelay: Story = {
|
|
216
|
-
render: () => (
|
|
217
|
-
<Tooltip content="Stays visible for 500ms" closeDelay={500}>
|
|
218
|
-
<Button>Close delay</Button>
|
|
219
|
-
</Tooltip>
|
|
220
|
-
),
|
|
221
|
-
};
|
|
222
|
-
|
|
223
|
-
// =============================================================================
|
|
224
|
-
// With Provider (Shared Delays)
|
|
225
|
-
// =============================================================================
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* Multiple tooltips with shared delay using TooltipProvider.
|
|
229
|
-
* After opening one tooltip, others open instantly.
|
|
230
|
-
*/
|
|
231
|
-
export const WithProvider: Story = {
|
|
232
|
-
render: () => (
|
|
233
|
-
<TooltipProvider delay={300} closeDelay={0}>
|
|
234
|
-
<div className="flex items-center gap-16">
|
|
235
|
-
<Tooltip content="First tooltip">
|
|
236
|
-
<Button variant="outline">First</Button>
|
|
237
|
-
</Tooltip>
|
|
238
|
-
<Tooltip content="Second tooltip">
|
|
239
|
-
<Button variant="outline">Second</Button>
|
|
240
|
-
</Tooltip>
|
|
241
|
-
<Tooltip content="Third tooltip">
|
|
242
|
-
<Button variant="outline">Third</Button>
|
|
243
|
-
</Tooltip>
|
|
244
|
-
</div>
|
|
245
|
-
</TooltipProvider>
|
|
246
|
-
),
|
|
247
|
-
};
|
|
248
|
-
|
|
249
|
-
// =============================================================================
|
|
250
|
-
// Compound Component API
|
|
251
|
-
// =============================================================================
|
|
252
|
-
|
|
253
|
-
/**
|
|
254
|
-
* Using the compound component API for full control.
|
|
255
|
-
*/
|
|
256
|
-
export const CompoundAPI: Story = {
|
|
257
|
-
render: () => (
|
|
258
|
-
<TooltipParts>
|
|
259
|
-
<TooltipTrigger>
|
|
260
|
-
<Button variant="primary">Custom Tooltip</Button>
|
|
261
|
-
</TooltipTrigger>
|
|
262
|
-
<TooltipPortal>
|
|
263
|
-
<TooltipPositioner side="bottom" sideOffset={12}>
|
|
264
|
-
<TooltipPopup>
|
|
265
|
-
<TooltipArrow />
|
|
266
|
-
Built with compound components
|
|
267
|
-
</TooltipPopup>
|
|
268
|
-
</TooltipPositioner>
|
|
269
|
-
</TooltipPortal>
|
|
270
|
-
</TooltipParts>
|
|
271
|
-
),
|
|
272
|
-
};
|
|
273
|
-
|
|
274
|
-
// =============================================================================
|
|
275
|
-
// On Different Elements
|
|
276
|
-
// =============================================================================
|
|
277
|
-
|
|
278
|
-
/**
|
|
279
|
-
* Tooltip on various trigger elements.
|
|
280
|
-
*/
|
|
281
|
-
export const OnDifferentElements: Story = {
|
|
282
|
-
render: () => (
|
|
283
|
-
<div className="flex items-center gap-24">
|
|
284
|
-
<Tooltip content="Button tooltip">
|
|
285
|
-
<Button>Button</Button>
|
|
286
|
-
</Tooltip>
|
|
287
|
-
|
|
288
|
-
<Tooltip content="Icon tooltip">
|
|
289
|
-
<button
|
|
290
|
-
type="button"
|
|
291
|
-
className="flex size-36 items-center justify-center rounded-surface-ui-small bg-bg-section text-text-primary hover:bg-bg-section-secondary"
|
|
292
|
-
>
|
|
293
|
-
<svg
|
|
294
|
-
className="size-20"
|
|
295
|
-
fill="none"
|
|
296
|
-
viewBox="0 0 24 24"
|
|
297
|
-
stroke="currentColor"
|
|
298
|
-
aria-hidden="true"
|
|
299
|
-
>
|
|
300
|
-
<path
|
|
301
|
-
strokeLinecap="round"
|
|
302
|
-
strokeLinejoin="round"
|
|
303
|
-
strokeWidth={2}
|
|
304
|
-
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
|
305
|
-
/>
|
|
306
|
-
</svg>
|
|
307
|
-
<span className="sr-only">Info</span>
|
|
308
|
-
</button>
|
|
309
|
-
</Tooltip>
|
|
310
|
-
|
|
311
|
-
<Tooltip content="Text tooltip">
|
|
312
|
-
<span className="cursor-help border-b border-dashed border-fg-muted text-text-secondary">
|
|
313
|
-
Hover this text
|
|
314
|
-
</span>
|
|
315
|
-
</Tooltip>
|
|
316
|
-
</div>
|
|
317
|
-
),
|
|
318
|
-
};
|
|
319
|
-
|
|
320
|
-
// =============================================================================
|
|
321
|
-
// Controlled
|
|
322
|
-
// =============================================================================
|
|
323
|
-
|
|
324
|
-
/**
|
|
325
|
-
* Controlled tooltip with external state management.
|
|
326
|
-
*/
|
|
327
|
-
export const Controlled: Story = {
|
|
328
|
-
render: function ControlledStory() {
|
|
329
|
-
const [open, setOpen] = React.useState(false);
|
|
330
|
-
|
|
331
|
-
return (
|
|
332
|
-
<div className="flex flex-col items-center gap-16">
|
|
333
|
-
<Tooltip
|
|
334
|
-
content="Controlled tooltip"
|
|
335
|
-
open={open}
|
|
336
|
-
onOpenChange={setOpen}
|
|
337
|
-
>
|
|
338
|
-
<Button>Hover or click button below</Button>
|
|
339
|
-
</Tooltip>
|
|
340
|
-
<Button variant="outline" onClick={() => setOpen(!open)}>
|
|
341
|
-
{open ? "Close tooltip" : "Open tooltip"}
|
|
342
|
-
</Button>
|
|
343
|
-
</div>
|
|
344
|
-
);
|
|
345
|
-
},
|
|
346
|
-
};
|
|
347
|
-
|
|
348
|
-
import * as React from "react";
|
|
@@ -1,363 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test, vi } from "vitest";
|
|
2
|
-
import { page, userEvent } from "vitest/browser";
|
|
3
|
-
import { render } from "vitest-browser-react";
|
|
4
|
-
import { Button } from "../button";
|
|
5
|
-
import {
|
|
6
|
-
Tooltip,
|
|
7
|
-
TooltipArrow,
|
|
8
|
-
TooltipParts,
|
|
9
|
-
TooltipPopup,
|
|
10
|
-
TooltipPortal,
|
|
11
|
-
TooltipPositioner,
|
|
12
|
-
TooltipProvider,
|
|
13
|
-
TooltipTrigger,
|
|
14
|
-
} from "./tooltip";
|
|
15
|
-
|
|
16
|
-
describe("Tooltip", () => {
|
|
17
|
-
describe("Accessibility", () => {
|
|
18
|
-
test("trigger element is accessible", async () => {
|
|
19
|
-
render(
|
|
20
|
-
<Tooltip content="Helpful tip">
|
|
21
|
-
<Button>Hover me</Button>
|
|
22
|
-
</Tooltip>,
|
|
23
|
-
);
|
|
24
|
-
await expect
|
|
25
|
-
.element(page.getByRole("button", { name: "Hover me" }))
|
|
26
|
-
.toBeInTheDocument();
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
test("tooltip has correct role when visible", async () => {
|
|
30
|
-
render(
|
|
31
|
-
<Tooltip content="Helpful tip" defaultOpen>
|
|
32
|
-
<Button>Hover me</Button>
|
|
33
|
-
</Tooltip>,
|
|
34
|
-
);
|
|
35
|
-
await expect
|
|
36
|
-
.element(page.getByRole("tooltip", { name: "Helpful tip" }))
|
|
37
|
-
.toBeInTheDocument();
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
test("trigger element is focusable", async () => {
|
|
41
|
-
render(
|
|
42
|
-
<Tooltip content="Helpful tip">
|
|
43
|
-
<Button>Focus me</Button>
|
|
44
|
-
</Tooltip>,
|
|
45
|
-
);
|
|
46
|
-
await userEvent.keyboard("{Tab}");
|
|
47
|
-
await expect
|
|
48
|
-
.element(page.getByRole("button", { name: "Focus me" }))
|
|
49
|
-
.toHaveFocus();
|
|
50
|
-
});
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
describe("Interactions", () => {
|
|
54
|
-
test("shows tooltip on hover", async () => {
|
|
55
|
-
render(
|
|
56
|
-
<Tooltip content="Hover tooltip">
|
|
57
|
-
<Button>Hover me</Button>
|
|
58
|
-
</Tooltip>,
|
|
59
|
-
);
|
|
60
|
-
|
|
61
|
-
// Tooltip should not be visible initially
|
|
62
|
-
await expect
|
|
63
|
-
.element(page.getByRole("tooltip", { name: "Hover tooltip" }))
|
|
64
|
-
.not.toBeInTheDocument();
|
|
65
|
-
|
|
66
|
-
// Hover over the trigger
|
|
67
|
-
await page.getByRole("button", { name: "Hover me" }).hover();
|
|
68
|
-
|
|
69
|
-
// Tooltip should now be visible
|
|
70
|
-
await expect
|
|
71
|
-
.element(page.getByRole("tooltip", { name: "Hover tooltip" }))
|
|
72
|
-
.toBeInTheDocument();
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
test("shows tooltip on focus", async () => {
|
|
76
|
-
render(
|
|
77
|
-
<Tooltip content="Focus tooltip">
|
|
78
|
-
<Button>Focus me</Button>
|
|
79
|
-
</Tooltip>,
|
|
80
|
-
);
|
|
81
|
-
|
|
82
|
-
// Tooltip should not be visible initially
|
|
83
|
-
await expect
|
|
84
|
-
.element(page.getByRole("tooltip", { name: "Focus tooltip" }))
|
|
85
|
-
.not.toBeInTheDocument();
|
|
86
|
-
|
|
87
|
-
// Focus the trigger
|
|
88
|
-
page.getByRole("button", { name: "Focus me" }).element().focus();
|
|
89
|
-
|
|
90
|
-
// Tooltip should now be visible
|
|
91
|
-
await expect
|
|
92
|
-
.element(page.getByRole("tooltip", { name: "Focus tooltip" }))
|
|
93
|
-
.toBeInTheDocument();
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
test("hides tooltip on blur", async () => {
|
|
97
|
-
render(
|
|
98
|
-
<>
|
|
99
|
-
<Tooltip content="Focus tooltip">
|
|
100
|
-
<Button>Focus me</Button>
|
|
101
|
-
</Tooltip>
|
|
102
|
-
<Button>Other button</Button>
|
|
103
|
-
</>,
|
|
104
|
-
);
|
|
105
|
-
|
|
106
|
-
// Focus the trigger to show tooltip
|
|
107
|
-
page.getByRole("button", { name: "Focus me" }).element().focus();
|
|
108
|
-
await expect
|
|
109
|
-
.element(page.getByRole("tooltip", { name: "Focus tooltip" }))
|
|
110
|
-
.toBeInTheDocument();
|
|
111
|
-
|
|
112
|
-
// Blur by focusing another element
|
|
113
|
-
page.getByRole("button", { name: "Other button" }).element().focus();
|
|
114
|
-
|
|
115
|
-
// Tooltip should be hidden
|
|
116
|
-
await expect
|
|
117
|
-
.element(page.getByRole("tooltip", { name: "Focus tooltip" }))
|
|
118
|
-
.not.toBeInTheDocument();
|
|
119
|
-
});
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
describe("Controlled State", () => {
|
|
123
|
-
test("respects controlled open state", async () => {
|
|
124
|
-
render(
|
|
125
|
-
<Tooltip content="Controlled tooltip" open={true}>
|
|
126
|
-
<Button>Trigger</Button>
|
|
127
|
-
</Tooltip>,
|
|
128
|
-
);
|
|
129
|
-
|
|
130
|
-
// Tooltip should be visible when open=true
|
|
131
|
-
await expect
|
|
132
|
-
.element(page.getByRole("tooltip", { name: "Controlled tooltip" }))
|
|
133
|
-
.toBeInTheDocument();
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
test("respects controlled closed state", async () => {
|
|
137
|
-
render(
|
|
138
|
-
<Tooltip content="Controlled tooltip" open={false}>
|
|
139
|
-
<Button>Trigger</Button>
|
|
140
|
-
</Tooltip>,
|
|
141
|
-
);
|
|
142
|
-
|
|
143
|
-
// Tooltip should not be visible when open=false
|
|
144
|
-
await expect
|
|
145
|
-
.element(page.getByRole("tooltip", { name: "Controlled tooltip" }))
|
|
146
|
-
.not.toBeInTheDocument();
|
|
147
|
-
|
|
148
|
-
// Should not show on hover when controlled
|
|
149
|
-
await page.getByRole("button", { name: "Trigger" }).hover();
|
|
150
|
-
await expect
|
|
151
|
-
.element(page.getByRole("tooltip", { name: "Controlled tooltip" }))
|
|
152
|
-
.not.toBeInTheDocument();
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
test("calls onOpenChange callback", async () => {
|
|
156
|
-
const handleOpenChange = vi.fn();
|
|
157
|
-
render(
|
|
158
|
-
<Tooltip content="Callback tooltip" onOpenChange={handleOpenChange}>
|
|
159
|
-
<Button>Trigger</Button>
|
|
160
|
-
</Tooltip>,
|
|
161
|
-
);
|
|
162
|
-
|
|
163
|
-
// Hover to trigger open
|
|
164
|
-
await page.getByRole("button", { name: "Trigger" }).hover();
|
|
165
|
-
|
|
166
|
-
// Wait for tooltip to appear (ensures callback has been called)
|
|
167
|
-
await expect
|
|
168
|
-
.element(page.getByRole("tooltip", { name: "Callback tooltip" }))
|
|
169
|
-
.toBeInTheDocument();
|
|
170
|
-
|
|
171
|
-
// Callback should have been called with true as first argument
|
|
172
|
-
// (Base UI passes additional context as second argument)
|
|
173
|
-
expect(handleOpenChange).toHaveBeenCalled();
|
|
174
|
-
expect(handleOpenChange.mock.calls[0][0]).toBe(true);
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
test("defaultOpen shows tooltip initially", async () => {
|
|
178
|
-
render(
|
|
179
|
-
<Tooltip content="Default open tooltip" defaultOpen>
|
|
180
|
-
<Button>Trigger</Button>
|
|
181
|
-
</Tooltip>,
|
|
182
|
-
);
|
|
183
|
-
|
|
184
|
-
// Tooltip should be visible initially
|
|
185
|
-
await expect
|
|
186
|
-
.element(page.getByRole("tooltip", { name: "Default open tooltip" }))
|
|
187
|
-
.toBeInTheDocument();
|
|
188
|
-
});
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
describe("Content", () => {
|
|
192
|
-
test("displays text content", async () => {
|
|
193
|
-
render(
|
|
194
|
-
<Tooltip content="Simple text" defaultOpen>
|
|
195
|
-
<Button>Trigger</Button>
|
|
196
|
-
</Tooltip>,
|
|
197
|
-
);
|
|
198
|
-
|
|
199
|
-
await expect.element(page.getByText("Simple text")).toBeInTheDocument();
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
test("displays React node content", async () => {
|
|
203
|
-
render(
|
|
204
|
-
<Tooltip
|
|
205
|
-
content={
|
|
206
|
-
<span data-testid="custom-content">
|
|
207
|
-
<strong>Bold</strong> text
|
|
208
|
-
</span>
|
|
209
|
-
}
|
|
210
|
-
defaultOpen
|
|
211
|
-
>
|
|
212
|
-
<Button>Trigger</Button>
|
|
213
|
-
</Tooltip>,
|
|
214
|
-
);
|
|
215
|
-
|
|
216
|
-
await expect
|
|
217
|
-
.element(page.getByTestId("custom-content"))
|
|
218
|
-
.toBeInTheDocument();
|
|
219
|
-
await expect.element(page.getByText("Bold")).toBeInTheDocument();
|
|
220
|
-
});
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
describe("Arrow", () => {
|
|
224
|
-
test("shows arrow by default", async () => {
|
|
225
|
-
render(
|
|
226
|
-
<Tooltip content="With arrow" defaultOpen>
|
|
227
|
-
<Button>Trigger</Button>
|
|
228
|
-
</Tooltip>,
|
|
229
|
-
);
|
|
230
|
-
|
|
231
|
-
// The arrow is an SVG element rendered by Base UI
|
|
232
|
-
const tooltip = page.getByRole("tooltip");
|
|
233
|
-
await expect.element(tooltip).toBeInTheDocument();
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
test("hides arrow when showArrow is false", async () => {
|
|
237
|
-
render(
|
|
238
|
-
<Tooltip content="Without arrow" defaultOpen showArrow={false}>
|
|
239
|
-
<Button>Trigger</Button>
|
|
240
|
-
</Tooltip>,
|
|
241
|
-
);
|
|
242
|
-
|
|
243
|
-
const tooltip = page.getByRole("tooltip");
|
|
244
|
-
await expect.element(tooltip).toBeInTheDocument();
|
|
245
|
-
});
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
describe("Compound Components", () => {
|
|
249
|
-
test("renders with compound component API", async () => {
|
|
250
|
-
render(
|
|
251
|
-
<TooltipParts defaultOpen>
|
|
252
|
-
<TooltipTrigger>
|
|
253
|
-
<Button>Compound trigger</Button>
|
|
254
|
-
</TooltipTrigger>
|
|
255
|
-
<TooltipPortal>
|
|
256
|
-
<TooltipPositioner>
|
|
257
|
-
<TooltipPopup>
|
|
258
|
-
<TooltipArrow />
|
|
259
|
-
Compound tooltip content
|
|
260
|
-
</TooltipPopup>
|
|
261
|
-
</TooltipPositioner>
|
|
262
|
-
</TooltipPortal>
|
|
263
|
-
</TooltipParts>,
|
|
264
|
-
);
|
|
265
|
-
|
|
266
|
-
await expect
|
|
267
|
-
.element(page.getByRole("button", { name: "Compound trigger" }))
|
|
268
|
-
.toBeInTheDocument();
|
|
269
|
-
await expect
|
|
270
|
-
.element(page.getByText("Compound tooltip content"))
|
|
271
|
-
.toBeInTheDocument();
|
|
272
|
-
});
|
|
273
|
-
});
|
|
274
|
-
|
|
275
|
-
describe("Provider", () => {
|
|
276
|
-
test("TooltipProvider wraps children", async () => {
|
|
277
|
-
render(
|
|
278
|
-
<TooltipProvider>
|
|
279
|
-
<Tooltip content="Provider tooltip" defaultOpen>
|
|
280
|
-
<Button>Trigger</Button>
|
|
281
|
-
</Tooltip>
|
|
282
|
-
</TooltipProvider>,
|
|
283
|
-
);
|
|
284
|
-
|
|
285
|
-
await expect
|
|
286
|
-
.element(page.getByRole("tooltip", { name: "Provider tooltip" }))
|
|
287
|
-
.toBeInTheDocument();
|
|
288
|
-
});
|
|
289
|
-
});
|
|
290
|
-
|
|
291
|
-
describe("Styles", () => {
|
|
292
|
-
test("tooltip popup has dark background", async () => {
|
|
293
|
-
render(
|
|
294
|
-
<Tooltip content="Styled tooltip" defaultOpen>
|
|
295
|
-
<Button>Trigger</Button>
|
|
296
|
-
</Tooltip>,
|
|
297
|
-
);
|
|
298
|
-
|
|
299
|
-
const tooltip = page.getByRole("tooltip");
|
|
300
|
-
await expect.element(tooltip).toBeInTheDocument();
|
|
301
|
-
|
|
302
|
-
const element = tooltip.element();
|
|
303
|
-
const styles = window.getComputedStyle(element);
|
|
304
|
-
|
|
305
|
-
// Tooltip should have a light background (not transparent)
|
|
306
|
-
expect(styles.backgroundColor).not.toBe("rgba(0, 0, 0, 0)");
|
|
307
|
-
expect(styles.backgroundColor).not.toBe("transparent");
|
|
308
|
-
});
|
|
309
|
-
|
|
310
|
-
test("tooltip has border radius", async () => {
|
|
311
|
-
render(
|
|
312
|
-
<Tooltip content="Styled tooltip" defaultOpen>
|
|
313
|
-
<Button>Trigger</Button>
|
|
314
|
-
</Tooltip>,
|
|
315
|
-
);
|
|
316
|
-
|
|
317
|
-
const tooltip = page.getByRole("tooltip");
|
|
318
|
-
await expect.element(tooltip).toBeInTheDocument();
|
|
319
|
-
|
|
320
|
-
const element = tooltip.element();
|
|
321
|
-
const styles = window.getComputedStyle(element);
|
|
322
|
-
|
|
323
|
-
// Should have border radius
|
|
324
|
-
const borderRadius = parseFloat(styles.borderRadius);
|
|
325
|
-
expect(borderRadius).toBeGreaterThan(0);
|
|
326
|
-
});
|
|
327
|
-
|
|
328
|
-
test("tooltip has shadow", async () => {
|
|
329
|
-
render(
|
|
330
|
-
<Tooltip content="Styled tooltip" defaultOpen>
|
|
331
|
-
<Button>Trigger</Button>
|
|
332
|
-
</Tooltip>,
|
|
333
|
-
);
|
|
334
|
-
|
|
335
|
-
const tooltip = page.getByRole("tooltip");
|
|
336
|
-
await expect.element(tooltip).toBeInTheDocument();
|
|
337
|
-
|
|
338
|
-
const element = tooltip.element();
|
|
339
|
-
const styles = window.getComputedStyle(element);
|
|
340
|
-
|
|
341
|
-
// Should have a box shadow
|
|
342
|
-
expect(styles.boxShadow).not.toBe("none");
|
|
343
|
-
});
|
|
344
|
-
|
|
345
|
-
test("tooltip has high z-index", async () => {
|
|
346
|
-
render(
|
|
347
|
-
<Tooltip content="Styled tooltip" defaultOpen>
|
|
348
|
-
<Button>Trigger</Button>
|
|
349
|
-
</Tooltip>,
|
|
350
|
-
);
|
|
351
|
-
|
|
352
|
-
const tooltip = page.getByRole("tooltip");
|
|
353
|
-
await expect.element(tooltip).toBeInTheDocument();
|
|
354
|
-
|
|
355
|
-
const element = tooltip.element();
|
|
356
|
-
const styles = window.getComputedStyle(element);
|
|
357
|
-
|
|
358
|
-
// Should have z-index of 50 or higher
|
|
359
|
-
const zIndex = parseInt(styles.zIndex, 10);
|
|
360
|
-
expect(zIndex).toBeGreaterThanOrEqual(50);
|
|
361
|
-
});
|
|
362
|
-
});
|
|
363
|
-
});
|