@musecat/uikit 0.1.1 → 0.1.2

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 (56) hide show
  1. package/.agents/references/Components/Box.md +60 -0
  2. package/.agents/references/Components/Button.md +49 -0
  3. package/.agents/references/Components/Card.md +67 -0
  4. package/.agents/references/Components/Checkbox.md +48 -0
  5. package/.agents/references/Components/CodeBox.md +31 -0
  6. package/.agents/references/Components/ContextMenu.md +82 -0
  7. package/.agents/references/Components/ContributionGraph.md +61 -0
  8. package/.agents/references/Components/DatePicker.md +92 -0
  9. package/.agents/references/Components/Divider.md +56 -0
  10. package/.agents/references/Components/Header.md +52 -0
  11. package/.agents/references/Components/Icon.md +82 -0
  12. package/.agents/references/Components/Input.md +60 -0
  13. package/.agents/references/Components/Label.md +78 -0
  14. package/.agents/references/Components/Layout.md +102 -0
  15. package/.agents/references/Components/Maps.md +63 -0
  16. package/.agents/references/Components/Nav.md +68 -0
  17. package/.agents/references/Components/Pagination.md +67 -0
  18. package/.agents/references/Components/Pill.md +75 -0
  19. package/.agents/references/Components/Profile.md +76 -0
  20. package/.agents/references/Components/Progress.md +72 -0
  21. package/.agents/references/Components/Radio.md +68 -0
  22. package/.agents/references/Components/Select.md +80 -0
  23. package/.agents/references/Components/Skeleton.md +48 -0
  24. package/.agents/references/Components/Spinner.md +62 -0
  25. package/.agents/references/Components/Text.md +73 -0
  26. package/.agents/references/Components/TimePicker.md +72 -0
  27. package/.agents/references/Components/Timeline.md +97 -0
  28. package/.agents/references/Components/Title.md +108 -0
  29. package/.agents/references/Components/Toggle.md +53 -0
  30. package/.agents/references/Components/Tooltip.md +62 -0
  31. package/.agents/references/Frameworks/DNDView.md +82 -0
  32. package/.agents/references/Frameworks/Dialog.md +109 -0
  33. package/.agents/references/Frameworks/EdgeEffect.md +64 -0
  34. package/.agents/references/Frameworks/HScrollView.md +76 -0
  35. package/.agents/references/Frameworks/ImageView.md +67 -0
  36. package/.agents/references/Frameworks/Motion.md +62 -0
  37. package/.agents/references/Frameworks/Pressable.md +79 -0
  38. package/.agents/references/Frameworks/Squircle.md +50 -0
  39. package/.agents/references/Frameworks/Theme.md +68 -0
  40. package/.agents/references/Frameworks/Toaster.md +67 -0
  41. package/.agents/references/Frameworks/View.md +81 -0
  42. package/.agents/references/Frameworks/_shared.md +74 -0
  43. package/.agents/references/Styles/Animation.md +43 -0
  44. package/.agents/references/Styles/Color.md +45 -0
  45. package/.agents/references/Styles/Font.md +37 -0
  46. package/.agents/references/Styles/Icon.md +43 -0
  47. package/.agents/references/Styles/Importer.md +19 -0
  48. package/.agents/references/Styles/System.md +27 -0
  49. package/.agents/references/Styles/Textstyle.md +45 -0
  50. package/.agents/references/Styles/Theme.md +51 -0
  51. package/.agents/references/Styles/Viewport-global.md +42 -0
  52. package/.agents/references/Styles/Viewport.md +42 -0
  53. package/README.md +4 -0
  54. package/package.json +2 -1
  55. package/packages/Styles/_icon.scss +2 -0
  56. package/packages/Styles/_importer.scss +0 -1
@@ -0,0 +1,62 @@
1
+ # Tooltip
2
+
3
+ ## 1. Purpose
4
+
5
+ A component that displays a popup bubble (`content`) with additional explanation or information when hovering over or focusing a specific UI element (`trigger`).
6
+
7
+ ## 2. Usage Logic
8
+
9
+ - Positions the `content` popup above the React element passed as `trigger`.
10
+ - Built-in position auto-adjustment (clamp and flip) logic calculates and adjusts (ClampShift) the position so it is not clipped at screen edges.
11
+ - The `placement` prop specifies the bubble's default position and alignment direction (default: `"top"`).
12
+ - The `delay` prop adjusts the delay before the tooltip appears on hover.
13
+ - Flexible controlled and uncontrolled usage via `open`, `defaultOpen`, `onOpenChange`.
14
+ - Setting `interactive` to `true` keeps the bubble from disappearing immediately when the mouse moves over it, enabling interaction.
15
+
16
+ ## 3. Type Signatures
17
+
18
+ ```tsx
19
+ export type TooltipPlacement =
20
+ "top" | "top-start" | "top-end" | "bottom" | "bottom-start" | "bottom-end";
21
+
22
+ export interface TooltipProps extends BorderProps {
23
+ trigger: React.ReactNode;
24
+ content: React.ReactNode;
25
+ placement?: TooltipPlacement;
26
+ open?: boolean;
27
+ defaultOpen?: boolean;
28
+ onOpenChange?: (open: boolean) => void;
29
+ delay?: number;
30
+ disabled?: boolean;
31
+ interactive?: boolean;
32
+ flip?: boolean;
33
+ className?: string;
34
+ contentClassName?: string;
35
+ maxWidth?: number | string;
36
+
37
+ themePreset?: ThemePreset;
38
+ background?: ThemeBackgroundPaint;
39
+ color?: ThemePaint;
40
+ radius?: RadiusValue;
41
+
42
+ "data-color-mode"?: string;
43
+ }
44
+ ```
45
+
46
+ ## 4. Example Code
47
+
48
+ ```tsx
49
+ import Tooltip from "./Tooltip";
50
+ import Pressable from "../../Frameworks/Pressable/Pressable";
51
+
52
+ function Example() {
53
+ return (
54
+ <Tooltip
55
+ placement="top"
56
+ content="This is some additional information."
57
+ delay={300}
58
+ trigger={<Pressable>Hover me</Pressable>}
59
+ />
60
+ );
61
+ }
62
+ ```
@@ -0,0 +1,82 @@
1
+ # DNDView Framework
2
+
3
+ ## Purpose
4
+
5
+ `DNDView` is a component that provides list reordering (Reorder) via drag-and-drop (DnD). Internally uses `@dnd-kit/core` and `@dnd-kit/sortable`, fully supporting mouse, touch, and keyboard accessibility.
6
+
7
+ ## Usage Logic
8
+
9
+ - Provide an `items` array and a `getKey` function to uniquely identify them.
10
+ - Define each item's appearance via the `renderItem` function; rendering the `handle` property from the `state` argument passed in makes that area the drag handle.
11
+ - When order changes, the `onReorder(newItems)` callback is called, so update state in the parent component.
12
+ - The `strategy` prop selects the sorting algorithm (`vertical`, `horizontal`, `rect`), and keyboard navigation is optimized for direction-key movement per this strategy.
13
+
14
+ ## Type Signatures
15
+
16
+ ```typescript
17
+ import type { UniqueIdentifier } from "@dnd-kit/core";
18
+ import type { ReactNode } from "react";
19
+
20
+ export type DNDViewItemState<T> = {
21
+ item: T;
22
+ id: UniqueIdentifier;
23
+ index: number;
24
+ dragging: boolean;
25
+ sorting: boolean;
26
+ handle: ReactNode;
27
+ };
28
+
29
+ export type DNDViewStrategy = "vertical" | "horizontal" | "rect";
30
+
31
+ export interface DNDViewProps<T> extends ViewProps {
32
+ items: T[];
33
+ onReorder: (items: T[]) => void;
34
+ getKey: (item: T) => UniqueIdentifier;
35
+ renderItem: (item: T, state: DNDViewItemState<T>) => ReactNode;
36
+ renderHandle?: (
37
+ props: HTMLAttributes<HTMLElement>,
38
+ state: DNDViewItemState<T>,
39
+ ) => ReactNode;
40
+ dragHandle?: boolean;
41
+ keyboard?: boolean;
42
+ strategy?: DNDViewStrategy;
43
+ }
44
+ ```
45
+
46
+ ## Example Code
47
+
48
+ ```tsx
49
+ import View from "@/packages/Frameworks/View";
50
+ import { useState } from "react";
51
+
52
+ function SortableList() {
53
+ const [items, setItems] = useState([
54
+ { id: "1", name: "Item 1" },
55
+ { id: "2", name: "Item 2" },
56
+ { id: "3", name: "Item 3" },
57
+ ]);
58
+
59
+ return (
60
+ <View.DND
61
+ items={items}
62
+ getKey={(item) => item.id}
63
+ onReorder={setItems}
64
+ strategy="vertical"
65
+ gap={8}
66
+ renderItem={(item, { dragging, handle }) => (
67
+ <View
68
+ row
69
+ alignItems="center"
70
+ padding={16}
71
+ radius="R8"
72
+ background="Base1"
73
+ shadow={dragging ? "Bold" : "None"} // emphasize while dragging
74
+ >
75
+ {handle} {/* Grab and drag this part */}
76
+ <span style={{ marginLeft: 16 }}>{item.name}</span>
77
+ </View>
78
+ )}
79
+ />
80
+ );
81
+ }
82
+ ```
@@ -0,0 +1,109 @@
1
+ # Dialog Framework
2
+
3
+ ## Purpose
4
+
5
+ The `Dialog` framework is a universal framework that centrally manages all overlay UI such as popover, modal, sheet, and funnel. It supports both a global-state-based imperative API (`dialog(...)`) and a declarative component (`<Dialog />`).
6
+
7
+ ## Usage Logic
8
+
9
+ - **Imperative**: Call `dialog.modal({ ... })` or `dialog.popover(element, { ... })` to render a dialog from anywhere. (Mounting `<DialogBootstrap />` somewhere in the app root is required)
10
+ - **Declarative**: Declare inside a component's JSX as `<Dialog open={isOpen} onOpenChange={setIsOpen} mode="modal" ... />`.
11
+ - **Per-mode characteristics**:
12
+ - `popover`: Positioned around a specific element (`anchorRef`).
13
+ - `modal`: A traditional modal positioned at the center of the screen.
14
+ - `sheet`: A Bottom Sheet that rises from the bottom on mobile. (Supports gestures, snap points)
15
+ - `mobileMode`: A useful option that is `modal` on desktop but automatically converts to `sheet` on mobile (when `isMobile` condition is met).
16
+ - **Common components**: Header, Footer (button arrangement automation), background (Dim), exit animation handling, keyboard Escape handling, etc.
17
+
18
+ ## Type Signatures
19
+
20
+ ```typescript
21
+ import type { ReactNode, RefObject } from "react";
22
+ import type {
23
+ PopoverConfig,
24
+ ModalConfig,
25
+ SheetConfig,
26
+ FunnelConfig,
27
+ ExitConfig,
28
+ } from "./Dialog.types";
29
+ import type { ThemeSystemProps, BorderProps } from "../Theme/Theme.types";
30
+ import type { RadiusProps } from "../Theme/Radius.types";
31
+
32
+ export type DialogMode = "popover" | "modal" | "sheet";
33
+ export type DialogMobileMode = "modal" | "sheet";
34
+
35
+ // Shared by all mode configs
36
+ type DialogBaseConfig = ThemeSystemProps & BorderProps & RadiusProps;
37
+
38
+ export interface DialogProps {
39
+ open?: boolean;
40
+ onOpenChange?: (open: boolean) => void;
41
+ id?: string;
42
+ mode: DialogMode;
43
+ mobileMode?: DialogMobileMode;
44
+
45
+ // Per-mode config (choose one)
46
+ popover?: PopoverConfig;
47
+ modal?: ModalConfig;
48
+ sheet?: SheetConfig;
49
+ funnel?: FunnelConfig; // multi-step funnel flow control
50
+
51
+ content?: ReactNode; // dialog body
52
+ exit?: ExitConfig; // outside click, cancel button behavior
53
+ }
54
+
55
+ // Imperative API
56
+ export function dialog(props: DialogProps): DialogInstance;
57
+ dialog.modal = (props: Omit<DialogProps, "mode">) => DialogInstance;
58
+ dialog.sheet = (props: Omit<DialogProps, "mode">) => DialogInstance;
59
+ dialog.popover = (anchor: HTMLElement, props: Omit<DialogProps, "mode">) =>
60
+ DialogInstance;
61
+ ```
62
+
63
+ ## Example Code
64
+
65
+ ```tsx
66
+ import Dialog, { dialog } from "@/packages/Frameworks/Dialog/Dialog";
67
+ import Pressable from "@/packages/Frameworks/Pressable";
68
+ import { useState } from "react";
69
+
70
+ function Example() {
71
+ const [open, setOpen] = useState(false);
72
+
73
+ // 1. Imperative modal call
74
+ const showModal = () => {
75
+ dialog.modal({
76
+ modal: {
77
+ header: { title: "Imperative Modal" },
78
+ footer: {
79
+ buttons: [{ text: "Confirm", onClick: (e, close) => close() }],
80
+ },
81
+ },
82
+ content: <div>This modal can be called from anywhere.</div>,
83
+ });
84
+ };
85
+
86
+ return (
87
+ <div>
88
+ <button onClick={showModal}>Open Imperative Modal</button>
89
+ <button onClick={() => setOpen(true)}>Open Declarative Sheet</button>
90
+
91
+ {/* 2. Declarative sheet rendering */}
92
+ <Dialog
93
+ mode="sheet"
94
+ open={open}
95
+ onOpenChange={setOpen}
96
+ sheet={{
97
+ header: { title: "Select Option" },
98
+ snapPoints: [300, 600],
99
+ }}
100
+ >
101
+ <div style={{ padding: 20 }}>
102
+ <Pressable>Menu 1</Pressable>
103
+ <Pressable>Menu 2</Pressable>
104
+ </div>
105
+ </Dialog>
106
+ </div>
107
+ );
108
+ }
109
+ ```
@@ -0,0 +1,64 @@
1
+ # EdgeEffect Framework
2
+
3
+ ## Purpose
4
+
5
+ The `EdgeEffect` framework adds a blurry gradient overlay to a specific directional edge (top, bottom, left, right) of a container, providing a visual effect where the inner content fades out smoothly at both ends of the screen.
6
+
7
+ ## Usage Logic
8
+
9
+ - Rendered on top of the `View` component and mainly used to apply a gradient to the edge of a scrollable element.
10
+ - Specifying one of `"left"`, `"right"`, `"top"`, `"bottom"` for the `side` prop spreads the gradient toward the opposite direction of that side.
11
+ - `pointerEvents: "none"` is applied by default so it does not interfere with click/touch events.
12
+
13
+ ## Type Signatures
14
+
15
+ ```typescript
16
+ import type { ViewProps } from "../View/View.types";
17
+
18
+ export interface EdgeEffectProps extends Omit<ViewProps, "children"> {
19
+ side?: "left" | "right" | "top" | "bottom";
20
+ }
21
+ ```
22
+
23
+ ## Example Code
24
+
25
+ ```tsx
26
+ import EdgeEffect from "@/packages/Frameworks/EdgeEffect";
27
+ import View from "@/packages/Frameworks/View";
28
+
29
+ function ScrollContainer() {
30
+ return (
31
+ <View style={{ position: "relative", height: 300, overflow: "hidden" }}>
32
+ {/* Top edge fade effect */}
33
+ <EdgeEffect
34
+ side="top"
35
+ style={{
36
+ position: "absolute",
37
+ top: 0,
38
+ left: 0,
39
+ right: 0,
40
+ height: 40,
41
+ zIndex: 10,
42
+ }}
43
+ />
44
+
45
+ <View style={{ overflowY: "auto", height: "100%" }}>
46
+ {/* contents... */}
47
+ </View>
48
+
49
+ {/* Bottom edge fade effect */}
50
+ <EdgeEffect
51
+ side="bottom"
52
+ style={{
53
+ position: "absolute",
54
+ bottom: 0,
55
+ left: 0,
56
+ right: 0,
57
+ height: 40,
58
+ zIndex: 10,
59
+ }}
60
+ />
61
+ </View>
62
+ );
63
+ }
64
+ ```
@@ -0,0 +1,76 @@
1
+ # HScrollView Framework
2
+
3
+ ## Purpose
4
+
5
+ `HScrollView` is a horizontal scroll container supporting both mobile and desktop environments. Internally uses `embla-carousel-react` to provide a smooth horizontal scroll experience based on touch swipe and mouse wheel, and can automatically apply EdgeEffect at both ends.
6
+
7
+ ## Usage Logic
8
+
9
+ - The `active` prop specifies whether scrolling is enabled. Passing a string-based viewport breakpoint ("w1", "w2", "w3", "w4") allows responsive activation of the swiper only below a specific breakpoint.
10
+ - The carousel engine (Embla) is activated only when there are multiple child elements; with one or fewer, or when inactive, it falls back to a normal Flexbox structure.
11
+ - The `renderControls` render prop can freely inject left/right scroll control buttons outside or inside the swiper.
12
+
13
+ ## Type Signatures
14
+
15
+ ```typescript
16
+ import type { CSSProperties, ReactNode } from "react";
17
+ import type { ViewProps } from "../View.types";
18
+
19
+ export type HScrollViewViewport = "w1" | "w2" | "w3" | "w4";
20
+ export type HScrollViewActive = boolean | HScrollViewViewport;
21
+
22
+ export interface HScrollViewControls {
23
+ scrollPrev: () => void;
24
+ scrollNext: () => void;
25
+ canScrollPrev: boolean;
26
+ canScrollNext: boolean;
27
+ isScrollActive: boolean;
28
+ }
29
+
30
+ export interface HScrollViewProps extends Omit<
31
+ HTMLAttributes<HTMLDivElement>,
32
+ "color"
33
+ > {
34
+ active?: HScrollViewActive;
35
+ rootStyle?: CSSProperties;
36
+ containerStyle?: CSSProperties;
37
+ activeContainerStyle?: CSSProperties;
38
+ inactiveContainerStyle?: CSSProperties;
39
+ itemWidth?: number | string;
40
+ itemHeight?: number | string;
41
+ renderControls?: (controls: HScrollViewControls) => ReactNode;
42
+ showEdgeEffect?: boolean;
43
+ // ... ViewProps (gap, padding, margin, width, theme, etc.)
44
+ }
45
+ ```
46
+
47
+ ## Example Code
48
+
49
+ ```tsx
50
+ import HScrollView from "@/packages/Frameworks/View/HScrollView/HScrollView";
51
+ import View from "@/packages/Frameworks/View";
52
+
53
+ function HorizontalList() {
54
+ return (
55
+ <HScrollView
56
+ active="w3" // enable horizontal scroll only below 768px
57
+ gap={16}
58
+ showEdgeEffect={true}
59
+ itemWidth="20rem"
60
+ >
61
+ <View background="Base3" padding={24}>
62
+ Item 1
63
+ </View>
64
+ <View background="Base3" padding={24}>
65
+ Item 2
66
+ </View>
67
+ <View background="Base3" padding={24}>
68
+ Item 3
69
+ </View>
70
+ <View background="Base3" padding={24}>
71
+ Item 4
72
+ </View>
73
+ </HScrollView>
74
+ );
75
+ }
76
+ ```
@@ -0,0 +1,67 @@
1
+ # ImageView Framework
2
+
3
+ ## Purpose
4
+
5
+ The `ImageView` framework is a composite component that renders (single and multiple) images optimally and provides a full-screen or popup modal zoom/slide view (gallery) on click. Internally supports Next.js's `next/image`, and uses `embla-carousel` in slide mode.
6
+
7
+ ## Usage Logic
8
+
9
+ - Passing a single string to `src` renders one image; passing an array (`string[]` or `ImageItem[]`) displays it as a horizontally scrolling gallery.
10
+ - Passing the `dialog` prop opens an immersive image viewer as a modal based on the `Dialog` framework when the image is clicked.
11
+ - Includes its own blur data generation utility (fallback blur) to provide a natural placeholder during loading.
12
+
13
+ ## Type Signatures
14
+
15
+ ```typescript
16
+ export type ImageItem = {
17
+ id: number;
18
+ src: string;
19
+ alt: string;
20
+ srcDialog?: string; // high-quality image to show in dialog mode
21
+ blurDataURL?: string;
22
+ };
23
+
24
+ export interface ImageProps extends RadiusProps {
25
+ src: string | string[] | ImageItem[];
26
+ alt?: string | string[];
27
+ width?: number | string | (number | string)[];
28
+ height?: number | string | (number | string)[];
29
+ priority?: boolean;
30
+ groupWidth?: string;
31
+ groupHeight?: string;
32
+ groupGap?: number | string;
33
+ overlay?: ReactNode | ReactNode[];
34
+ control?: boolean | { left?: boolean; right?: boolean /* ... */ };
35
+ dialog?: {
36
+ overlay?: ReactNode | ReactNode[];
37
+ header?: { content?: ReactNode };
38
+ footer?: { list?: boolean; counter?: boolean /* ... */ };
39
+ };
40
+ }
41
+ ```
42
+
43
+ ## Example Code
44
+
45
+ ```tsx
46
+ import View from "@/packages/Frameworks/View";
47
+
48
+ function PhotoGallery() {
49
+ const images = [
50
+ { id: 1, src: "/img1.jpg", alt: "Photo 1" },
51
+ { id: 2, src: "/img2.jpg", alt: "Photo 2" },
52
+ ];
53
+
54
+ return (
55
+ <ImageView
56
+ src={images}
57
+ radius="R12"
58
+ groupWidth="240px"
59
+ groupHeight="160px"
60
+ control={{ left: true, right: true }}
61
+ dialog={{
62
+ footer: { list: true, counter: true },
63
+ }}
64
+ />
65
+ );
66
+ }
67
+ ```
@@ -0,0 +1,62 @@
1
+ # Motion Framework
2
+
3
+ ## Purpose
4
+
5
+ The `Motion` framework is used to provide consistent animation effects and transition presets within UIKit. It centrally manages `framer-motion` (or `motion/react`) configuration values mainly applied to motion-based interfaces such as modals, sheets, and popovers.
6
+
7
+ ## Usage Logic
8
+
9
+ - `motionTransitions`: An object managing animation physical properties (stiffness, damping, mass, etc.). Defines default behaviors such as spring or tween.
10
+ - `motionPresets`: Provides `initial`, `animate`, `exit` state definition objects or factory functions for specific UI components like modal, popover, and backdrop.
11
+
12
+ ## Type Signatures
13
+
14
+ ```typescript
15
+ // Inside Motion.presets.ts
16
+
17
+ export const motionTransitions = {
18
+ sheet: { snap, entrance, exit },
19
+ modal: { transition },
20
+ popover: { transition },
21
+ backdrop: { transition },
22
+ };
23
+
24
+ export const motionPresets = {
25
+ modal: { initial, animate, exit, transition },
26
+ popover: (isPositionReady: boolean) => ({
27
+ initial,
28
+ animate,
29
+ exit,
30
+ transition,
31
+ }),
32
+ backdrop: (open?: boolean) => ({ initial, animate, exit, transition }),
33
+ };
34
+ ```
35
+
36
+ ## Example Code
37
+
38
+ ```tsx
39
+ import { motion } from "motion/react";
40
+ import { motionPresets } from "@/packages/Frameworks/Motion";
41
+
42
+ function AnimatedModal({ isOpen, children }) {
43
+ return (
44
+ <AnimatePresence>
45
+ {isOpen && (
46
+ <>
47
+ {/* Backdrop animation */}
48
+ <motion.div
49
+ {...motionPresets.backdrop(isOpen)}
50
+ className="backdrop"
51
+ />
52
+
53
+ {/* Modal body animation */}
54
+ <motion.div {...motionPresets.modal} className="modal-content">
55
+ {children}
56
+ </motion.div>
57
+ </>
58
+ )}
59
+ </AnimatePresence>
60
+ );
61
+ }
62
+ ```
@@ -0,0 +1,79 @@
1
+ # Pressable Framework
2
+
3
+ ## Purpose
4
+
5
+ The `Pressable` framework is a versatile multipurpose wrapper component that handles user interactions such as click, touch, and hover. It dynamically identifies its role—link (`<a>`, `Link`), button (`<button>`), form control (`checkbox`, `radio`), or custom popover trigger—and renders the appropriate DOM element and accessibility attributes. It also uniformly applies Squircle shapes, motion wrapping, and theme-based styling.
6
+
7
+ ## Usage Logic
8
+
9
+ - When an `href` prop is given, it internally renders as Next.js's `Link` component or a plain `<a>` tag.
10
+ - With `type="checkbox"` or `type="radio"`, it renders as a custom label (`<label>`) together with a visually hidden `<input>` element.
11
+ - With a button action or `onClick`, it renders as a `<button>`. The `popover` prop lets you declaratively write a popover trigger and inner content together.
12
+ - Use `themePreset` etc. to automate styling for press/hover interactions.
13
+
14
+ ## Type Signatures
15
+
16
+ ```typescript
17
+ import type { CSSProperties } from "react";
18
+ import type { LinkProps } from "next/link";
19
+ import type { MotionProps } from "motion/react";
20
+ import type { PopoverConfig } from "../Dialog/Dialog.types";
21
+ import type { WindProps } from "../_shared/Wind.types";
22
+ import type { ThemeSystemProps, BorderProps } from "../Theme/Theme.types";
23
+ import type { RadiusProps } from "../Theme/Radius.types";
24
+
25
+ export interface PressableProps
26
+ extends WindProps, ThemeSystemProps, BorderProps, RadiusProps /* ...others omitted */ {
27
+ href?: LinkProps["href"];
28
+ onClick?: (e: React.MouseEvent) => void;
29
+ type?: HTMLButtonElement["type"] | "checkbox" | "radio";
30
+ disabled?: boolean;
31
+ checked?: HTMLInputElement["checked"];
32
+ popover?: Omit<PopoverConfig, "anchorRef"> & {
33
+ content: React.ReactNode;
34
+ open?: boolean;
35
+ defaultOpen?: boolean;
36
+ onOpenChange?: (open: boolean) => void;
37
+ };
38
+ motion?: MotionProps;
39
+ noSquircle?: boolean; // whether to prevent Squircle corner application
40
+ // other various event handlers and layout properties
41
+ }
42
+ ```
43
+
44
+ ## Example Code
45
+
46
+ ```tsx
47
+ import Pressable from "@/packages/Frameworks/Pressable/Pressable";
48
+
49
+ function Example() {
50
+ return (
51
+ <div style={{ display: "flex", gap: 16 }}>
52
+ {/* 1. Normal button */}
53
+ <Pressable themePreset="UIPrimary" onClick={() => alert("Clicked")}>
54
+ Primary Button
55
+ </Pressable>
56
+
57
+ {/* 2. Link button */}
58
+ <Pressable href="/about" themePreset="BaseFull" radius="R16">
59
+ Go to About
60
+ </Pressable>
61
+
62
+ {/* 3. Checkbox control */}
63
+ <Pressable type="checkbox" checked={true} onChange={() => {}}>
64
+ Toggle Checked
65
+ </Pressable>
66
+
67
+ {/* 4. Popover trigger combined */}
68
+ <Pressable
69
+ themePreset="UISecondary"
70
+ popover={{
71
+ content: <div style={{ padding: 16 }}>This is popover content.</div>,
72
+ }}
73
+ >
74
+ Open Popover
75
+ </Pressable>
76
+ </div>
77
+ );
78
+ }
79
+ ```
@@ -0,0 +1,50 @@
1
+ # Squircle Framework
2
+
3
+ ## Purpose
4
+
5
+ The `Squircle` framework is a component for rendering the "Super Ellipse" (squircle) corners mainly used in the Apple ecosystem within React applications. Using the `figma-squircle` library, it dynamically calculates and applies an SVG Path-based `clip-path`, providing smooth and soft rounded-corner design.
6
+
7
+ ## Usage Logic
8
+
9
+ - Renders as a `<div>` by default, and can be changed to the desired element via the `as` prop.
10
+ - The `radius` prop specifies the corner roundness (can be set individually); internally observes the element size (ResizeObserver) to generate the accurate SVG `clip-path`.
11
+ - When a `motion` object is passed, it renders as a motion squircle component combined with framer-motion.
12
+
13
+ ## Type Signatures
14
+
15
+ ```typescript
16
+ import type { ElementType, HTMLAttributes } from "react";
17
+ import type { MotionProps } from "motion/react";
18
+ import type { RadiusValue } from "../Theme/Radius.types";
19
+
20
+ export interface SquircleProps extends Omit<
21
+ HTMLAttributes<HTMLElement>,
22
+ "color"
23
+ > {
24
+ as?: ElementType; // element to render (default: "div")
25
+ radius?: RadiusValue; // corner radius (scale or pixel unit)
26
+ cornerRadius?: number; // hardcoded corner radius
27
+ cornerSmoothing?: number; // smoothing degree (default: 0.6)
28
+ preserveSmoothing?: boolean;
29
+ motion?: MotionProps; // animation properties
30
+ }
31
+ ```
32
+
33
+ ## Example Code
34
+
35
+ ```tsx
36
+ import Squircle from "@/packages/Frameworks/Squircle";
37
+
38
+ function Card() {
39
+ return (
40
+ <Squircle
41
+ as="section"
42
+ radius="R24" // UIKit Radius system token
43
+ style={{ background: "white", padding: 20 }}
44
+ >
45
+ <h2>Soft-corner card</h2>
46
+ <p>Super Ellipse curvature applied.</p>
47
+ </Squircle>
48
+ );
49
+ }
50
+ ```