@fuf-stack/pixels 0.0.3 → 0.0.5
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/.eslintrc +16 -0
- package/.storybook/main.ts +8 -0
- package/.storybook/preview-head.html +3 -0
- package/.storybook/preview.tsx +7 -0
- package/CHANGELOG.md +36 -0
- package/Globals.d.ts +3 -0
- package/dist/Button/Button.cjs +3 -3
- package/dist/Button/Button.cjs.map +1 -1
- package/dist/Button/Button.js +2 -2
- package/dist/Button/index.cjs +5 -5
- package/dist/Button/index.cjs.map +1 -1
- package/dist/Button/index.js +3 -3
- package/dist/Button/index.js.map +1 -1
- package/dist/Button/subcomponents/LoadingSpinner.cjs +1 -1
- package/dist/Button/subcomponents/LoadingSpinner.cjs.map +1 -1
- package/dist/Button/subcomponents/LoadingSpinner.js +1 -1
- package/dist/Card/Card.cjs +1 -1
- package/dist/Card/Card.cjs.map +1 -1
- package/dist/Card/Card.js +1 -1
- package/dist/Card/index.cjs +3 -3
- package/dist/Card/index.cjs.map +1 -1
- package/dist/Card/index.js +2 -2
- package/dist/Card/index.js.map +1 -1
- package/dist/{chunk-ZXTDGCUF.js → chunk-WQN756O7.js} +3 -3
- package/dist/chunk-WQN756O7.js.map +1 -0
- package/dist/{chunk-XPTSDDXG.js → chunk-XWTXH2TR.js} +2 -2
- package/dist/chunk-XWTXH2TR.js.map +1 -0
- package/dist/{chunk-ZFEVTQWW.js → chunk-YOPQSZ46.js} +2 -2
- package/dist/chunk-YOPQSZ46.js.map +1 -0
- package/package.json +9 -8
- package/src/components/Button/Button.stories.tsx +75 -0
- package/src/components/Button/Button.test.tsx +9 -0
- package/src/components/Button/Button.tsx +74 -0
- package/src/components/Button/__snapshots__/Button.test.tsx.snap +235 -0
- package/src/components/Button/index.ts +7 -0
- package/src/components/Button/subcomponents/LoadingSpinner.tsx +26 -0
- package/src/components/Card/Card.stories.tsx +56 -0
- package/src/components/Card/Card.test.tsx +9 -0
- package/src/components/Card/Card.tsx +120 -0
- package/src/components/Card/__snapshots__/Card.test.tsx.snap +94 -0
- package/src/components/Card/index.ts +3 -0
- package/tailwind.config.js +7 -0
- package/tsconfig.json +7 -0
- package/tsup.config.ts +15 -0
- package/vitest.config.ts +9 -0
- package/dist/chunk-XPTSDDXG.js.map +0 -1
- package/dist/chunk-ZFEVTQWW.js.map +0 -1
- package/dist/chunk-ZXTDGCUF.js.map +0 -1
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { ButtonProps as NextButtonProps } from '@nextui-org/button';
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
import { Button as NextButton } from '@nextui-org/button';
|
|
5
|
+
import cn from 'classnames';
|
|
6
|
+
|
|
7
|
+
import LoadingSpinner from './subcomponents/LoadingSpinner';
|
|
8
|
+
|
|
9
|
+
export interface ButtonProps {
|
|
10
|
+
/** sets HTML aria-label attribute */
|
|
11
|
+
ariaLabel?: string;
|
|
12
|
+
/** child components */
|
|
13
|
+
children?: ReactNode;
|
|
14
|
+
/** CSS class name */
|
|
15
|
+
className?: string | string[];
|
|
16
|
+
/** next ui button color */
|
|
17
|
+
color?: NextButtonProps['color'];
|
|
18
|
+
/** disables function of the button. */
|
|
19
|
+
disabled?: boolean;
|
|
20
|
+
/** If set loading animation is shown */
|
|
21
|
+
loading?: boolean;
|
|
22
|
+
/** optional icon */
|
|
23
|
+
icon?: ReactNode;
|
|
24
|
+
/** on click event */
|
|
25
|
+
onClick?: NextButtonProps['onPress'];
|
|
26
|
+
/** 3 size options */
|
|
27
|
+
size?: NextButtonProps['size'];
|
|
28
|
+
/** HTML data-testid attribute used in e2e tests */
|
|
29
|
+
testId?: string;
|
|
30
|
+
/** sets the button type. */
|
|
31
|
+
type?: 'button' | 'submit' | 'reset' | undefined;
|
|
32
|
+
/** next ui button variants */
|
|
33
|
+
variant?: NextButtonProps['variant'];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Button component based on [NextUI Button](https://nextui.org/docs/components/button)
|
|
38
|
+
*/
|
|
39
|
+
const Button = ({
|
|
40
|
+
ariaLabel = undefined,
|
|
41
|
+
children = undefined,
|
|
42
|
+
className = undefined,
|
|
43
|
+
color = 'default',
|
|
44
|
+
disabled = false,
|
|
45
|
+
icon = undefined,
|
|
46
|
+
loading = false,
|
|
47
|
+
onClick = undefined,
|
|
48
|
+
size = undefined,
|
|
49
|
+
testId = undefined,
|
|
50
|
+
type = undefined,
|
|
51
|
+
variant = 'solid',
|
|
52
|
+
}: ButtonProps) => {
|
|
53
|
+
return (
|
|
54
|
+
<NextButton
|
|
55
|
+
aria-label={ariaLabel}
|
|
56
|
+
className={cn(className)}
|
|
57
|
+
color={color}
|
|
58
|
+
data-testid={testId}
|
|
59
|
+
isDisabled={disabled}
|
|
60
|
+
isIconOnly={!!(icon && !children)}
|
|
61
|
+
isLoading={loading}
|
|
62
|
+
onPress={onClick}
|
|
63
|
+
size={size}
|
|
64
|
+
spinner={<LoadingSpinner />}
|
|
65
|
+
type={type}
|
|
66
|
+
variant={variant}
|
|
67
|
+
>
|
|
68
|
+
{icon}
|
|
69
|
+
{children}
|
|
70
|
+
</NextButton>
|
|
71
|
+
);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export default Button;
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`Story Snapshots > AllColors 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div
|
|
6
|
+
style="margin-top: 10px;"
|
|
7
|
+
>
|
|
8
|
+
<button
|
|
9
|
+
class="z-0 group relative inline-flex items-center justify-center box-border appearance-none select-none whitespace-nowrap font-normal subpixel-antialiased overflow-hidden tap-highlight-transparent outline-none data-[focus-visible=true]:z-10 data-[focus-visible=true]:outline-2 data-[focus-visible=true]:outline-focus data-[focus-visible=true]:outline-offset-2 px-unit-4 min-w-unit-20 h-unit-10 text-small gap-unit-2 rounded-medium [&>svg]:max-w-[theme(spacing.unit-8)] data-[pressed=true]:scale-[0.97] transition-transform-colors-opacity motion-reduce:transition-none bg-default text-default-foreground data-[hover=true]:opacity-hover"
|
|
10
|
+
type="button"
|
|
11
|
+
>
|
|
12
|
+
default
|
|
13
|
+
</button>
|
|
14
|
+
</div>
|
|
15
|
+
<div
|
|
16
|
+
style="margin-top: 10px;"
|
|
17
|
+
>
|
|
18
|
+
<button
|
|
19
|
+
class="z-0 group relative inline-flex items-center justify-center box-border appearance-none select-none whitespace-nowrap font-normal subpixel-antialiased overflow-hidden tap-highlight-transparent outline-none data-[focus-visible=true]:z-10 data-[focus-visible=true]:outline-2 data-[focus-visible=true]:outline-focus data-[focus-visible=true]:outline-offset-2 px-unit-4 min-w-unit-20 h-unit-10 text-small gap-unit-2 rounded-medium [&>svg]:max-w-[theme(spacing.unit-8)] data-[pressed=true]:scale-[0.97] transition-transform-colors-opacity motion-reduce:transition-none bg-primary text-primary-foreground data-[hover=true]:opacity-hover"
|
|
20
|
+
type="button"
|
|
21
|
+
>
|
|
22
|
+
primary
|
|
23
|
+
</button>
|
|
24
|
+
</div>
|
|
25
|
+
<div
|
|
26
|
+
style="margin-top: 10px;"
|
|
27
|
+
>
|
|
28
|
+
<button
|
|
29
|
+
class="z-0 group relative inline-flex items-center justify-center box-border appearance-none select-none whitespace-nowrap font-normal subpixel-antialiased overflow-hidden tap-highlight-transparent outline-none data-[focus-visible=true]:z-10 data-[focus-visible=true]:outline-2 data-[focus-visible=true]:outline-focus data-[focus-visible=true]:outline-offset-2 px-unit-4 min-w-unit-20 h-unit-10 text-small gap-unit-2 rounded-medium [&>svg]:max-w-[theme(spacing.unit-8)] data-[pressed=true]:scale-[0.97] transition-transform-colors-opacity motion-reduce:transition-none bg-secondary text-secondary-foreground data-[hover=true]:opacity-hover"
|
|
30
|
+
type="button"
|
|
31
|
+
>
|
|
32
|
+
secondary
|
|
33
|
+
</button>
|
|
34
|
+
</div>
|
|
35
|
+
<div
|
|
36
|
+
style="margin-top: 10px;"
|
|
37
|
+
>
|
|
38
|
+
<button
|
|
39
|
+
class="z-0 group relative inline-flex items-center justify-center box-border appearance-none select-none whitespace-nowrap font-normal subpixel-antialiased overflow-hidden tap-highlight-transparent outline-none data-[focus-visible=true]:z-10 data-[focus-visible=true]:outline-2 data-[focus-visible=true]:outline-focus data-[focus-visible=true]:outline-offset-2 px-unit-4 min-w-unit-20 h-unit-10 text-small gap-unit-2 rounded-medium [&>svg]:max-w-[theme(spacing.unit-8)] data-[pressed=true]:scale-[0.97] transition-transform-colors-opacity motion-reduce:transition-none bg-success text-success-foreground data-[hover=true]:opacity-hover"
|
|
40
|
+
type="button"
|
|
41
|
+
>
|
|
42
|
+
success
|
|
43
|
+
</button>
|
|
44
|
+
</div>
|
|
45
|
+
<div
|
|
46
|
+
style="margin-top: 10px;"
|
|
47
|
+
>
|
|
48
|
+
<button
|
|
49
|
+
class="z-0 group relative inline-flex items-center justify-center box-border appearance-none select-none whitespace-nowrap font-normal subpixel-antialiased overflow-hidden tap-highlight-transparent outline-none data-[focus-visible=true]:z-10 data-[focus-visible=true]:outline-2 data-[focus-visible=true]:outline-focus data-[focus-visible=true]:outline-offset-2 px-unit-4 min-w-unit-20 h-unit-10 text-small gap-unit-2 rounded-medium [&>svg]:max-w-[theme(spacing.unit-8)] data-[pressed=true]:scale-[0.97] transition-transform-colors-opacity motion-reduce:transition-none bg-warning text-warning-foreground data-[hover=true]:opacity-hover"
|
|
50
|
+
type="button"
|
|
51
|
+
>
|
|
52
|
+
warning
|
|
53
|
+
</button>
|
|
54
|
+
</div>
|
|
55
|
+
<div
|
|
56
|
+
style="margin-top: 10px;"
|
|
57
|
+
>
|
|
58
|
+
<button
|
|
59
|
+
class="z-0 group relative inline-flex items-center justify-center box-border appearance-none select-none whitespace-nowrap font-normal subpixel-antialiased overflow-hidden tap-highlight-transparent outline-none data-[focus-visible=true]:z-10 data-[focus-visible=true]:outline-2 data-[focus-visible=true]:outline-focus data-[focus-visible=true]:outline-offset-2 px-unit-4 min-w-unit-20 h-unit-10 text-small gap-unit-2 rounded-medium [&>svg]:max-w-[theme(spacing.unit-8)] data-[pressed=true]:scale-[0.97] transition-transform-colors-opacity motion-reduce:transition-none bg-danger text-danger-foreground data-[hover=true]:opacity-hover"
|
|
60
|
+
type="button"
|
|
61
|
+
>
|
|
62
|
+
danger
|
|
63
|
+
</button>
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
`;
|
|
67
|
+
|
|
68
|
+
exports[`Story Snapshots > AllSizes 1`] = `
|
|
69
|
+
<div>
|
|
70
|
+
<div
|
|
71
|
+
style="margin-top: 10px;"
|
|
72
|
+
>
|
|
73
|
+
<button
|
|
74
|
+
class="z-0 group relative inline-flex items-center justify-center box-border appearance-none select-none whitespace-nowrap font-normal subpixel-antialiased overflow-hidden tap-highlight-transparent outline-none data-[focus-visible=true]:z-10 data-[focus-visible=true]:outline-2 data-[focus-visible=true]:outline-focus data-[focus-visible=true]:outline-offset-2 px-unit-3 min-w-unit-16 h-unit-8 text-tiny gap-unit-2 rounded-small [&>svg]:max-w-[theme(spacing.unit-8)] data-[pressed=true]:scale-[0.97] transition-transform-colors-opacity motion-reduce:transition-none bg-default text-default-foreground data-[hover=true]:opacity-hover"
|
|
75
|
+
type="button"
|
|
76
|
+
>
|
|
77
|
+
sm
|
|
78
|
+
</button>
|
|
79
|
+
</div>
|
|
80
|
+
<div
|
|
81
|
+
style="margin-top: 10px;"
|
|
82
|
+
>
|
|
83
|
+
<button
|
|
84
|
+
class="z-0 group relative inline-flex items-center justify-center box-border appearance-none select-none whitespace-nowrap font-normal subpixel-antialiased overflow-hidden tap-highlight-transparent outline-none data-[focus-visible=true]:z-10 data-[focus-visible=true]:outline-2 data-[focus-visible=true]:outline-focus data-[focus-visible=true]:outline-offset-2 px-unit-4 min-w-unit-20 h-unit-10 text-small gap-unit-2 rounded-medium [&>svg]:max-w-[theme(spacing.unit-8)] data-[pressed=true]:scale-[0.97] transition-transform-colors-opacity motion-reduce:transition-none bg-default text-default-foreground data-[hover=true]:opacity-hover"
|
|
85
|
+
type="button"
|
|
86
|
+
>
|
|
87
|
+
md
|
|
88
|
+
</button>
|
|
89
|
+
</div>
|
|
90
|
+
<div
|
|
91
|
+
style="margin-top: 10px;"
|
|
92
|
+
>
|
|
93
|
+
<button
|
|
94
|
+
class="z-0 group relative inline-flex items-center justify-center box-border appearance-none select-none whitespace-nowrap font-normal subpixel-antialiased overflow-hidden tap-highlight-transparent outline-none data-[focus-visible=true]:z-10 data-[focus-visible=true]:outline-2 data-[focus-visible=true]:outline-focus data-[focus-visible=true]:outline-offset-2 px-unit-6 min-w-unit-24 h-unit-12 text-medium gap-unit-3 rounded-large [&>svg]:max-w-[theme(spacing.unit-8)] data-[pressed=true]:scale-[0.97] transition-transform-colors-opacity motion-reduce:transition-none bg-default text-default-foreground data-[hover=true]:opacity-hover"
|
|
95
|
+
type="button"
|
|
96
|
+
>
|
|
97
|
+
lg
|
|
98
|
+
</button>
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
`;
|
|
102
|
+
|
|
103
|
+
exports[`Story Snapshots > AllVariants 1`] = `
|
|
104
|
+
<div>
|
|
105
|
+
<div
|
|
106
|
+
style="margin-top: 10px;"
|
|
107
|
+
>
|
|
108
|
+
<button
|
|
109
|
+
class="z-0 group relative inline-flex items-center justify-center box-border appearance-none select-none whitespace-nowrap font-normal subpixel-antialiased overflow-hidden tap-highlight-transparent outline-none data-[focus-visible=true]:z-10 data-[focus-visible=true]:outline-2 data-[focus-visible=true]:outline-focus data-[focus-visible=true]:outline-offset-2 px-unit-4 min-w-unit-20 h-unit-10 text-small gap-unit-2 rounded-medium [&>svg]:max-w-[theme(spacing.unit-8)] data-[pressed=true]:scale-[0.97] transition-transform-colors-opacity motion-reduce:transition-none bg-default text-default-foreground data-[hover=true]:opacity-hover"
|
|
110
|
+
type="button"
|
|
111
|
+
>
|
|
112
|
+
solid
|
|
113
|
+
</button>
|
|
114
|
+
</div>
|
|
115
|
+
<div
|
|
116
|
+
style="margin-top: 10px;"
|
|
117
|
+
>
|
|
118
|
+
<button
|
|
119
|
+
class="z-0 group relative inline-flex items-center justify-center box-border appearance-none select-none whitespace-nowrap font-normal subpixel-antialiased overflow-hidden tap-highlight-transparent outline-none data-[focus-visible=true]:z-10 data-[focus-visible=true]:outline-2 data-[focus-visible=true]:outline-focus data-[focus-visible=true]:outline-offset-2 border-medium px-unit-4 min-w-unit-20 h-unit-10 text-small gap-unit-2 rounded-medium [&>svg]:max-w-[theme(spacing.unit-8)] data-[pressed=true]:scale-[0.97] transition-transform-colors-opacity motion-reduce:transition-none bg-transparent border-default text-foreground data-[hover=true]:opacity-hover"
|
|
120
|
+
type="button"
|
|
121
|
+
>
|
|
122
|
+
bordered
|
|
123
|
+
</button>
|
|
124
|
+
</div>
|
|
125
|
+
<div
|
|
126
|
+
style="margin-top: 10px;"
|
|
127
|
+
>
|
|
128
|
+
<button
|
|
129
|
+
class="z-0 group relative inline-flex items-center justify-center box-border appearance-none select-none whitespace-nowrap font-normal subpixel-antialiased overflow-hidden tap-highlight-transparent outline-none data-[focus-visible=true]:z-10 data-[focus-visible=true]:outline-2 data-[focus-visible=true]:outline-focus data-[focus-visible=true]:outline-offset-2 px-unit-4 min-w-unit-20 h-unit-10 text-small gap-unit-2 rounded-medium [&>svg]:max-w-[theme(spacing.unit-8)] data-[pressed=true]:scale-[0.97] transition-transform-colors-opacity motion-reduce:transition-none bg-transparent text-default-foreground data-[hover=true]:bg-default/40"
|
|
130
|
+
type="button"
|
|
131
|
+
>
|
|
132
|
+
light
|
|
133
|
+
</button>
|
|
134
|
+
</div>
|
|
135
|
+
<div
|
|
136
|
+
style="margin-top: 10px;"
|
|
137
|
+
>
|
|
138
|
+
<button
|
|
139
|
+
class="z-0 group relative inline-flex items-center justify-center box-border appearance-none select-none whitespace-nowrap font-normal subpixel-antialiased overflow-hidden tap-highlight-transparent outline-none data-[focus-visible=true]:z-10 data-[focus-visible=true]:outline-2 data-[focus-visible=true]:outline-focus data-[focus-visible=true]:outline-offset-2 px-unit-4 min-w-unit-20 h-unit-10 text-small gap-unit-2 rounded-medium [&>svg]:max-w-[theme(spacing.unit-8)] data-[pressed=true]:scale-[0.97] transition-transform-colors-opacity motion-reduce:transition-none bg-default/40 text-default-foreground data-[hover=true]:opacity-hover"
|
|
140
|
+
type="button"
|
|
141
|
+
>
|
|
142
|
+
flat
|
|
143
|
+
</button>
|
|
144
|
+
</div>
|
|
145
|
+
<div
|
|
146
|
+
style="margin-top: 10px;"
|
|
147
|
+
>
|
|
148
|
+
<button
|
|
149
|
+
class="z-0 group relative inline-flex items-center justify-center box-border appearance-none select-none whitespace-nowrap font-normal subpixel-antialiased overflow-hidden tap-highlight-transparent outline-none data-[focus-visible=true]:z-10 data-[focus-visible=true]:outline-2 data-[focus-visible=true]:outline-focus data-[focus-visible=true]:outline-offset-2 border-medium px-unit-4 min-w-unit-20 h-unit-10 text-small gap-unit-2 rounded-medium [&>svg]:max-w-[theme(spacing.unit-8)] data-[pressed=true]:scale-[0.97] transition-transform-colors-opacity motion-reduce:transition-none border-default bg-default-100 text-default-foreground data-[hover=true]:opacity-hover"
|
|
150
|
+
type="button"
|
|
151
|
+
>
|
|
152
|
+
faded
|
|
153
|
+
</button>
|
|
154
|
+
</div>
|
|
155
|
+
<div
|
|
156
|
+
style="margin-top: 10px;"
|
|
157
|
+
>
|
|
158
|
+
<button
|
|
159
|
+
class="z-0 group relative inline-flex items-center justify-center box-border appearance-none select-none whitespace-nowrap font-normal subpixel-antialiased overflow-hidden tap-highlight-transparent outline-none data-[focus-visible=true]:z-10 data-[focus-visible=true]:outline-2 data-[focus-visible=true]:outline-focus data-[focus-visible=true]:outline-offset-2 px-unit-4 min-w-unit-20 h-unit-10 text-small gap-unit-2 rounded-medium [&>svg]:max-w-[theme(spacing.unit-8)] data-[pressed=true]:scale-[0.97] transition-transform-colors-opacity motion-reduce:transition-none shadow-lg shadow-default/50 bg-default text-default-foreground data-[hover=true]:opacity-hover"
|
|
160
|
+
type="button"
|
|
161
|
+
>
|
|
162
|
+
shadow
|
|
163
|
+
</button>
|
|
164
|
+
</div>
|
|
165
|
+
<div
|
|
166
|
+
style="margin-top: 10px;"
|
|
167
|
+
>
|
|
168
|
+
<button
|
|
169
|
+
class="z-0 group relative inline-flex items-center justify-center box-border appearance-none select-none whitespace-nowrap font-normal subpixel-antialiased overflow-hidden tap-highlight-transparent outline-none data-[focus-visible=true]:z-10 data-[focus-visible=true]:outline-2 data-[focus-visible=true]:outline-focus data-[focus-visible=true]:outline-offset-2 border-medium bg-transparent px-unit-4 min-w-unit-20 h-unit-10 text-small gap-unit-2 rounded-medium [&>svg]:max-w-[theme(spacing.unit-8)] data-[pressed=true]:scale-[0.97] transition-transform-colors-opacity motion-reduce:transition-none border-default text-default-foreground hover:!bg-default"
|
|
170
|
+
type="button"
|
|
171
|
+
>
|
|
172
|
+
ghost
|
|
173
|
+
</button>
|
|
174
|
+
</div>
|
|
175
|
+
</div>
|
|
176
|
+
`;
|
|
177
|
+
|
|
178
|
+
exports[`Story Snapshots > Default 1`] = `
|
|
179
|
+
<div>
|
|
180
|
+
<button
|
|
181
|
+
class="z-0 group relative inline-flex items-center justify-center box-border appearance-none select-none whitespace-nowrap font-normal subpixel-antialiased overflow-hidden tap-highlight-transparent outline-none data-[focus-visible=true]:z-10 data-[focus-visible=true]:outline-2 data-[focus-visible=true]:outline-focus data-[focus-visible=true]:outline-offset-2 px-unit-4 min-w-unit-20 h-unit-10 text-small gap-unit-2 rounded-medium [&>svg]:max-w-[theme(spacing.unit-8)] data-[pressed=true]:scale-[0.97] transition-transform-colors-opacity motion-reduce:transition-none bg-default text-default-foreground data-[hover=true]:opacity-hover"
|
|
182
|
+
data-testid="some-test-id"
|
|
183
|
+
type="button"
|
|
184
|
+
>
|
|
185
|
+
Button
|
|
186
|
+
</button>
|
|
187
|
+
</div>
|
|
188
|
+
`;
|
|
189
|
+
|
|
190
|
+
exports[`Story Snapshots > Disabled 1`] = `
|
|
191
|
+
<div>
|
|
192
|
+
<button
|
|
193
|
+
class="z-0 group relative inline-flex items-center justify-center box-border appearance-none select-none whitespace-nowrap font-normal subpixel-antialiased overflow-hidden tap-highlight-transparent outline-none data-[focus-visible=true]:z-10 data-[focus-visible=true]:outline-2 data-[focus-visible=true]:outline-focus data-[focus-visible=true]:outline-offset-2 px-unit-4 min-w-unit-20 h-unit-10 text-small gap-unit-2 rounded-medium opacity-disabled pointer-events-none [&>svg]:max-w-[theme(spacing.unit-8)] data-[pressed=true]:scale-[0.97] transition-transform-colors-opacity motion-reduce:transition-none bg-default text-default-foreground data-[hover=true]:opacity-hover"
|
|
194
|
+
data-disabled="true"
|
|
195
|
+
disabled=""
|
|
196
|
+
type="button"
|
|
197
|
+
>
|
|
198
|
+
Button
|
|
199
|
+
</button>
|
|
200
|
+
</div>
|
|
201
|
+
`;
|
|
202
|
+
|
|
203
|
+
exports[`Story Snapshots > Loading 1`] = `
|
|
204
|
+
<div>
|
|
205
|
+
<button
|
|
206
|
+
class="z-0 group relative inline-flex items-center justify-center box-border appearance-none select-none whitespace-nowrap font-normal subpixel-antialiased overflow-hidden tap-highlight-transparent outline-none data-[focus-visible=true]:z-10 data-[focus-visible=true]:outline-2 data-[focus-visible=true]:outline-focus data-[focus-visible=true]:outline-offset-2 px-unit-4 min-w-unit-20 h-unit-10 text-small gap-unit-2 rounded-medium opacity-disabled pointer-events-none [&>svg]:max-w-[theme(spacing.unit-8)] data-[pressed=true]:scale-[0.97] transition-transform-colors-opacity motion-reduce:transition-none bg-default text-default-foreground data-[hover=true]:opacity-hover"
|
|
207
|
+
data-disabled="true"
|
|
208
|
+
data-loading="true"
|
|
209
|
+
disabled=""
|
|
210
|
+
type="button"
|
|
211
|
+
>
|
|
212
|
+
<svg
|
|
213
|
+
class="animate-spin h-5 w-5 text-current"
|
|
214
|
+
fill="none"
|
|
215
|
+
viewBox="0 0 24 24"
|
|
216
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
217
|
+
>
|
|
218
|
+
<circle
|
|
219
|
+
class="opacity-25"
|
|
220
|
+
cx="12"
|
|
221
|
+
cy="12"
|
|
222
|
+
r="10"
|
|
223
|
+
stroke="currentColor"
|
|
224
|
+
stroke-width="4"
|
|
225
|
+
/>
|
|
226
|
+
<path
|
|
227
|
+
class="opacity-75"
|
|
228
|
+
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
|
229
|
+
fill="currentColor"
|
|
230
|
+
/>
|
|
231
|
+
</svg>
|
|
232
|
+
Button
|
|
233
|
+
</button>
|
|
234
|
+
</div>
|
|
235
|
+
`;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* svg loading spinner for button
|
|
3
|
+
* @see https://nextui.org/docs/components/button#loading
|
|
4
|
+
* */
|
|
5
|
+
export default () => (
|
|
6
|
+
<svg
|
|
7
|
+
className="animate-spin h-5 w-5 text-current"
|
|
8
|
+
fill="none"
|
|
9
|
+
viewBox="0 0 24 24"
|
|
10
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
11
|
+
>
|
|
12
|
+
<circle
|
|
13
|
+
className="opacity-25"
|
|
14
|
+
cx="12"
|
|
15
|
+
cy="12"
|
|
16
|
+
r="10"
|
|
17
|
+
stroke="currentColor"
|
|
18
|
+
strokeWidth="4"
|
|
19
|
+
/>
|
|
20
|
+
<path
|
|
21
|
+
className="opacity-75"
|
|
22
|
+
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
|
23
|
+
fill="currentColor"
|
|
24
|
+
/>
|
|
25
|
+
</svg>
|
|
26
|
+
);
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
|
|
3
|
+
import Card from './Card';
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof Card> = {
|
|
6
|
+
title: 'pixels/Card',
|
|
7
|
+
component: Card,
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export default meta;
|
|
11
|
+
type Story = StoryObj<typeof Card>;
|
|
12
|
+
|
|
13
|
+
export const Default: Story = {
|
|
14
|
+
args: {
|
|
15
|
+
children: (
|
|
16
|
+
<p className="w-96">
|
|
17
|
+
Lorem commodo nulla adipisicing cillum Lorem sunt laboris exercitation
|
|
18
|
+
esse. Exercitation ut cillum cupidatat deserunt occaecat pariatur
|
|
19
|
+
laborum ut reprehenderit veniam. Culpa fugiat aliqua consectetur sit
|
|
20
|
+
esse.
|
|
21
|
+
</p>
|
|
22
|
+
),
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const FooterAndHeader: Story = {
|
|
27
|
+
args: {
|
|
28
|
+
footer: 'Footer',
|
|
29
|
+
header: 'Header',
|
|
30
|
+
children: (
|
|
31
|
+
<p className="w-96">
|
|
32
|
+
Lorem commodo nulla adipisicing cillum Lorem sunt laboris exercitation
|
|
33
|
+
esse. Exercitation ut cillum cupidatat deserunt occaecat pariatur
|
|
34
|
+
laborum ut reprehenderit veniam. Culpa fugiat aliqua consectetur sit
|
|
35
|
+
esse.
|
|
36
|
+
</p>
|
|
37
|
+
),
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export const CustomSlotStyles: Story = {
|
|
42
|
+
args: {
|
|
43
|
+
footer: 'Footer',
|
|
44
|
+
header: 'Header',
|
|
45
|
+
children: (
|
|
46
|
+
<p className="w-96">
|
|
47
|
+
Lorem commodo nulla adipisicing cillum Lorem sunt laboris exercitatio
|
|
48
|
+
</p>
|
|
49
|
+
),
|
|
50
|
+
className: {
|
|
51
|
+
base: 'text-blue-400',
|
|
52
|
+
body: 'text-green-400',
|
|
53
|
+
divider: 'bg-yellow-400',
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
};
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { VariantProps } from 'tailwind-variants';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
Card as NextCard,
|
|
6
|
+
CardBody as NextCardBody,
|
|
7
|
+
CardFooter as NextCardFooter,
|
|
8
|
+
CardHeader as NextCardHeader,
|
|
9
|
+
} from '@nextui-org/card';
|
|
10
|
+
import { Divider as NextDivider } from '@nextui-org/divider';
|
|
11
|
+
import createDebug from 'debug';
|
|
12
|
+
import { tv } from 'tailwind-variants';
|
|
13
|
+
|
|
14
|
+
const debug = createDebug('component:Card');
|
|
15
|
+
|
|
16
|
+
// card styling variants
|
|
17
|
+
export const cardVariants = tv({
|
|
18
|
+
slots: {
|
|
19
|
+
base: 'border border-slate-300',
|
|
20
|
+
body: '',
|
|
21
|
+
divider: 'my-0 bg-slate-300',
|
|
22
|
+
footer: '',
|
|
23
|
+
header: 'text-base font-semibold',
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
type CardVariantProps = VariantProps<typeof cardVariants>;
|
|
28
|
+
type CardVariantSlots = Partial<
|
|
29
|
+
Record<keyof ReturnType<typeof cardVariants>, string>
|
|
30
|
+
>;
|
|
31
|
+
|
|
32
|
+
export interface CardProps extends CardVariantProps {
|
|
33
|
+
/** child components */
|
|
34
|
+
children?: ReactNode;
|
|
35
|
+
/** CSS class name */
|
|
36
|
+
className?: string | CardVariantSlots;
|
|
37
|
+
/** footer content */
|
|
38
|
+
footer?: ReactNode;
|
|
39
|
+
/** header content */
|
|
40
|
+
header?: ReactNode;
|
|
41
|
+
/** HTML data-testid attribute used in e2e tests */
|
|
42
|
+
testId?: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Card component based on [NextUI Card](https://nextui.org/docs/components/card)
|
|
47
|
+
*/
|
|
48
|
+
const Card = ({
|
|
49
|
+
children = null,
|
|
50
|
+
className = undefined,
|
|
51
|
+
testId = undefined,
|
|
52
|
+
header = undefined,
|
|
53
|
+
footer = undefined,
|
|
54
|
+
}: CardProps) => {
|
|
55
|
+
debug('Card', { className, testId });
|
|
56
|
+
const {
|
|
57
|
+
base: baseSlot,
|
|
58
|
+
body: bodySlot,
|
|
59
|
+
divider: dividerSlot,
|
|
60
|
+
footer: footerSlot,
|
|
61
|
+
header: headerSlot,
|
|
62
|
+
} = cardVariants();
|
|
63
|
+
|
|
64
|
+
return (
|
|
65
|
+
<NextCard
|
|
66
|
+
data-testid={testId && `card_${testId}`}
|
|
67
|
+
className={baseSlot({
|
|
68
|
+
className: typeof className === 'object' ? className.base : className,
|
|
69
|
+
})}
|
|
70
|
+
fullWidth
|
|
71
|
+
radius="sm"
|
|
72
|
+
shadow="none"
|
|
73
|
+
>
|
|
74
|
+
{header && (
|
|
75
|
+
<>
|
|
76
|
+
<NextCardHeader
|
|
77
|
+
data-testid={testId && `card_header_${testId}`}
|
|
78
|
+
className={headerSlot({
|
|
79
|
+
className: typeof className === 'object' && className.header,
|
|
80
|
+
})}
|
|
81
|
+
>
|
|
82
|
+
{header}
|
|
83
|
+
</NextCardHeader>
|
|
84
|
+
<NextDivider
|
|
85
|
+
className={dividerSlot({
|
|
86
|
+
className: typeof className === 'object' && className.divider,
|
|
87
|
+
})}
|
|
88
|
+
/>
|
|
89
|
+
</>
|
|
90
|
+
)}
|
|
91
|
+
<NextCardBody
|
|
92
|
+
data-testid={testId && `card_body_${testId}`}
|
|
93
|
+
className={bodySlot({
|
|
94
|
+
className: typeof className === 'object' && className.body,
|
|
95
|
+
})}
|
|
96
|
+
>
|
|
97
|
+
{children}
|
|
98
|
+
</NextCardBody>
|
|
99
|
+
{footer && (
|
|
100
|
+
<>
|
|
101
|
+
<NextDivider
|
|
102
|
+
className={dividerSlot({
|
|
103
|
+
className: typeof className === 'object' && className.divider,
|
|
104
|
+
})}
|
|
105
|
+
/>
|
|
106
|
+
<NextCardFooter
|
|
107
|
+
data-testid={testId && `card_footer_${testId}`}
|
|
108
|
+
className={footerSlot({
|
|
109
|
+
className: typeof className === 'object' && className.footer,
|
|
110
|
+
})}
|
|
111
|
+
>
|
|
112
|
+
{footer}
|
|
113
|
+
</NextCardFooter>
|
|
114
|
+
</>
|
|
115
|
+
)}
|
|
116
|
+
</NextCard>
|
|
117
|
+
);
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
export default Card;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`Story Snapshots > CustomSlotStyles 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div
|
|
6
|
+
class="flex flex-col relative overflow-hidden height-auto box-border bg-content1 outline-none data-[focus-visible=true]:z-10 data-[focus-visible=true]:outline-2 data-[focus-visible=true]:outline-focus data-[focus-visible=true]:outline-offset-2 shadow-none rounded-small w-full transition-transform-background motion-reduce:transition-none border border-slate-300 text-blue-400"
|
|
7
|
+
tabindex="-1"
|
|
8
|
+
>
|
|
9
|
+
<div
|
|
10
|
+
class="flex p-3 z-10 w-full justify-start items-center shrink-0 overflow-inherit color-inherit subpixel-antialiased rounded-t-small text-base font-semibold"
|
|
11
|
+
>
|
|
12
|
+
Header
|
|
13
|
+
</div>
|
|
14
|
+
<hr
|
|
15
|
+
class="shrink-0 border-none w-full h-divider my-0 bg-yellow-400"
|
|
16
|
+
role="separator"
|
|
17
|
+
/>
|
|
18
|
+
<div
|
|
19
|
+
class="relative flex w-full p-3 flex-auto flex-col place-content-inherit align-items-inherit h-auto break-words text-left overflow-y-auto subpixel-antialiased text-green-400"
|
|
20
|
+
>
|
|
21
|
+
<p
|
|
22
|
+
class="w-96"
|
|
23
|
+
>
|
|
24
|
+
Lorem commodo nulla adipisicing cillum Lorem sunt laboris exercitatio
|
|
25
|
+
</p>
|
|
26
|
+
</div>
|
|
27
|
+
<hr
|
|
28
|
+
class="shrink-0 border-none w-full h-divider my-0 bg-yellow-400"
|
|
29
|
+
role="separator"
|
|
30
|
+
/>
|
|
31
|
+
<div
|
|
32
|
+
class="p-3 h-auto flex w-full items-center overflow-hidden color-inherit subpixel-antialiased rounded-b-small"
|
|
33
|
+
>
|
|
34
|
+
Footer
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
`;
|
|
39
|
+
|
|
40
|
+
exports[`Story Snapshots > Default 1`] = `
|
|
41
|
+
<div>
|
|
42
|
+
<div
|
|
43
|
+
class="flex flex-col relative overflow-hidden height-auto text-foreground box-border bg-content1 outline-none data-[focus-visible=true]:z-10 data-[focus-visible=true]:outline-2 data-[focus-visible=true]:outline-focus data-[focus-visible=true]:outline-offset-2 shadow-none rounded-small w-full transition-transform-background motion-reduce:transition-none border border-slate-300"
|
|
44
|
+
tabindex="-1"
|
|
45
|
+
>
|
|
46
|
+
<div
|
|
47
|
+
class="relative flex w-full p-3 flex-auto flex-col place-content-inherit align-items-inherit h-auto break-words text-left overflow-y-auto subpixel-antialiased"
|
|
48
|
+
>
|
|
49
|
+
<p
|
|
50
|
+
class="w-96"
|
|
51
|
+
>
|
|
52
|
+
Lorem commodo nulla adipisicing cillum Lorem sunt laboris exercitation esse. Exercitation ut cillum cupidatat deserunt occaecat pariatur laborum ut reprehenderit veniam. Culpa fugiat aliqua consectetur sit esse.
|
|
53
|
+
</p>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
`;
|
|
58
|
+
|
|
59
|
+
exports[`Story Snapshots > FooterAndHeader 1`] = `
|
|
60
|
+
<div>
|
|
61
|
+
<div
|
|
62
|
+
class="flex flex-col relative overflow-hidden height-auto text-foreground box-border bg-content1 outline-none data-[focus-visible=true]:z-10 data-[focus-visible=true]:outline-2 data-[focus-visible=true]:outline-focus data-[focus-visible=true]:outline-offset-2 shadow-none rounded-small w-full transition-transform-background motion-reduce:transition-none border border-slate-300"
|
|
63
|
+
tabindex="-1"
|
|
64
|
+
>
|
|
65
|
+
<div
|
|
66
|
+
class="flex p-3 z-10 w-full justify-start items-center shrink-0 overflow-inherit color-inherit subpixel-antialiased rounded-t-small text-base font-semibold"
|
|
67
|
+
>
|
|
68
|
+
Header
|
|
69
|
+
</div>
|
|
70
|
+
<hr
|
|
71
|
+
class="shrink-0 border-none w-full h-divider my-0 bg-slate-300"
|
|
72
|
+
role="separator"
|
|
73
|
+
/>
|
|
74
|
+
<div
|
|
75
|
+
class="relative flex w-full p-3 flex-auto flex-col place-content-inherit align-items-inherit h-auto break-words text-left overflow-y-auto subpixel-antialiased"
|
|
76
|
+
>
|
|
77
|
+
<p
|
|
78
|
+
class="w-96"
|
|
79
|
+
>
|
|
80
|
+
Lorem commodo nulla adipisicing cillum Lorem sunt laboris exercitation esse. Exercitation ut cillum cupidatat deserunt occaecat pariatur laborum ut reprehenderit veniam. Culpa fugiat aliqua consectetur sit esse.
|
|
81
|
+
</p>
|
|
82
|
+
</div>
|
|
83
|
+
<hr
|
|
84
|
+
class="shrink-0 border-none w-full h-divider my-0 bg-slate-300"
|
|
85
|
+
role="separator"
|
|
86
|
+
/>
|
|
87
|
+
<div
|
|
88
|
+
class="p-3 h-auto flex w-full items-center overflow-hidden color-inherit subpixel-antialiased rounded-b-small"
|
|
89
|
+
>
|
|
90
|
+
Footer
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
`;
|
package/tsconfig.json
ADDED
package/tsup.config.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
2
|
+
import { defineConfig } from 'tsup';
|
|
3
|
+
|
|
4
|
+
export default defineConfig({
|
|
5
|
+
clean: true,
|
|
6
|
+
dts: true,
|
|
7
|
+
entry: [
|
|
8
|
+
'src',
|
|
9
|
+
'!src/**/__snapshots__/**',
|
|
10
|
+
'!src/**/*.stories.*',
|
|
11
|
+
'!src/**/*.test.*',
|
|
12
|
+
],
|
|
13
|
+
format: ['cjs', 'esm'],
|
|
14
|
+
sourcemap: true,
|
|
15
|
+
});
|