@kushagradhawan/kookie-ui 0.1.117 → 0.1.119
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/components.css +77 -0
- package/dist/cjs/components/image.d.ts +6 -1
- package/dist/cjs/components/image.d.ts.map +1 -1
- package/dist/cjs/components/image.js.map +2 -2
- package/dist/cjs/components/index.d.ts +1 -0
- package/dist/cjs/components/index.d.ts.map +1 -1
- package/dist/cjs/components/index.js +1 -1
- package/dist/cjs/components/index.js.map +3 -3
- package/dist/cjs/components/toolbar.d.ts +42 -0
- package/dist/cjs/components/toolbar.d.ts.map +1 -0
- package/dist/cjs/components/toolbar.js +2 -0
- package/dist/cjs/components/toolbar.js.map +7 -0
- package/dist/esm/components/image.d.ts +6 -1
- package/dist/esm/components/image.d.ts.map +1 -1
- package/dist/esm/components/image.js.map +2 -2
- package/dist/esm/components/index.d.ts +1 -0
- package/dist/esm/components/index.d.ts.map +1 -1
- package/dist/esm/components/index.js +1 -1
- package/dist/esm/components/index.js.map +3 -3
- package/dist/esm/components/toolbar.d.ts +42 -0
- package/dist/esm/components/toolbar.d.ts.map +1 -0
- package/dist/esm/components/toolbar.js +2 -0
- package/dist/esm/components/toolbar.js.map +7 -0
- package/package.json +1 -1
- package/schemas/base-button.json +1 -1
- package/schemas/button.json +1 -1
- package/schemas/icon-button.json +1 -1
- package/schemas/index.json +6 -6
- package/schemas/toggle-button.json +1 -1
- package/schemas/toggle-icon-button.json +1 -1
- package/src/components/image.tsx +6 -1
- package/src/components/index.css +1 -0
- package/src/components/index.tsx +1 -0
- package/src/components/toolbar.css +161 -0
- package/src/components/toolbar.tsx +251 -0
- package/src/styles/index.css +1 -0
- package/src/styles/scrollbar.css +31 -0
- package/styles.css +98 -0
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import classNames from 'classnames';
|
|
3
|
+
|
|
4
|
+
import { Card } from './card.js';
|
|
5
|
+
import { Flex } from './flex.js';
|
|
6
|
+
import { Heading } from './heading.js';
|
|
7
|
+
|
|
8
|
+
import type { CardProps } from './card.js';
|
|
9
|
+
import type { ComponentPropsWithout, RemovedProps } from '../helpers/component-props.js';
|
|
10
|
+
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// Toolbar Root
|
|
13
|
+
// ============================================================================
|
|
14
|
+
|
|
15
|
+
type ToolbarRootElement = React.ElementRef<'div'>;
|
|
16
|
+
type Anchor = 'top' | 'bottom' | 'left' | 'right';
|
|
17
|
+
type SpaceScale = '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
|
|
18
|
+
|
|
19
|
+
interface ToolbarRootProps extends Omit<CardProps, 'asChild'> {
|
|
20
|
+
/**
|
|
21
|
+
* Which edge to anchor to. Sets position: sticky and the appropriate edge.
|
|
22
|
+
* @default "top"
|
|
23
|
+
*/
|
|
24
|
+
anchor?: Anchor;
|
|
25
|
+
/**
|
|
26
|
+
* Floating variant adds margin from edges for a detached look.
|
|
27
|
+
* When floating, shows full card treatment. When not floating, only shows exposed edge border.
|
|
28
|
+
* @default false
|
|
29
|
+
*/
|
|
30
|
+
floating?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Margin offset from edges when floating. Uses space scale values.
|
|
33
|
+
* @default "2"
|
|
34
|
+
*/
|
|
35
|
+
offset?: SpaceScale;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const ToolbarRoot = React.forwardRef<ToolbarRootElement, ToolbarRootProps>(
|
|
39
|
+
(props, forwardedRef) => {
|
|
40
|
+
const {
|
|
41
|
+
anchor = 'top',
|
|
42
|
+
floating = false,
|
|
43
|
+
offset = '2',
|
|
44
|
+
size = '1',
|
|
45
|
+
variant = 'ghost',
|
|
46
|
+
material,
|
|
47
|
+
className,
|
|
48
|
+
style,
|
|
49
|
+
children,
|
|
50
|
+
...restProps
|
|
51
|
+
} = props;
|
|
52
|
+
|
|
53
|
+
const isHorizontal = anchor === 'top' || anchor === 'bottom';
|
|
54
|
+
const internalRef = React.useRef<HTMLDivElement>(null);
|
|
55
|
+
|
|
56
|
+
// Merge refs
|
|
57
|
+
const mergedRef = React.useCallback(
|
|
58
|
+
(node: HTMLDivElement | null) => {
|
|
59
|
+
(internalRef as React.MutableRefObject<HTMLDivElement | null>).current = node;
|
|
60
|
+
if (typeof forwardedRef === 'function') {
|
|
61
|
+
forwardedRef(node);
|
|
62
|
+
} else if (forwardedRef) {
|
|
63
|
+
forwardedRef.current = node;
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
[forwardedRef],
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
// Measure and expose height/width as CSS variable on parent element
|
|
70
|
+
// so that sibling elements can access it
|
|
71
|
+
React.useEffect(() => {
|
|
72
|
+
const element = internalRef.current;
|
|
73
|
+
if (!element) return;
|
|
74
|
+
|
|
75
|
+
const parent = element.parentElement;
|
|
76
|
+
if (!parent) return;
|
|
77
|
+
|
|
78
|
+
const updateDimension = () => {
|
|
79
|
+
let dimension = isHorizontal ? element.offsetHeight : element.offsetWidth;
|
|
80
|
+
|
|
81
|
+
// For floating toolbars, include the margin offset (2x for top + bottom or left + right)
|
|
82
|
+
if (floating) {
|
|
83
|
+
const computedStyle = getComputedStyle(element);
|
|
84
|
+
const margin = parseFloat(computedStyle.marginTop) || 0;
|
|
85
|
+
dimension += margin * 2;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (isHorizontal) {
|
|
89
|
+
parent.style.setProperty('--rt-toolbar-height', `${dimension}px`);
|
|
90
|
+
} else {
|
|
91
|
+
parent.style.setProperty('--rt-toolbar-width', `${dimension}px`);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
updateDimension();
|
|
96
|
+
|
|
97
|
+
const resizeObserver = new ResizeObserver(updateDimension);
|
|
98
|
+
resizeObserver.observe(element);
|
|
99
|
+
|
|
100
|
+
return () => resizeObserver.disconnect();
|
|
101
|
+
}, [isHorizontal, floating]);
|
|
102
|
+
|
|
103
|
+
const floatingStyle = floating
|
|
104
|
+
? { margin: `var(--space-${offset})`, ...style }
|
|
105
|
+
: style;
|
|
106
|
+
|
|
107
|
+
return (
|
|
108
|
+
<Card
|
|
109
|
+
ref={mergedRef}
|
|
110
|
+
size={size}
|
|
111
|
+
variant={variant}
|
|
112
|
+
material={material}
|
|
113
|
+
data-anchor={anchor}
|
|
114
|
+
data-floating={floating || undefined}
|
|
115
|
+
className={classNames('rt-Toolbar', className)}
|
|
116
|
+
style={floatingStyle}
|
|
117
|
+
{...restProps}
|
|
118
|
+
>
|
|
119
|
+
<Flex
|
|
120
|
+
align="center"
|
|
121
|
+
justify="between"
|
|
122
|
+
direction={isHorizontal ? 'row' : 'column'}
|
|
123
|
+
gap="2"
|
|
124
|
+
className="rt-ToolbarInner"
|
|
125
|
+
>
|
|
126
|
+
{children}
|
|
127
|
+
</Flex>
|
|
128
|
+
</Card>
|
|
129
|
+
);
|
|
130
|
+
},
|
|
131
|
+
);
|
|
132
|
+
ToolbarRoot.displayName = 'Toolbar.Root';
|
|
133
|
+
|
|
134
|
+
// ============================================================================
|
|
135
|
+
// Toolbar Left (for horizontal) / Start (alias)
|
|
136
|
+
// ============================================================================
|
|
137
|
+
|
|
138
|
+
type ToolbarSectionElement = React.ElementRef<'div'>;
|
|
139
|
+
interface ToolbarSectionProps extends ComponentPropsWithout<'div', RemovedProps> {}
|
|
140
|
+
|
|
141
|
+
const ToolbarLeft = React.forwardRef<ToolbarSectionElement, ToolbarSectionProps>(
|
|
142
|
+
({ className, children, ...props }, forwardedRef) => (
|
|
143
|
+
<Flex
|
|
144
|
+
ref={forwardedRef}
|
|
145
|
+
align="center"
|
|
146
|
+
gap="2"
|
|
147
|
+
flexShrink="0"
|
|
148
|
+
className={classNames('rt-ToolbarSection', 'rt-ToolbarLeft', className)}
|
|
149
|
+
{...props}
|
|
150
|
+
>
|
|
151
|
+
{children}
|
|
152
|
+
</Flex>
|
|
153
|
+
),
|
|
154
|
+
);
|
|
155
|
+
ToolbarLeft.displayName = 'Toolbar.Left';
|
|
156
|
+
|
|
157
|
+
// ============================================================================
|
|
158
|
+
// Toolbar Center
|
|
159
|
+
// ============================================================================
|
|
160
|
+
|
|
161
|
+
const ToolbarCenter = React.forwardRef<ToolbarSectionElement, ToolbarSectionProps>(
|
|
162
|
+
({ className, children, ...props }, forwardedRef) => (
|
|
163
|
+
<Flex
|
|
164
|
+
ref={forwardedRef}
|
|
165
|
+
align="center"
|
|
166
|
+
justify="center"
|
|
167
|
+
flexGrow="1"
|
|
168
|
+
minWidth="0"
|
|
169
|
+
className={classNames('rt-ToolbarSection', 'rt-ToolbarCenter', className)}
|
|
170
|
+
{...props}
|
|
171
|
+
>
|
|
172
|
+
{children}
|
|
173
|
+
</Flex>
|
|
174
|
+
),
|
|
175
|
+
);
|
|
176
|
+
ToolbarCenter.displayName = 'Toolbar.Center';
|
|
177
|
+
|
|
178
|
+
// ============================================================================
|
|
179
|
+
// Toolbar Right (for horizontal) / End (alias)
|
|
180
|
+
// ============================================================================
|
|
181
|
+
|
|
182
|
+
const ToolbarRight = React.forwardRef<ToolbarSectionElement, ToolbarSectionProps>(
|
|
183
|
+
({ className, children, ...props }, forwardedRef) => (
|
|
184
|
+
<Flex
|
|
185
|
+
ref={forwardedRef}
|
|
186
|
+
align="center"
|
|
187
|
+
gap="2"
|
|
188
|
+
flexShrink="0"
|
|
189
|
+
className={classNames('rt-ToolbarSection', 'rt-ToolbarRight', className)}
|
|
190
|
+
{...props}
|
|
191
|
+
>
|
|
192
|
+
{children}
|
|
193
|
+
</Flex>
|
|
194
|
+
),
|
|
195
|
+
);
|
|
196
|
+
ToolbarRight.displayName = 'Toolbar.Right';
|
|
197
|
+
|
|
198
|
+
// ============================================================================
|
|
199
|
+
// Toolbar Title
|
|
200
|
+
// ============================================================================
|
|
201
|
+
|
|
202
|
+
type ToolbarTitleElement = React.ElementRef<typeof Heading>;
|
|
203
|
+
interface ToolbarTitleProps extends React.ComponentPropsWithoutRef<typeof Heading> {}
|
|
204
|
+
|
|
205
|
+
const ToolbarTitle = React.forwardRef<ToolbarTitleElement, ToolbarTitleProps>(
|
|
206
|
+
({ className, size = '3', weight = 'medium', truncate = true, children, ...props }, forwardedRef) => (
|
|
207
|
+
<Heading
|
|
208
|
+
ref={forwardedRef}
|
|
209
|
+
size={size}
|
|
210
|
+
weight={weight}
|
|
211
|
+
truncate={truncate}
|
|
212
|
+
className={classNames('rt-ToolbarTitle', className)}
|
|
213
|
+
{...props}
|
|
214
|
+
>
|
|
215
|
+
{children}
|
|
216
|
+
</Heading>
|
|
217
|
+
),
|
|
218
|
+
);
|
|
219
|
+
ToolbarTitle.displayName = 'Toolbar.Title';
|
|
220
|
+
|
|
221
|
+
// ============================================================================
|
|
222
|
+
// Exports
|
|
223
|
+
// ============================================================================
|
|
224
|
+
|
|
225
|
+
const Toolbar = ToolbarRoot as typeof ToolbarRoot & {
|
|
226
|
+
Left: typeof ToolbarLeft;
|
|
227
|
+
Center: typeof ToolbarCenter;
|
|
228
|
+
Right: typeof ToolbarRight;
|
|
229
|
+
Title: typeof ToolbarTitle;
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
Toolbar.Left = ToolbarLeft;
|
|
233
|
+
Toolbar.Center = ToolbarCenter;
|
|
234
|
+
Toolbar.Right = ToolbarRight;
|
|
235
|
+
Toolbar.Title = ToolbarTitle;
|
|
236
|
+
|
|
237
|
+
export {
|
|
238
|
+
Toolbar,
|
|
239
|
+
ToolbarRoot as Root,
|
|
240
|
+
ToolbarLeft as Left,
|
|
241
|
+
ToolbarCenter as Center,
|
|
242
|
+
ToolbarRight as Right,
|
|
243
|
+
ToolbarTitle as Title,
|
|
244
|
+
};
|
|
245
|
+
export type {
|
|
246
|
+
ToolbarRootProps as RootProps,
|
|
247
|
+
ToolbarSectionProps as LeftProps,
|
|
248
|
+
ToolbarSectionProps as CenterProps,
|
|
249
|
+
ToolbarSectionProps as RightProps,
|
|
250
|
+
ToolbarTitleProps as TitleProps,
|
|
251
|
+
};
|
package/src/styles/index.css
CHANGED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/* Global scrollbar styling for kookie-ui */
|
|
2
|
+
/* Provides thin, subtle scrollbars that match the design system */
|
|
3
|
+
|
|
4
|
+
/* Firefox */
|
|
5
|
+
* {
|
|
6
|
+
scrollbar-width: thin;
|
|
7
|
+
scrollbar-color: var(--gray-a5) transparent;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/* WebKit browsers (Chrome, Safari, Edge) */
|
|
11
|
+
::-webkit-scrollbar {
|
|
12
|
+
width: 8px;
|
|
13
|
+
height: 8px;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
::-webkit-scrollbar-track {
|
|
17
|
+
background: transparent;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
::-webkit-scrollbar-thumb {
|
|
21
|
+
background: var(--gray-a5);
|
|
22
|
+
border-radius: 4px;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
::-webkit-scrollbar-thumb:hover {
|
|
26
|
+
background: var(--gray-a7);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
::-webkit-scrollbar-corner {
|
|
30
|
+
background: transparent;
|
|
31
|
+
}
|
package/styles.css
CHANGED
|
@@ -5048,6 +5048,27 @@
|
|
|
5048
5048
|
[data-opacity='full']{
|
|
5049
5049
|
--opacity-factor: 2.0;
|
|
5050
5050
|
}
|
|
5051
|
+
*{
|
|
5052
|
+
scrollbar-width: thin;
|
|
5053
|
+
scrollbar-color: var(--gray-a5) transparent;
|
|
5054
|
+
}
|
|
5055
|
+
::-webkit-scrollbar{
|
|
5056
|
+
width: 8px;
|
|
5057
|
+
height: 8px;
|
|
5058
|
+
}
|
|
5059
|
+
::-webkit-scrollbar-track{
|
|
5060
|
+
background: transparent;
|
|
5061
|
+
}
|
|
5062
|
+
::-webkit-scrollbar-thumb{
|
|
5063
|
+
background: var(--gray-a5);
|
|
5064
|
+
border-radius: 4px;
|
|
5065
|
+
}
|
|
5066
|
+
::-webkit-scrollbar-thumb:hover{
|
|
5067
|
+
background: var(--gray-a7);
|
|
5068
|
+
}
|
|
5069
|
+
::-webkit-scrollbar-corner{
|
|
5070
|
+
background: transparent;
|
|
5071
|
+
}
|
|
5051
5072
|
.rt-reset:where(body, blockquote, dl, dd, figure, p){
|
|
5052
5073
|
margin: 0;
|
|
5053
5074
|
}
|
|
@@ -25000,6 +25021,83 @@
|
|
|
25000
25021
|
outline-style: solid;
|
|
25001
25022
|
outline-color: var(--accent-9);
|
|
25002
25023
|
}
|
|
25024
|
+
.rt-Toolbar{
|
|
25025
|
+
position: sticky;
|
|
25026
|
+
z-index: 1;
|
|
25027
|
+
}
|
|
25028
|
+
.rt-ToolbarInner{
|
|
25029
|
+
width: 100%;
|
|
25030
|
+
height: 100%;
|
|
25031
|
+
}
|
|
25032
|
+
.rt-Toolbar:where([data-anchor='top']){
|
|
25033
|
+
top: 0;
|
|
25034
|
+
left: 0;
|
|
25035
|
+
right: 0;
|
|
25036
|
+
}
|
|
25037
|
+
.rt-Toolbar:where([data-anchor='bottom']){
|
|
25038
|
+
bottom: 0;
|
|
25039
|
+
left: 0;
|
|
25040
|
+
right: 0;
|
|
25041
|
+
}
|
|
25042
|
+
.rt-Toolbar:where([data-anchor='left']){
|
|
25043
|
+
top: 0;
|
|
25044
|
+
bottom: 0;
|
|
25045
|
+
left: 0;
|
|
25046
|
+
}
|
|
25047
|
+
.rt-Toolbar:where([data-anchor='right']){
|
|
25048
|
+
top: 0;
|
|
25049
|
+
bottom: 0;
|
|
25050
|
+
right: 0;
|
|
25051
|
+
}
|
|
25052
|
+
.rt-Toolbar:where(:not([data-floating])){
|
|
25053
|
+
--base-card-border-radius: 0;
|
|
25054
|
+
}
|
|
25055
|
+
.rt-Toolbar:where([data-anchor='top']:not([data-floating]))::after{
|
|
25056
|
+
box-shadow: inset 0 -1px 0 0 var(--gray-6);
|
|
25057
|
+
}
|
|
25058
|
+
:where([data-panel-background='translucent'], [data-material='translucent']) .rt-Toolbar:where([data-anchor='top']:not([data-floating]))::after, .rt-Toolbar:where([data-anchor='top']:not([data-floating])):where([data-panel-background='translucent'], [data-material='translucent'])::after{
|
|
25059
|
+
box-shadow: inset 0 -1px 0 0 var(--gray-a6);
|
|
25060
|
+
}
|
|
25061
|
+
.rt-Toolbar:where([data-anchor='bottom']:not([data-floating]))::after{
|
|
25062
|
+
box-shadow: inset 0 1px 0 0 var(--gray-6);
|
|
25063
|
+
}
|
|
25064
|
+
:where([data-panel-background='translucent'], [data-material='translucent']) .rt-Toolbar:where([data-anchor='bottom']:not([data-floating]))::after, .rt-Toolbar:where([data-anchor='bottom']:not([data-floating])):where([data-panel-background='translucent'], [data-material='translucent'])::after{
|
|
25065
|
+
box-shadow: inset 0 1px 0 0 var(--gray-a6);
|
|
25066
|
+
}
|
|
25067
|
+
.rt-Toolbar:where([data-anchor='left']:not([data-floating]))::after{
|
|
25068
|
+
box-shadow: inset -1px 0 0 0 var(--gray-6);
|
|
25069
|
+
}
|
|
25070
|
+
:where([data-panel-background='translucent'], [data-material='translucent']) .rt-Toolbar:where([data-anchor='left']:not([data-floating]))::after, .rt-Toolbar:where([data-anchor='left']:not([data-floating])):where([data-panel-background='translucent'], [data-material='translucent'])::after{
|
|
25071
|
+
box-shadow: inset -1px 0 0 0 var(--gray-a6);
|
|
25072
|
+
}
|
|
25073
|
+
.rt-Toolbar:where([data-anchor='right']:not([data-floating]))::after{
|
|
25074
|
+
box-shadow: inset 1px 0 0 0 var(--gray-6);
|
|
25075
|
+
}
|
|
25076
|
+
:where([data-panel-background='translucent'], [data-material='translucent']) .rt-Toolbar:where([data-anchor='right']:not([data-floating]))::after, .rt-Toolbar:where([data-anchor='right']:not([data-floating])):where([data-panel-background='translucent'], [data-material='translucent'])::after{
|
|
25077
|
+
box-shadow: inset 1px 0 0 0 var(--gray-a6);
|
|
25078
|
+
}
|
|
25079
|
+
.rt-Toolbar:where(.rt-variant-ghost:not([data-floating]))::after{
|
|
25080
|
+
box-shadow: none;
|
|
25081
|
+
}
|
|
25082
|
+
.rt-Toolbar:where(.rt-variant-soft:not([data-floating]))::after{
|
|
25083
|
+
box-shadow: none;
|
|
25084
|
+
}
|
|
25085
|
+
.rt-Toolbar:where([data-floating]){
|
|
25086
|
+
position: absolute;
|
|
25087
|
+
}
|
|
25088
|
+
.rt-ToolbarTitle{
|
|
25089
|
+
min-width: 0;
|
|
25090
|
+
flex-shrink: 1;
|
|
25091
|
+
}
|
|
25092
|
+
.rt-ToolbarLeft{
|
|
25093
|
+
justify-content: flex-start;
|
|
25094
|
+
}
|
|
25095
|
+
.rt-ToolbarCenter{
|
|
25096
|
+
justify-content: center;
|
|
25097
|
+
}
|
|
25098
|
+
.rt-ToolbarRight{
|
|
25099
|
+
justify-content: flex-end;
|
|
25100
|
+
}
|
|
25003
25101
|
.rt-TooltipContent{
|
|
25004
25102
|
box-sizing: border-box;
|
|
25005
25103
|
padding: var(--space-1) var(--space-2);
|