Skip to content

Commit 5f98e5c

Browse files
committed
feat: add radix-ui aggregate package
1 parent 86a2006 commit 5f98e5c

9 files changed

Lines changed: 498 additions & 0 deletions

File tree

packages/radix-ui/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# @fictjs/radix-ui
2+
3+
Aggregate entry points for Fict UI primitives, modeled after `radix-ui`.
4+
5+
Exports:
6+
7+
- `@fictjs/radix-ui` for the public primitive namespaces
8+
- `@fictjs/radix-ui/internal` for lower-level building blocks and utilities

packages/radix-ui/package.json

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
{
2+
"name": "@fictjs/radix-ui",
3+
"version": "0.1.0",
4+
"description": "Aggregate exports for Fict UI primitives.",
5+
"license": "MIT",
6+
"type": "module",
7+
"sideEffects": false,
8+
"main": "./dist/index.cjs",
9+
"module": "./dist/index.js",
10+
"types": "./dist/index.d.ts",
11+
"exports": {
12+
".": {
13+
"types": "./dist/index.d.ts",
14+
"import": "./dist/index.js",
15+
"require": "./dist/index.cjs"
16+
},
17+
"./internal": {
18+
"types": "./dist/internal.d.ts",
19+
"import": "./dist/internal.js",
20+
"require": "./dist/internal.cjs"
21+
}
22+
},
23+
"files": [
24+
"dist",
25+
"README.md"
26+
],
27+
"engines": {
28+
"node": ">=22.13.0"
29+
},
30+
"publishConfig": {
31+
"access": "public",
32+
"provenance": true
33+
},
34+
"keywords": [
35+
"fict",
36+
"radix",
37+
"radix-ui",
38+
"ui-primitives"
39+
],
40+
"repository": {
41+
"type": "git",
42+
"url": "git+https://github.com/fictjs/ui-primitives.git",
43+
"directory": "packages/radix-ui"
44+
},
45+
"scripts": {
46+
"build": "tsup",
47+
"clean": "rimraf coverage dist",
48+
"dev": "tsup --watch",
49+
"lint": "eslint . --max-warnings=0",
50+
"lint:fix": "eslint . --fix",
51+
"test": "vitest run --config ./vitest.config.ts",
52+
"test:coverage": "vitest run --config ./vitest.config.ts --coverage",
53+
"test:watch": "vitest --config ./vitest.config.ts",
54+
"typecheck": "tsc --noEmit -p tsconfig.json"
55+
},
56+
"dependencies": {
57+
"@fictjs/accessible-icon": "workspace:*",
58+
"@fictjs/accordion": "workspace:*",
59+
"@fictjs/alert-dialog": "workspace:*",
60+
"@fictjs/arrow": "workspace:*",
61+
"@fictjs/aspect-ratio": "workspace:*",
62+
"@fictjs/avatar": "workspace:*",
63+
"@fictjs/checkbox": "workspace:*",
64+
"@fictjs/collapsible": "workspace:*",
65+
"@fictjs/collection": "workspace:*",
66+
"@fictjs/compose-refs": "workspace:*",
67+
"@fictjs/context": "workspace:*",
68+
"@fictjs/context-menu": "workspace:*",
69+
"@fictjs/core-primitive": "workspace:*",
70+
"@fictjs/dialog": "workspace:*",
71+
"@fictjs/direction": "workspace:*",
72+
"@fictjs/dismissable-layer": "workspace:*",
73+
"@fictjs/dropdown-menu": "workspace:*",
74+
"@fictjs/focus-guards": "workspace:*",
75+
"@fictjs/focus-scope": "workspace:*",
76+
"@fictjs/form": "workspace:*",
77+
"@fictjs/hover-card": "workspace:*",
78+
"@fictjs/label": "workspace:*",
79+
"@fictjs/menu": "workspace:*",
80+
"@fictjs/menubar": "workspace:*",
81+
"@fictjs/navigation-menu": "workspace:*",
82+
"@fictjs/one-time-password-field": "workspace:*",
83+
"@fictjs/password-toggle-field": "workspace:*",
84+
"@fictjs/popover": "workspace:*",
85+
"@fictjs/popper": "workspace:*",
86+
"@fictjs/portal": "workspace:*",
87+
"@fictjs/presence": "workspace:*",
88+
"@fictjs/primitive": "workspace:*",
89+
"@fictjs/progress": "workspace:*",
90+
"@fictjs/radio-group": "workspace:*",
91+
"@fictjs/roving-focus": "workspace:*",
92+
"@fictjs/scroll-area": "workspace:*",
93+
"@fictjs/select": "workspace:*",
94+
"@fictjs/separator": "workspace:*",
95+
"@fictjs/slider": "workspace:*",
96+
"@fictjs/slot": "workspace:*",
97+
"@fictjs/switch": "workspace:*",
98+
"@fictjs/tabs": "workspace:*",
99+
"@fictjs/toast": "workspace:*",
100+
"@fictjs/toggle": "workspace:*",
101+
"@fictjs/toggle-group": "workspace:*",
102+
"@fictjs/toolbar": "workspace:*",
103+
"@fictjs/tooltip": "workspace:*",
104+
"@fictjs/use-callback-ref": "workspace:*",
105+
"@fictjs/use-controllable-state": "workspace:*",
106+
"@fictjs/use-effect-event": "workspace:*",
107+
"@fictjs/use-escape-keydown": "workspace:*",
108+
"@fictjs/use-is-hydrated": "workspace:*",
109+
"@fictjs/use-layout-effect": "workspace:*",
110+
"@fictjs/use-size": "workspace:*",
111+
"@fictjs/visually-hidden": "workspace:*"
112+
},
113+
"peerDependencies": {
114+
"@fictjs/runtime": ">=0.17.0"
115+
},
116+
"devDependencies": {
117+
"@fictjs/runtime": "catalog:",
118+
"jsdom": "catalog:"
119+
}
120+
}

packages/radix-ui/src/index.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
export * as AccessibleIcon from '@fictjs/accessible-icon'
2+
export * as Accordion from '@fictjs/accordion'
3+
export * as AlertDialog from '@fictjs/alert-dialog'
4+
export * as AspectRatio from '@fictjs/aspect-ratio'
5+
export * as Avatar from '@fictjs/avatar'
6+
export * as Checkbox from '@fictjs/checkbox'
7+
export * as Collapsible from '@fictjs/collapsible'
8+
export * as ContextMenu from '@fictjs/context-menu'
9+
export * as Dialog from '@fictjs/dialog'
10+
export * as Direction from '@fictjs/direction'
11+
export * as DropdownMenu from '@fictjs/dropdown-menu'
12+
export * as Form from '@fictjs/form'
13+
export * as HoverCard from '@fictjs/hover-card'
14+
export * as Label from '@fictjs/label'
15+
export * as Menubar from '@fictjs/menubar'
16+
export * as NavigationMenu from '@fictjs/navigation-menu'
17+
export * as unstable_OneTimePasswordField from '@fictjs/one-time-password-field'
18+
export * as unstable_PasswordToggleField from '@fictjs/password-toggle-field'
19+
export * as Popover from '@fictjs/popover'
20+
export * as Portal from '@fictjs/portal'
21+
export * as Progress from '@fictjs/progress'
22+
export * as RadioGroup from '@fictjs/radio-group'
23+
export * as ScrollArea from '@fictjs/scroll-area'
24+
export * as Select from '@fictjs/select'
25+
export * as Separator from '@fictjs/separator'
26+
export * as Slider from '@fictjs/slider'
27+
export * as Slot from '@fictjs/slot'
28+
export * as Switch from '@fictjs/switch'
29+
export * as Tabs from '@fictjs/tabs'
30+
export * as Toast from '@fictjs/toast'
31+
export * as Toggle from '@fictjs/toggle'
32+
export * as ToggleGroup from '@fictjs/toggle-group'
33+
export * as Toolbar from '@fictjs/toolbar'
34+
export * as Tooltip from '@fictjs/tooltip'
35+
export * as VisuallyHidden from '@fictjs/visually-hidden'

packages/radix-ui/src/internal.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import {
2+
Primitive as BasePrimitive,
3+
Root as PrimitiveRoot,
4+
dispatchDiscreteCustomEvent,
5+
} from '@fictjs/primitive'
6+
7+
export * as Arrow from '@fictjs/arrow'
8+
export * as Collection from '@fictjs/collection'
9+
export { composeRefs, useComposedRefs } from '@fictjs/compose-refs'
10+
export * as Context from '@fictjs/context'
11+
export * as DismissableLayer from '@fictjs/dismissable-layer'
12+
export * as FocusGuards from '@fictjs/focus-guards'
13+
export * as FocusScope from '@fictjs/focus-scope'
14+
export * as Menu from '@fictjs/menu'
15+
export * as Popper from '@fictjs/popper'
16+
export * as Presence from '@fictjs/presence'
17+
export type { PrimitivePropsWithRef } from '@fictjs/primitive'
18+
export * as RovingFocus from '@fictjs/roving-focus'
19+
export { useCallbackRef } from '@fictjs/use-callback-ref'
20+
export { useControllableState, useControllableStateReducer } from '@fictjs/use-controllable-state'
21+
export { useEffectEvent } from '@fictjs/use-effect-event'
22+
export { useEscapeKeydown } from '@fictjs/use-escape-keydown'
23+
export { useIsHydrated } from '@fictjs/use-is-hydrated'
24+
export { useLayoutEffect } from '@fictjs/use-layout-effect'
25+
export { useSize } from '@fictjs/use-size'
26+
export { composeEventHandlers } from '@fictjs/core-primitive'
27+
28+
const Primitive = BasePrimitive as typeof BasePrimitive & {
29+
Root: typeof PrimitiveRoot
30+
dispatchDiscreteCustomEvent: typeof dispatchDiscreteCustomEvent
31+
}
32+
33+
Primitive.dispatchDiscreteCustomEvent = dispatchDiscreteCustomEvent
34+
Primitive.Root = PrimitiveRoot
35+
36+
export { Primitive }
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { describe, expect, it } from 'vitest'
2+
3+
import * as RadixUI from '../src/index.js'
4+
import * as Internal from '../src/internal.js'
5+
6+
describe('@fictjs/radix-ui', () => {
7+
it('exports public primitive namespaces', () => {
8+
expect(typeof RadixUI.Dialog.Root).toBe('function')
9+
expect(typeof RadixUI.Tooltip.Provider).toBe('function')
10+
expect(typeof RadixUI.Toolbar.Root).toBe('function')
11+
expect(typeof RadixUI.unstable_OneTimePasswordField.Root).toBe('function')
12+
expect(typeof RadixUI.unstable_PasswordToggleField.Root).toBe('function')
13+
})
14+
15+
it('exports internal helpers and primitive shims', () => {
16+
expect(typeof Internal.composeRefs).toBe('function')
17+
expect(typeof Internal.useControllableState).toBe('function')
18+
expect(typeof Internal.useControllableStateReducer).toBe('function')
19+
expect(typeof Internal.composeEventHandlers).toBe('function')
20+
expect(typeof Internal.Primitive.button).toBe('function')
21+
expect(Internal.Primitive.Root).toBe(Internal.Primitive)
22+
expect(typeof Internal.Primitive.dispatchDiscreteCustomEvent).toBe('function')
23+
})
24+
})

packages/radix-ui/tsconfig.json

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"extends": "../../tsconfig.library.json",
3+
"compilerOptions": {
4+
"baseUrl": ".",
5+
"jsx": "react-jsx",
6+
"jsxImportSource": "@fictjs/runtime",
7+
"lib": ["ES2023", "DOM", "DOM.Iterable"],
8+
"paths": {
9+
"@fictjs/radix-ui": ["./src/index.ts"],
10+
"@fictjs/radix-ui/internal": ["./src/internal.ts"],
11+
"@fictjs/dismissable-layer": ["../dismissable-layer/src/index.tsx"],
12+
"@fictjs/roving-focus": ["../roving-focus/src/index.tsx"],
13+
"@fictjs/runtime": ["../../../packages/runtime/dist/index.d.ts"],
14+
"@fictjs/runtime/advanced": ["../../../packages/runtime/dist/advanced.d.ts"],
15+
"@fictjs/runtime/jsx-runtime": ["../../../packages/runtime/dist/jsx-runtime.d.ts"],
16+
"@fictjs/runtime/jsx-dev-runtime": ["../../../packages/runtime/dist/jsx-dev-runtime.d.ts"]
17+
},
18+
"tsBuildInfoFile": "./node_modules/.cache/tsconfig.tsbuildinfo"
19+
},
20+
"include": [
21+
"src/**/*.ts",
22+
"src/**/*.tsx",
23+
"test/**/*.ts",
24+
"test/**/*.tsx",
25+
"tsup.config.ts",
26+
"vitest.config.ts"
27+
],
28+
"exclude": ["coverage", "dist"]
29+
}

packages/radix-ui/tsup.config.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { defineConfig } from 'tsup'
2+
3+
export default defineConfig({
4+
clean: true,
5+
dts: true,
6+
entry: ['src/index.ts', 'src/internal.ts'],
7+
format: ['esm', 'cjs'],
8+
platform: 'neutral',
9+
sourcemap: true,
10+
target: 'es2022',
11+
treeshake: true,
12+
})

packages/radix-ui/vitest.config.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import fs from 'node:fs'
2+
import path from 'node:path'
3+
import { fileURLToPath } from 'node:url'
4+
5+
import { defineConfig } from 'vitest/config'
6+
7+
const currentDir = path.dirname(fileURLToPath(import.meta.url))
8+
const packagesRoot = path.resolve(currentDir, '..')
9+
const libsRoot = path.resolve(currentDir, '../../libs')
10+
const packageJson = JSON.parse(
11+
fs.readFileSync(path.resolve(currentDir, 'package.json'), 'utf8'),
12+
) as {
13+
dependencies: Record<string, string>
14+
}
15+
16+
function resolveWorkspaceEntry(name: string): string {
17+
const candidates = [
18+
path.resolve(packagesRoot, name, 'src/index.ts'),
19+
path.resolve(packagesRoot, name, 'src/index.tsx'),
20+
path.resolve(libsRoot, name, 'src/index.ts'),
21+
path.resolve(libsRoot, name, 'src/index.tsx'),
22+
]
23+
24+
for (const candidate of candidates) {
25+
if (fs.existsSync(candidate)) {
26+
return candidate
27+
}
28+
}
29+
30+
return path.resolve(packagesRoot, name)
31+
}
32+
33+
const workspaceAliases = Object.keys(packageJson.dependencies)
34+
.filter((dependency) => dependency.startsWith('@fictjs/'))
35+
.map((dependency) => ({
36+
find: dependency,
37+
replacement: resolveWorkspaceEntry(dependency.slice('@fictjs/'.length)),
38+
}))
39+
40+
export default defineConfig({
41+
resolve: {
42+
alias: [
43+
{
44+
find: '@fictjs/fict-remove-scroll-bar/constants',
45+
replacement: path.resolve(libsRoot, 'fict-remove-scroll-bar/src/constants.ts'),
46+
},
47+
...workspaceAliases,
48+
],
49+
},
50+
test: {
51+
coverage: {
52+
provider: 'v8',
53+
reporter: ['text', 'html'],
54+
reportsDirectory: './coverage',
55+
},
56+
environment: 'jsdom',
57+
include: ['test/**/*.test.ts', 'test/**/*.test.tsx'],
58+
},
59+
})

0 commit comments

Comments
 (0)