@musecat/uikit 0.1.1
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/LICENSE +9 -0
- package/README.md +51 -0
- package/index.ts +78 -0
- package/package.json +103 -0
- package/packages/Components/Box/Box.tsx +173 -0
- package/packages/Components/Box/Box.types.ts +48 -0
- package/packages/Components/Button/Button.tsx +275 -0
- package/packages/Components/Button/Button.types.ts +44 -0
- package/packages/Components/Card/Card.default.tsx +180 -0
- package/packages/Components/Card/Card.foldable.tsx +383 -0
- package/packages/Components/Card/Card.module.scss +23 -0
- package/packages/Components/Card/Card.tsx +8 -0
- package/packages/Components/Card/Card.types.ts +91 -0
- package/packages/Components/Card/Card.utils.ts +66 -0
- package/packages/Components/Checkbox/Checkbox.module.scss +11 -0
- package/packages/Components/Checkbox/Checkbox.tsx +104 -0
- package/packages/Components/Checkbox/Checkbox.types.ts +24 -0
- package/packages/Components/CodeBox/CodeBox.copy.tsx +43 -0
- package/packages/Components/CodeBox/CodeBox.module.scss +72 -0
- package/packages/Components/CodeBox/CodeBox.tsx +91 -0
- package/packages/Components/CodeBox/CodeBox.types.ts +17 -0
- package/packages/Components/ContextMenu/ContextMenu.module.scss +8 -0
- package/packages/Components/ContextMenu/ContextMenu.options.tsx +126 -0
- package/packages/Components/ContextMenu/ContextMenu.tsx +381 -0
- package/packages/Components/ContextMenu/ContextMenu.types.ts +46 -0
- package/packages/Components/ContributionGraph/ContributionGraph.module.scss +42 -0
- package/packages/Components/ContributionGraph/ContributionGraph.tsx +454 -0
- package/packages/Components/ContributionGraph/ContributionGraph.types.ts +27 -0
- package/packages/Components/DatePicker/DatePicker.calendar.tsx +161 -0
- package/packages/Components/DatePicker/DatePicker.core.tsx +582 -0
- package/packages/Components/DatePicker/DatePicker.module.scss +26 -0
- package/packages/Components/DatePicker/DatePicker.tsx +786 -0
- package/packages/Components/DatePicker/DatePicker.types.ts +36 -0
- package/packages/Components/DatePicker/DatePicker.utils.ts +80 -0
- package/packages/Components/DatePicker/hooks/useCalendar.ts +61 -0
- package/packages/Components/DatePicker/hooks/useSelection.ts +208 -0
- package/packages/Components/Divider/Divider.tsx +46 -0
- package/packages/Components/Divider/Divider.types.ts +12 -0
- package/packages/Components/Header/Header.module.scss +74 -0
- package/packages/Components/Header/Header.tsx +47 -0
- package/packages/Components/Header/Header.types.ts +8 -0
- package/packages/Components/Icon/Icon.group.tsx +122 -0
- package/packages/Components/Icon/Icon.group.types.ts +20 -0
- package/packages/Components/Icon/Icon.tsx +341 -0
- package/packages/Components/Icon/Icon.types.ts +59 -0
- package/packages/Components/Icon/SVG/data.tsx +232 -0
- package/packages/Components/Input/Input.module.scss +5 -0
- package/packages/Components/Input/Input.tsx +87 -0
- package/packages/Components/Input/Input.types.ts +14 -0
- package/packages/Components/Label/Label.module.scss +19 -0
- package/packages/Components/Label/Label.tsx +115 -0
- package/packages/Components/Label/Label.types.ts +28 -0
- package/packages/Components/Layout/Layout.docs.module.scss +42 -0
- package/packages/Components/Layout/Layout.docs.tsx +150 -0
- package/packages/Components/Layout/Layout.docs.types.ts +18 -0
- package/packages/Components/Layout/Layout.module.scss +91 -0
- package/packages/Components/Layout/Layout.tsx +306 -0
- package/packages/Components/Layout/Layout.types.ts +71 -0
- package/packages/Components/Maps/OSM/MapOSM.module.scss +11 -0
- package/packages/Components/Maps/OSM/MapOSM.shared.ts +121 -0
- package/packages/Components/Maps/OSM/MapOSM.tsx +279 -0
- package/packages/Components/Maps/OSM/MapOSM.types.ts +18 -0
- package/packages/Components/Nav/Nav.module.scss +137 -0
- package/packages/Components/Nav/Nav.tsx +304 -0
- package/packages/Components/Nav/Nav.types.ts +32 -0
- package/packages/Components/Nav/hooks/useNavDrag.ts +374 -0
- package/packages/Components/Nav/hooks/useNavIndicator.ts +137 -0
- package/packages/Components/Pagination/Pagination.tsx +254 -0
- package/packages/Components/Pagination/Pagination.types.ts +18 -0
- package/packages/Components/Pill/Pill.tsx +127 -0
- package/packages/Components/Pill/Pill.types.ts +33 -0
- package/packages/Components/Profile/Profile.shared.ts +74 -0
- package/packages/Components/Profile/Profile.tsx +382 -0
- package/packages/Components/Profile/Profile.types.ts +55 -0
- package/packages/Components/Progress/Progress.module.scss +15 -0
- package/packages/Components/Progress/Progress.tsx +88 -0
- package/packages/Components/Progress/Progress.types.ts +22 -0
- package/packages/Components/Radio/Radio.module.scss +11 -0
- package/packages/Components/Radio/Radio.tsx +121 -0
- package/packages/Components/Radio/Radio.types.ts +20 -0
- package/packages/Components/Select/Select.keyboard.tsx +76 -0
- package/packages/Components/Select/Select.trigger.tsx +88 -0
- package/packages/Components/Select/Select.tsx +11 -0
- package/packages/Components/Select/Select.types.ts +38 -0
- package/packages/Components/Select/Select.utils.ts +84 -0
- package/packages/Components/Select/hooks/useSelectNavigation.ts +461 -0
- package/packages/Components/Select/hooks/useSelectSelection.ts +142 -0
- package/packages/Components/Select/hooks/useSelectState.ts +314 -0
- package/packages/Components/Select/select.control.tsx +228 -0
- package/packages/Components/Select/select.inner.tsx +312 -0
- package/packages/Components/Skeleton/Skeleton.tsx +30 -0
- package/packages/Components/Skeleton/Skeleton.types.ts +12 -0
- package/packages/Components/Spinner/Spinner.module.scss +78 -0
- package/packages/Components/Spinner/Spinner.tsx +125 -0
- package/packages/Components/Spinner/Spinner.types.ts +19 -0
- package/packages/Components/Text/Text.module.scss +7 -0
- package/packages/Components/Text/Text.tsx +49 -0
- package/packages/Components/Text/Text.types.ts +33 -0
- package/packages/Components/TimePicker/TimePicker.core.tsx +448 -0
- package/packages/Components/TimePicker/TimePicker.module.scss +30 -0
- package/packages/Components/TimePicker/TimePicker.tsx +511 -0
- package/packages/Components/TimePicker/TimePicker.types.ts +22 -0
- package/packages/Components/Timeline/Timeline.tsx +111 -0
- package/packages/Components/Timeline/Timeline.types.ts +23 -0
- package/packages/Components/Title/Title.tsx +305 -0
- package/packages/Components/Title/Title.types.ts +64 -0
- package/packages/Components/Toggle/Toggle.module.scss +32 -0
- package/packages/Components/Toggle/Toggle.tsx +272 -0
- package/packages/Components/Toggle/Toggle.types.ts +17 -0
- package/packages/Components/Tooltip/Tooltip.module.scss +44 -0
- package/packages/Components/Tooltip/Tooltip.tsx +340 -0
- package/packages/Components/Tooltip/Tooltip.types.ts +38 -0
- package/packages/Frameworks/Dialog/Dialog.background.tsx +88 -0
- package/packages/Frameworks/Dialog/Dialog.boot.tsx +32 -0
- package/packages/Frameworks/Dialog/Dialog.store.ts +199 -0
- package/packages/Frameworks/Dialog/Dialog.tsx +185 -0
- package/packages/Frameworks/Dialog/Dialog.types.ts +264 -0
- package/packages/Frameworks/Dialog/Dialog.utils.ts +22 -0
- package/packages/Frameworks/Dialog/contents/Dialog.footer.tsx +79 -0
- package/packages/Frameworks/Dialog/contents/Dialog.funnel.tsx +260 -0
- package/packages/Frameworks/Dialog/contents/Dialog.header.tsx +137 -0
- package/packages/Frameworks/Dialog/hooks/useDialogPosition.ts +298 -0
- package/packages/Frameworks/Dialog/hooks/useSheetDrag.ts +325 -0
- package/packages/Frameworks/Dialog/hooks/useSheetGeometry.ts +201 -0
- package/packages/Frameworks/Dialog/hooks/useSheetProgressive.ts +98 -0
- package/packages/Frameworks/Dialog/renderers/renderModal.tsx +228 -0
- package/packages/Frameworks/Dialog/renderers/renderPopover.tsx +220 -0
- package/packages/Frameworks/Dialog/renderers/renderSheet.tsx +571 -0
- package/packages/Frameworks/EdgeEffect/EdgeEffect.tsx +52 -0
- package/packages/Frameworks/EdgeEffect/EdgeEffect.types.ts +5 -0
- package/packages/Frameworks/Motion/Motion.presets.ts +49 -0
- package/packages/Frameworks/Pressable/Pressable.module.scss +19 -0
- package/packages/Frameworks/Pressable/Pressable.tsx +651 -0
- package/packages/Frameworks/Pressable/Pressable.types.ts +73 -0
- package/packages/Frameworks/Squircle/Squircle.tsx +263 -0
- package/packages/Frameworks/Squircle/Squircle.types.ts +15 -0
- package/packages/Frameworks/Theme/Radius.types.ts +55 -0
- package/packages/Frameworks/Theme/Theme.types.ts +325 -0
- package/packages/Frameworks/Toaster/Toaster.boot.tsx +47 -0
- package/packages/Frameworks/Toaster/Toaster.module.scss +168 -0
- package/packages/Frameworks/Toaster/Toaster.types.ts +13 -0
- package/packages/Frameworks/View/DNDView/DNDView.module.scss +8 -0
- package/packages/Frameworks/View/DNDView/DNDView.tsx +470 -0
- package/packages/Frameworks/View/DNDView/DNDView.types.ts +61 -0
- package/packages/Frameworks/View/HScrollView/HScrollView.module.scss +59 -0
- package/packages/Frameworks/View/HScrollView/HScrollView.tsx +386 -0
- package/packages/Frameworks/View/HScrollView/HScrollView.types.ts +46 -0
- package/packages/Frameworks/View/ImageView/Dialog/ImageDialog.counter.tsx +27 -0
- package/packages/Frameworks/View/ImageView/Dialog/ImageDialog.footer.tsx +76 -0
- package/packages/Frameworks/View/ImageView/Dialog/ImageDialog.header.tsx +49 -0
- package/packages/Frameworks/View/ImageView/Dialog/ImageDialog.list.tsx +74 -0
- package/packages/Frameworks/View/ImageView/Dialog/ImageDialog.slide.tsx +71 -0
- package/packages/Frameworks/View/ImageView/Dialog/ImageDialog.tsx +175 -0
- package/packages/Frameworks/View/ImageView/Image.controls.tsx +39 -0
- package/packages/Frameworks/View/ImageView/Image.hooks.ts +82 -0
- package/packages/Frameworks/View/ImageView/Image.module.scss +7 -0
- package/packages/Frameworks/View/ImageView/Image.tsx +375 -0
- package/packages/Frameworks/View/ImageView/Image.types.ts +71 -0
- package/packages/Frameworks/View/ImageView/Image.utils.ts +79 -0
- package/packages/Frameworks/View/View.module.scss +34 -0
- package/packages/Frameworks/View/View.tsx +200 -0
- package/packages/Frameworks/View/View.types.ts +36 -0
- package/packages/Frameworks/_shared/Padding.types.ts +52 -0
- package/packages/Frameworks/_shared/StopParentInteraction.tsx +45 -0
- package/packages/Frameworks/_shared/Wind.types.ts +17 -0
- package/packages/Frameworks/_shared/bodyScrollLock.ts +127 -0
- package/packages/Frameworks/_shared/layer.constants.ts +8 -0
- package/packages/Frameworks/_shared/normalize.ts +39 -0
- package/packages/Frameworks/_shared/sizing.ts +55 -0
- package/packages/Frameworks/_shared/useControllableState.ts +29 -0
- package/packages/Styles/_animation.scss +42 -0
- package/packages/Styles/_color.scss +131 -0
- package/packages/Styles/_font.scss +30 -0
- package/packages/Styles/_icon.scss +782 -0
- package/packages/Styles/_importer.scss +9 -0
- package/packages/Styles/_system.scss +69 -0
- package/packages/Styles/_textstyle.scss +111 -0
- package/packages/Styles/_theme.scss +452 -0
- package/packages/Styles/_viewport-global.scss +99 -0
- package/packages/Styles/_viewport.scss +108 -0
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import clsx from "clsx";
|
|
2
|
+
import { motion } from "motion/react";
|
|
3
|
+
import { type CSSProperties, forwardRef } from "react";
|
|
4
|
+
import { resolvePadding } from "@/packages/Frameworks/_shared/Padding.types";
|
|
5
|
+
import { Size } from "@/packages/Frameworks/_shared/sizing";
|
|
6
|
+
import Squircle from "@/packages/Frameworks/Squircle/Squircle";
|
|
7
|
+
import { Radius } from "@/packages/Frameworks/Theme/Radius.types";
|
|
8
|
+
import {
|
|
9
|
+
BackgroundBlur,
|
|
10
|
+
Border,
|
|
11
|
+
resolveThemeClasses,
|
|
12
|
+
resolveThemeHasBorder,
|
|
13
|
+
Shadow,
|
|
14
|
+
} from "@/packages/Frameworks/Theme/Theme.types";
|
|
15
|
+
import DNDView from "@/packages/Frameworks/View/DNDView/DNDView";
|
|
16
|
+
import styles from "@/packages/Frameworks/View/View.module.scss";
|
|
17
|
+
import type { ViewProps } from "@/packages/Frameworks/View/View.types";
|
|
18
|
+
|
|
19
|
+
type ViewStyle = CSSProperties & {
|
|
20
|
+
"--view-default-gap"?: string | number;
|
|
21
|
+
"--view-mobile-order"?: string | number;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
type ViewComponent = ReturnType<
|
|
25
|
+
typeof forwardRef<HTMLDivElement, ViewProps>
|
|
26
|
+
> & {
|
|
27
|
+
DND: typeof DNDView;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const ViewBase = forwardRef<HTMLDivElement, ViewProps>(function View(
|
|
31
|
+
{
|
|
32
|
+
children,
|
|
33
|
+
themePreset,
|
|
34
|
+
background,
|
|
35
|
+
color,
|
|
36
|
+
themeInteractive,
|
|
37
|
+
selected,
|
|
38
|
+
disabled,
|
|
39
|
+
readOnly,
|
|
40
|
+
border,
|
|
41
|
+
className,
|
|
42
|
+
style,
|
|
43
|
+
alignItems,
|
|
44
|
+
justifyContent,
|
|
45
|
+
alignSelf,
|
|
46
|
+
wrap,
|
|
47
|
+
order,
|
|
48
|
+
opacity,
|
|
49
|
+
gridTemplateColumns,
|
|
50
|
+
gridTemplateRows,
|
|
51
|
+
gridAutoFlow,
|
|
52
|
+
column,
|
|
53
|
+
row,
|
|
54
|
+
inline,
|
|
55
|
+
gap,
|
|
56
|
+
mobileStrict,
|
|
57
|
+
mobileOrder,
|
|
58
|
+
fullWidth,
|
|
59
|
+
width,
|
|
60
|
+
height,
|
|
61
|
+
padding,
|
|
62
|
+
paddingHorizontal,
|
|
63
|
+
paddingVertical,
|
|
64
|
+
margin,
|
|
65
|
+
radius,
|
|
66
|
+
sticky,
|
|
67
|
+
top,
|
|
68
|
+
bottom,
|
|
69
|
+
backgroundBlur,
|
|
70
|
+
shadow,
|
|
71
|
+
motion: motionProps,
|
|
72
|
+
"data-color-mode": dataColorMode,
|
|
73
|
+
noSquircle,
|
|
74
|
+
...rest
|
|
75
|
+
}: ViewProps,
|
|
76
|
+
ref,
|
|
77
|
+
) {
|
|
78
|
+
const isGrid = Boolean(
|
|
79
|
+
gridTemplateColumns || gridTemplateRows || gridAutoFlow,
|
|
80
|
+
);
|
|
81
|
+
const defaultGap = 24;
|
|
82
|
+
const resolvedDefaultGap = Size(defaultGap);
|
|
83
|
+
const resolvedGap = gap === undefined ? undefined : Size(gap);
|
|
84
|
+
|
|
85
|
+
const themeClasses = resolveThemeClasses({
|
|
86
|
+
themePreset,
|
|
87
|
+
background,
|
|
88
|
+
color,
|
|
89
|
+
shadow,
|
|
90
|
+
themeInteractive,
|
|
91
|
+
selected,
|
|
92
|
+
disabled,
|
|
93
|
+
readOnly,
|
|
94
|
+
isInteractive: false,
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
const viewClassName = clsx(
|
|
98
|
+
styles.View,
|
|
99
|
+
...themeClasses,
|
|
100
|
+
Border(border),
|
|
101
|
+
Shadow(shadow),
|
|
102
|
+
BackgroundBlur(backgroundBlur),
|
|
103
|
+
fullWidth && styles.FullWidth,
|
|
104
|
+
mobileStrict && styles.MobileStrict,
|
|
105
|
+
mobileOrder !== undefined && styles.MobileOrder,
|
|
106
|
+
className,
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
const rootStyle: ViewStyle = {
|
|
110
|
+
"--view-default-gap": resolvedDefaultGap,
|
|
111
|
+
"--view-mobile-order": mobileOrder,
|
|
112
|
+
alignSelf,
|
|
113
|
+
order,
|
|
114
|
+
...(opacity !== undefined ? { opacity } : {}),
|
|
115
|
+
width: Size(width),
|
|
116
|
+
height: Size(height),
|
|
117
|
+
padding: resolvePadding(padding, paddingHorizontal, paddingVertical),
|
|
118
|
+
margin: Size(margin),
|
|
119
|
+
borderRadius: Radius(radius),
|
|
120
|
+
position: sticky ? "sticky" : undefined,
|
|
121
|
+
top: sticky === true ? 0 : sticky ? Size(sticky) : Size(top),
|
|
122
|
+
bottom: Size(bottom),
|
|
123
|
+
...style,
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
const layoutStyle: CSSProperties = {
|
|
127
|
+
display: isGrid ? "grid" : inline ? "inline-flex" : "flex",
|
|
128
|
+
alignItems,
|
|
129
|
+
justifyContent,
|
|
130
|
+
flexDirection: !isGrid && column ? "column" : row ? "row" : undefined,
|
|
131
|
+
flexWrap: !isGrid ? wrap : undefined,
|
|
132
|
+
gridTemplateColumns,
|
|
133
|
+
gridTemplateRows,
|
|
134
|
+
gridAutoFlow,
|
|
135
|
+
gap: resolvedGap,
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const hasRadius = Boolean(radius && radius !== "None");
|
|
139
|
+
const hasBorder = resolveThemeHasBorder({ border, themePreset });
|
|
140
|
+
const _hasShadow = Boolean(shadow && shadow !== "None");
|
|
141
|
+
const isSquircle = hasRadius && !hasBorder && !noSquircle;
|
|
142
|
+
|
|
143
|
+
if (isSquircle) {
|
|
144
|
+
return (
|
|
145
|
+
<Squircle
|
|
146
|
+
ref={ref}
|
|
147
|
+
radius={radius}
|
|
148
|
+
motion={motionProps}
|
|
149
|
+
data-color-mode={dataColorMode}
|
|
150
|
+
{...rest}
|
|
151
|
+
className={viewClassName}
|
|
152
|
+
style={{
|
|
153
|
+
...layoutStyle,
|
|
154
|
+
...rootStyle,
|
|
155
|
+
}}
|
|
156
|
+
>
|
|
157
|
+
{children}
|
|
158
|
+
</Squircle>
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (motionProps) {
|
|
163
|
+
return (
|
|
164
|
+
<motion.div
|
|
165
|
+
ref={ref}
|
|
166
|
+
data-color-mode={dataColorMode}
|
|
167
|
+
{...(rest as any)}
|
|
168
|
+
{...(motionProps as any)}
|
|
169
|
+
className={viewClassName}
|
|
170
|
+
style={{
|
|
171
|
+
...layoutStyle,
|
|
172
|
+
...rootStyle,
|
|
173
|
+
...motionProps.style,
|
|
174
|
+
}}
|
|
175
|
+
>
|
|
176
|
+
{children}
|
|
177
|
+
</motion.div>
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return (
|
|
182
|
+
<div
|
|
183
|
+
ref={ref}
|
|
184
|
+
data-color-mode={dataColorMode}
|
|
185
|
+
{...rest}
|
|
186
|
+
className={viewClassName}
|
|
187
|
+
style={{
|
|
188
|
+
...layoutStyle,
|
|
189
|
+
...rootStyle,
|
|
190
|
+
}}
|
|
191
|
+
>
|
|
192
|
+
{children}
|
|
193
|
+
</div>
|
|
194
|
+
);
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
const View = ViewBase as ViewComponent;
|
|
198
|
+
View.DND = DNDView;
|
|
199
|
+
|
|
200
|
+
export default View;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { MotionProps } from "motion/react";
|
|
2
|
+
import type { CSSProperties, HTMLAttributes } from "react";
|
|
3
|
+
import type { PaddingProps } from "@/packages/Frameworks/_shared/Padding.types";
|
|
4
|
+
import type { UIKitSizeValue } from "@/packages/Frameworks/_shared/sizing";
|
|
5
|
+
import type { WindProps } from "@/packages/Frameworks/_shared/Wind.types";
|
|
6
|
+
import type { RadiusProps } from "@/packages/Frameworks/Theme/Radius.types";
|
|
7
|
+
import type {
|
|
8
|
+
BorderProps,
|
|
9
|
+
ThemeSystemProps,
|
|
10
|
+
} from "@/packages/Frameworks/Theme/Theme.types";
|
|
11
|
+
|
|
12
|
+
export interface ViewProps
|
|
13
|
+
extends Omit<HTMLAttributes<HTMLDivElement>, "color">,
|
|
14
|
+
ThemeSystemProps,
|
|
15
|
+
BorderProps,
|
|
16
|
+
RadiusProps,
|
|
17
|
+
PaddingProps,
|
|
18
|
+
WindProps {
|
|
19
|
+
"data-color-mode"?: string;
|
|
20
|
+
motion?: MotionProps;
|
|
21
|
+
wrap?: CSSProperties["flexWrap"];
|
|
22
|
+
order?: CSSProperties["order"];
|
|
23
|
+
|
|
24
|
+
gridTemplateColumns?: string;
|
|
25
|
+
gridTemplateRows?: string;
|
|
26
|
+
gridAutoFlow?: CSSProperties["gridAutoFlow"];
|
|
27
|
+
|
|
28
|
+
inline?: boolean;
|
|
29
|
+
|
|
30
|
+
mobileStrict?: boolean;
|
|
31
|
+
mobileOrder?: number;
|
|
32
|
+
|
|
33
|
+
sticky?: boolean | UIKitSizeValue;
|
|
34
|
+
top?: UIKitSizeValue;
|
|
35
|
+
bottom?: UIKitSizeValue;
|
|
36
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Size,
|
|
3
|
+
type UIKitSizeValue,
|
|
4
|
+
} from "@/packages/Frameworks/_shared/sizing";
|
|
5
|
+
|
|
6
|
+
type PaddingUnitValue = UIKitSizeValue;
|
|
7
|
+
|
|
8
|
+
export type PaddingValue =
|
|
9
|
+
| PaddingUnitValue
|
|
10
|
+
| readonly [PaddingUnitValue]
|
|
11
|
+
| readonly [PaddingUnitValue, PaddingUnitValue]
|
|
12
|
+
| readonly [PaddingUnitValue, PaddingUnitValue, PaddingUnitValue]
|
|
13
|
+
| readonly [
|
|
14
|
+
PaddingUnitValue,
|
|
15
|
+
PaddingUnitValue,
|
|
16
|
+
PaddingUnitValue,
|
|
17
|
+
PaddingUnitValue,
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
export interface PaddingProps {
|
|
21
|
+
padding?: PaddingValue;
|
|
22
|
+
paddingHorizontal?: UIKitSizeValue;
|
|
23
|
+
paddingVertical?: UIKitSizeValue;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function PaddingValue(
|
|
27
|
+
padding?: PaddingValue,
|
|
28
|
+
): string | number | undefined {
|
|
29
|
+
if (padding === undefined || padding === null) {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (Array.isArray(padding)) {
|
|
34
|
+
return padding.map((value) => Size(value)).join(" ");
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return Size(padding as UIKitSizeValue);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function resolvePadding(
|
|
41
|
+
padding?: PaddingValue,
|
|
42
|
+
paddingHorizontal?: UIKitSizeValue,
|
|
43
|
+
paddingVertical?: UIKitSizeValue,
|
|
44
|
+
): string | number | undefined {
|
|
45
|
+
if (paddingHorizontal !== undefined || paddingVertical !== undefined) {
|
|
46
|
+
const vertical = Size(paddingVertical);
|
|
47
|
+
const horizontal = Size(paddingHorizontal);
|
|
48
|
+
return `${vertical ?? 0} ${horizontal ?? 0}`;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return PaddingValue(padding);
|
|
52
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import type React from "react";
|
|
4
|
+
import View from "@/packages/Frameworks/View/View";
|
|
5
|
+
|
|
6
|
+
interface StopParentInteractionProps {
|
|
7
|
+
children: React.ReactNode;
|
|
8
|
+
className?: string;
|
|
9
|
+
style?: React.CSSProperties;
|
|
10
|
+
blockDefault?: boolean;
|
|
11
|
+
alignItems?: "center" | "start" | "end" | "stretch";
|
|
12
|
+
gap?: number;
|
|
13
|
+
"data-stop-parent-interaction-state"?: boolean;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export default function StopParentInteraction({
|
|
17
|
+
children,
|
|
18
|
+
className,
|
|
19
|
+
style,
|
|
20
|
+
blockDefault,
|
|
21
|
+
alignItems,
|
|
22
|
+
gap,
|
|
23
|
+
"data-stop-parent-interaction-state": dataStopState,
|
|
24
|
+
}: StopParentInteractionProps) {
|
|
25
|
+
const handleInteraction = (event: React.MouseEvent) => {
|
|
26
|
+
if (blockDefault) {
|
|
27
|
+
event.preventDefault();
|
|
28
|
+
}
|
|
29
|
+
event.stopPropagation();
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<View
|
|
34
|
+
alignItems={alignItems}
|
|
35
|
+
gap={gap}
|
|
36
|
+
className={className}
|
|
37
|
+
style={style}
|
|
38
|
+
data-stop-parent-interaction-state={dataStopState}
|
|
39
|
+
onMouseDown={handleInteraction}
|
|
40
|
+
onClick={handleInteraction}
|
|
41
|
+
>
|
|
42
|
+
{children}
|
|
43
|
+
</View>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { CSSProperties } from "react";
|
|
2
|
+
import type { UIKitSizeValue } from "@/packages/Frameworks/_shared/sizing";
|
|
3
|
+
|
|
4
|
+
export interface WindProps {
|
|
5
|
+
width?: UIKitSizeValue;
|
|
6
|
+
height?: UIKitSizeValue;
|
|
7
|
+
margin?: UIKitSizeValue;
|
|
8
|
+
gap?: UIKitSizeValue;
|
|
9
|
+
alignItems?: CSSProperties["alignItems"];
|
|
10
|
+
justifyContent?: CSSProperties["justifyContent"];
|
|
11
|
+
alignSelf?: CSSProperties["alignSelf"];
|
|
12
|
+
column?: boolean;
|
|
13
|
+
row?: boolean;
|
|
14
|
+
fullWidth?: boolean;
|
|
15
|
+
opacity?: CSSProperties["opacity"];
|
|
16
|
+
noSquircle?: boolean;
|
|
17
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useEffect } from "react";
|
|
4
|
+
|
|
5
|
+
let bodyScrollLockCount = 0;
|
|
6
|
+
let bodyScrollTouchStartY = 0;
|
|
7
|
+
|
|
8
|
+
type BodyScrollLockSnapshot = {
|
|
9
|
+
overflow: string;
|
|
10
|
+
overscrollBehavior: string;
|
|
11
|
+
documentOverflow: string;
|
|
12
|
+
documentOverscrollBehavior: string;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
let originalBodyStyles: BodyScrollLockSnapshot | null = null;
|
|
16
|
+
|
|
17
|
+
function getScrollableAncestor(target: EventTarget | null) {
|
|
18
|
+
if (!(target instanceof Element)) return null;
|
|
19
|
+
|
|
20
|
+
let element: Element | null = target;
|
|
21
|
+
while (element && element !== document.body) {
|
|
22
|
+
if (element instanceof HTMLElement) {
|
|
23
|
+
const style = window.getComputedStyle(element);
|
|
24
|
+
const canScrollY =
|
|
25
|
+
/(auto|scroll)/.test(style.overflowY) &&
|
|
26
|
+
element.scrollHeight > element.clientHeight;
|
|
27
|
+
|
|
28
|
+
if (canScrollY) return element;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
element = element.parentElement;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function handleBodyScrollTouchStart(event: TouchEvent) {
|
|
38
|
+
bodyScrollTouchStartY = event.touches[0]?.clientY ?? 0;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function handleBodyScrollTouchMove(event: TouchEvent) {
|
|
42
|
+
const currentY = event.touches[0]?.clientY ?? bodyScrollTouchStartY;
|
|
43
|
+
const deltaY = currentY - bodyScrollTouchStartY;
|
|
44
|
+
const scrollable = getScrollableAncestor(event.target);
|
|
45
|
+
|
|
46
|
+
if (!scrollable) {
|
|
47
|
+
event.preventDefault();
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const isAtTop = scrollable.scrollTop <= 0;
|
|
52
|
+
const isAtBottom =
|
|
53
|
+
scrollable.scrollTop + scrollable.clientHeight >= scrollable.scrollHeight;
|
|
54
|
+
|
|
55
|
+
if ((isAtTop && deltaY > 0) || (isAtBottom && deltaY < 0)) {
|
|
56
|
+
event.preventDefault();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function acquireBodyScrollLock() {
|
|
61
|
+
if (typeof document === "undefined") return;
|
|
62
|
+
|
|
63
|
+
const body = document.body;
|
|
64
|
+
const root = document.documentElement;
|
|
65
|
+
|
|
66
|
+
if (bodyScrollLockCount === 0) {
|
|
67
|
+
originalBodyStyles = {
|
|
68
|
+
overflow: body.style.overflow,
|
|
69
|
+
overscrollBehavior: body.style.overscrollBehavior,
|
|
70
|
+
documentOverflow: root.style.overflow,
|
|
71
|
+
documentOverscrollBehavior: root.style.overscrollBehavior,
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
body.style.overflow = "hidden";
|
|
75
|
+
body.style.overscrollBehavior = "none";
|
|
76
|
+
root.style.overflow = "hidden";
|
|
77
|
+
root.style.overscrollBehavior = "none";
|
|
78
|
+
document.addEventListener("touchstart", handleBodyScrollTouchStart, {
|
|
79
|
+
passive: true,
|
|
80
|
+
});
|
|
81
|
+
document.addEventListener("touchmove", handleBodyScrollTouchMove, {
|
|
82
|
+
passive: false,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
bodyScrollLockCount += 1;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function releaseBodyScrollLock() {
|
|
90
|
+
if (typeof document === "undefined") return;
|
|
91
|
+
if (bodyScrollLockCount === 0) return;
|
|
92
|
+
|
|
93
|
+
bodyScrollLockCount -= 1;
|
|
94
|
+
if (bodyScrollLockCount > 0) return;
|
|
95
|
+
|
|
96
|
+
const body = document.body;
|
|
97
|
+
const root = document.documentElement;
|
|
98
|
+
const snapshot = originalBodyStyles;
|
|
99
|
+
|
|
100
|
+
document.removeEventListener("touchstart", handleBodyScrollTouchStart);
|
|
101
|
+
document.removeEventListener("touchmove", handleBodyScrollTouchMove);
|
|
102
|
+
originalBodyStyles = null;
|
|
103
|
+
|
|
104
|
+
if (!snapshot) return;
|
|
105
|
+
|
|
106
|
+
body.style.overflow = snapshot.overflow;
|
|
107
|
+
body.style.overscrollBehavior = snapshot.overscrollBehavior;
|
|
108
|
+
root.style.overflow = snapshot.documentOverflow;
|
|
109
|
+
root.style.overscrollBehavior = snapshot.documentOverscrollBehavior;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function useScrollLock(locked = true) {
|
|
113
|
+
useEffect(() => {
|
|
114
|
+
if (!locked) return;
|
|
115
|
+
|
|
116
|
+
acquireBodyScrollLock();
|
|
117
|
+
|
|
118
|
+
return () => {
|
|
119
|
+
releaseBodyScrollLock();
|
|
120
|
+
};
|
|
121
|
+
}, [locked]);
|
|
122
|
+
|
|
123
|
+
return {
|
|
124
|
+
lockScroll: acquireBodyScrollLock,
|
|
125
|
+
openScroll: releaseBodyScrollLock,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
function isAlreadyResolvedImageSrc(value: string) {
|
|
2
|
+
return /^(https?:\/\/|\/|data:|blob:)/i.test(value);
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function normalizeUIKitImageSrc(src?: string) {
|
|
6
|
+
const resolvedSrc = typeof src === "string" ? src.trim() : "";
|
|
7
|
+
|
|
8
|
+
if (!resolvedSrc) {
|
|
9
|
+
return "";
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
if (isAlreadyResolvedImageSrc(resolvedSrc)) {
|
|
13
|
+
return resolvedSrc;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return `/${resolvedSrc}`;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function normalizeBrandIconClass(iconBrand?: string) {
|
|
20
|
+
if (!iconBrand) {
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
if (/^iBrand[A-Z]/.test(iconBrand)) {
|
|
24
|
+
return iconBrand;
|
|
25
|
+
}
|
|
26
|
+
if (/^i[A-Z]/.test(iconBrand)) {
|
|
27
|
+
return `iBrand${iconBrand.slice(1)}`;
|
|
28
|
+
}
|
|
29
|
+
return `iBrand${iconBrand}`;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function normalizeLang(language?: string) {
|
|
33
|
+
const raw = (language || "text").toLowerCase();
|
|
34
|
+
if (raw === "html") return "markup";
|
|
35
|
+
if (raw === "js") return "javascript";
|
|
36
|
+
if (raw === "ts") return "typescript";
|
|
37
|
+
if (raw === "md") return "markdown";
|
|
38
|
+
return raw;
|
|
39
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export type UIKitSizeValue = number | string;
|
|
2
|
+
|
|
3
|
+
function normalizeNumericSize(value: number) {
|
|
4
|
+
const remValue = value / 10;
|
|
5
|
+
return `${Number.isInteger(remValue) ? remValue.toFixed(0) : remValue}rem`;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function Size(value?: UIKitSizeValue | null) {
|
|
9
|
+
if (value === undefined || value === null || value === "") {
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
14
|
+
return normalizeNumericSize(value);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return value;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function SizePX(
|
|
21
|
+
value: UIKitSizeValue | undefined,
|
|
22
|
+
fallback: number,
|
|
23
|
+
rootFontSize = 16,
|
|
24
|
+
) {
|
|
25
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
26
|
+
return value * 0.1 * rootFontSize;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (typeof value === "string") {
|
|
30
|
+
const normalized = value.trim().toLowerCase();
|
|
31
|
+
const numeric = parsePixelValue(normalized);
|
|
32
|
+
|
|
33
|
+
if (numeric === undefined) return fallback;
|
|
34
|
+
if (normalized.endsWith("px")) return numeric;
|
|
35
|
+
if (normalized.endsWith("rem")) return numeric * rootFontSize;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return fallback;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function parsePixelValue(value?: string | null) {
|
|
42
|
+
if (!value) return undefined;
|
|
43
|
+
|
|
44
|
+
const numeric = Number.parseFloat(value);
|
|
45
|
+
if (!Number.isFinite(numeric)) return undefined;
|
|
46
|
+
|
|
47
|
+
return numeric;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function getComputedPixelValue(
|
|
51
|
+
element: Element,
|
|
52
|
+
property: keyof CSSStyleDeclaration,
|
|
53
|
+
) {
|
|
54
|
+
return parsePixelValue(window.getComputedStyle(element)[property] as string);
|
|
55
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
|
|
3
|
+
interface UseControllableStateOptions<T> {
|
|
4
|
+
value?: T;
|
|
5
|
+
defaultValue: T;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function useControllableState<T>({
|
|
9
|
+
value,
|
|
10
|
+
defaultValue,
|
|
11
|
+
}: UseControllableStateOptions<T>) {
|
|
12
|
+
const [internalValue, setInternalValue] = useState(defaultValue);
|
|
13
|
+
const isControlled = value !== undefined;
|
|
14
|
+
const currentValue = isControlled ? value : internalValue;
|
|
15
|
+
|
|
16
|
+
const setValue = (nextValue: T | ((prevValue: T) => T)) => {
|
|
17
|
+
if (isControlled) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
setInternalValue((prevValue) =>
|
|
22
|
+
typeof nextValue === "function"
|
|
23
|
+
? (nextValue as (prevValue: T) => T)(prevValue)
|
|
24
|
+
: nextValue,
|
|
25
|
+
);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
return [currentValue, setValue, isControlled] as const;
|
|
29
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--transition-surface-duration: 420ms; // keep in sync with THEME_COLOR_TRANSITION_MS
|
|
3
|
+
--transition-surface-ease: cubic-bezier(0.22, 1, 0.36, 1);
|
|
4
|
+
--transition-background: background var(--transition-surface-duration)
|
|
5
|
+
var(--transition-surface-ease);
|
|
6
|
+
--transition-color: color 250ms ease-out;
|
|
7
|
+
--transition-font-size: font-size 250ms ease-out;
|
|
8
|
+
--transition-opacity: opacity 250ms ease-out;
|
|
9
|
+
--transition-border: border var(--transition-surface-duration)
|
|
10
|
+
var(--transition-surface-ease);
|
|
11
|
+
--transition-transform: transform 250ms ease-out;
|
|
12
|
+
--transition-shadow: box-shadow 250ms ease-out;
|
|
13
|
+
--transition-radius: border-radius 250ms ease-out;
|
|
14
|
+
--transition-filter: filter 250ms ease-out, backdrop-filter 250ms ease-out;
|
|
15
|
+
--transition-fill: fill 250ms ease-out;
|
|
16
|
+
--transition-stroke: stroke 250ms ease-out;
|
|
17
|
+
--transition-icon:
|
|
18
|
+
var(--transition-fill), var(--transition-stroke), var(--transition-color);
|
|
19
|
+
--transition-surface:
|
|
20
|
+
var(--transition-border), var(--transition-background),
|
|
21
|
+
var(--transition-outline);
|
|
22
|
+
--transition-default:
|
|
23
|
+
var(--transition-background), var(--transition-color),
|
|
24
|
+
var(--transition-font-size), var(--transition-outline),
|
|
25
|
+
var(--transition-opacity), var(--transition-border),
|
|
26
|
+
var(--transition-transform);
|
|
27
|
+
--transition-fade: opacity 250ms ease-in-out;
|
|
28
|
+
--transition-pressable:
|
|
29
|
+
background 200ms ease, opacity 200ms ease, transform 200ms ease,
|
|
30
|
+
box-shadow 200ms ease;
|
|
31
|
+
--transition-pressable-content: opacity 200ms ease, color 200ms ease;
|
|
32
|
+
--transition-slide:
|
|
33
|
+
left 250ms cubic-bezier(0.4, 0, 0.2, 1),
|
|
34
|
+
width 250ms cubic-bezier(0.4, 0, 0.2, 1), opacity 200ms ease;
|
|
35
|
+
--transition-image:
|
|
36
|
+
transform 150ms ease, box-shadow 150ms ease, outline-color 150ms ease;
|
|
37
|
+
--transition-image-thumbnail:
|
|
38
|
+
opacity 150ms ease, border-color 150ms ease, transform 150ms ease;
|
|
39
|
+
--transition-color-fast: color 150ms ease;
|
|
40
|
+
--s-shallow: scaleX(0.99) scaleY(0.99);
|
|
41
|
+
--s: scaleX(0.96) scaleY(0.96);
|
|
42
|
+
}
|