@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.
Files changed (38) hide show
  1. package/components.css +77 -0
  2. package/dist/cjs/components/image.d.ts +6 -1
  3. package/dist/cjs/components/image.d.ts.map +1 -1
  4. package/dist/cjs/components/image.js.map +2 -2
  5. package/dist/cjs/components/index.d.ts +1 -0
  6. package/dist/cjs/components/index.d.ts.map +1 -1
  7. package/dist/cjs/components/index.js +1 -1
  8. package/dist/cjs/components/index.js.map +3 -3
  9. package/dist/cjs/components/toolbar.d.ts +42 -0
  10. package/dist/cjs/components/toolbar.d.ts.map +1 -0
  11. package/dist/cjs/components/toolbar.js +2 -0
  12. package/dist/cjs/components/toolbar.js.map +7 -0
  13. package/dist/esm/components/image.d.ts +6 -1
  14. package/dist/esm/components/image.d.ts.map +1 -1
  15. package/dist/esm/components/image.js.map +2 -2
  16. package/dist/esm/components/index.d.ts +1 -0
  17. package/dist/esm/components/index.d.ts.map +1 -1
  18. package/dist/esm/components/index.js +1 -1
  19. package/dist/esm/components/index.js.map +3 -3
  20. package/dist/esm/components/toolbar.d.ts +42 -0
  21. package/dist/esm/components/toolbar.d.ts.map +1 -0
  22. package/dist/esm/components/toolbar.js +2 -0
  23. package/dist/esm/components/toolbar.js.map +7 -0
  24. package/package.json +1 -1
  25. package/schemas/base-button.json +1 -1
  26. package/schemas/button.json +1 -1
  27. package/schemas/icon-button.json +1 -1
  28. package/schemas/index.json +6 -6
  29. package/schemas/toggle-button.json +1 -1
  30. package/schemas/toggle-icon-button.json +1 -1
  31. package/src/components/image.tsx +6 -1
  32. package/src/components/index.css +1 -0
  33. package/src/components/index.tsx +1 -0
  34. package/src/components/toolbar.css +161 -0
  35. package/src/components/toolbar.tsx +251 -0
  36. package/src/styles/index.css +1 -0
  37. package/src/styles/scrollbar.css +31 -0
  38. 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
+ };
@@ -1,5 +1,6 @@
1
1
  @import './fonts.css';
2
2
  @import './tokens/index.css';
3
3
  @import './breakpoints.css';
4
+ @import './scrollbar.css';
4
5
  @import '../components/index.css';
5
6
  @import './utilities/index.css';
@@ -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);