@jbpark/ui-kit 9.1.0 → 10.0.0
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/README.ko.md +18 -17
- package/README.md +18 -17
- package/dist/Button.d.mts +1 -1
- package/dist/Button.d.mts.map +1 -1
- package/dist/Button.mjs +4 -5
- package/dist/Button.mjs.map +1 -1
- package/dist/Tag.d.mts.map +1 -1
- package/dist/Tag.mjs.map +1 -1
- package/dist/components/atoms/checkbox/checkbox.mjs +1 -1
- package/dist/components/atoms/checkbox/checkbox.mjs.map +1 -1
- package/dist/components/atoms/option-group.mjs.map +1 -1
- package/dist/components/atoms/popover.d.mts +3 -1
- package/dist/components/atoms/popover.d.mts.map +1 -1
- package/dist/components/atoms/popover.mjs +10 -111
- package/dist/components/atoms/popover.mjs.map +1 -1
- package/dist/components/atoms/progress.mjs +3 -4
- package/dist/components/atoms/progress.mjs.map +1 -1
- package/dist/components/atoms/radio/context.mjs +2 -2
- package/dist/components/atoms/radio/context.mjs.map +1 -1
- package/dist/components/atoms/radio/group.d.mts.map +1 -1
- package/dist/components/atoms/radio/group.mjs +8 -6
- package/dist/components/atoms/radio/group.mjs.map +1 -1
- package/dist/components/atoms/radio/radio.d.mts +2 -5
- package/dist/components/atoms/radio/radio.d.mts.map +1 -1
- package/dist/components/atoms/radio/radio.mjs +0 -1
- package/dist/components/atoms/radio/radio.mjs.map +1 -1
- package/dist/components/atoms/rich-text-editor/content-classes.mjs +1 -1
- package/dist/components/atoms/rich-text-editor/content-classes.mjs.map +1 -1
- package/dist/components/atoms/rich-text-editor/rich-text-editor.mjs +1 -1
- package/dist/components/atoms/rich-text-editor/rich-text-editor.mjs.map +1 -1
- package/dist/components/atoms/rich-text-editor/toolbar-button.mjs.map +1 -1
- package/dist/components/atoms/rich-text-editor/toolbar-presets.mjs.map +1 -1
- package/dist/components/atoms/rich-text-editor/toolbar.mjs +1 -1
- package/dist/components/atoms/rich-text-editor/toolbar.mjs.map +1 -1
- package/dist/components/atoms/select.mjs +5 -1
- package/dist/components/atoms/select.mjs.map +1 -1
- package/dist/components/atoms/slider/slider.mjs.map +1 -1
- package/dist/components/atoms/switch.d.mts +1 -1
- package/dist/components/atoms/switch.d.mts.map +1 -1
- package/dist/components/atoms/switch.mjs +3 -3
- package/dist/components/atoms/switch.mjs.map +1 -1
- package/dist/components/molecules/collapse.mjs +3 -10
- package/dist/components/molecules/collapse.mjs.map +1 -1
- package/dist/components/organisms/drawer.d.mts +1 -2
- package/dist/components/organisms/drawer.d.mts.map +1 -1
- package/dist/components/organisms/drawer.mjs +5 -7
- package/dist/components/organisms/drawer.mjs.map +1 -1
- package/dist/components/organisms/modal.d.mts.map +1 -1
- package/dist/components/organisms/modal.mjs +1 -3
- package/dist/components/organisms/modal.mjs.map +1 -1
- package/dist/components/templates/container.d.mts +4 -3
- package/dist/components/templates/container.d.mts.map +1 -1
- package/dist/components/templates/container.mjs +10 -6
- package/dist/components/templates/container.mjs.map +1 -1
- package/dist/components/templates/index.d.mts +13 -0
- package/dist/components/templates/layout/content.d.mts +4 -3
- package/dist/components/templates/layout/content.d.mts.map +1 -1
- package/dist/components/templates/layout/content.mjs +14 -9
- package/dist/components/templates/layout/content.mjs.map +1 -1
- package/dist/core/accordion.d.mts +1 -1
- package/dist/core/accordion.mjs +12 -12
- package/dist/core/accordion.mjs.map +1 -1
- package/dist/core/badge.d.mts +4 -16
- package/dist/core/badge.d.mts.map +1 -1
- package/dist/core/badge.mjs +12 -21
- package/dist/core/badge.mjs.map +1 -1
- package/dist/core/button.d.mts +5 -4
- package/dist/core/button.d.mts.map +1 -1
- package/dist/core/button.mjs +4 -4
- package/dist/core/button.mjs.map +1 -1
- package/dist/core/calendar.mjs +2 -1
- package/dist/core/calendar.mjs.map +1 -1
- package/dist/core/checkbox.d.mts +1 -1
- package/dist/core/checkbox.mjs +14 -14
- package/dist/core/checkbox.mjs.map +1 -1
- package/dist/core/dialog.d.mts +1 -1
- package/dist/core/dialog.mjs +25 -33
- package/dist/core/dialog.mjs.map +1 -1
- package/dist/core/drawer.d.mts +1 -1
- package/dist/core/drawer.mjs +45 -46
- package/dist/core/drawer.mjs.map +1 -1
- package/dist/core/label.d.mts +1 -2
- package/dist/core/label.mjs +1 -3
- package/dist/core/label.mjs.map +1 -1
- package/dist/core/popover.d.mts +1 -1
- package/dist/core/popover.mjs +42 -37
- package/dist/core/popover.mjs.map +1 -1
- package/dist/core/progress.d.mts +1 -1
- package/dist/core/progress.mjs +7 -10
- package/dist/core/progress.mjs.map +1 -1
- package/dist/core/radio-group.d.mts +3 -7
- package/dist/core/radio-group.mjs +15 -20
- package/dist/core/radio-group.mjs.map +1 -1
- package/dist/core/select.d.mts +7 -3
- package/dist/core/select.d.mts.map +1 -1
- package/dist/core/select.mjs +60 -56
- package/dist/core/select.mjs.map +1 -1
- package/dist/core/separator.d.mts +1 -1
- package/dist/core/separator.mjs +6 -5
- package/dist/core/separator.mjs.map +1 -1
- package/dist/core/slider.d.mts +1 -1
- package/dist/core/slider.mjs +38 -27
- package/dist/core/slider.mjs.map +1 -1
- package/dist/core/switch.d.mts +1 -1
- package/dist/core/switch.mjs +15 -15
- package/dist/core/switch.mjs.map +1 -1
- package/dist/index.d.mts +1 -0
- package/dist/lib/z-layers.mjs +4 -6
- package/dist/lib/z-layers.mjs.map +1 -1
- package/dist/providers/config/config.mjs +2 -2
- package/dist/providers/config/config.mjs.map +1 -1
- package/dist/style.css +330 -455
- package/package.json +8 -20
- package/dist/core/radio-group.d.mts.map +0 -1
package/README.ko.md
CHANGED
|
@@ -25,7 +25,7 @@ src/
|
|
|
25
25
|
│ ├── molecules/ # 🔬 분자 - 원자들의 조합
|
|
26
26
|
│ ├── organisms/ # 🦠 유기체 - 복잡한 UI 블록
|
|
27
27
|
│ └── templates/ # 📄 템플릿 - 페이지 레이아웃
|
|
28
|
-
├── core/ # ⚙️ 핵심 UI 로직 (
|
|
28
|
+
├── core/ # ⚙️ 핵심 UI 로직 (Base UI 기반)
|
|
29
29
|
├── lib/
|
|
30
30
|
│ ├── enums/ # 📋 열거형 타입
|
|
31
31
|
│ └── utils/ # 🛠 유틸리티 함수
|
|
@@ -90,15 +90,15 @@ src/
|
|
|
90
90
|
|
|
91
91
|
### Core 모듈
|
|
92
92
|
|
|
93
|
-
|
|
93
|
+
Base UI 기반의 접근성 우선 핵심 컴포넌트들:
|
|
94
94
|
|
|
95
|
-
- `accordion.tsx` - 아코디언 컴포넌트 (
|
|
95
|
+
- `accordion.tsx` - 아코디언 컴포넌트 (Base UI 기반)
|
|
96
96
|
- `button.tsx` - 버튼 컴포넌트 (class-variance-authority로 variants 관리)
|
|
97
|
-
- `dialog.tsx` - 다이얼로그 컴포넌트 (
|
|
98
|
-
- `drawer.tsx` - 드로어 컴포넌트 (
|
|
99
|
-
- `progress.tsx` - 진행률 컴포넌트 (
|
|
97
|
+
- `dialog.tsx` - 다이얼로그 컴포넌트 (Base UI 기반)
|
|
98
|
+
- `drawer.tsx` - 드로어 컴포넌트 (Base UI dialog 기반)
|
|
99
|
+
- `progress.tsx` - 진행률 컴포넌트 (Base UI 기반)
|
|
100
100
|
- `skeleton.tsx` - 스켈레톤 컴포넌트
|
|
101
|
-
- `switch.tsx` - 스위치 컴포넌트 (
|
|
101
|
+
- `switch.tsx` - 스위치 컴포넌트 (Base UI 기반)
|
|
102
102
|
|
|
103
103
|
### 유틸리티
|
|
104
104
|
|
|
@@ -129,14 +129,20 @@ import '@jbpark/ui-kit/style.css';
|
|
|
129
129
|
|
|
130
130
|
function App() {
|
|
131
131
|
return (
|
|
132
|
-
<
|
|
133
|
-
<
|
|
134
|
-
|
|
135
|
-
|
|
132
|
+
<div data-ui-root>
|
|
133
|
+
<Layout>
|
|
134
|
+
<Typography.Title>안녕하세요!</Typography.Title>
|
|
135
|
+
<Button variant="primary">클릭하세요</Button>
|
|
136
|
+
</Layout>
|
|
137
|
+
</div>
|
|
136
138
|
);
|
|
137
139
|
}
|
|
138
140
|
```
|
|
139
141
|
|
|
142
|
+
애플리케이션 레이아웃 루트에 `data-ui-root`를 지정하세요. 패키지 스타일시트가
|
|
143
|
+
해당 요소에 `isolation: isolate`를 적용해 Base UI 포털이 앱 내부의 z-index와
|
|
144
|
+
경쟁하지 않고 페이지 콘텐츠 위에 표시되도록 합니다.
|
|
145
|
+
|
|
140
146
|
### 개별 컴포넌트 import
|
|
141
147
|
|
|
142
148
|
```tsx
|
|
@@ -210,12 +216,7 @@ import '@jbpark/ui-kit/style.css';
|
|
|
210
216
|
|
|
211
217
|
### UI 라이브러리
|
|
212
218
|
|
|
213
|
-
- **
|
|
214
|
-
- `@radix-ui/react-accordion` (1.2.12)
|
|
215
|
-
- `@radix-ui/react-dialog` (1.1.15)
|
|
216
|
-
- `@radix-ui/react-progress` (1.1.7)
|
|
217
|
-
- `@radix-ui/react-slot` (1.2.3)
|
|
218
|
-
- `@radix-ui/react-switch` (1.2.6)
|
|
219
|
+
- **Base UI** - 접근성 우선 헤드리스 UI 컴포넌트
|
|
219
220
|
- **Lucide React 0.542.0** - 아이콘 라이브러리
|
|
220
221
|
- **Motion 12.23.12** - 애니메이션 라이브러리
|
|
221
222
|
- **Swiper 11.2.10** - 터치 슬라이더
|
package/README.md
CHANGED
|
@@ -25,7 +25,7 @@ src/
|
|
|
25
25
|
│ ├── molecules/ # 🔬 Molecules - Combinations of atoms
|
|
26
26
|
│ ├── organisms/ # 🦠 Organisms - Complex UI blocks
|
|
27
27
|
│ └── templates/ # 📄 Templates - Page layouts
|
|
28
|
-
├── core/ # ⚙️ Core UI logic (
|
|
28
|
+
├── core/ # ⚙️ Core UI logic (Base UI based)
|
|
29
29
|
├── lib/
|
|
30
30
|
│ ├── enums/ # 📋 Enumeration types
|
|
31
31
|
│ └── utils/ # 🛠 Utility functions
|
|
@@ -90,15 +90,15 @@ Page layout templates
|
|
|
90
90
|
|
|
91
91
|
### Core Module
|
|
92
92
|
|
|
93
|
-
Accessibility-first core components based on
|
|
93
|
+
Accessibility-first core components based on Base UI:
|
|
94
94
|
|
|
95
|
-
- `accordion.tsx` - Accordion component (
|
|
95
|
+
- `accordion.tsx` - Accordion component (Base UI based)
|
|
96
96
|
- `button.tsx` - Button component (variants managed with class-variance-authority)
|
|
97
|
-
- `dialog.tsx` - Dialog component (
|
|
98
|
-
- `drawer.tsx` - Drawer component (
|
|
99
|
-
- `progress.tsx` - Progress component (
|
|
97
|
+
- `dialog.tsx` - Dialog component (Base UI based)
|
|
98
|
+
- `drawer.tsx` - Drawer component (Base UI dialog based)
|
|
99
|
+
- `progress.tsx` - Progress component (Base UI based)
|
|
100
100
|
- `skeleton.tsx` - Skeleton component
|
|
101
|
-
- `switch.tsx` - Switch component (
|
|
101
|
+
- `switch.tsx` - Switch component (Base UI based)
|
|
102
102
|
|
|
103
103
|
### Utilities
|
|
104
104
|
|
|
@@ -129,14 +129,20 @@ import '@jbpark/ui-kit/style.css';
|
|
|
129
129
|
|
|
130
130
|
function App() {
|
|
131
131
|
return (
|
|
132
|
-
<
|
|
133
|
-
<
|
|
134
|
-
|
|
135
|
-
|
|
132
|
+
<div data-ui-root>
|
|
133
|
+
<Layout>
|
|
134
|
+
<Typography.Title>Hello!</Typography.Title>
|
|
135
|
+
<Button variant="primary">Click me</Button>
|
|
136
|
+
</Layout>
|
|
137
|
+
</div>
|
|
136
138
|
);
|
|
137
139
|
}
|
|
138
140
|
```
|
|
139
141
|
|
|
142
|
+
Put `data-ui-root` on your application layout root. The included stylesheet
|
|
143
|
+
applies `isolation: isolate` there so Base UI portals render above page content
|
|
144
|
+
without competing with z-index values inside the app.
|
|
145
|
+
|
|
140
146
|
### Import Individual Components
|
|
141
147
|
|
|
142
148
|
```tsx
|
|
@@ -210,12 +216,7 @@ import '@jbpark/ui-kit/style.css';
|
|
|
210
216
|
|
|
211
217
|
### UI Libraries
|
|
212
218
|
|
|
213
|
-
- **
|
|
214
|
-
- `@radix-ui/react-accordion` (1.2.12)
|
|
215
|
-
- `@radix-ui/react-dialog` (1.1.15)
|
|
216
|
-
- `@radix-ui/react-progress` (1.1.7)
|
|
217
|
-
- `@radix-ui/react-slot` (1.2.3)
|
|
218
|
-
- `@radix-ui/react-switch` (1.2.6)
|
|
219
|
+
- **Base UI** - Accessible headless UI components
|
|
219
220
|
- **Lucide React 0.542.0** - Icon library
|
|
220
221
|
- **Motion 12.23.12** - Animation library
|
|
221
222
|
- **Swiper 11.2.10** - Touch slider
|
package/dist/Button.d.mts
CHANGED
|
@@ -90,7 +90,7 @@ interface Props extends Omit<React$1.ComponentProps<typeof Core>, 'size' | 'vari
|
|
|
90
90
|
icon: React$1.ReactNode;
|
|
91
91
|
};
|
|
92
92
|
}
|
|
93
|
-
declare const Button: ({ icon, className, type, variant, htmlType, size, color, shape, block, disabled, loading, danger,
|
|
93
|
+
declare const Button: ({ icon, className, type, variant, htmlType, size, color, shape, block, disabled, loading, danger, nativeButton, children, onMouseDown, ...props }: Props) => React$1.JSX.Element;
|
|
94
94
|
//#endregion
|
|
95
95
|
export { Props, Button as default };
|
|
96
96
|
//# sourceMappingURL=Button.d.mts.map
|
package/dist/Button.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Button.d.mts","names":[],"sources":["../src/components/atoms/button.tsx"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"Button.d.mts","names":[],"sources":["../src/components/atoms/button.tsx"],"mappings":";;;;;cAYM,aAAI;;;;;;;;;;;;;KAcL;;;;;;;;KAUA;UAGY,cAAc,KAC7B,QAAM,sBAAsB;EAG5B,OAAO,QAAM;EACb;EACA;EACA;;;;;;;;EAQA,sCAAsC;;;;;;;;;;;;;;;;;;EAkBtC;;;;;;;;;;;;;;;;EAgBA,yEAOI;;;;;;EAMJ;EACA;;;;;;;EAOA,QAAQ;EACR;IAAsB,MAAM,QAAM;;;cAmH9B,WAAU,MAAA,WAAA,MAAA,SAAA,UAAA,MAAA,OAAA,OAAA,OAAA,UAAA,SAAA,QAAA,cAAA,UAAA,gBAAA,SAiBb,UAAK,QAAA,IAAA"}
|
package/dist/Button.mjs
CHANGED
|
@@ -3,7 +3,6 @@ import { cn } from "./utils.mjs";
|
|
|
3
3
|
import { useConfig } from "./providers/config/context.mjs";
|
|
4
4
|
import { Button as Button$1 } from "./core/button.mjs";
|
|
5
5
|
import "react";
|
|
6
|
-
import { Slottable } from "@radix-ui/react-slot";
|
|
7
6
|
import { LoaderCircle } from "lucide-react";
|
|
8
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
8
|
//#region src/components/atoms/button.tsx
|
|
@@ -106,7 +105,7 @@ const shapesClasses = {
|
|
|
106
105
|
circle: "rounded-full",
|
|
107
106
|
round: "rounded-2xl"
|
|
108
107
|
};
|
|
109
|
-
const Button = ({ icon, className, type, variant, htmlType = "button", size, color, shape, block = false, disabled, loading, danger,
|
|
108
|
+
const Button = ({ icon, className, type, variant, htmlType = "button", size, color, shape, block = false, disabled, loading, danger, nativeButton = true, children, onMouseDown, ...props }) => {
|
|
110
109
|
const { componentSize, defaultProps } = useConfig();
|
|
111
110
|
const buttonDefaults = defaultProps?.button;
|
|
112
111
|
const resolvedShape = shape ?? buttonDefaults?.shape ?? "default";
|
|
@@ -123,7 +122,7 @@ const Button = ({ icon, className, type, variant, htmlType = "button", size, col
|
|
|
123
122
|
return /* @__PURE__ */ jsxs(Core, {
|
|
124
123
|
variant: null,
|
|
125
124
|
size: null,
|
|
126
|
-
|
|
125
|
+
nativeButton,
|
|
127
126
|
"data-slot": "button",
|
|
128
127
|
"data-variant": resolvedVariant,
|
|
129
128
|
"data-size": resolvedSize,
|
|
@@ -134,7 +133,7 @@ const Button = ({ icon, className, type, variant, htmlType = "button", size, col
|
|
|
134
133
|
"text-(--btn-fg)",
|
|
135
134
|
"border-(--btn-border)"
|
|
136
135
|
] : ["text-(--btn-bg)", "border-[color-mix(in_oklch,var(--btn-border),transparent_50%)]"]), className),
|
|
137
|
-
type: htmlType,
|
|
136
|
+
type: nativeButton ? htmlType : void 0,
|
|
138
137
|
disabled: disabled || isLoading,
|
|
139
138
|
"aria-busy": isLoading,
|
|
140
139
|
"data-color": computedColor,
|
|
@@ -142,7 +141,7 @@ const Button = ({ icon, className, type, variant, htmlType = "button", size, col
|
|
|
142
141
|
onMouseDown?.(e);
|
|
143
142
|
},
|
|
144
143
|
...props,
|
|
145
|
-
children: [displayIcon,
|
|
144
|
+
children: [displayIcon, children]
|
|
146
145
|
});
|
|
147
146
|
};
|
|
148
147
|
//#endregion
|
package/dist/Button.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Button.mjs","names":["button.Button"],"sources":["../src/components/atoms/button.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\n\nimport { Slottable } from '@radix-ui/react-slot';\nimport { LoaderCircle } from 'lucide-react';\n\nimport { useConfig } from '@repo/ui/providers';\nimport { cn } from '@repo/ui/utils';\n\nimport { button } from '../../core';\nimport { type PresetColor } from '../../lib/colors';\n\nconst Core = button.Button;\n\n/**\n * shadcn's own `variant` words, accepted on top of this component's own\n * vocabulary rather than replacing it. They are sugar in exactly the sense\n * `type` is: each expands to a `(color, variant)` pair, so a snippet copied\n * from the shadcn docs renders as the nearest thing on this library's scale\n * instead of erroring.\n *\n * `link` is deliberately absent: it already exists as one of this component's\n * own variants and already renders what shadcn's `link` renders, so mapping it\n * would change `variant=\"link\"`'s resolved colour from `default` to `primary`\n * for existing callers.\n */\ntype ShadcnVariant =\n 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost';\n\n/**\n * shadcn's `size` words. The `icon*` entries additionally force the icon-only\n * (square, unpadded) treatment, which this component otherwise infers from\n * `icon` being set with no children — without that, the shadcn idiom of\n * passing the icon as *children* (`<Button size=\"icon\"><Trash /></Button>`)\n * would render a normal padded button.\n */\ntype ShadcnSize =\n 'default' | 'xs' | 'sm' | 'lg' | 'icon' | 'icon-xs' | 'icon-sm' | 'icon-lg';\n\nexport interface Props extends Omit<\n React.ComponentProps<typeof Core>,\n 'size' | 'variant' | 'type'\n> {\n icon?: React.ReactNode;\n block?: boolean;\n danger?: boolean;\n disabled?: boolean;\n /**\n * Size on this library's antd-style scale. shadcn's words are accepted too\n * and map onto that scale: `sm`/`xs` → `small`, `default` → `middle`,\n * `lg` → `large`. There is no separate `xs` step here, so `xs` renders as\n * `small`. The `icon*` entries pick the same sizes and additionally force\n * the icon-only treatment.\n */\n size?: 'small' | 'middle' | 'large' | ShadcnSize;\n /**\n * Syntactic sugar for a `(color, variant)` pair. **Will follow `variant` and\n * `color` if provided** — `type` only fills in the axes you leave unset.\n *\n * | `type` | equivalent to |\n * | --------- | -------------------------------------- |\n * | `primary` | `color=\"primary\" variant=\"solid\"` |\n * | `default` | `color=\"default\" variant=\"outlined\"` |\n * | `dashed` | `color=\"default\" variant=\"dashed\"` |\n * | `text` | `color=\"default\" variant=\"text\"` |\n * | `link` | `color=\"primary\" variant=\"link\"` |\n *\n * So `<Button type=\"primary\">` is the same as\n * `<Button color=\"primary\" variant=\"solid\">`, and\n * `<Button type=\"primary\" variant=\"filled\">` keeps the primary color but\n * renders filled. `danger` still overrides the resolved color.\n */\n type?: 'primary' | 'default' | 'dashed' | 'text' | 'link';\n /**\n * Visual fill style, independent of `color`. Defaults to `'outlined'`.\n * Takes precedence over whatever `type` would have supplied.\n *\n * shadcn's words are accepted here as well and expand to a `(color, variant)`\n * pair the same way `type` does — `destructive` ≡ `color=\"danger\"\n * variant=\"solid\"`, `outline` ≡ `outlined`, `secondary` ≡ `filled`,\n * `ghost` ≡ `text`, `default` ≡ `color=\"primary\" variant=\"solid\"`. An\n * explicit `color` still wins over the one the word implies.\n *\n * ⚠️ `variant=\"default\"` (shadcn: a filled primary button) and\n * `type=\"default\"` (antd: a plain outlined button) mean opposite things.\n * They are different props, so nothing collides at runtime, but don't read\n * one as the other.\n */\n variant?:\n | 'solid'\n | 'outlined'\n | 'dashed'\n | 'filled'\n | 'text'\n | 'link'\n | ShadcnVariant;\n /**\n * Native `<button>` `type` (`button`/`submit`/`reset`), kept separate\n * from the antd-style `type` above. Defaults to `'button'` so a Button\n * placed inside a `<form>` doesn't submit it unless explicitly opted in.\n */\n htmlType?: 'button' | 'submit' | 'reset';\n shape?: 'default' | 'circle' | 'round';\n /**\n * Color, independent of `variant`. Defaults to `'default'`, or to whatever\n * `type` maps to when `type` is set. `danger` overrides this.\n *\n * Preset hues use Tailwind's colour names (#342).\n */\n color?: PresetColor | 'default' | 'primary' | 'danger';\n loading?: boolean | { icon: React.ReactNode };\n}\n\n// Geometry, the focus/aria/disabled chassis and the svg sizing come from\n// `core/button` again (#278 ③ is reversed here — see the core membership rule\n// in CLAUDE.md). Unlike Tag, Button pins no core variant at all: it passes\n// `variant={null} size={null}`, which cva treats as \"skip this axis entirely\",\n// so the primitive contributes only its base string and the atom keeps full\n// ownership of every colour and size class below. That leaves nothing for the\n// `variant=\"…\"` smell check to flag.\n//\n// The base still carries `rounded-md` and `text-sm`; the `rounded-*` from\n// `shapesClasses` and the `text-*` from `sizesClasses` come later in the class\n// list and override them, exactly as they did when this was absorbed.\nconst BUTTON_BASE = cn(\n 'gap-2 whitespace-nowrap font-medium transition-all',\n 'has-[>svg]:px-3',\n);\n\nconst variantClasses: Record<string, string> = {\n // solid used to inherit its fill from core/button's default variant; carry it\n // explicitly now that the primitive is absorbed. A colored solid overrides\n // this with the --btn-* custom properties further down.\n solid: cn('bg-primary text-primary-foreground', 'hover:bg-primary/90'),\n outlined: cn(\n 'border border-[color-mix(in_oklch,var(--btn-border),transparent_50%)]',\n 'bg-background text-foreground',\n 'hover:bg-accent',\n ),\n dashed: cn(\n 'border border-dashed border-[color-mix(in_oklch,var(--btn-border),transparent_50%)]',\n 'bg-background text-foreground',\n 'hover:bg-accent',\n ),\n filled: cn('bg-muted text-foreground', 'hover:bg-muted/80'),\n text: cn('bg-transparent text-foreground', 'hover:bg-accent'),\n link: cn(\n 'bg-transparent text-primary',\n 'underline-offset-4 hover:underline',\n 'hover:bg-primary/10',\n ),\n};\n\n/**\n * antd-style syntactic sugar: each `type` expands to a `(color, variant)` pair.\n * Explicit `color`/`variant` props win over whatever the `type` maps to, so\n * `type` only fills in the axes the caller left unset.\n *\n * Mirrors antd: `<Button type=\"primary\">` ≡ `<Button color=\"primary\" variant=\"solid\">`.\n */\nconst typeToColorVariant: Record<\n NonNullable<Props['type']>,\n { color: NonNullable<Props['color']>; variant: NonNullable<Props['variant']> }\n> = {\n primary: { color: 'primary', variant: 'solid' },\n default: { color: 'default', variant: 'outlined' },\n dashed: { color: 'default', variant: 'dashed' },\n text: { color: 'default', variant: 'text' },\n link: { color: 'primary', variant: 'link' },\n};\n\n/** The half of `variant` that is this component's own vocabulary. */\ntype OwnVariant = Exclude<NonNullable<Props['variant']>, ShadcnVariant>;\n\ntype OwnSize = 'small' | 'middle' | 'large';\n\n/**\n * shadcn's variant words → the `(color, variant)` pair each stands for here.\n * Same contract as `typeToColorVariant` above: the word only fills axes the\n * caller left unset, so an explicit `color` still wins over the implied one.\n */\nconst shadcnVariantToColorVariant: Record<\n ShadcnVariant,\n { color: NonNullable<Props['color']>; variant: OwnVariant }\n> = {\n default: { color: 'primary', variant: 'solid' },\n destructive: { color: 'danger', variant: 'solid' },\n outline: { color: 'default', variant: 'outlined' },\n secondary: { color: 'default', variant: 'filled' },\n ghost: { color: 'default', variant: 'text' },\n};\n\n/** shadcn's size words → this library's scale. */\nconst shadcnSizeToSize: Record<ShadcnSize, OwnSize> = {\n default: 'middle',\n xs: 'small',\n sm: 'small',\n lg: 'large',\n icon: 'middle',\n 'icon-xs': 'small',\n 'icon-sm': 'small',\n 'icon-lg': 'large',\n};\n\n/** The `size` words that also mean \"render this icon-only\". */\nconst ICON_SIZES = new Set<string>(['icon', 'icon-xs', 'icon-sm', 'icon-lg']);\n\nconst sizesClasses: Record<string, string> = {\n small: 'h-6 px-3 text-sm',\n middle: 'h-8 px-4 text-base',\n large: 'h-10 px-5 text-lg',\n};\n\nconst iconClasses: Record<string, string> = {\n small: `size-6 [&_svg:not([class*='size-'])]:size-3`,\n middle: `size-8 [&_svg:not([class*='size-'])]:size-4`,\n large: `size-10 [&_svg:not([class*='size-'])]:size-5`,\n};\n\nconst shapesClasses = {\n default: 'rounded-sm',\n circle: 'rounded-full',\n round: 'rounded-2xl',\n};\n\nconst Button = ({\n icon,\n className,\n type,\n variant,\n htmlType = 'button',\n size,\n color,\n shape,\n block = false,\n disabled,\n loading,\n danger,\n asChild = false,\n children,\n onMouseDown,\n ...props\n}: Props) => {\n const { componentSize, defaultProps } = useConfig();\n const buttonDefaults = defaultProps?.button as\n Partial<Pick<Props, 'shape' | 'variant' | 'color'>> | undefined;\n const resolvedShape = shape ?? buttonDefaults?.shape ?? 'default';\n // Both `variant` and `size` accept this library's own words *and* shadcn's.\n // Translate the shadcn ones first so everything below reasons in one\n // vocabulary; a word this library already owns (`link`, `text`, `small`, …)\n // is passed through untouched.\n const variantAlias =\n variant && variant in shadcnVariantToColorVariant\n ? shadcnVariantToColorVariant[variant as ShadcnVariant]\n : undefined;\n const ownVariant =\n variantAlias?.variant ?? (variant as OwnVariant | undefined);\n const ownSize =\n size && size in shadcnSizeToSize\n ? shadcnSizeToSize[size as ShadcnSize]\n : (size as OwnSize | undefined);\n const resolvedSize = ownSize ?? componentSize ?? 'middle';\n // A shadcn `size=\"icon*\"` says \"icon-only\" explicitly; otherwise it is\n // inferred from an `icon` with no children, which is how this component has\n // always detected it.\n const iconOnly =\n (size != null && ICON_SIZES.has(size)) || !!(icon && !children);\n // `type` is syntactic sugar that expands to a (color, variant) pair; explicit\n // `color`/`variant` win over it, so `type` only fills the axes left unset.\n // A shadcn `variant` word carries an implied colour and sits between the two:\n // more specific than `type`, less than an explicit `color`.\n // A `Config` default sits below the call-site `type` (which is more specific)\n // but above the library built-in. `danger` still trumps everything, matching\n // antd. Defaults live here rather than on the parameters so `type` gets a\n // chance to supply them first.\n const typeDefaults = type ? typeToColorVariant[type] : undefined;\n const resolvedVariant =\n ownVariant ??\n typeDefaults?.variant ??\n buttonDefaults?.variant ??\n 'outlined';\n const computedColor = danger\n ? 'danger'\n : (color ??\n variantAlias?.color ??\n typeDefaults?.color ??\n buttonDefaults?.color ??\n 'default');\n const colored = computedColor !== 'default';\n const isLoading = !!loading;\n\n const displayIcon = loading ? (\n typeof loading === 'object' ? (\n loading.icon\n ) : (\n <LoaderCircle className=\"animate-spin\" />\n )\n ) : (\n icon\n );\n\n return (\n <Core\n // cva skips an axis entirely when it is passed `null`, so the primitive\n // contributes only its base string and this atom keeps ownership of\n // every colour/size class.\n variant={null}\n size={null}\n asChild={asChild}\n data-slot=\"button\"\n data-variant={resolvedVariant}\n data-size={resolvedSize}\n className={cn(\n BUTTON_BASE,\n 'inline-flex items-center justify-center gap-x-2',\n 'rounded-lg',\n 'cursor-pointer',\n 'h-auto py-0',\n 'transition-all',\n variantClasses[resolvedVariant],\n sizesClasses[resolvedSize],\n iconOnly && ['p-0', iconClasses[resolvedSize]],\n shapesClasses[resolvedShape],\n block && 'w-full',\n colored &&\n (resolvedVariant === 'solid'\n ? [\n 'bg-(--btn-bg)',\n 'hover:bg-(--btn-bg-hover)',\n 'active:bg-(--btn-bg-active)',\n 'text-(--btn-fg)',\n 'border-(--btn-border)',\n ]\n : [\n 'text-(--btn-bg)',\n 'border-[color-mix(in_oklch,var(--btn-border),transparent_50%)]',\n //\n ]),\n className,\n //\n )}\n type={htmlType}\n disabled={disabled || isLoading}\n aria-busy={isLoading}\n data-color={computedColor}\n onMouseDown={e => {\n onMouseDown?.(e);\n }}\n {...props}\n >\n {displayIcon}\n {/*\n A Button renders two children (the icon slot and the caller's content),\n but Radix's Slot accepts multiple children only when exactly one is\n marked `Slottable` — without this marker `asChild` threw\n \"Slot failed to slot onto its children\" for *every* call, icon or not.\n `Slottable` is a plain fragment when `asChild` is false, so the\n non-asChild markup is unchanged.\n */}\n <Slottable>{children}</Slottable>\n </Core>\n );\n};\n\nexport default Button;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Button.mjs","names":["button.Button"],"sources":["../src/components/atoms/button.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\n\nimport { LoaderCircle } from 'lucide-react';\n\nimport { useConfig } from '@repo/ui/providers';\nimport { cn } from '@repo/ui/utils';\n\nimport { button } from '../../core';\nimport { type PresetColor } from '../../lib/colors';\n\nconst Core = button.Button;\n\n/**\n * shadcn's own `variant` words, accepted on top of this component's own\n * vocabulary rather than replacing it. They are sugar in exactly the sense\n * `type` is: each expands to a `(color, variant)` pair, so a snippet copied\n * from the shadcn docs renders as the nearest thing on this library's scale\n * instead of erroring.\n *\n * `link` is deliberately absent: it already exists as one of this component's\n * own variants and already renders what shadcn's `link` renders, so mapping it\n * would change `variant=\"link\"`'s resolved colour from `default` to `primary`\n * for existing callers.\n */\ntype ShadcnVariant =\n 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost';\n\n/**\n * shadcn's `size` words. The `icon*` entries additionally force the icon-only\n * (square, unpadded) treatment, which this component otherwise infers from\n * `icon` being set with no children — without that, the shadcn idiom of\n * passing the icon as *children* (`<Button size=\"icon\"><Trash /></Button>`)\n * would render a normal padded button.\n */\ntype ShadcnSize =\n 'default' | 'xs' | 'sm' | 'lg' | 'icon' | 'icon-xs' | 'icon-sm' | 'icon-lg';\n\nexport interface Props extends Omit<\n React.ComponentProps<typeof Core>,\n 'size' | 'variant' | 'type'\n> {\n icon?: React.ReactNode;\n block?: boolean;\n danger?: boolean;\n disabled?: boolean;\n /**\n * Size on this library's antd-style scale. shadcn's words are accepted too\n * and map onto that scale: `sm`/`xs` → `small`, `default` → `middle`,\n * `lg` → `large`. There is no separate `xs` step here, so `xs` renders as\n * `small`. The `icon*` entries pick the same sizes and additionally force\n * the icon-only treatment.\n */\n size?: 'small' | 'middle' | 'large' | ShadcnSize;\n /**\n * Syntactic sugar for a `(color, variant)` pair. **Will follow `variant` and\n * `color` if provided** — `type` only fills in the axes you leave unset.\n *\n * | `type` | equivalent to |\n * | --------- | -------------------------------------- |\n * | `primary` | `color=\"primary\" variant=\"solid\"` |\n * | `default` | `color=\"default\" variant=\"outlined\"` |\n * | `dashed` | `color=\"default\" variant=\"dashed\"` |\n * | `text` | `color=\"default\" variant=\"text\"` |\n * | `link` | `color=\"primary\" variant=\"link\"` |\n *\n * So `<Button type=\"primary\">` is the same as\n * `<Button color=\"primary\" variant=\"solid\">`, and\n * `<Button type=\"primary\" variant=\"filled\">` keeps the primary color but\n * renders filled. `danger` still overrides the resolved color.\n */\n type?: 'primary' | 'default' | 'dashed' | 'text' | 'link';\n /**\n * Visual fill style, independent of `color`. Defaults to `'outlined'`.\n * Takes precedence over whatever `type` would have supplied.\n *\n * shadcn's words are accepted here as well and expand to a `(color, variant)`\n * pair the same way `type` does — `destructive` ≡ `color=\"danger\"\n * variant=\"solid\"`, `outline` ≡ `outlined`, `secondary` ≡ `filled`,\n * `ghost` ≡ `text`, `default` ≡ `color=\"primary\" variant=\"solid\"`. An\n * explicit `color` still wins over the one the word implies.\n *\n * ⚠️ `variant=\"default\"` (shadcn: a filled primary button) and\n * `type=\"default\"` (antd: a plain outlined button) mean opposite things.\n * They are different props, so nothing collides at runtime, but don't read\n * one as the other.\n */\n variant?:\n | 'solid'\n | 'outlined'\n | 'dashed'\n | 'filled'\n | 'text'\n | 'link'\n | ShadcnVariant;\n /**\n * Native `<button>` `type` (`button`/`submit`/`reset`), kept separate\n * from the antd-style `type` above. Defaults to `'button'` so a Button\n * placed inside a `<form>` doesn't submit it unless explicitly opted in.\n */\n htmlType?: 'button' | 'submit' | 'reset';\n shape?: 'default' | 'circle' | 'round';\n /**\n * Color, independent of `variant`. Defaults to `'default'`, or to whatever\n * `type` maps to when `type` is set. `danger` overrides this.\n *\n * Preset hues use Tailwind's colour names (#342).\n */\n color?: PresetColor | 'default' | 'primary' | 'danger';\n loading?: boolean | { icon: React.ReactNode };\n}\n\n// Geometry, the focus/aria/disabled chassis and the svg sizing come from\n// `core/button` again (#278 ③ is reversed here — see the core membership rule\n// in CLAUDE.md). Unlike Tag, Button pins no core variant at all: it passes\n// `variant={null} size={null}`, which cva treats as \"skip this axis entirely\",\n// so the primitive contributes only its base string and the atom keeps full\n// ownership of every colour and size class below. That leaves nothing for the\n// `variant=\"…\"` smell check to flag.\n//\n// The base still carries `rounded-md` and `text-sm`; the `rounded-*` from\n// `shapesClasses` and the `text-*` from `sizesClasses` come later in the class\n// list and override them, exactly as they did when this was absorbed.\nconst BUTTON_BASE = cn(\n 'gap-2 whitespace-nowrap font-medium transition-all',\n 'has-[>svg]:px-3',\n);\n\nconst variantClasses: Record<string, string> = {\n // solid used to inherit its fill from core/button's default variant; carry it\n // explicitly now that the primitive is absorbed. A colored solid overrides\n // this with the --btn-* custom properties further down.\n solid: cn('bg-primary text-primary-foreground', 'hover:bg-primary/90'),\n outlined: cn(\n 'border border-[color-mix(in_oklch,var(--btn-border),transparent_50%)]',\n 'bg-background text-foreground',\n 'hover:bg-accent',\n ),\n dashed: cn(\n 'border border-dashed border-[color-mix(in_oklch,var(--btn-border),transparent_50%)]',\n 'bg-background text-foreground',\n 'hover:bg-accent',\n ),\n filled: cn('bg-muted text-foreground', 'hover:bg-muted/80'),\n text: cn('bg-transparent text-foreground', 'hover:bg-accent'),\n link: cn(\n 'bg-transparent text-primary',\n 'underline-offset-4 hover:underline',\n 'hover:bg-primary/10',\n ),\n};\n\n/**\n * antd-style syntactic sugar: each `type` expands to a `(color, variant)` pair.\n * Explicit `color`/`variant` props win over whatever the `type` maps to, so\n * `type` only fills in the axes the caller left unset.\n *\n * Mirrors antd: `<Button type=\"primary\">` ≡ `<Button color=\"primary\" variant=\"solid\">`.\n */\nconst typeToColorVariant: Record<\n NonNullable<Props['type']>,\n { color: NonNullable<Props['color']>; variant: NonNullable<Props['variant']> }\n> = {\n primary: { color: 'primary', variant: 'solid' },\n default: { color: 'default', variant: 'outlined' },\n dashed: { color: 'default', variant: 'dashed' },\n text: { color: 'default', variant: 'text' },\n link: { color: 'primary', variant: 'link' },\n};\n\n/** The half of `variant` that is this component's own vocabulary. */\ntype OwnVariant = Exclude<NonNullable<Props['variant']>, ShadcnVariant>;\n\ntype OwnSize = 'small' | 'middle' | 'large';\n\n/**\n * shadcn's variant words → the `(color, variant)` pair each stands for here.\n * Same contract as `typeToColorVariant` above: the word only fills axes the\n * caller left unset, so an explicit `color` still wins over the implied one.\n */\nconst shadcnVariantToColorVariant: Record<\n ShadcnVariant,\n { color: NonNullable<Props['color']>; variant: OwnVariant }\n> = {\n default: { color: 'primary', variant: 'solid' },\n destructive: { color: 'danger', variant: 'solid' },\n outline: { color: 'default', variant: 'outlined' },\n secondary: { color: 'default', variant: 'filled' },\n ghost: { color: 'default', variant: 'text' },\n};\n\n/** shadcn's size words → this library's scale. */\nconst shadcnSizeToSize: Record<ShadcnSize, OwnSize> = {\n default: 'middle',\n xs: 'small',\n sm: 'small',\n lg: 'large',\n icon: 'middle',\n 'icon-xs': 'small',\n 'icon-sm': 'small',\n 'icon-lg': 'large',\n};\n\n/** The `size` words that also mean \"render this icon-only\". */\nconst ICON_SIZES = new Set<string>(['icon', 'icon-xs', 'icon-sm', 'icon-lg']);\n\nconst sizesClasses: Record<string, string> = {\n small: 'h-6 px-3 text-sm',\n middle: 'h-8 px-4 text-base',\n large: 'h-10 px-5 text-lg',\n};\n\nconst iconClasses: Record<string, string> = {\n small: `size-6 [&_svg:not([class*='size-'])]:size-3`,\n middle: `size-8 [&_svg:not([class*='size-'])]:size-4`,\n large: `size-10 [&_svg:not([class*='size-'])]:size-5`,\n};\n\nconst shapesClasses = {\n default: 'rounded-sm',\n circle: 'rounded-full',\n round: 'rounded-2xl',\n};\n\nconst Button = ({\n icon,\n className,\n type,\n variant,\n htmlType = 'button',\n size,\n color,\n shape,\n block = false,\n disabled,\n loading,\n danger,\n nativeButton = true,\n children,\n onMouseDown,\n ...props\n}: Props) => {\n const { componentSize, defaultProps } = useConfig();\n const buttonDefaults = defaultProps?.button as\n Partial<Pick<Props, 'shape' | 'variant' | 'color'>> | undefined;\n const resolvedShape = shape ?? buttonDefaults?.shape ?? 'default';\n // Both `variant` and `size` accept this library's own words *and* shadcn's.\n // Translate the shadcn ones first so everything below reasons in one\n // vocabulary; a word this library already owns (`link`, `text`, `small`, …)\n // is passed through untouched.\n const variantAlias =\n variant && variant in shadcnVariantToColorVariant\n ? shadcnVariantToColorVariant[variant as ShadcnVariant]\n : undefined;\n const ownVariant =\n variantAlias?.variant ?? (variant as OwnVariant | undefined);\n const ownSize =\n size && size in shadcnSizeToSize\n ? shadcnSizeToSize[size as ShadcnSize]\n : (size as OwnSize | undefined);\n const resolvedSize = ownSize ?? componentSize ?? 'middle';\n // A shadcn `size=\"icon*\"` says \"icon-only\" explicitly; otherwise it is\n // inferred from an `icon` with no children, which is how this component has\n // always detected it.\n const iconOnly =\n (size != null && ICON_SIZES.has(size)) || !!(icon && !children);\n // `type` is syntactic sugar that expands to a (color, variant) pair; explicit\n // `color`/`variant` win over it, so `type` only fills the axes left unset.\n // A shadcn `variant` word carries an implied colour and sits between the two:\n // more specific than `type`, less than an explicit `color`.\n // A `Config` default sits below the call-site `type` (which is more specific)\n // but above the library built-in. `danger` still trumps everything, matching\n // antd. Defaults live here rather than on the parameters so `type` gets a\n // chance to supply them first.\n const typeDefaults = type ? typeToColorVariant[type] : undefined;\n const resolvedVariant =\n ownVariant ??\n typeDefaults?.variant ??\n buttonDefaults?.variant ??\n 'outlined';\n const computedColor = danger\n ? 'danger'\n : (color ??\n variantAlias?.color ??\n typeDefaults?.color ??\n buttonDefaults?.color ??\n 'default');\n const colored = computedColor !== 'default';\n const isLoading = !!loading;\n\n const displayIcon = loading ? (\n typeof loading === 'object' ? (\n loading.icon\n ) : (\n <LoaderCircle className=\"animate-spin\" />\n )\n ) : (\n icon\n );\n\n return (\n <Core\n // cva skips an axis entirely when it is passed `null`, so the primitive\n // contributes only its base string and this atom keeps ownership of\n // every colour/size class.\n variant={null}\n size={null}\n nativeButton={nativeButton}\n data-slot=\"button\"\n data-variant={resolvedVariant}\n data-size={resolvedSize}\n className={cn(\n BUTTON_BASE,\n 'inline-flex items-center justify-center gap-x-2',\n 'rounded-lg',\n 'cursor-pointer',\n 'h-auto py-0',\n 'transition-all',\n variantClasses[resolvedVariant],\n sizesClasses[resolvedSize],\n iconOnly && ['p-0', iconClasses[resolvedSize]],\n shapesClasses[resolvedShape],\n block && 'w-full',\n colored &&\n (resolvedVariant === 'solid'\n ? [\n 'bg-(--btn-bg)',\n 'hover:bg-(--btn-bg-hover)',\n 'active:bg-(--btn-bg-active)',\n 'text-(--btn-fg)',\n 'border-(--btn-border)',\n ]\n : [\n 'text-(--btn-bg)',\n 'border-[color-mix(in_oklch,var(--btn-border),transparent_50%)]',\n //\n ]),\n className,\n //\n )}\n type={nativeButton ? htmlType : undefined}\n disabled={disabled || isLoading}\n aria-busy={isLoading}\n data-color={computedColor}\n onMouseDown={e => {\n onMouseDown?.(e);\n }}\n {...props}\n >\n {displayIcon}\n {children}\n </Core>\n );\n};\n\nexport default Button;\n"],"mappings":"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"}
|
package/dist/Tag.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tag.d.mts","names":[],"sources":["../src/components/atoms/tag.tsx"],"mappings":";;;;;cAUM,aAAI;UAEO,cAAc,KAC7B,QAAM,sBAAsB;;;;;;EAQ5B;;;;;;;;;;;;EAYA,mEAC6D;;
|
|
1
|
+
{"version":3,"file":"Tag.d.mts","names":[],"sources":["../src/components/atoms/tag.tsx"],"mappings":";;;;;cAUM,aAAI;UAEO,cAAc,KAC7B,QAAM,sBAAsB;;;;;;EAQ5B;;;;;;;;;;;;EAYA,mEAC6D;;cAuBzD,QAAO,WAAA,SAAA,OAAA,aAAA,SAAmD,UAAK,QAAA,IAAA"}
|
package/dist/Tag.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tag.mjs","names":["badge.Badge"],"sources":["../src/components/atoms/tag.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\n\nimport { useConfig } from '@repo/ui/providers';\nimport { cn } from '@repo/ui/utils';\n\nimport { badge } from '../../core';\nimport { type PresetColor } from '../../lib/colors';\n\nconst Core = badge.Badge;\n\nexport interface Props extends Omit<\n React.ComponentProps<typeof Core>,\n 'variant' | 'color'\n> {\n /**\n * Fill style, aligned with `Button`'s vocabulary (#320). The pre-7.0\n * `'default'` spelling was removed — use `'filled'`, which renders\n * identically.\n */\n variant?: 'filled' | 'outlined';\n /**\n * Colour. Every value — the semantic states (`primary`/`success`/`warning`/\n * `danger`) as well as the palette shared with `Button` (`blue`, `red`,\n * `amber`, …) — resolves through the same `data-color` + `--tag-*` system\n * (#320), so any of them can be re-themed the same way.\n *\n * `success`/`warning` have no `Button` counterpart on purpose: a Tag marks\n * state, which is why antd's Tag also carries them while its Button does not.\n *\n * Preset hues use Tailwind's colour names (#342).\n */\n color?:\n 'default' | 'primary' | 'success' | 'warning' | 'danger' | PresetColor;\n}\n\n// Geometry, the focus/aria chassis and the svg sizing all come from\n// `core/badge
|
|
1
|
+
{"version":3,"file":"Tag.mjs","names":["badge.Badge"],"sources":["../src/components/atoms/tag.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\n\nimport { useConfig } from '@repo/ui/providers';\nimport { cn } from '@repo/ui/utils';\n\nimport { badge } from '../../core';\nimport { type PresetColor } from '../../lib/colors';\n\nconst Core = badge.Badge;\n\nexport interface Props extends Omit<\n React.ComponentProps<typeof Core>,\n 'variant' | 'color'\n> {\n /**\n * Fill style, aligned with `Button`'s vocabulary (#320). The pre-7.0\n * `'default'` spelling was removed — use `'filled'`, which renders\n * identically.\n */\n variant?: 'filled' | 'outlined';\n /**\n * Colour. Every value — the semantic states (`primary`/`success`/`warning`/\n * `danger`) as well as the palette shared with `Button` (`blue`, `red`,\n * `amber`, …) — resolves through the same `data-color` + `--tag-*` system\n * (#320), so any of them can be re-themed the same way.\n *\n * `success`/`warning` have no `Button` counterpart on purpose: a Tag marks\n * state, which is why antd's Tag also carries them while its Button does not.\n *\n * Preset hues use Tailwind's colour names (#342).\n */\n color?:\n 'default' | 'primary' | 'success' | 'warning' | 'danger' | PresetColor;\n}\n\n// Geometry, the focus/aria chassis and the svg sizing all come from the\n// repo-owned `core/badge`. Tag pins the core `outline` variant because it\n// supplies exactly the neutral base Tag wants — a border plus `text-foreground`\n// and the `[a&]` hover treatment — then repaints border/text/fill from the\n// `--tag-*` custom properties below.\nconst CORE_VARIANT = 'outline';\n\n// Every colour — semantic states and shared presets alike — resolves from the\n// `--tag-*` custom properties that `globals.css` sets per `data-color` (#320).\n// Before 7.0 only the presets took this path while the states carried bespoke\n// Tailwind classes, which meant `[data-color]` hooks and `--tag-*` overrides\n// worked on some colours but silently not on others.\n//\n// --tag-bg the hue; the border in `outlined`\n// --tag-fg text colour (defaults to --tag-bg)\n// --tag-tint the fill behind `filled` (defaults to a 10% --tag-bg wash)\nconst fillClasses = cn('border-transparent bg-(--tag-tint) text-(--tag-fg)');\n\nconst outlinedClasses = cn('border-(--tag-bg) text-(--tag-fg)');\n\nconst Tag = ({ className, variant, color, children, ...props }: Props) => {\n const { defaultProps } = useConfig();\n const tagDefaults = defaultProps?.tag as\n Partial<Pick<Props, 'variant' | 'color'>> | undefined;\n // An explicit prop wins over a `Config` default, which wins over the built-in\n // — the same resolution order `Button` uses.\n const resolvedVariant = variant ?? tagDefaults?.variant ?? 'filled';\n const resolvedColor = color ?? tagDefaults?.color ?? 'default';\n const isOutlined = resolvedVariant === 'outlined';\n\n return (\n <Core\n variant={CORE_VARIANT}\n // Overrides the core primitive's own `data-slot=\"badge\"`. The slot now\n // matches the public component name, which frees `badge` for the\n // antd-style Badge (a count/dot decorator, a different component from\n // this chip — shadcn's Badge is what antd calls a Tag).\n data-slot=\"tag\"\n // Emitted for every colour, not just the presets, so consumers can hook\n // `[data-color]` / `[data-variant]` uniformly. `data-variant` is what\n // lets `globals.css` give `default` a different text colour when\n // outlined without reintroducing a second class path here; it also\n // replaces the core primitive's own `data-variant`, which would\n // otherwise report the pinned core variant rather than Tag's.\n data-color={resolvedColor}\n data-variant={resolvedVariant}\n className={cn(\n 'rounded-full px-2.5 py-1',\n isOutlined ? outlinedClasses : fillClasses,\n className,\n //\n )}\n {...props}\n >\n {children}\n </Core>\n );\n};\n\nexport default Tag;\n"],"mappings":";;;;;;;AAUA,MAAM,OAAOA;AAgCb,MAAM,eAAe;AAWrB,MAAM,cAAc,GAAG,oDAAoD;AAE3E,MAAM,kBAAkB,GAAG,mCAAmC;AAE9D,MAAM,OAAO,EAAE,WAAW,SAAS,OAAO,UAAU,GAAG,YAAmB;CACxE,MAAM,EAAE,iBAAiB,UAAU;CACnC,MAAM,cAAc,cAAc;CAIlC,MAAM,kBAAkB,WAAW,aAAa,WAAW;CAC3D,MAAM,gBAAgB,SAAS,aAAa,SAAS;CAGrD,OACE,oBAAC,MAAD;EACE,SAAS;EAKT,aAAU;EAOV,cAAY;EACZ,gBAAc;EACd,WAAW,GACT,4BAnBa,oBAAoB,aAoBpB,kBAAkB,aAC/B,SAEF;EACA,GAAI;EAEH;CACG,CAAA;AAEV"}
|
|
@@ -66,7 +66,7 @@ const Checkbox = ({ placement = "left", value: _value = "", children, className,
|
|
|
66
66
|
value: itemValue,
|
|
67
67
|
checked,
|
|
68
68
|
disabled,
|
|
69
|
-
className: cn(cursorClassName),
|
|
69
|
+
className: cn("rounded-sm", cursorClassName),
|
|
70
70
|
onCheckedChange: onChange
|
|
71
71
|
}), children && /* @__PURE__ */ jsx(CoreLabel, {
|
|
72
72
|
htmlFor: id,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkbox.mjs","names":["checkbox","label"],"sources":["../../../../src/components/atoms/checkbox/checkbox.tsx"],"sourcesContent":["'use client';\n\nimport { useId, useRef } from 'react';\n\nimport { useControllableState, useKeyPress } from '@jbpark/use-hooks';\nimport { Square, SquareCheck } from 'lucide-react';\n\nimport { cn } from '@repo/ui/utils';\n\nimport { checkbox, label } from '../../../core';\nimport { type OptionValue } from './group';\n\nconst { Checkbox: CoreCheckbox } = checkbox;\nconst { Label: CoreLabel } = label;\n\nexport interface Props extends Omit<\n React.ComponentPropsWithoutRef<'div'>,\n 'onChange'\n> {\n placement?: 'left' | 'right';\n defaultChecked?: boolean;\n checked?: boolean;\n value?: OptionValue;\n /** Native form field name — participates in `FormData` when set. */\n name?: string;\n disabled?: boolean;\n icons?: Partial<{ checked: React.ReactNode; unchecked: React.ReactNode }>;\n children?: React.ReactNode;\n onChange?: (checked: boolean) => void;\n}\n\nconst Checkbox = ({\n placement = 'left',\n value: _value = '',\n children,\n className,\n icons,\n disabled,\n defaultChecked,\n checked: _checked,\n name,\n onChange: _onChange = () => {},\n ...props\n}: Props) => {\n const [checked, setChecked] = useControllableState<boolean>({\n value: _checked,\n defaultValue: defaultChecked ?? false,\n onChange: _onChange,\n });\n\n const id = useId();\n const itemValue = String(_value);\n\n const cursorClassName = disabled ? 'cursor-not-allowed' : 'cursor-pointer';\n\n const onChange = (next: boolean) => {\n if (disabled) {\n return;\n }\n\n setChecked(next);\n };\n\n const iconTriggerRef = useRef<HTMLSpanElement>(null);\n\n useKeyPress(\n ['Enter', 'space'],\n event => {\n event.preventDefault();\n onChange(!checked);\n },\n { target: iconTriggerRef, enabled: !!icons && !disabled },\n );\n\n const renderContent = icons ? (\n <>\n <input\n id={id}\n hidden\n type=\"checkbox\"\n name={name}\n value={itemValue}\n checked={checked}\n disabled={disabled}\n onChange={e => {\n onChange(e.target.checked);\n }}\n />\n <span\n ref={iconTriggerRef}\n role=\"checkbox\"\n aria-checked={checked}\n aria-disabled={disabled}\n tabIndex={disabled ? -1 : 0}\n className={cn(cursorClassName, disabled && 'opacity-50')}\n onClick={() => {\n onChange(!checked);\n }}\n >\n {checked\n ? (icons.checked ?? <SquareCheck />)\n : (icons.unchecked ?? <Square />)}\n </span>\n {children && (\n <label\n className={cn(cursorClassName, disabled && 'opacity-50')}\n htmlFor={id}\n >\n {children}\n </label>\n )}\n </>\n ) : (\n <>\n <CoreCheckbox\n id={id}\n name={name}\n value={itemValue}\n checked={checked}\n disabled={disabled}\n className={cn(cursorClassName)}\n onCheckedChange={onChange}\n />\n {children && (\n <CoreLabel htmlFor={id} className={cn(cursorClassName, 'text-left')}>\n {children}\n </CoreLabel>\n )}\n </>\n );\n\n return (\n <div\n className={cn(\n 'flex items-center gap-x-2',\n placement === 'right' && 'flex-row-reverse',\n cursorClassName,\n className,\n //\n )}\n {...props}\n >\n {renderContent}\n </div>\n );\n};\n\nexport default Checkbox;\n"],"mappings":";;;;;;;;;AAYA,MAAM,EAAE,UAAU,iBAAiBA;AACnC,MAAM,EAAE,OAAO,cAAcC;AAkB7B,MAAM,YAAY,EAChB,YAAY,QACZ,OAAO,SAAS,IAChB,UACA,WACA,OACA,UACA,gBACA,SAAS,UACT,MACA,UAAU,kBAAkB,CAAC,GAC7B,GAAG,YACQ;CACX,MAAM,CAAC,SAAS,cAAc,qBAA8B;EAC1D,OAAO;EACP,cAAc,kBAAkB;EAChC,UAAU;CACZ,CAAC;CAED,MAAM,KAAK,MAAM;CACjB,MAAM,YAAY,OAAO,MAAM;CAE/B,MAAM,kBAAkB,WAAW,uBAAuB;CAE1D,MAAM,YAAY,SAAkB;EAClC,IAAI,UACF;EAGF,WAAW,IAAI;CACjB;CAEA,MAAM,iBAAiB,OAAwB,IAAI;CAEnD,YACE,CAAC,SAAS,OAAO,IACjB,UAAS;EACP,MAAM,eAAe;EACrB,SAAS,CAAC,OAAO;CACnB,GACA;EAAE,QAAQ;EAAgB,SAAS,CAAC,CAAC,SAAS,CAAC;CAAS,CAC1D;CAEA,MAAM,gBAAgB,QACpB,qBAAA,YAAA,EAAA,UAAA;EACE,oBAAC,SAAD;GACM;GACJ,QAAA;GACA,MAAK;GACC;GACN,OAAO;GACE;GACC;GACV,WAAU,MAAK;IACb,SAAS,EAAE,OAAO,OAAO;GAC3B;EACD,CAAA;EACD,oBAAC,QAAD;GACE,KAAK;GACL,MAAK;GACL,gBAAc;GACd,iBAAe;GACf,UAAU,WAAW,KAAK;GAC1B,WAAW,GAAG,iBAAiB,YAAY,YAAY;GACvD,eAAe;IACb,SAAS,CAAC,OAAO;GACnB;GAEC,UAAA,UACI,MAAM,WAAW,oBAAC,aAAD,CAAc,CAAA,IAC/B,MAAM,aAAa,oBAAC,QAAD,CAAS,CAAA;EAC7B,CAAA;EACL,YACC,oBAAC,SAAD;GACE,WAAW,GAAG,iBAAiB,YAAY,YAAY;GACvD,SAAS;GAER;EACI,CAAA;CAET,EAAA,CAAA,IAEF,qBAAA,YAAA,EAAA,UAAA,CACE,oBAAC,cAAD;EACM;EACE;EACN,OAAO;EACE;EACC;
|
|
1
|
+
{"version":3,"file":"checkbox.mjs","names":["checkbox","label"],"sources":["../../../../src/components/atoms/checkbox/checkbox.tsx"],"sourcesContent":["'use client';\n\nimport { useId, useRef } from 'react';\n\nimport { useControllableState, useKeyPress } from '@jbpark/use-hooks';\nimport { Square, SquareCheck } from 'lucide-react';\n\nimport { cn } from '@repo/ui/utils';\n\nimport { checkbox, label } from '../../../core';\nimport { type OptionValue } from './group';\n\nconst { Checkbox: CoreCheckbox } = checkbox;\nconst { Label: CoreLabel } = label;\n\nexport interface Props extends Omit<\n React.ComponentPropsWithoutRef<'div'>,\n 'onChange'\n> {\n placement?: 'left' | 'right';\n defaultChecked?: boolean;\n checked?: boolean;\n value?: OptionValue;\n /** Native form field name — participates in `FormData` when set. */\n name?: string;\n disabled?: boolean;\n icons?: Partial<{ checked: React.ReactNode; unchecked: React.ReactNode }>;\n children?: React.ReactNode;\n onChange?: (checked: boolean) => void;\n}\n\nconst Checkbox = ({\n placement = 'left',\n value: _value = '',\n children,\n className,\n icons,\n disabled,\n defaultChecked,\n checked: _checked,\n name,\n onChange: _onChange = () => {},\n ...props\n}: Props) => {\n const [checked, setChecked] = useControllableState<boolean>({\n value: _checked,\n defaultValue: defaultChecked ?? false,\n onChange: _onChange,\n });\n\n const id = useId();\n const itemValue = String(_value);\n\n const cursorClassName = disabled ? 'cursor-not-allowed' : 'cursor-pointer';\n\n const onChange = (next: boolean) => {\n if (disabled) {\n return;\n }\n\n setChecked(next);\n };\n\n const iconTriggerRef = useRef<HTMLSpanElement>(null);\n\n useKeyPress(\n ['Enter', 'space'],\n event => {\n event.preventDefault();\n onChange(!checked);\n },\n { target: iconTriggerRef, enabled: !!icons && !disabled },\n );\n\n const renderContent = icons ? (\n <>\n <input\n id={id}\n hidden\n type=\"checkbox\"\n name={name}\n value={itemValue}\n checked={checked}\n disabled={disabled}\n onChange={e => {\n onChange(e.target.checked);\n }}\n />\n <span\n ref={iconTriggerRef}\n role=\"checkbox\"\n aria-checked={checked}\n aria-disabled={disabled}\n tabIndex={disabled ? -1 : 0}\n className={cn(cursorClassName, disabled && 'opacity-50')}\n onClick={() => {\n onChange(!checked);\n }}\n >\n {checked\n ? (icons.checked ?? <SquareCheck />)\n : (icons.unchecked ?? <Square />)}\n </span>\n {children && (\n <label\n className={cn(cursorClassName, disabled && 'opacity-50')}\n htmlFor={id}\n >\n {children}\n </label>\n )}\n </>\n ) : (\n <>\n <CoreCheckbox\n id={id}\n name={name}\n value={itemValue}\n checked={checked}\n disabled={disabled}\n // Keep the atom's established 4px radius after the Base UI migration;\n // tailwind-merge lets this override the core primitive's radius (#361).\n className={cn('rounded-sm', cursorClassName)}\n onCheckedChange={onChange}\n />\n {children && (\n <CoreLabel htmlFor={id} className={cn(cursorClassName, 'text-left')}>\n {children}\n </CoreLabel>\n )}\n </>\n );\n\n return (\n <div\n className={cn(\n 'flex items-center gap-x-2',\n placement === 'right' && 'flex-row-reverse',\n cursorClassName,\n className,\n //\n )}\n {...props}\n >\n {renderContent}\n </div>\n );\n};\n\nexport default Checkbox;\n"],"mappings":";;;;;;;;;AAYA,MAAM,EAAE,UAAU,iBAAiBA;AACnC,MAAM,EAAE,OAAO,cAAcC;AAkB7B,MAAM,YAAY,EAChB,YAAY,QACZ,OAAO,SAAS,IAChB,UACA,WACA,OACA,UACA,gBACA,SAAS,UACT,MACA,UAAU,kBAAkB,CAAC,GAC7B,GAAG,YACQ;CACX,MAAM,CAAC,SAAS,cAAc,qBAA8B;EAC1D,OAAO;EACP,cAAc,kBAAkB;EAChC,UAAU;CACZ,CAAC;CAED,MAAM,KAAK,MAAM;CACjB,MAAM,YAAY,OAAO,MAAM;CAE/B,MAAM,kBAAkB,WAAW,uBAAuB;CAE1D,MAAM,YAAY,SAAkB;EAClC,IAAI,UACF;EAGF,WAAW,IAAI;CACjB;CAEA,MAAM,iBAAiB,OAAwB,IAAI;CAEnD,YACE,CAAC,SAAS,OAAO,IACjB,UAAS;EACP,MAAM,eAAe;EACrB,SAAS,CAAC,OAAO;CACnB,GACA;EAAE,QAAQ;EAAgB,SAAS,CAAC,CAAC,SAAS,CAAC;CAAS,CAC1D;CAEA,MAAM,gBAAgB,QACpB,qBAAA,YAAA,EAAA,UAAA;EACE,oBAAC,SAAD;GACM;GACJ,QAAA;GACA,MAAK;GACC;GACN,OAAO;GACE;GACC;GACV,WAAU,MAAK;IACb,SAAS,EAAE,OAAO,OAAO;GAC3B;EACD,CAAA;EACD,oBAAC,QAAD;GACE,KAAK;GACL,MAAK;GACL,gBAAc;GACd,iBAAe;GACf,UAAU,WAAW,KAAK;GAC1B,WAAW,GAAG,iBAAiB,YAAY,YAAY;GACvD,eAAe;IACb,SAAS,CAAC,OAAO;GACnB;GAEC,UAAA,UACI,MAAM,WAAW,oBAAC,aAAD,CAAc,CAAA,IAC/B,MAAM,aAAa,oBAAC,QAAD,CAAS,CAAA;EAC7B,CAAA;EACL,YACC,oBAAC,SAAD;GACE,WAAW,GAAG,iBAAiB,YAAY,YAAY;GACvD,SAAS;GAER;EACI,CAAA;CAET,EAAA,CAAA,IAEF,qBAAA,YAAA,EAAA,UAAA,CACE,oBAAC,cAAD;EACM;EACE;EACN,OAAO;EACE;EACC;EAGV,WAAW,GAAG,cAAc,eAAe;EAC3C,iBAAiB;CAClB,CAAA,GACA,YACC,oBAAC,WAAD;EAAW,SAAS;EAAI,WAAW,GAAG,iBAAiB,WAAW;EAC/D;CACQ,CAAA,CAEb,EAAA,CAAA;CAGJ,OACE,oBAAC,OAAD;EACE,WAAW,GACT,6BACA,cAAc,WAAW,oBACzB,iBACA,SAEF;EACA,GAAI;EAEH,UAAA;CACE,CAAA;AAET"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"option-group.mjs","names":[],"sources":["../../../src/components/atoms/option-group.ts"],"sourcesContent":["export type OptionValue = string | number | boolean;\n\nexport interface Option {\n label: string;\n value: OptionValue;\n disabled?: boolean;\n}\n\nexport type Options = string[] | number[] | boolean[] | Option[];\n\nexport interface OptionGroupClassNames {\n wrapper?: string;\n item?: string;\n}\n\nexport const normalizeOptions = (options: Options): Option[] =>\n options.map(item =>\n typeof item === 'object'\n ? item\n : {\n label: `${item}`,\n value: item,\n },\n );\n\n// Radio.Group/Checkbox.Group both key selection off `value` (
|
|
1
|
+
{"version":3,"file":"option-group.mjs","names":[],"sources":["../../../src/components/atoms/option-group.ts"],"sourcesContent":["export type OptionValue = string | number | boolean;\n\nexport interface Option {\n label: string;\n value: OptionValue;\n disabled?: boolean;\n}\n\nexport type Options = string[] | number[] | boolean[] | Option[];\n\nexport interface OptionGroupClassNames {\n wrapper?: string;\n item?: string;\n}\n\nexport const normalizeOptions = (options: Options): Option[] =>\n options.map(item =>\n typeof item === 'object'\n ? item\n : {\n label: `${item}`,\n value: item,\n },\n );\n\n// Radio.Group/Checkbox.Group both key selection off `value` (Base UI's\n// Radio.Group matches items by it, and Checkbox.Group tests membership via\n// `value.includes(...)`), so two options sharing a value aren't just a\n// React list-key collision — they become indistinguishable to the\n// component's own selection logic, e.g. both rendering aria-checked=true\n// together. A duplicate is virtually always a caller mistake (two radios\n// for the \"same\" value can't be meaningfully different choices), so warn\n// instead of silently accepting it.\nexport const warnOnDuplicateOptionValues = (\n options: Option[],\n componentName: string,\n) => {\n const nodeEnv = (globalThis as { process?: { env?: { NODE_ENV?: string } } })\n .process?.env?.NODE_ENV;\n\n if (nodeEnv === 'production') {\n return;\n }\n\n const seen = new Set<OptionValue>();\n const duplicates = new Set<OptionValue>();\n\n for (const option of options) {\n if (seen.has(option.value)) {\n duplicates.add(option.value);\n }\n seen.add(option.value);\n }\n\n if (duplicates.size > 0) {\n console.warn(\n `${componentName}: duplicate option value(s) [${[...duplicates].map(v => JSON.stringify(v)).join(', ')}] — options sharing a value render as if selecting one selects all of them, since selection is matched by value.`,\n );\n }\n};\n"],"mappings":";AAeA,MAAa,oBAAoB,YAC/B,QAAQ,KAAI,SACV,OAAO,SAAS,WACZ,OACA;CACE,OAAO,GAAG;CACV,OAAO;AACT,CACN;AAUF,MAAa,+BACX,SACA,kBACG;CAIH,IAHiB,WACd,SAAS,KAAK,aAED,cACd;CAGF,MAAM,uBAAO,IAAI,IAAiB;CAClC,MAAM,6BAAa,IAAI,IAAiB;CAExC,KAAK,MAAM,UAAU,SAAS;EAC5B,IAAI,KAAK,IAAI,OAAO,KAAK,GACvB,WAAW,IAAI,OAAO,KAAK;EAE7B,KAAK,IAAI,OAAO,KAAK;CACvB;CAEA,IAAI,WAAW,OAAO,GACpB,QAAQ,KACN,GAAG,cAAc,+BAA+B,CAAC,GAAG,UAAU,CAAC,CAAC,KAAI,MAAK,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,iHACzG;AAEJ"}
|
|
@@ -2,13 +2,15 @@
|
|
|
2
2
|
type Placement = 'top' | 'left' | 'right' | 'bottom' | 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight' | 'leftTop' | 'leftBottom' | 'rightTop' | 'rightBottom';
|
|
3
3
|
interface Props extends Omit<React.ComponentPropsWithoutRef<'div'>, 'title' | 'content'> {
|
|
4
4
|
title?: React.ReactNode;
|
|
5
|
+
/** Set to false when a custom trigger component renders a non-button element. */
|
|
6
|
+
nativeButton?: boolean;
|
|
5
7
|
placement?: Placement;
|
|
6
8
|
content: React.ReactNode;
|
|
7
9
|
open?: boolean;
|
|
8
10
|
defaultOpen?: boolean;
|
|
9
11
|
onOpenChange?: (open: boolean) => void;
|
|
10
12
|
}
|
|
11
|
-
declare const Popover: ({ title, placement, className, content, children, open: _open, defaultOpen, onOpenChange, ...props }: Props) => import("react").JSX.Element;
|
|
13
|
+
declare const Popover: ({ title, nativeButton, placement, className, content, children, open: _open, defaultOpen, onOpenChange, ...props }: Props) => import("react").JSX.Element;
|
|
12
14
|
//#endregion
|
|
13
15
|
export { Props, Popover as default };
|
|
14
16
|
//# sourceMappingURL=popover.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"popover.d.mts","names":[],"sources":["../../../src/components/atoms/popover.tsx"],"mappings":";
|
|
1
|
+
{"version":3,"file":"popover.d.mts","names":[],"sources":["../../../src/components/atoms/popover.tsx"],"mappings":";KAmBK;UAcY,cAAc,KAC7B,MAAM;EAGN,QAAQ,MAAM;;EAEd;EACA,YAAY;EACZ,SAAS,MAAM;EACf;EACA;EACA,gBAAgB;;cAqBZ,YAAW,OAAA,cAAA,WAAA,WAAA,SAAA,UAAA,MAAA,OAAA,aAAA,iBAAA,SAWd,0BAAK,IAAA"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
"use client";
|
|
1
2
|
import { cn, renderConditional } from "../../utils.mjs";
|
|
2
3
|
import { popover_exports } from "../../core/popover.mjs";
|
|
3
4
|
import Typography from "../../Typography.mjs";
|
|
5
|
+
import { Children } from "react";
|
|
4
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
7
|
import { useControllableState } from "@jbpark/use-hooks";
|
|
6
8
|
//#region src/components/atoms/popover.tsx
|
|
7
|
-
const { Popover: CorePopover, PopoverContent, PopoverTrigger } = popover_exports;
|
|
9
|
+
const { Popover: CorePopover, PopoverContent, PopoverTrigger, PopoverArrow, PopoverTitle } = popover_exports;
|
|
8
10
|
const placementMap = {
|
|
9
11
|
top: {
|
|
10
12
|
side: "top",
|
|
@@ -55,123 +57,20 @@ const placementMap = {
|
|
|
55
57
|
align: "end"
|
|
56
58
|
}
|
|
57
59
|
};
|
|
58
|
-
const
|
|
59
|
-
const afterBase = "after:content-[\"\"] after:absolute after:h-0 after:w-0";
|
|
60
|
-
const vBorderShape = "before:border-l-[9px] before:border-r-[9px] before:border-l-transparent before:border-r-transparent";
|
|
61
|
-
const hBorderShape = "before:border-t-[9px] before:border-b-[9px] before:border-t-transparent before:border-b-transparent";
|
|
62
|
-
const vFillShape = "after:border-l-8 after:border-r-8 after:border-l-transparent after:border-r-transparent";
|
|
63
|
-
const hFillShape = "after:border-t-8 after:border-b-8 after:border-t-transparent after:border-b-transparent";
|
|
64
|
-
const borderShapeBySide = {
|
|
65
|
-
top: vBorderShape,
|
|
66
|
-
bottom: vBorderShape,
|
|
67
|
-
left: hBorderShape,
|
|
68
|
-
right: hBorderShape
|
|
69
|
-
};
|
|
70
|
-
const fillShapeBySide = {
|
|
71
|
-
top: vFillShape,
|
|
72
|
-
bottom: vFillShape,
|
|
73
|
-
left: hFillShape,
|
|
74
|
-
right: hFillShape
|
|
75
|
-
};
|
|
76
|
-
const borderColorBySide = {
|
|
77
|
-
top: "before:border-t-[9px] before:border-t-border",
|
|
78
|
-
bottom: "before:border-b-[9px] before:border-b-border",
|
|
79
|
-
left: "before:border-l-[9px] before:border-l-border",
|
|
80
|
-
right: "before:border-r-[9px] before:border-r-border"
|
|
81
|
-
};
|
|
82
|
-
const fillColorBySide = {
|
|
83
|
-
top: "after:border-t-8 after:border-t-popover",
|
|
84
|
-
bottom: "after:border-b-8 after:border-b-popover",
|
|
85
|
-
left: "after:border-l-8 after:border-l-popover",
|
|
86
|
-
right: "after:border-r-8 after:border-r-popover"
|
|
87
|
-
};
|
|
88
|
-
const POSITION_CLASSES = {
|
|
89
|
-
top: {
|
|
90
|
-
start: {
|
|
91
|
-
wrapper: "top-full left-4",
|
|
92
|
-
before: "before:top-0 before:left-0",
|
|
93
|
-
after: "after:-top-px after:left-px"
|
|
94
|
-
},
|
|
95
|
-
center: {
|
|
96
|
-
wrapper: "top-full left-1/2 -translate-x-1/2",
|
|
97
|
-
before: "before:top-0 before:left-1/2 before:-translate-x-1/2",
|
|
98
|
-
after: "after:-top-px after:left-1/2 after:-translate-x-1/2"
|
|
99
|
-
},
|
|
100
|
-
end: {
|
|
101
|
-
wrapper: "top-full right-4",
|
|
102
|
-
before: "before:top-0 before:right-0",
|
|
103
|
-
after: "after:-top-px after:right-px"
|
|
104
|
-
}
|
|
105
|
-
},
|
|
106
|
-
bottom: {
|
|
107
|
-
start: {
|
|
108
|
-
wrapper: "bottom-full left-4",
|
|
109
|
-
before: "before:bottom-0 before:left-0",
|
|
110
|
-
after: "after:-bottom-px after:left-px"
|
|
111
|
-
},
|
|
112
|
-
center: {
|
|
113
|
-
wrapper: "bottom-full left-1/2 -translate-x-1/2",
|
|
114
|
-
before: "before:bottom-0 before:left-1/2 before:-translate-x-1/2",
|
|
115
|
-
after: "after:-bottom-px after:left-1/2 after:-translate-x-1/2"
|
|
116
|
-
},
|
|
117
|
-
end: {
|
|
118
|
-
wrapper: "bottom-full right-4",
|
|
119
|
-
before: "before:bottom-0 before:right-0",
|
|
120
|
-
after: "after:-bottom-px after:right-px"
|
|
121
|
-
}
|
|
122
|
-
},
|
|
123
|
-
left: {
|
|
124
|
-
start: {
|
|
125
|
-
wrapper: "left-full top-4",
|
|
126
|
-
before: "before:left-0 before:top-0",
|
|
127
|
-
after: "after:-left-px after:top-px"
|
|
128
|
-
},
|
|
129
|
-
center: {
|
|
130
|
-
wrapper: "left-full top-1/2 -translate-y-1/2",
|
|
131
|
-
before: "before:left-0 before:top-1/2 before:-translate-y-1/2",
|
|
132
|
-
after: "after:-left-px after:top-1/2 after:-translate-y-1/2"
|
|
133
|
-
},
|
|
134
|
-
end: {
|
|
135
|
-
wrapper: "left-full bottom-4",
|
|
136
|
-
before: "before:left-0 before:bottom-0",
|
|
137
|
-
after: "after:-left-px after:bottom-px"
|
|
138
|
-
}
|
|
139
|
-
},
|
|
140
|
-
right: {
|
|
141
|
-
start: {
|
|
142
|
-
wrapper: "right-full top-4",
|
|
143
|
-
before: "before:right-0 before:top-0",
|
|
144
|
-
after: "after:-right-px after:top-px"
|
|
145
|
-
},
|
|
146
|
-
center: {
|
|
147
|
-
wrapper: "right-full top-1/2 -translate-y-1/2",
|
|
148
|
-
before: "before:right-0 before:top-1/2 before:-translate-y-1/2",
|
|
149
|
-
after: "after:-right-px after:top-1/2 after:-translate-y-1/2"
|
|
150
|
-
},
|
|
151
|
-
end: {
|
|
152
|
-
wrapper: "right-full bottom-4",
|
|
153
|
-
before: "before:right-0 before:bottom-0",
|
|
154
|
-
after: "after:-right-px after:bottom-px"
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
};
|
|
158
|
-
const getArrowClassName = (side, align) => {
|
|
159
|
-
const { wrapper, before, after } = POSITION_CLASSES[side][align];
|
|
160
|
-
return cn("absolute", wrapper, beforeBase, before, borderShapeBySide[side], borderColorBySide[side], afterBase, after, fillShapeBySide[side], fillColorBySide[side]);
|
|
161
|
-
};
|
|
162
|
-
const Popover = ({ title, placement = "top", className, content, children, open: _open, defaultOpen, onOpenChange, ...props }) => {
|
|
60
|
+
const Popover = ({ title, nativeButton, placement = "top", className, content, children, open: _open, defaultOpen, onOpenChange, ...props }) => {
|
|
163
61
|
const [open, setOpen] = useControllableState({
|
|
164
62
|
value: _open,
|
|
165
63
|
defaultValue: defaultOpen ?? false,
|
|
166
64
|
onChange: onOpenChange
|
|
167
65
|
});
|
|
168
66
|
const { side, align } = placementMap[placement];
|
|
67
|
+
const trigger = Children.only(children);
|
|
169
68
|
return /* @__PURE__ */ jsxs(CorePopover, {
|
|
170
69
|
open,
|
|
171
70
|
onOpenChange: setOpen,
|
|
172
71
|
children: [/* @__PURE__ */ jsx(PopoverTrigger, {
|
|
173
|
-
|
|
174
|
-
|
|
72
|
+
render: trigger,
|
|
73
|
+
nativeButton: nativeButton ?? (typeof trigger.type !== "string" || trigger.type === "button")
|
|
175
74
|
}), /* @__PURE__ */ jsxs(PopoverContent, {
|
|
176
75
|
...props,
|
|
177
76
|
align,
|
|
@@ -179,12 +78,12 @@ const Popover = ({ title, placement = "top", className, content, children, open:
|
|
|
179
78
|
sideOffset: 16,
|
|
180
79
|
className: cn("relative w-auto", className),
|
|
181
80
|
children: [
|
|
182
|
-
renderConditional(title, (v) => /* @__PURE__ */ jsx(
|
|
183
|
-
level: 6,
|
|
81
|
+
renderConditional(title, (v) => /* @__PURE__ */ jsx(PopoverTitle, {
|
|
82
|
+
render: /* @__PURE__ */ jsx(Typography.Title, { level: 6 }),
|
|
184
83
|
children: v
|
|
185
84
|
})),
|
|
186
85
|
content,
|
|
187
|
-
/* @__PURE__ */ jsx(
|
|
86
|
+
/* @__PURE__ */ jsx(PopoverArrow, {})
|
|
188
87
|
]
|
|
189
88
|
})]
|
|
190
89
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"popover.mjs","names":["popover"],"sources":["../../../src/components/atoms/popover.tsx"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"popover.mjs","names":["popover"],"sources":["../../../src/components/atoms/popover.tsx"],"sourcesContent":["'use client';\n\nimport { Children, type ReactElement } from 'react';\n\nimport { useControllableState } from '@jbpark/use-hooks';\n\nimport { cn, renderConditional } from '@repo/ui/utils';\n\nimport { popover } from '../../core';\nimport Typography from './typography';\n\nconst {\n Popover: CorePopover,\n PopoverContent,\n PopoverTrigger,\n PopoverArrow,\n PopoverTitle,\n} = popover;\n\ntype Placement =\n | 'top'\n | 'left'\n | 'right'\n | 'bottom'\n | 'topLeft'\n | 'topRight'\n | 'bottomLeft'\n | 'bottomRight'\n | 'leftTop'\n | 'leftBottom'\n | 'rightTop'\n | 'rightBottom';\n\nexport interface Props extends Omit<\n React.ComponentPropsWithoutRef<'div'>,\n 'title' | 'content'\n> {\n title?: React.ReactNode;\n /** Set to false when a custom trigger component renders a non-button element. */\n nativeButton?: boolean;\n placement?: Placement;\n content: React.ReactNode;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n}\n\ntype Side = 'top' | 'bottom' | 'left' | 'right';\ntype Align = 'start' | 'center' | 'end';\n\nconst placementMap: Record<Placement, { side: Side; align: Align }> = {\n top: { side: 'top', align: 'center' },\n left: { side: 'left', align: 'center' },\n right: { side: 'right', align: 'center' },\n bottom: { side: 'bottom', align: 'center' },\n topLeft: { side: 'top', align: 'start' },\n topRight: { side: 'top', align: 'end' },\n bottomLeft: { side: 'bottom', align: 'start' },\n bottomRight: { side: 'bottom', align: 'end' },\n leftTop: { side: 'left', align: 'start' },\n leftBottom: { side: 'left', align: 'end' },\n rightTop: { side: 'right', align: 'start' },\n rightBottom: { side: 'right', align: 'end' },\n};\n\nconst Popover = ({\n title,\n nativeButton,\n placement = 'top',\n className,\n content,\n children,\n open: _open,\n defaultOpen,\n onOpenChange,\n ...props\n}: Props) => {\n const [open, setOpen] = useControllableState<boolean>({\n value: _open,\n defaultValue: defaultOpen ?? false,\n onChange: onOpenChange,\n });\n\n const { side, align } = placementMap[placement];\n\n const trigger = Children.only(children) as ReactElement;\n\n return (\n <CorePopover open={open} onOpenChange={setOpen}>\n {/* Deliberately no `data-slot` here: Base UI merges the trigger's own\n props over the rendered element's, so a `data-slot` set here replaces\n the child's. A `Button` trigger would lose `data-slot=\"button\"` and\n with it every `--btn-*` token rule in globals.css. */}\n <PopoverTrigger\n render={trigger}\n nativeButton={\n nativeButton ??\n (typeof trigger.type !== 'string' || trigger.type === 'button')\n }\n />\n <PopoverContent\n {...props}\n align={align}\n side={side}\n sideOffset={16}\n className={cn('relative w-auto', className)}\n >\n {renderConditional(title, v => (\n <PopoverTitle render={<Typography.Title level={6} />}>\n {v}\n </PopoverTitle>\n ))}\n {content}\n <PopoverArrow />\n </PopoverContent>\n </CorePopover>\n );\n};\n\nexport default Popover;\n"],"mappings":";;;;;;;;AAWA,MAAM,EACJ,SAAS,aACT,gBACA,gBACA,cACA,iBACEA;AAiCJ,MAAM,eAAgE;CACpE,KAAK;EAAE,MAAM;EAAO,OAAO;CAAS;CACpC,MAAM;EAAE,MAAM;EAAQ,OAAO;CAAS;CACtC,OAAO;EAAE,MAAM;EAAS,OAAO;CAAS;CACxC,QAAQ;EAAE,MAAM;EAAU,OAAO;CAAS;CAC1C,SAAS;EAAE,MAAM;EAAO,OAAO;CAAQ;CACvC,UAAU;EAAE,MAAM;EAAO,OAAO;CAAM;CACtC,YAAY;EAAE,MAAM;EAAU,OAAO;CAAQ;CAC7C,aAAa;EAAE,MAAM;EAAU,OAAO;CAAM;CAC5C,SAAS;EAAE,MAAM;EAAQ,OAAO;CAAQ;CACxC,YAAY;EAAE,MAAM;EAAQ,OAAO;CAAM;CACzC,UAAU;EAAE,MAAM;EAAS,OAAO;CAAQ;CAC1C,aAAa;EAAE,MAAM;EAAS,OAAO;CAAM;AAC7C;AAEA,MAAM,WAAW,EACf,OACA,cACA,YAAY,OACZ,WACA,SACA,UACA,MAAM,OACN,aACA,cACA,GAAG,YACQ;CACX,MAAM,CAAC,MAAM,WAAW,qBAA8B;EACpD,OAAO;EACP,cAAc,eAAe;EAC7B,UAAU;CACZ,CAAC;CAED,MAAM,EAAE,MAAM,UAAU,aAAa;CAErC,MAAM,UAAU,SAAS,KAAK,QAAQ;CAEtC,OACE,qBAAC,aAAD;EAAmB;EAAM,cAAc;EAAvC,UAAA,CAKE,oBAAC,gBAAD;GACE,QAAQ;GACR,cACE,iBACC,OAAO,QAAQ,SAAS,YAAY,QAAQ,SAAS;EAEzD,CAAA,GACD,qBAAC,gBAAD;GACE,GAAI;GACG;GACD;GACN,YAAY;GACZ,WAAW,GAAG,mBAAmB,SAAS;GAL5C,UAAA;IAOG,kBAAkB,QAAO,MACxB,oBAAC,cAAD;KAAc,QAAQ,oBAAC,WAAW,OAAZ,EAAkB,OAAO,EAAI,CAAA;KAChD,UAAA;IACW,CAAA,CACf;IACA;IACD,oBAAC,cAAD,CAAe,CAAA;GACD;EACL,CAAA,CAAA;;AAEjB"}
|
|
@@ -5,16 +5,15 @@ import { jsx } from "react/jsx-runtime";
|
|
|
5
5
|
const { Progress: Core } = progress_exports;
|
|
6
6
|
const Progress = ({ value, className, direction = "horizontal", classNames, ...props }) => {
|
|
7
7
|
const isHorizontal = direction === "horizontal";
|
|
8
|
-
const dimension = isHorizontal ? "width" : "height";
|
|
9
8
|
const normalizedValue = Number.isFinite(value) ? Math.min(100, Math.max(0, value)) : 0;
|
|
10
9
|
return /* @__PURE__ */ jsx(Core, {
|
|
11
10
|
...props,
|
|
12
11
|
value: normalizedValue,
|
|
13
12
|
className: cn(isHorizontal ? "h-4 w-full" : "flex h-full w-4 flex-col justify-end", className, classNames?.background),
|
|
14
13
|
barClassName: cn("flex-none", classNames?.bar),
|
|
15
|
-
barStyle: {
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
barStyle: isHorizontal ? { width: `${normalizedValue}%` } : {
|
|
15
|
+
width: "100%",
|
|
16
|
+
height: `${normalizedValue}%`
|
|
18
17
|
}
|
|
19
18
|
});
|
|
20
19
|
};
|