├── .nvmrc ├── .npmrc ├── .husky ├── pre-commit └── commit-msg ├── .stylelintignore ├── packages ├── components │ ├── index.ts │ ├── README.md │ ├── avatar │ │ ├── index.ts │ │ └── ng-package.json │ ├── kbd │ │ ├── index.ts │ │ ├── ng-package.json │ │ └── src │ │ │ └── kbd.component.ts │ ├── switch │ │ ├── index.ts │ │ └── ng-package.json │ ├── code │ │ ├── index.ts │ │ └── ng-package.json │ ├── theme │ │ ├── index.ts │ │ ├── ng-package.json │ │ └── README.md │ ├── types │ │ ├── ng-package.json │ │ └── index.ts │ ├── .storybook │ │ ├── manager.ts │ │ ├── rdxTheme.ts │ │ ├── tsconfig.json │ │ └── main.ts │ ├── tsconfig.doc.json │ ├── ng-package.json │ ├── tsconfig.lib.prod.json │ ├── tsconfig.spec.json │ ├── tsconfig.lib.json │ ├── .compodocrc.json │ ├── package.json │ └── jest.config.ts └── primitives │ ├── form-field │ └── src │ │ └── .gitkeep │ ├── index.ts │ ├── tabs │ ├── __tests__ │ │ └── .gitkeep │ ├── ng-package.json │ ├── src │ │ └── utils.ts │ └── index.ts │ ├── arrow │ ├── README.md │ ├── index.ts │ ├── ng-package.json │ └── src │ │ └── arrow.ts │ ├── label │ ├── README.md │ ├── index.ts │ └── ng-package.json │ ├── menu │ ├── README.md │ ├── ng-package.json │ └── src │ │ ├── menu-label.directive.ts │ │ ├── menu-directive.ts │ │ ├── menu-radio-group.directive.ts │ │ ├── menu-separator.directive.ts │ │ ├── menu-group.directive.ts │ │ ├── menu-content.directive.ts │ │ └── utils.ts │ ├── radio │ ├── README.md │ ├── ng-package.json │ ├── index.ts │ └── src │ │ ├── radio-tokens.ts │ │ └── radio-indicator.directive.ts │ ├── avatar │ ├── README.md │ ├── ng-package.json │ ├── src │ │ ├── types.ts │ │ ├── avatar-context.token.ts │ │ └── avatar-root.directive.ts │ └── index.ts │ ├── cropper │ ├── README.md │ ├── ng-package.json │ └── src │ │ ├── cropper-crop-area.directive.ts │ │ ├── cropper-description.directive.ts │ │ └── cropper-context.token.ts │ ├── dialog │ ├── README.md │ ├── ng-package.json │ ├── src │ │ ├── dialog-title.directive.ts │ │ ├── dialog-description.directive.ts │ │ ├── dialog-close.directive.ts │ │ ├── dialog-dismiss.directive.ts │ │ └── dialog.injectors.ts │ └── stories │ │ └── sheet.docs.mdx │ ├── menubar │ ├── README.md │ ├── ng-package.json │ └── src │ │ ├── menubar-radio-group.directive.ts │ │ ├── menubar-group.directive.ts │ │ ├── menubar-content.directive.ts │ │ ├── menubar-separator.directive.ts │ │ ├── menubar-item-indicator.directive.ts │ │ ├── menubar-root.directive.ts │ │ ├── menubar-item-radio.directive.ts │ │ ├── menubar-item.directive.ts │ │ ├── menubar-item-checkbox.directive.ts │ │ └── menubar-trigger.directive.ts │ ├── portal │ ├── README.md │ ├── index.ts │ └── ng-package.json │ ├── select │ ├── README.md │ ├── ng-package.json │ ├── src │ │ ├── select-label.directive.ts │ │ ├── select-group.directive.ts │ │ ├── select-icon.directive.ts │ │ ├── select-separator.directive.ts │ │ ├── select-item-indicator.directive.ts │ │ └── select-value.directive.ts │ └── __tests__ │ │ ├── select.directive.spec.ts │ │ ├── select-item.directive.spec.ts │ │ ├── select-content.directive.spec.ts │ │ └── select-trigger.directive.spec.ts │ ├── slider │ ├── README.md │ ├── ng-package.json │ └── src │ │ ├── slider-thumb.component.ts │ │ ├── slider-track.component.ts │ │ └── slider-orientation-context.service.ts │ ├── stepper │ ├── README.md │ ├── src │ │ ├── types.ts │ │ ├── stepper-indicator.directive.ts │ │ ├── stepper-title.directive.ts │ │ ├── stepper-description.directive.ts │ │ └── stepper-item-context.token.ts │ └── ng-package.json │ ├── switch │ ├── README.md │ ├── ng-package.json │ ├── src │ │ └── switch-thumb.directive.ts │ └── index.ts │ ├── accordion │ ├── README.md │ ├── ng-package.json │ ├── __tests__ │ │ ├── accordion-item.directive.spec.ts │ │ ├── accordion-root.directive.spec.ts │ │ ├── accordion-header.directive.spec.ts │ │ ├── accordion-content.directive.spec.ts │ │ └── accordion-trigger.directive.spec.ts │ └── src │ │ ├── accordion-content-presence.directive.ts │ │ └── accordion-header.directive.ts │ ├── aspect-ratio │ ├── README.md │ ├── index.ts │ ├── ng-package.json │ └── stories │ │ └── aspect-ratio.docs.mdx │ ├── calendar │ ├── README.md │ ├── ng-package.json │ └── src │ │ ├── calendar-header.directive.ts │ │ ├── calendar-grid-row.directive.ts │ │ ├── calendar-head-cell.directive.ts │ │ ├── calendar-grid-body.directive.ts │ │ ├── calendar-grid-head.directive.ts │ │ ├── calendar-heading.directive.ts │ │ └── calendar-grid.directive.ts │ ├── checkbox │ ├── README.md │ ├── ng-package.json │ └── src │ │ ├── checkbox-indicator.ts │ │ └── checkbox-indicator-presence.ts │ ├── collection │ ├── README.md │ ├── ng-package.json │ ├── index.ts │ └── src │ │ ├── collection-context.ts │ │ └── collection-provider.ts │ ├── date-field │ ├── README.md │ ├── ng-package.json │ └── index.ts │ ├── editable │ ├── README.md │ ├── index.ts │ ├── ng-package.json │ ├── src │ │ ├── editable-submit-trigger.ts │ │ ├── editable-edit-trigger.ts │ │ └── editable-cancel-trigger.ts │ └── stories │ │ └── editable.stories.ts │ ├── pagination │ ├── README.md │ ├── ng-package.json │ └── src │ │ ├── pagination-ellipsis.directive.ts │ │ ├── pagination-context.token.ts │ │ ├── pagination-first.directive.ts │ │ ├── pagination-list.directive.ts │ │ ├── pagination-prev.directive.ts │ │ └── pagination-last.directive.ts │ ├── time-field │ ├── README.md │ ├── ng-package.json │ └── index.ts │ ├── alert-dialog │ ├── README.md │ ├── ng-package.json │ └── src │ │ ├── alert-dialog-title.directive.ts │ │ ├── alert-dialog-cancel.directive.ts │ │ ├── alert-dialog-trigger.directive.ts │ │ ├── alert-dialog-root.directive.ts │ │ └── alert-dialog-content.directive.ts │ ├── collapsible │ ├── README.md │ ├── ng-package.json │ └── src │ │ ├── collapsible-content-presence.directive.ts │ │ └── collapsible-trigger.directive.ts │ ├── context-menu │ ├── README.md │ ├── ng-package.json │ └── src │ │ ├── context-menu-label.directive.ts │ │ ├── context-menu-separator.directive.ts │ │ ├── context-menu-item-indicator.directive.ts │ │ └── context-menu-item-selectable.ts │ ├── focus-guards │ ├── README.md │ ├── index.ts │ └── ng-package.json │ ├── focus-scope │ ├── README.md │ ├── index.ts │ ├── ng-package.json │ └── stories │ │ └── focus-scope.docs.mdx │ ├── number-field │ ├── README.md │ ├── ng-package.json │ └── src │ │ └── types.ts │ ├── dropdown-menu │ ├── README.md │ ├── ng-package.json │ └── src │ │ ├── dropdown-menu-label.directive.ts │ │ ├── dropdown-menu-separator.directive.ts │ │ ├── dropdown-menu-item-indicator.directive.ts │ │ └── dropdown-menu-item-selectable.ts │ ├── separator │ ├── index.ts │ ├── ng-package.json │ └── README.md │ ├── dismissable-layer │ ├── README.md │ ├── ng-package.json │ └── index.ts │ ├── config │ ├── index.ts │ └── ng-package.json │ ├── core │ ├── ng-package.json │ └── src │ │ ├── is-number.ts │ │ ├── is-nullish.ts │ │ ├── document.ts │ │ ├── is-client.ts │ │ ├── is-inside-form.ts │ │ ├── date-time │ │ └── index.ts │ │ ├── focus-initial.directive.ts │ │ ├── getActiveElement.ts │ │ ├── is-equal.ts │ │ ├── window.ts │ │ ├── chunk.ts │ │ ├── accessor │ │ └── provide-value-accessor.ts │ │ └── mount.ts │ ├── popover │ ├── ng-package.json │ ├── src │ │ ├── utils │ │ │ ├── constants.ts │ │ │ └── types.ts │ │ ├── popover-arrow.token.ts │ │ ├── popover-close.token.ts │ │ ├── popover-anchor.token.ts │ │ ├── popover-content-attributes.token.ts │ │ ├── popover.types.ts │ │ └── popover-root.inject.ts │ ├── README.md │ └── stories │ │ └── utils │ │ └── constants.ts │ ├── popper │ ├── ng-package.json │ ├── README.md │ ├── src │ │ ├── popper-anchor.ts │ │ └── popper.ts │ ├── stories │ │ └── popper.docs.mdx │ └── index.ts │ ├── toggle │ ├── ng-package.json │ ├── README.md │ ├── index.ts │ └── src │ │ └── toggle-visually-hidden-input.directive.ts │ ├── toolbar │ ├── ng-package.json │ ├── README.md │ ├── src │ │ ├── toolbar-separator.directive.ts │ │ ├── toolbar-toggle-item.directive.ts │ │ ├── toolbar-toggle-group.directive.ts │ │ ├── toolbar-link.directive.ts │ │ ├── toolbar-root.token.ts │ │ └── toolbar-root.directive.ts │ └── stories │ │ └── toolbar.docs.mdx │ ├── tooltip │ ├── ng-package.json │ ├── src │ │ ├── utils │ │ │ ├── constants.ts │ │ │ └── types.ts │ │ ├── tooltip-arrow.token.ts │ │ ├── tooltip-close.token.ts │ │ ├── tooltip-anchor.token.ts │ │ ├── tooltip-content-attributes.token.ts │ │ ├── tooltip.types.ts │ │ └── tooltip-root.inject.ts │ ├── README.md │ └── stories │ │ └── utils │ │ └── constants.ts │ ├── hover-card │ ├── ng-package.json │ ├── src │ │ ├── utils │ │ │ ├── constants.ts │ │ │ └── types.ts │ │ ├── hover-card-arrow.token.ts │ │ ├── hover-card-close.token.ts │ │ ├── hover-card-anchor.token.ts │ │ ├── hover-card-content-attributes.token.ts │ │ ├── hover-card.types.ts │ │ └── hover-card-root.inject.ts │ ├── README.md │ └── stories │ │ └── utils │ │ └── constants.ts │ ├── presence │ ├── ng-package.json │ ├── index.ts │ └── src │ │ ├── types.ts │ │ └── transitions │ │ └── transition.toast.ts │ ├── progress │ ├── ng-package.json │ ├── README.md │ └── index.ts │ ├── roving-focus │ ├── ng-package.json │ ├── README.md │ └── index.ts │ ├── toggle-group │ ├── ng-package.json │ ├── README.md │ ├── index.ts │ └── src │ │ ├── toggle-group-item.token.ts │ │ └── toggle-group.token.ts │ ├── tooltip2 │ ├── ng-package.json │ ├── README.md │ └── src │ │ ├── tooltip-portal.ts │ │ ├── tooltip-content.ts │ │ ├── tooltip-arrow.ts │ │ └── tooltip-portal-presence.ts │ ├── navigation-menu │ ├── ng-package.json │ ├── README.md │ └── src │ │ └── navigation-menu.types.ts │ ├── visually-hidden │ ├── ng-package.json │ ├── README.md │ └── index.ts │ ├── tsconfig.doc.json │ ├── ng-package.json │ ├── test-setup.ts │ ├── tsconfig.lib.prod.json │ ├── schematics │ └── collection.json │ ├── tsconfig.spec.json │ ├── tsconfig.schematics.json │ ├── README.md │ ├── tsconfig.typedoc.json │ ├── tsconfig.lib.json │ └── jest.config.ts ├── .vscode ├── mcp.json ├── settings.json └── extensions.json ├── .postcssrc.json ├── .gitattributes ├── pnpm-workspace.yaml ├── jest.preset.cjs ├── project.json ├── apps ├── radix-docs │ ├── public │ │ └── robots.txt │ ├── src │ │ ├── components │ │ │ ├── mdx │ │ │ │ ├── Description.astro │ │ │ │ ├── li.astro │ │ │ │ ├── ol.astro │ │ │ │ ├── ul.astro │ │ │ │ ├── p.astro │ │ │ │ ├── h1.astro │ │ │ │ ├── h3.astro │ │ │ │ ├── code.astro │ │ │ │ ├── h2.astro │ │ │ │ ├── Tabs.astro │ │ │ │ ├── FeatureList.astro │ │ │ │ ├── TabsList.astro │ │ │ │ ├── a.astro │ │ │ │ ├── TabsContent.astro │ │ │ │ └── TabsTrigger.astro │ │ │ ├── code-editor │ │ │ │ ├── types.ts │ │ │ │ └── example-app │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── index-html.ts │ │ │ │ │ ├── main.ts │ │ │ │ │ └── styles-css.ts │ │ │ ├── tabs │ │ │ │ ├── index.ts │ │ │ │ ├── TabsList.astro │ │ │ │ ├── TabsContent.astro │ │ │ │ ├── TabsTrigger.astro │ │ │ │ └── Tabs.astro │ │ │ ├── theme │ │ │ │ └── theme-head-script.astro │ │ │ ├── layouts │ │ │ │ ├── Announcement.astro │ │ │ │ ├── DemoNoopContainer.astro │ │ │ │ └── TocHeading.astro │ │ │ └── demo-component-preview │ │ │ │ └── ComponentThemesPreview.astro │ │ ├── entrypoints │ │ │ └── alpine.ts │ │ ├── demos │ │ │ ├── primitives │ │ │ │ ├── dropdown-menu │ │ │ │ │ └── attrs.ts │ │ │ │ ├── aspect-ratio │ │ │ │ │ └── aspect-ratio-demo.css │ │ │ │ ├── progress │ │ │ │ │ ├── attrs.ts │ │ │ │ │ └── progress-demo.css │ │ │ │ ├── separator │ │ │ │ │ └── separator-demo.css │ │ │ │ ├── collapsible │ │ │ │ │ └── attrs.ts │ │ │ │ ├── label │ │ │ │ │ ├── label-demo.ts │ │ │ │ │ └── label-demo.css │ │ │ │ ├── toggle │ │ │ │ │ ├── toggle-demo.ts │ │ │ │ │ └── toggle-demo.css │ │ │ │ ├── slider │ │ │ │ │ └── slider-demo.ts │ │ │ │ └── avatar │ │ │ │ │ └── avatar-demo.css │ │ │ └── components │ │ │ │ ├── kbd │ │ │ │ └── kbd-demo.ts │ │ │ │ ├── code │ │ │ │ ├── code-demo.ts │ │ │ │ └── code-variants-demo.ts │ │ │ │ ├── switch │ │ │ │ ├── switch-demo.ts │ │ │ │ ├── switch-sizes-demo.ts │ │ │ │ └── switch-radius-demo.ts │ │ │ │ └── avatar │ │ │ │ ├── avatar-variant-demo.ts │ │ │ │ └── avatar-radius-demo.ts │ │ ├── contributor-names.json │ │ ├── config │ │ │ └── site-config.ts │ │ ├── pages │ │ │ ├── robots.txt.ts │ │ │ └── llms.txt.ts │ │ ├── utils │ │ │ ├── typedoc.ts │ │ │ └── index.ts │ │ ├── env.d.ts │ │ ├── content │ │ │ ├── config.ts │ │ │ ├── themes │ │ │ │ ├── typography │ │ │ │ │ └── kbd.mdx │ │ │ │ ├── utilities │ │ │ │ │ └── theme.mdx │ │ │ │ ├── components │ │ │ │ │ └── switch.mdx │ │ │ │ └── theme │ │ │ │ │ └── overview.mdx │ │ │ └── primitives │ │ │ │ └── components │ │ │ │ ├── separator.mdx │ │ │ │ ├── aspect-ratio.mdx │ │ │ │ └── select.mdx │ │ ├── contributors.ts │ │ └── types │ │ │ └── index.ts │ ├── .gitignore │ ├── README.md │ ├── tsconfig.json │ └── plugins │ │ └── unist.ts ├── radix-storybook │ └── .storybook │ │ ├── manager.tsx │ │ ├── main.css │ │ ├── plugins │ │ └── compodoc.ts │ │ ├── tsconfig.json │ │ └── themes.ts └── radix-ssr-testing │ ├── public │ └── favicon.ico │ ├── tsconfig.editor.json │ ├── src │ ├── main.ts │ ├── app │ │ ├── app.ts │ │ ├── app.routes.server.ts │ │ ├── components │ │ │ ├── label │ │ │ │ └── page.ts │ │ │ ├── switch │ │ │ │ └── page.ts │ │ │ ├── separator │ │ │ │ └── page.ts │ │ │ ├── avatar │ │ │ │ └── page.ts │ │ │ └── toggle-group │ │ │ │ └── page.ts │ │ ├── app.config.server.ts │ │ └── app.config.ts │ ├── main.server.ts │ ├── test-setup.ts │ └── index.html │ ├── tsconfig.app.json │ ├── tsconfig.spec.json │ ├── .eslintrc.json │ └── jest.config.ts ├── jest.config.ts ├── .eslintignore ├── tsconfig.eslint.json ├── tools └── scripts │ ├── api-doc │ ├── utility │ │ ├── index.mjs │ │ └── get-types.mjs │ └── constants.mjs │ ├── tsconfig.json │ └── docs-copy.mjs ├── .lintstagedrc.cjs ├── SECURITY.md ├── .prettierignore ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── Documentation.md │ ├── Question.md │ └── Feature_request.md ├── PULL_REQUEST_TEMPLATE.md ├── workflows │ ├── pr-commitlint.yml │ ├── chromatic.yml │ └── algolia-docsearch-crawler.yml ├── actions │ └── setup │ │ └── action.yml └── DISCUSSION_TEMPLATE │ └── example-request.yml └── .editorconfig /.nvmrc: -------------------------------------------------------------------------------- 1 | 20.19 2 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | engine-strict=true 2 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | pnpm lint-staged 2 | -------------------------------------------------------------------------------- /.stylelintignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | -------------------------------------------------------------------------------- /packages/components/index.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | -------------------------------------------------------------------------------- /packages/primitives/form-field/src/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/primitives/index.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | -------------------------------------------------------------------------------- /packages/primitives/tabs/__tests__/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | pnpm commitlint --edit $1 2 | -------------------------------------------------------------------------------- /.vscode/mcp.json: -------------------------------------------------------------------------------- 1 | { 2 | "servers": {} 3 | } 4 | -------------------------------------------------------------------------------- /packages/components/README.md: -------------------------------------------------------------------------------- 1 | # RadixNG Components 2 | -------------------------------------------------------------------------------- /packages/primitives/arrow/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/arrow 2 | -------------------------------------------------------------------------------- /packages/primitives/arrow/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src/arrow'; 2 | -------------------------------------------------------------------------------- /packages/primitives/label/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/label 2 | -------------------------------------------------------------------------------- /packages/primitives/menu/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/menu 2 | -------------------------------------------------------------------------------- /packages/primitives/radio/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/radio 2 | -------------------------------------------------------------------------------- /packages/components/avatar/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src/avatar'; 2 | -------------------------------------------------------------------------------- /packages/components/kbd/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src/kbd.component'; 2 | -------------------------------------------------------------------------------- /packages/components/switch/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src/switch'; 2 | -------------------------------------------------------------------------------- /packages/primitives/avatar/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/avatar 2 | -------------------------------------------------------------------------------- /packages/primitives/cropper/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/cropper 2 | -------------------------------------------------------------------------------- /packages/primitives/dialog/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/dialog 2 | -------------------------------------------------------------------------------- /packages/primitives/menubar/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/menubar 2 | -------------------------------------------------------------------------------- /packages/primitives/portal/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/portal 2 | -------------------------------------------------------------------------------- /packages/primitives/portal/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src/portal'; 2 | -------------------------------------------------------------------------------- /packages/primitives/select/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/select 2 | -------------------------------------------------------------------------------- /packages/primitives/slider/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/slider 2 | -------------------------------------------------------------------------------- /packages/primitives/stepper/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/stepper 2 | -------------------------------------------------------------------------------- /packages/primitives/switch/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/switch 2 | -------------------------------------------------------------------------------- /packages/components/code/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src/code.component'; 2 | -------------------------------------------------------------------------------- /packages/primitives/accordion/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/accordion 2 | -------------------------------------------------------------------------------- /packages/primitives/aspect-ratio/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/avatar 2 | -------------------------------------------------------------------------------- /packages/primitives/calendar/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/calendar 2 | -------------------------------------------------------------------------------- /packages/primitives/checkbox/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/checkbox 2 | -------------------------------------------------------------------------------- /packages/primitives/collection/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/collection 2 | -------------------------------------------------------------------------------- /packages/primitives/date-field/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/date-field 2 | -------------------------------------------------------------------------------- /packages/primitives/editable/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/editable 2 | -------------------------------------------------------------------------------- /packages/primitives/editable/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src/editable-root'; 2 | -------------------------------------------------------------------------------- /packages/primitives/label/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src/label.directive'; 2 | -------------------------------------------------------------------------------- /packages/primitives/pagination/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/pagination 2 | -------------------------------------------------------------------------------- /packages/primitives/time-field/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/time-field 2 | -------------------------------------------------------------------------------- /packages/primitives/alert-dialog/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/alert-dialog 2 | -------------------------------------------------------------------------------- /packages/primitives/collapsible/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/collapsible 2 | -------------------------------------------------------------------------------- /packages/primitives/context-menu/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/context-menu 2 | -------------------------------------------------------------------------------- /packages/primitives/focus-guards/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/focus-guards 2 | -------------------------------------------------------------------------------- /packages/primitives/focus-guards/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src/focus-guards'; 2 | -------------------------------------------------------------------------------- /packages/primitives/focus-scope/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/focus-scope 2 | -------------------------------------------------------------------------------- /packages/primitives/focus-scope/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src/focus-scope'; 2 | -------------------------------------------------------------------------------- /packages/primitives/number-field/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/number-field 2 | -------------------------------------------------------------------------------- /packages/primitives/dropdown-menu/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/dropdown-menu 2 | -------------------------------------------------------------------------------- /packages/primitives/separator/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src/separator.directive'; 2 | -------------------------------------------------------------------------------- /packages/primitives/aspect-ratio/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src/aspect-ratio.directive'; 2 | -------------------------------------------------------------------------------- /packages/primitives/dismissable-layer/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/dismissable-layer 2 | -------------------------------------------------------------------------------- /.postcssrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": { 3 | "@tailwindcss/postcss": {} 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set the default behavior, in case people don't have core.autocrlf set. 2 | * text=auto 3 | -------------------------------------------------------------------------------- /packages/primitives/stepper/src/types.ts: -------------------------------------------------------------------------------- 1 | export type StepperState = 'completed' | 'active' | 'inactive'; 2 | -------------------------------------------------------------------------------- /packages/primitives/config/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src/config'; 2 | export * from './src/config.provider'; 3 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - "apps/radix-docs/**" 3 | - "packages/**" 4 | - "!**/dist/**" 5 | -------------------------------------------------------------------------------- /jest.preset.cjs: -------------------------------------------------------------------------------- 1 | const nxPreset = require('@nx/jest/preset').default; 2 | 3 | module.exports = { ...nxPreset }; 4 | -------------------------------------------------------------------------------- /packages/components/avatar/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/components/code/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/components/kbd/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/components/switch/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/components/theme/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src/theme.directive'; 2 | export * from './src/theme.service'; 3 | -------------------------------------------------------------------------------- /packages/components/theme/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/components/types/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/arrow/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/avatar/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/config/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/core/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/core/src/is-number.ts: -------------------------------------------------------------------------------- 1 | export const isNumber = (v: any): v is number => typeof v === 'number'; 2 | -------------------------------------------------------------------------------- /packages/primitives/cropper/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/dialog/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/label/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/menu/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/menubar/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/popover/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/popper/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/portal/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/radio/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/select/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/slider/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/stepper/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/switch/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/tabs/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/toggle/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/toolbar/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/tooltip/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /project.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "radix-ng", 3 | "$schema": "node_modules/nx/schemas/project-schema.json" 4 | } 5 | -------------------------------------------------------------------------------- /apps/radix-docs/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Allow: / 3 | 4 | Sitemap: https://radix-ng.com/sitemap-index.xml 5 | -------------------------------------------------------------------------------- /packages/primitives/accordion/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/alert-dialog/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/aspect-ratio/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/calendar/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/checkbox/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/collapsible/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/collection/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/context-menu/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/date-field/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/editable/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/focus-guards/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/focus-scope/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/hover-card/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/number-field/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/pagination/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/presence/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/progress/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/roving-focus/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/separator/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/time-field/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/toggle-group/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/tooltip2/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /apps/radix-storybook/.storybook/manager.tsx: -------------------------------------------------------------------------------- 1 | import { addons } from 'storybook/manager-api'; 2 | 3 | addons.setConfig({}); 4 | -------------------------------------------------------------------------------- /packages/primitives/dismissable-layer/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/dropdown-menu/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/navigation-menu/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/visually-hidden/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "index.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/primitives/popover/src/utils/constants.ts: -------------------------------------------------------------------------------- 1 | export const RdxCdkEventServiceWindowKey = Symbol('__RdxCdkEventService__'); 2 | -------------------------------------------------------------------------------- /packages/primitives/progress/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/progress 2 | 3 | Secondary entry point of `@radix-ng/primitives`. 4 | -------------------------------------------------------------------------------- /packages/primitives/tooltip/src/utils/constants.ts: -------------------------------------------------------------------------------- 1 | export const RdxCdkEventServiceWindowKey = Symbol('__RdxCdkEventService__'); 2 | -------------------------------------------------------------------------------- /apps/radix-ssr-testing/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radix-ng/primitives/HEAD/apps/radix-ssr-testing/public/favicon.ico -------------------------------------------------------------------------------- /packages/primitives/hover-card/src/utils/constants.ts: -------------------------------------------------------------------------------- 1 | export const RdxCdkEventServiceWindowKey = Symbol('__RdxCdkEventService__'); 2 | -------------------------------------------------------------------------------- /packages/primitives/separator/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/separator 2 | 3 | Secondary entry point of `@radix-ng/primitives`. 4 | -------------------------------------------------------------------------------- /packages/primitives/toggle/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/toggle 2 | 3 | Secondary entry point of `@radix-ng/primitives/toggle`. 4 | -------------------------------------------------------------------------------- /packages/primitives/toolbar/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/toolbar 2 | 3 | Secondary entry point of `@radix-ng/primitives/toolbar`. 4 | -------------------------------------------------------------------------------- /packages/primitives/roving-focus/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/roving-focus 2 | 3 | Secondary entry point of `@radix-ng/primitives`. 4 | -------------------------------------------------------------------------------- /packages/primitives/number-field/src/types.ts: -------------------------------------------------------------------------------- 1 | export type InputMode = 'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url'; 2 | -------------------------------------------------------------------------------- /packages/primitives/toggle-group/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/toggle-group 2 | 3 | Secondary entry point of `@radix-ng/primitives/toggle-group`. 4 | -------------------------------------------------------------------------------- /apps/radix-docs/src/components/mdx/Description.astro: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | -------------------------------------------------------------------------------- /jest.config.ts: -------------------------------------------------------------------------------- 1 | import { getJestProjectsAsync } from '@nx/jest'; 2 | 3 | export default async () => ({ 4 | projects: await getJestProjectsAsync() 5 | }); 6 | -------------------------------------------------------------------------------- /packages/primitives/core/src/is-nullish.ts: -------------------------------------------------------------------------------- 1 | export function isNullish(value: any): value is null | undefined { 2 | return value === null || value === undefined; 3 | } 4 | -------------------------------------------------------------------------------- /packages/primitives/core/src/document.ts: -------------------------------------------------------------------------------- 1 | import { DOCUMENT, inject } from '@angular/core'; 2 | 3 | export function injectDocument(): Document { 4 | return inject(DOCUMENT); 5 | } 6 | -------------------------------------------------------------------------------- /packages/components/.storybook/manager.ts: -------------------------------------------------------------------------------- 1 | import { addons } from 'storybook/manager-api'; 2 | import rdxTheme from './rdxTheme'; 3 | 4 | addons.setConfig({ 5 | theme: rdxTheme 6 | }); 7 | -------------------------------------------------------------------------------- /packages/primitives/popper/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/popper 2 | 3 | Secondary entry point of `@radix-ng/primitives`. It can be used by importing from `@radix-ng/primitives/popper`. 4 | -------------------------------------------------------------------------------- /packages/primitives/popover/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/popover 2 | 3 | Secondary entry point of `@radix-ng/primitives`. It can be used by importing from `@radix-ng/primitives/popover`. 4 | -------------------------------------------------------------------------------- /packages/primitives/tooltip/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/tooltip 2 | 3 | Secondary entry point of `@radix-ng/primitives`. It can be used by importing from `@radix-ng/primitives/tooltip`. 4 | -------------------------------------------------------------------------------- /packages/primitives/tooltip2/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/tooltip2 2 | 3 | Secondary entry point of `@radix-ng/primitives`. It can be used by importing from `@radix-ng/primitives/tooltip2`. 4 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.defaultFormatter": "esbenp.prettier-vscode", 3 | "css.validate": false, 4 | "scss.validate": false, 5 | "stylelint.validate": ["css", "scss"] 6 | } 7 | -------------------------------------------------------------------------------- /packages/components/tsconfig.doc.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["**/*.ts"], 3 | "exclude": ["**/*.spec.ts", "test-setup.ts", "jest.config.ts", "**/*.test.ts", "**/*.stories.ts", "**/*.stories.js"] 4 | } 5 | -------------------------------------------------------------------------------- /packages/primitives/hover-card/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/hover-card 2 | 3 | Secondary entry point of `@radix-ng/primitives`. It can be used by importing from `@radix-ng/primitives/hover-card`. 4 | -------------------------------------------------------------------------------- /packages/primitives/menu/src/menu-label.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[RdxMenuLabel]' 5 | }) 6 | export class RdxMenuLabelDirective {} 7 | -------------------------------------------------------------------------------- /packages/primitives/tsconfig.doc.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["**/*.ts"], 3 | "exclude": ["**/*.spec.ts", "test-setup.ts", "jest.config.ts", "**/*.test.ts", "**/*.stories.ts", "**/*.stories.js"] 4 | } 5 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | .angular 4 | .nx 5 | .vercel 6 | tmp 7 | 8 | # eslint ignores root level "dot" files by default 9 | !/.*.cjs 10 | 11 | # ignore index.html 12 | **/index.html 13 | -------------------------------------------------------------------------------- /apps/radix-docs/src/components/code-editor/types.ts: -------------------------------------------------------------------------------- 1 | export type Props = { 2 | code?: string; 3 | css?: string; 4 | title?: string; 5 | description?: string; 6 | selector?: string; 7 | }; 8 | -------------------------------------------------------------------------------- /apps/radix-docs/src/entrypoints/alpine.ts: -------------------------------------------------------------------------------- 1 | import focus from '@alpinejs/focus'; 2 | import type { Alpine } from 'alpinejs'; 3 | 4 | export default (Alpine: Alpine): void => { 5 | Alpine.plugin(focus); 6 | }; 7 | -------------------------------------------------------------------------------- /packages/primitives/collection/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src/collection-context'; 2 | export * from './src/collection-item'; 3 | export * from './src/collection-provider'; 4 | export * from './src/use-collection'; 5 | -------------------------------------------------------------------------------- /packages/primitives/visually-hidden/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/visually-hidden 2 | 3 | Secondary entry point of `@radix-ng/primitives`. It can be used by importing from `@radix-ng/primitives/visually-hidden`. 4 | -------------------------------------------------------------------------------- /packages/primitives/visually-hidden/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src/visually-hidden-input-bubble.directive'; 2 | export * from './src/visually-hidden-input.directive'; 3 | export * from './src/visually-hidden.directive'; 4 | -------------------------------------------------------------------------------- /tsconfig.eslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.base.json", 3 | "compilerOptions": { 4 | "noEmit": true, 5 | "incremental": true 6 | }, 7 | "include": ["**/*.ts", "**/*.html"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/components/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", 3 | "dest": "../../dist/components", 4 | "lib": { 5 | "entryFile": "index.ts" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/primitives/calendar/src/calendar-header.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: 'div[rdxCalendarHeader]' 5 | }) 6 | export class RdxCalendarHeaderDirective {} 7 | -------------------------------------------------------------------------------- /packages/primitives/dismissable-layer/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src/dismissable-layer'; 2 | export * from './src/dismissable-layer-branch'; 3 | export * from './src/dismissable-layer.config'; 4 | export * from './src/utils'; 5 | -------------------------------------------------------------------------------- /packages/primitives/toggle/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src/toggle-visually-hidden-input.directive'; 2 | export * from './src/toggle.directive'; 3 | 4 | export type { DataState, ToggleProps } from './src/toggle.directive'; 5 | -------------------------------------------------------------------------------- /tools/scripts/api-doc/utility/index.mjs: -------------------------------------------------------------------------------- 1 | export * from './get-emits.mjs'; 2 | export * from './get-events.mjs'; 3 | export * from './get-methods.mjs'; 4 | export * from './get-props.mjs'; 5 | export * from './get-types.mjs'; 6 | -------------------------------------------------------------------------------- /apps/radix-docs/src/demos/primitives/dropdown-menu/attrs.ts: -------------------------------------------------------------------------------- 1 | export const attrDataTrigger = [ 2 | { name: '[data-state]', value: '"open" | "closed"' }, 3 | { name: '[data-disabled]', value: 'Present when disabled' } 4 | ]; 5 | -------------------------------------------------------------------------------- /packages/primitives/calendar/src/calendar-grid-row.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: 'tr[rdxCalendarGridRow]' 5 | }) 6 | export class RdxCalendarGridRowDirective {} 7 | -------------------------------------------------------------------------------- /packages/primitives/calendar/src/calendar-head-cell.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: 'th[rdxCalendarHeadCell]' 5 | }) 6 | export class RdxCalendarHeadCellDirective {} 7 | -------------------------------------------------------------------------------- /packages/primitives/core/src/is-client.ts: -------------------------------------------------------------------------------- 1 | import { Platform } from '@angular/cdk/platform'; 2 | import { inject } from '@angular/core'; 3 | 4 | export function injectIsClient() { 5 | return inject(Platform).isBrowser; 6 | } 7 | -------------------------------------------------------------------------------- /apps/radix-ssr-testing/tsconfig.editor.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "include": ["src/**/*.ts"], 4 | "compilerOptions": {}, 5 | "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] 6 | } 7 | -------------------------------------------------------------------------------- /packages/components/theme/README.md: -------------------------------------------------------------------------------- 1 | ```angular2html 2 |
3 | 4 |
5 | ``` 6 | -------------------------------------------------------------------------------- /packages/primitives/calendar/src/calendar-grid-body.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: 'tbody[rdxCalendarGridBody]' 5 | }) 6 | export class RdxCalendarGridBodyDirective {} 7 | -------------------------------------------------------------------------------- /packages/primitives/dialog/src/dialog-title.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[rdxDialogTitle]', 5 | standalone: true 6 | }) 7 | export class RdxDialogTitleDirective {} 8 | -------------------------------------------------------------------------------- /packages/primitives/radio/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src/radio-root.directive'; 2 | 3 | export * from './src/radio-indicator.directive'; 4 | export * from './src/radio-item-input.directive'; 5 | export * from './src/radio-item.directive'; 6 | -------------------------------------------------------------------------------- /apps/radix-docs/src/components/mdx/li.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { cn } from '@/utils/utils'; 3 | 4 | const { className, ...props } = Astro.props; 5 | --- 6 | 7 |
  • 8 | 9 |
  • 10 | -------------------------------------------------------------------------------- /.lintstagedrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | '*.{css,scss,md,mdx,yml,json,js,cjs,mjs,html,ts,astro}': 'prettier --write', 3 | '*.{css,scss}': 'stylelint --max-warnings=0 --fix', 4 | '*.{js,cjs,mjs,ts,html}': 'eslint --max-warnings=0 --fix' 5 | }; 6 | -------------------------------------------------------------------------------- /packages/primitives/dialog/src/dialog-description.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[rdxDialogDescription]', 5 | standalone: true 6 | }) 7 | export class RdxDialogDescriptionDirective {} 8 | -------------------------------------------------------------------------------- /apps/radix-docs/src/components/mdx/ol.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { cn } from '@/utils/utils'; 3 | 4 | const { className, ...props } = Astro.props; 5 | --- 6 | 7 |
      8 | 9 |
    10 | -------------------------------------------------------------------------------- /apps/radix-docs/src/components/mdx/ul.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { cn } from '@/utils/utils'; 3 | 4 | const { className, ...props } = Astro.props; 5 | --- 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/primitives/alert-dialog/src/alert-dialog-title.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[rdxAlertDialogTitle]', 5 | standalone: true 6 | }) 7 | export class RdxAlertDialogTitleDirective {} 8 | -------------------------------------------------------------------------------- /packages/primitives/context-menu/src/context-menu-label.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[rdxContextMenuLabel]', 5 | standalone: true 6 | }) 7 | export class RdxContextMenuLabelDirective {} 8 | -------------------------------------------------------------------------------- /packages/primitives/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", 3 | "dest": "../../dist/primitives", 4 | "lib": { 5 | "entryFile": "index.ts" 6 | }, 7 | "allowedNonPeerDependencies": [] 8 | } 9 | -------------------------------------------------------------------------------- /packages/primitives/presence/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src/presence'; 2 | export * from './src/presence.directive'; 3 | export * from './src/transitions/transition.collapse'; 4 | export * from './src/transitions/transition.toast'; 5 | export * from './src/types'; 6 | -------------------------------------------------------------------------------- /packages/primitives/test-setup.ts: -------------------------------------------------------------------------------- 1 | import '@testing-library/jest-dom'; 2 | import { toHaveNoViolations } from 'jest-axe'; 3 | import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone'; 4 | 5 | setupZoneTestEnv(); 6 | expect.extend(toHaveNoViolations); 7 | -------------------------------------------------------------------------------- /apps/radix-ssr-testing/src/main.ts: -------------------------------------------------------------------------------- 1 | import { bootstrapApplication } from '@angular/platform-browser'; 2 | import { App } from './app/app'; 3 | import { appConfig } from './app/app.config'; 4 | 5 | bootstrapApplication(App, appConfig).catch((err) => console.error(err)); 6 | -------------------------------------------------------------------------------- /packages/components/tsconfig.lib.prod.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.lib.json", 3 | "compilerOptions": { 4 | "declarationMap": false 5 | }, 6 | "angularCompilerOptions": { 7 | "compilationMode": "partial" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/primitives/navigation-menu/README.md: -------------------------------------------------------------------------------- 1 | # @radix-ng/primitives/navigation-menu 2 | 3 | A responsive navigation component that automatically collapses navigation items into a menu when space is limited. Follows the WAI-ARIA Menu Button Pattern for accessibility. 4 | -------------------------------------------------------------------------------- /apps/radix-docs/src/components/mdx/p.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { cn } from '@/utils/utils'; 3 | 4 | const { className, ...props } = Astro.props; 5 | --- 6 | 7 |

    8 | 9 |

    10 | -------------------------------------------------------------------------------- /packages/primitives/select/src/select-label.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[rdxSelectLabel]', 5 | standalone: true, 6 | exportAs: 'rdxSelectLabel' 7 | }) 8 | export class RdxSelectLabelDirective {} 9 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | The versions of the project that are currently supported with security updates. 6 | 7 | | Version | Supported | 8 | | ------- | ------------------ | 9 | | < 1.0 | :white_check_mark: | 10 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .angular 2 | .husky 3 | .nx 4 | .vercel 5 | .astro 6 | 7 | /node_modules 8 | /dist 9 | /coverage 10 | /tmp 11 | 12 | CHANGELOG.md 13 | 14 | apps/radix-docs/src/styles/*.css 15 | 16 | *.d.ts 17 | *.mdx 18 | 19 | pnpm-lock.yaml 20 | pnpm-workspace.yaml 21 | -------------------------------------------------------------------------------- /packages/components/.storybook/rdxTheme.ts: -------------------------------------------------------------------------------- 1 | import { create } from 'storybook/theming/create'; 2 | 3 | export default create({ 4 | base: 'light', 5 | brandTitle: 'Radix Angular', 6 | brandUrl: 'https://github.com/radix-ng/primitives', 7 | brandTarget: '_self' 8 | }); 9 | -------------------------------------------------------------------------------- /apps/radix-docs/src/components/tabs/index.ts: -------------------------------------------------------------------------------- 1 | import Tabs from './Tabs.astro'; 2 | import TabsContent from './TabsContent.astro'; 3 | import TabsList from './TabsList.astro'; 4 | import TabsTrigger from './TabsTrigger.astro'; 5 | 6 | export { Tabs, TabsContent, TabsList, TabsTrigger }; 7 | -------------------------------------------------------------------------------- /apps/radix-storybook/.storybook/main.css: -------------------------------------------------------------------------------- 1 | @import './tailwind.css'; 2 | @import './fonts.css'; 3 | 4 | @import './slider.css'; 5 | 6 | @import '../../../packages/primitives/dialog/stories/sheet/sheet.styles.css'; 7 | @import '../../../packages/primitives/checkbox/stories/checkbox.css'; 8 | -------------------------------------------------------------------------------- /packages/primitives/menu/src/menu-directive.ts: -------------------------------------------------------------------------------- 1 | import { CdkMenu } from '@angular/cdk/menu'; 2 | import { Directive } from '@angular/core'; 3 | 4 | @Directive({ 5 | selector: '[RdxMenuRoot],[RdxMenuSub]', 6 | hostDirectives: [CdkMenu] 7 | }) 8 | export class RdxMenuDirective {} 9 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Add the following users as reviewers on new pull requests 2 | 3 | * @pimenovoleg @artembelik 4 | 5 | /packages/primitives/hover-card/ @pawel-twardziak 6 | /packages/primitives/popover/ @pawel-twardziak 7 | /packages/primitives/tooltip/ @pawel-twardziak 8 | -------------------------------------------------------------------------------- /apps/radix-docs/src/components/code-editor/example-app/index.ts: -------------------------------------------------------------------------------- 1 | export * from './angular-json'; 2 | export * from './dependencies'; 3 | export * from './fonts-css'; 4 | export * from './index-html'; 5 | export * from './main'; 6 | export * from './styles-css'; 7 | export * from './tsconfig'; 8 | -------------------------------------------------------------------------------- /apps/radix-docs/src/components/mdx/h1.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { cn } from '@/utils/utils'; 3 | 4 | const { className, ...props } = Astro.props; 5 | --- 6 | 7 |

    8 | 9 |

    10 | -------------------------------------------------------------------------------- /apps/radix-docs/src/components/mdx/h3.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { cn } from '@/utils/utils'; 3 | 4 | const { className, ...props } = Astro.props; 5 | --- 6 | 7 |

    8 | 9 |

    10 | -------------------------------------------------------------------------------- /packages/primitives/popover/src/popover-arrow.token.ts: -------------------------------------------------------------------------------- 1 | import { InjectionToken } from '@angular/core'; 2 | import { RdxPopoverArrowDirective } from './popover-arrow.directive'; 3 | 4 | export const RdxPopoverArrowToken = new InjectionToken('RdxPopoverArrowToken'); 5 | -------------------------------------------------------------------------------- /packages/primitives/popover/src/popover-close.token.ts: -------------------------------------------------------------------------------- 1 | import { InjectionToken } from '@angular/core'; 2 | import { RdxPopoverCloseDirective } from './popover-close.directive'; 3 | 4 | export const RdxPopoverCloseToken = new InjectionToken('RdxPopoverCloseToken'); 5 | -------------------------------------------------------------------------------- /packages/primitives/popper/src/popper-anchor.ts: -------------------------------------------------------------------------------- 1 | import { Directive, ElementRef, inject } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[rdxPopperAnchor]' 5 | }) 6 | export class RdxPopperAnchor { 7 | readonly elementRef = inject>(ElementRef); 8 | } 9 | -------------------------------------------------------------------------------- /packages/primitives/tabs/src/utils.ts: -------------------------------------------------------------------------------- 1 | export function makeTriggerId(baseId: string, value: string | number) { 2 | return `${baseId}-trigger-${value}`; 3 | } 4 | 5 | export function makeContentId(baseId: string, value: string | number) { 6 | return `${baseId}-content-${value}`; 7 | } 8 | -------------------------------------------------------------------------------- /packages/primitives/tooltip/src/tooltip-arrow.token.ts: -------------------------------------------------------------------------------- 1 | import { InjectionToken } from '@angular/core'; 2 | import { RdxTooltipArrowDirective } from './tooltip-arrow.directive'; 3 | 4 | export const RdxTooltipArrowToken = new InjectionToken('RdxTooltipArrowToken'); 5 | -------------------------------------------------------------------------------- /packages/primitives/tooltip/src/tooltip-close.token.ts: -------------------------------------------------------------------------------- 1 | import { InjectionToken } from '@angular/core'; 2 | import { RdxTooltipCloseDirective } from './tooltip-close.directive'; 3 | 4 | export const RdxTooltipCloseToken = new InjectionToken('RdxTooltipCloseToken'); 5 | -------------------------------------------------------------------------------- /apps/radix-docs/src/components/mdx/code.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { cn } from '@/utils/utils'; 3 | 4 | const { className, ...props } = Astro.props; 5 | --- 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /packages/primitives/popover/src/popover-anchor.token.ts: -------------------------------------------------------------------------------- 1 | import { InjectionToken } from '@angular/core'; 2 | import { RdxPopoverAnchorDirective } from './popover-anchor.directive'; 3 | 4 | export const RdxPopoverAnchorToken = new InjectionToken('RdxPopoverAnchorToken'); 5 | -------------------------------------------------------------------------------- /packages/primitives/tooltip/src/tooltip-anchor.token.ts: -------------------------------------------------------------------------------- 1 | import { InjectionToken } from '@angular/core'; 2 | import { RdxTooltipAnchorDirective } from './tooltip-anchor.directive'; 3 | 4 | export const RdxTooltipAnchorToken = new InjectionToken('RdxTooltipAnchorToken'); 5 | -------------------------------------------------------------------------------- /packages/primitives/toggle-group/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src/toggle-group-item.directive'; 2 | export * from './src/toggle-group-item.token'; 3 | export * from './src/toggle-group-without-focus.directive'; 4 | export * from './src/toggle-group.directive'; 5 | export * from './src/toggle-group.token'; 6 | -------------------------------------------------------------------------------- /packages/primitives/hover-card/src/hover-card-arrow.token.ts: -------------------------------------------------------------------------------- 1 | import { InjectionToken } from '@angular/core'; 2 | import { RdxHoverCardArrowDirective } from './hover-card-arrow.directive'; 3 | 4 | export const RdxHoverCardArrowToken = new InjectionToken('RdxHoverCardArrowToken'); 5 | -------------------------------------------------------------------------------- /packages/primitives/hover-card/src/hover-card-close.token.ts: -------------------------------------------------------------------------------- 1 | import { InjectionToken } from '@angular/core'; 2 | import { RdxHoverCardCloseDirective } from './hover-card-close.directive'; 3 | 4 | export const RdxHoverCardCloseToken = new InjectionToken('RdxHoverCardCloseToken'); 5 | -------------------------------------------------------------------------------- /packages/primitives/popper/stories/popper.docs.mdx: -------------------------------------------------------------------------------- 1 | import { Primary, Controls, Meta } from '@storybook/addon-docs/blocks'; 2 | import * as PopperStories from './popper.stories'; 3 | 4 | 5 | 6 | # Popper 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /apps/radix-docs/src/components/mdx/h2.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { cn } from '@/utils/utils'; 3 | 4 | const { className, ...props } = Astro.props; 5 | --- 6 | 7 |

    8 | 9 |

    10 | -------------------------------------------------------------------------------- /packages/primitives/calendar/src/calendar-grid-head.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: 'thead[rdxCalendarGridHead]', 5 | host: { 6 | '[attr.aria-hidden]': 'true' 7 | } 8 | }) 9 | export class RdxCalendarGridHeadDirective {} 10 | -------------------------------------------------------------------------------- /packages/primitives/core/src/is-inside-form.ts: -------------------------------------------------------------------------------- 1 | import { ElementRef } from '@angular/core'; 2 | 3 | export function isInsideForm(el: ElementRef | null): boolean { 4 | if (!el || !el.nativeElement) { 5 | return true; 6 | } 7 | return Boolean(el.nativeElement.closest('form')); 8 | } 9 | -------------------------------------------------------------------------------- /packages/primitives/hover-card/src/hover-card-anchor.token.ts: -------------------------------------------------------------------------------- 1 | import { InjectionToken } from '@angular/core'; 2 | import { RdxHoverCardAnchorDirective } from './hover-card-anchor.directive'; 3 | 4 | export const RdxHoverCardAnchorToken = new InjectionToken('RdxHoverCardAnchorToken'); 5 | -------------------------------------------------------------------------------- /packages/primitives/menu/src/menu-radio-group.directive.ts: -------------------------------------------------------------------------------- 1 | import { CdkMenuGroup } from '@angular/cdk/menu'; 2 | import { Directive } from '@angular/core'; 3 | 4 | @Directive({ 5 | selector: '[RdxMenuRadioGroup]', 6 | hostDirectives: [CdkMenuGroup] 7 | }) 8 | export class RdxMenuRadioGroupDirective {} 9 | -------------------------------------------------------------------------------- /packages/primitives/pagination/src/pagination-ellipsis.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[rdxPaginationEllipsis]', 5 | host: { 6 | '[attr.data-type]': '"ellipsis"' 7 | } 8 | }) 9 | export class RdxPaginationEllipsisDirective {} 10 | -------------------------------------------------------------------------------- /apps/radix-docs/src/demos/primitives/aspect-ratio/aspect-ratio-demo.css: -------------------------------------------------------------------------------- 1 | .Container { 2 | width: 300px; 3 | border-radius: 6px; 4 | overflow: hidden; 5 | box-shadow: 0 2px 10px var(--black-a7); 6 | } 7 | 8 | .Image { 9 | object-fit: cover; 10 | width: 100%; 11 | height: 100%; 12 | } 13 | -------------------------------------------------------------------------------- /apps/radix-ssr-testing/src/app/app.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { RouterOutlet } from '@angular/router'; 3 | 4 | @Component({ 5 | selector: 'app-root', 6 | imports: [RouterOutlet], 7 | template: ` 8 | 9 | ` 10 | }) 11 | export class App {} 12 | -------------------------------------------------------------------------------- /packages/primitives/menubar/src/menubar-radio-group.directive.ts: -------------------------------------------------------------------------------- 1 | import { CdkMenuGroup } from '@angular/cdk/menu'; 2 | import { Directive } from '@angular/core'; 3 | 4 | @Directive({ 5 | selector: '[RdxMenuBarRadioGroup]', 6 | hostDirectives: [CdkMenuGroup] 7 | }) 8 | export class RdxMenubarRadioGroupDirective {} 9 | -------------------------------------------------------------------------------- /apps/radix-docs/src/contributor-names.json: -------------------------------------------------------------------------------- 1 | [ 2 | "pimenovoleg", 3 | "artembelik", 4 | "lskramarov", 5 | "mrfrac", 6 | "zizifn", 7 | "olegdenisov", 8 | "KamilEmeleev", 9 | "vitalyozza", 10 | "pawel-twardziak", 11 | "VictorZubr", 12 | "jpsullivan", 13 | "ayush-seth" 14 | ] 15 | -------------------------------------------------------------------------------- /packages/primitives/popper/src/popper.ts: -------------------------------------------------------------------------------- 1 | import { contentChild, Directive } from '@angular/core'; 2 | import { RdxPopperAnchor } from './popper-anchor'; 3 | 4 | @Directive({ 5 | selector: '[rdxPopperRoot]' 6 | }) 7 | export class RdxPopper { 8 | readonly anchor = contentChild.required(RdxPopperAnchor); 9 | } 10 | -------------------------------------------------------------------------------- /packages/primitives/menubar/src/menubar-group.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | import { RdxMenuGroupDirective } from '@radix-ng/primitives/menu'; 3 | 4 | @Directive({ 5 | selector: '[RdxMenuBarGroup]', 6 | hostDirectives: [RdxMenuGroupDirective] 7 | }) 8 | export class RdxMenubarGroupDirective {} 9 | -------------------------------------------------------------------------------- /packages/primitives/hover-card/stories/utils/constants.ts: -------------------------------------------------------------------------------- 1 | export const containerAlert = 2 | 'For the sake of option panels to play with the stories, the "onOverlayEscapeKeyDown" & "onOverlayOutsideClick" events are limited to the area inside the rectangle marked with a dashed line - the events work when the area is active (focused)'; 3 | -------------------------------------------------------------------------------- /packages/primitives/menu/src/menu-separator.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[RdxMenuSeparator]', 5 | host: { 6 | role: 'separator', 7 | '[attr.aria-orientation]': "'horizontal'" 8 | } 9 | }) 10 | export class RdxMenuSeparatorDirective {} 11 | -------------------------------------------------------------------------------- /packages/primitives/popover/stories/utils/constants.ts: -------------------------------------------------------------------------------- 1 | export const containerAlert = 2 | 'For the sake of option panels to play with the stories, the "onOverlayEscapeKeyDown" & "onOverlayOutsideClick" events are limited to the area inside the rectangle marked with a dashed line - the events work when the area is active (focused)'; 3 | -------------------------------------------------------------------------------- /packages/primitives/tooltip/stories/utils/constants.ts: -------------------------------------------------------------------------------- 1 | export const containerAlert = 2 | 'For the sake of option panels to play with the stories, the "onOverlayEscapeKeyDown" & "onOverlayOutsideClick" events are limited to the area inside the rectangle marked with a dashed line - the events work when the area is active (focused)'; 3 | -------------------------------------------------------------------------------- /apps/radix-docs/src/components/mdx/Tabs.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { cn } from '@/utils/utils'; 3 | import { Tabs as TabsComponent } from '../tabs'; 4 | 5 | const { class: className, ...rest } = Astro.props; 6 | --- 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /packages/primitives/core/src/date-time/index.ts: -------------------------------------------------------------------------------- 1 | export * from './calendar'; 2 | export * from './comparators'; 3 | export * from './formatter'; 4 | export * from './parser'; 5 | export * from './placeholders'; 6 | export * from './segment'; 7 | export * from './types'; 8 | export * from './useDateField'; 9 | export * from './utils'; 10 | -------------------------------------------------------------------------------- /packages/primitives/menubar/src/menubar-content.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | import { RdxMenuContentDirective } from '@radix-ng/primitives/menu'; 3 | 4 | @Directive({ 5 | selector: '[RdxMenuBarContent]', 6 | hostDirectives: [RdxMenuContentDirective] 7 | }) 8 | export class RdxMenuBarContentDirective {} 9 | -------------------------------------------------------------------------------- /packages/primitives/select/__tests__/select.directive.spec.ts: -------------------------------------------------------------------------------- 1 | import { RdxSelectComponent } from '../src/select.component'; 2 | 3 | xdescribe('RdxSelectDirective', () => { 4 | it('should create an instance', () => { 5 | const directive = new RdxSelectComponent(); 6 | expect(directive).toBeTruthy(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /apps/radix-docs/src/demos/primitives/progress/attrs.ts: -------------------------------------------------------------------------------- 1 | export const attrDataRoot = [ 2 | { name: '[data-state]', value: '"complete" | "indeterminate" | "loading"' }, 3 | { name: '[data-value]', value: 'The current value' }, 4 | { name: '[data-max]', value: 'The max value' } 5 | ]; 6 | 7 | export const attrDataIndicator = attrDataRoot; 8 | -------------------------------------------------------------------------------- /packages/primitives/dialog/stories/sheet.docs.mdx: -------------------------------------------------------------------------------- 1 | import { Canvas, Controls, Meta } from '@storybook/addon-docs/blocks'; 2 | import * as SheetStories from './sheet.stories'; 3 | 4 | 5 | 6 | # Sheet 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /packages/primitives/select/src/select-group.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[rdxSelectGroup]', 5 | standalone: true, 6 | exportAs: 'rdxSelectGroup', 7 | host: { 8 | '[attr.role]': '"group"' 9 | } 10 | }) 11 | export class RdxSelectGroupDirective {} 12 | -------------------------------------------------------------------------------- /packages/primitives/select/src/select-icon.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[rdxSelectIcon]', 5 | standalone: true, 6 | exportAs: 'rdxSelectIcon', 7 | host: { 8 | '[attr.aria-hidden]': 'true' 9 | } 10 | }) 11 | export class RdxSelectIconDirective {} 12 | -------------------------------------------------------------------------------- /tools/scripts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "declaration": true, 5 | "module": "commonjs", 6 | "moduleResolution": "node", 7 | "outDir": "../../dist/scripts", 8 | "types": ["node"] 9 | }, 10 | "include": ["**/*.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /apps/radix-docs/src/config/site-config.ts: -------------------------------------------------------------------------------- 1 | export const siteConfig = { 2 | title: 'radix-ng', 3 | url: 'https://radix-ng.com', 4 | description: 'Unstyled, accessible components for building high-quality design systems and web apps in Angular.', 5 | links: { 6 | github: 'https://github.com/radix-ng/primitives' 7 | } 8 | }; 9 | -------------------------------------------------------------------------------- /apps/radix-ssr-testing/src/main.server.ts: -------------------------------------------------------------------------------- 1 | import { bootstrapApplication, BootstrapContext } from '@angular/platform-browser'; 2 | import { App } from './app/app'; 3 | import { config } from './app/app.config.server'; 4 | 5 | const bootstrap = (context: BootstrapContext) => bootstrapApplication(App, config, context); 6 | 7 | export default bootstrap; 8 | -------------------------------------------------------------------------------- /apps/radix-ssr-testing/src/test-setup.ts: -------------------------------------------------------------------------------- 1 | // @ts-expect-error https://thymikee.github.io/jest-preset-angular/docs/getting-started/test-environment 2 | globalThis.ngJest = { 3 | testEnvironmentOptions: { 4 | errorOnUnknownElements: true, 5 | errorOnUnknownProperties: true 6 | } 7 | }; 8 | import 'jest-preset-angular/setup-jest'; 9 | -------------------------------------------------------------------------------- /packages/primitives/menubar/src/menubar-separator.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | import { RdxMenuSeparatorDirective } from '@radix-ng/primitives/menu'; 3 | 4 | @Directive({ 5 | selector: '[RdxMenuBarSeparator]', 6 | hostDirectives: [RdxMenuSeparatorDirective] 7 | }) 8 | export class RdxMenubarSeparatorDirective {} 9 | -------------------------------------------------------------------------------- /apps/radix-docs/.gitignore: -------------------------------------------------------------------------------- 1 | # build output 2 | dist/ 3 | # generated types 4 | .astro/ 5 | 6 | # dependencies 7 | node_modules/ 8 | 9 | # logs 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | pnpm-debug.log* 14 | 15 | 16 | # environment variables 17 | .env 18 | .env.production 19 | 20 | # macOS-specific files 21 | .DS_Store 22 | -------------------------------------------------------------------------------- /apps/radix-ssr-testing/src/app/app.routes.server.ts: -------------------------------------------------------------------------------- 1 | import { RenderMode, ServerRoute } from '@angular/ssr'; 2 | 3 | export const serverRoutes: ServerRoute[] = [ 4 | { 5 | path: 'list', 6 | renderMode: RenderMode.Prerender 7 | }, 8 | { 9 | path: '**', 10 | renderMode: RenderMode.Server 11 | } 12 | ]; 13 | -------------------------------------------------------------------------------- /packages/primitives/dropdown-menu/src/dropdown-menu-label.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | import { RdxMenuLabelDirective } from '@radix-ng/primitives/menu'; 3 | 4 | @Directive({ 5 | selector: '[rdxDropdownMenuLabel]', 6 | hostDirectives: [RdxMenuLabelDirective] 7 | }) 8 | export class RdxDropdownMenuLabelDirective {} 9 | -------------------------------------------------------------------------------- /packages/primitives/menu/src/menu-group.directive.ts: -------------------------------------------------------------------------------- 1 | import { CdkMenuGroup } from '@angular/cdk/menu'; 2 | import { Directive } from '@angular/core'; 3 | 4 | @Directive({ 5 | selector: '[RdxMenuGroup]', 6 | hostDirectives: [CdkMenuGroup], 7 | host: { 8 | role: 'group' 9 | } 10 | }) 11 | export class RdxMenuGroupDirective {} 12 | -------------------------------------------------------------------------------- /packages/primitives/select/__tests__/select-item.directive.spec.ts: -------------------------------------------------------------------------------- 1 | import { RdxSelectItemDirective } from '../src/select-item.directive'; 2 | 3 | xdescribe('RdxSelectItemDirective', () => { 4 | it('should create an instance', () => { 5 | const directive = new RdxSelectItemDirective(); 6 | expect(directive).toBeTruthy(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /packages/primitives/select/src/select-separator.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[rdxSelectSeparator]', 5 | standalone: true, 6 | exportAs: 'rdxSelectSeparator', 7 | host: { 8 | '[attr.aria-hidden]': 'true' 9 | } 10 | }) 11 | export class RdxSelectSeparatorDirective {} 12 | -------------------------------------------------------------------------------- /packages/primitives/menubar/src/menubar-item-indicator.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | import { RdxMenuItemIndicatorDirective } from '@radix-ng/primitives/menu'; 3 | 4 | @Directive({ 5 | selector: '[RdxMenuBarItemIndicator]', 6 | hostDirectives: [RdxMenuItemIndicatorDirective] 7 | }) 8 | export class RdxMenubarItemIndicatorDirective {} 9 | -------------------------------------------------------------------------------- /packages/primitives/tsconfig.lib.prod.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.lib.json", 3 | "compilerOptions": { 4 | "declarationMap": false, 5 | "paths": { 6 | "@radix-ng/primitives/*": ["./dist/primitives/*"] 7 | } 8 | }, 9 | "angularCompilerOptions": { 10 | "compilationMode": "partial" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/primitives/dropdown-menu/src/dropdown-menu-separator.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | import { RdxMenuSeparatorDirective } from '@radix-ng/primitives/menu'; 3 | 4 | @Directive({ 5 | selector: '[rdxDropdownMenuSeparator]', 6 | hostDirectives: [RdxMenuSeparatorDirective] 7 | }) 8 | export class RdxDropdownMenuSeparatorDirective {} 9 | -------------------------------------------------------------------------------- /packages/primitives/popover/src/popover-content-attributes.token.ts: -------------------------------------------------------------------------------- 1 | import { InjectionToken } from '@angular/core'; 2 | import { RdxPopoverContentAttributesComponent } from './popover-content-attributes.component'; 3 | 4 | export const RdxPopoverContentAttributesToken = new InjectionToken( 5 | 'RdxPopoverContentAttributesToken' 6 | ); 7 | -------------------------------------------------------------------------------- /packages/primitives/select/__tests__/select-content.directive.spec.ts: -------------------------------------------------------------------------------- 1 | import { RdxSelectContentDirective } from '../src/select-content.directive'; 2 | 3 | xdescribe('RdxSelectContentDirective', () => { 4 | it('should create an instance', () => { 5 | const directive = new RdxSelectContentDirective(); 6 | expect(directive).toBeTruthy(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /packages/primitives/select/__tests__/select-trigger.directive.spec.ts: -------------------------------------------------------------------------------- 1 | import { RdxSelectTriggerDirective } from '../src/select-trigger.directive'; 2 | 3 | xdescribe('RdxSelectTriggerDirective', () => { 4 | it('should create an instance', () => { 5 | const directive = new RdxSelectTriggerDirective(); 6 | expect(directive).toBeTruthy(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /packages/primitives/tooltip/src/tooltip-content-attributes.token.ts: -------------------------------------------------------------------------------- 1 | import { InjectionToken } from '@angular/core'; 2 | import { RdxTooltipContentAttributesComponent } from './tooltip-content-attributes.component'; 3 | 4 | export const RdxTooltipContentAttributesToken = new InjectionToken( 5 | 'RdxTooltipContentAttributesToken' 6 | ); 7 | -------------------------------------------------------------------------------- /apps/radix-docs/src/components/mdx/FeatureList.astro: -------------------------------------------------------------------------------- 1 | --- 2 | export interface Props { 3 | items: string[]; 4 | } 5 | 6 | const { items } = Astro.props; 7 | --- 8 | 9 |

    Features

    10 |
      11 | {items.map((item) =>
    • {item}
    • )} 12 |
    13 | -------------------------------------------------------------------------------- /apps/radix-ssr-testing/src/app/components/label/page.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { RdxLabelDirective } from '@radix-ng/primitives/label'; 3 | 4 | @Component({ 5 | selector: 'app-label', 6 | imports: [RdxLabelDirective], 7 | template: ` 8 | 9 | ` 10 | }) 11 | export default class Page {} 12 | -------------------------------------------------------------------------------- /packages/primitives/accordion/__tests__/accordion-item.directive.spec.ts: -------------------------------------------------------------------------------- 1 | import { RdxAccordionItemDirective } from '../src/accordion-item.directive'; 2 | 3 | xdescribe('RdxAccordionItemDirective', () => { 4 | it('should create an instance', () => { 5 | const directive = new RdxAccordionItemDirective(); 6 | expect(directive).toBeTruthy(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /packages/primitives/accordion/__tests__/accordion-root.directive.spec.ts: -------------------------------------------------------------------------------- 1 | import { RdxAccordionRootDirective } from '../src/accordion-root.directive'; 2 | 3 | xdescribe('RdxAccordionRootDirective', () => { 4 | it('should create an instance', () => { 5 | const directive = new RdxAccordionRootDirective(); 6 | expect(directive).toBeTruthy(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /packages/primitives/schematics/collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json", 3 | "schematics": { 4 | "ng-add": { 5 | "description": "Add RadixNG to the application.", 6 | "factory": "./ng-add/index#ngAdd", 7 | "aliases": ["install"] 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /apps/radix-docs/src/components/mdx/TabsList.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { cn } from '@/utils/utils'; 3 | import { TabsList as TabsComponent } from '../tabs'; 4 | 5 | const { class: className, ...rest } = Astro.props; 6 | --- 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /packages/primitives/accordion/__tests__/accordion-header.directive.spec.ts: -------------------------------------------------------------------------------- 1 | import { RdxAccordionHeaderDirective } from '../src/accordion-header.directive'; 2 | 3 | xdescribe('RdxAccordionHeaderDirective', () => { 4 | it('should create an instance', () => { 5 | const directive = new RdxAccordionHeaderDirective(); 6 | expect(directive).toBeTruthy(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "esbenp.prettier-vscode", 4 | "stylelint.vscode-stylelint", 5 | "astro-build.astro-vscode", 6 | "angular.ng-template", 7 | "editorconfig.editorconfig", 8 | "dbaeumer.vscode-eslint", 9 | "firsttris.vscode-jest-runner", 10 | "nrwl.angular-console" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /apps/radix-docs/README.md: -------------------------------------------------------------------------------- 1 | # RadixNG Docs 2 | 3 | ## Run Dev 4 | 5 | Build components and primitives 6 | 7 | 1. Build Radix Primitives 8 | 9 | ```bash 10 | pnpm -w run primitives:build 11 | ``` 12 | 13 | 2. Build Radix Components 14 | 15 | ```bash 16 | pnpm -w run components:build 17 | ``` 18 | 19 | 3. Start documentation 20 | 21 | ```bash 22 | pnpm -w run radix-docs:dev 23 | ``` 24 | -------------------------------------------------------------------------------- /apps/radix-docs/src/pages/robots.txt.ts: -------------------------------------------------------------------------------- 1 | import type { APIRoute } from 'astro'; 2 | 3 | const getRobotsTxt = (sitemapURL: URL) => ` 4 | User-agent: * 5 | Allow: / 6 | 7 | Sitemap: ${sitemapURL.href} 8 | `; 9 | 10 | export const GET: APIRoute = ({ site }) => { 11 | const sitemapURL = new URL('sitemap-index.xml', site); 12 | return new Response(getRobotsTxt(sitemapURL)); 13 | }; 14 | -------------------------------------------------------------------------------- /apps/radix-ssr-testing/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "types": ["node"] 6 | }, 7 | "files": ["src/main.ts", "src/main.server.ts", "server.ts"], 8 | "include": ["src/**/*.d.ts"], 9 | "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/primitives/accordion/__tests__/accordion-content.directive.spec.ts: -------------------------------------------------------------------------------- 1 | import { RdxAccordionContentDirective } from '../src/accordion-content.directive'; 2 | 3 | xdescribe('RdxAccordionContentDirective', () => { 4 | it('should create an instance', () => { 5 | const directive = new RdxAccordionContentDirective(); 6 | expect(directive).toBeTruthy(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /packages/primitives/accordion/__tests__/accordion-trigger.directive.spec.ts: -------------------------------------------------------------------------------- 1 | import { RdxAccordionTriggerDirective } from '../src/accordion-trigger.directive'; 2 | 3 | xdescribe('RdxAccordionTriggerDirective', () => { 4 | it('should create an instance', () => { 5 | const directive = new RdxAccordionTriggerDirective(); 6 | expect(directive).toBeTruthy(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /packages/primitives/hover-card/src/hover-card-content-attributes.token.ts: -------------------------------------------------------------------------------- 1 | import { InjectionToken } from '@angular/core'; 2 | import { RdxHoverCardContentAttributesComponent } from './hover-card-content-attributes.component'; 3 | 4 | export const RdxHoverCardContentAttributesToken = new InjectionToken( 5 | 'RdxHoverCardContentAttributesToken' 6 | ); 7 | -------------------------------------------------------------------------------- /packages/primitives/aspect-ratio/stories/aspect-ratio.docs.mdx: -------------------------------------------------------------------------------- 1 | import { Canvas, Meta } from '@storybook/addon-docs/blocks'; 2 | import * as AspectRatioStories from './aspect-ratio.stories'; 3 | 4 | 5 | 6 | # Aspect Ratio 7 | 8 | #### Displays content within a desired ratio. 9 | 10 | 11 | -------------------------------------------------------------------------------- /packages/primitives/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "target": "es2016", 7 | "types": ["jest", "node"] 8 | }, 9 | "files": ["test-setup.ts"], 10 | "include": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | max_line_length = 120 8 | indent_size = 4 9 | end_of_line = lf 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | max_line_length = off 15 | trim_trailing_whitespace = false 16 | 17 | [*.yml] 18 | indent_size = 2 19 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Documentation.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 'Documentation' 3 | about: 'Suggestions for Radix documentation' 4 | --- 5 | 6 | ## Documentation 7 | 8 | ### Relevant Radix Component(s) 9 | 10 | 11 | 12 | ### Examples from other doc sites 13 | 14 | 15 | -------------------------------------------------------------------------------- /packages/primitives/menu/src/menu-content.directive.ts: -------------------------------------------------------------------------------- 1 | import { CdkMenu } from '@angular/cdk/menu'; 2 | import { Directive } from '@angular/core'; 3 | 4 | @Directive({ 5 | selector: '[RdxMenuContent]', 6 | hostDirectives: [CdkMenu], 7 | host: { 8 | role: 'menu', 9 | '[attr.aria-orientation]': '"vertical"' 10 | } 11 | }) 12 | export class RdxMenuContentDirective {} 13 | -------------------------------------------------------------------------------- /packages/primitives/menu/src/utils.ts: -------------------------------------------------------------------------------- 1 | export type CheckedState = boolean | 'indeterminate'; 2 | 3 | export function isIndeterminate(checked?: CheckedState): checked is 'indeterminate' { 4 | return checked === 'indeterminate'; 5 | } 6 | 7 | export function getCheckedState(checked: CheckedState) { 8 | return isIndeterminate(checked) ? 'indeterminate' : checked ? 'checked' : 'unchecked'; 9 | } 10 | -------------------------------------------------------------------------------- /packages/primitives/toolbar/src/toolbar-separator.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | import { RdxSeparatorRootDirective } from '@radix-ng/primitives/separator'; 3 | 4 | @Directive({ 5 | selector: '[rdxToolbarSeparator]', 6 | hostDirectives: [{ directive: RdxSeparatorRootDirective, inputs: ['orientation', 'decorative'] }] 7 | }) 8 | export class RdxToolbarSeparatorDirective {} 9 | -------------------------------------------------------------------------------- /packages/components/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "target": "es2016", 7 | "types": ["jest", "node"] 8 | }, 9 | "files": ["src/test-setup.ts"], 10 | "include": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts", "src/**/*.d.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /packages/primitives/slider/src/slider-thumb.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { RdxSliderThumbImplDirective } from './slider-thumb-impl.directive'; 3 | 4 | @Component({ 5 | selector: 'rdx-slider-thumb', 6 | hostDirectives: [RdxSliderThumbImplDirective], 7 | template: ` 8 | 9 | ` 10 | }) 11 | export class RdxSliderThumbComponent {} 12 | -------------------------------------------------------------------------------- /packages/primitives/stepper/src/stepper-indicator.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | import { injectStepperItemContext } from './stepper-item-context.token'; 3 | 4 | @Directive({ 5 | selector: '[rdxStepperIndicator]', 6 | exportAs: 'rdxStepperIndicator' 7 | }) 8 | export class RdxStepperIndicatorDirective { 9 | readonly itemContext = injectStepperItemContext(); 10 | } 11 | -------------------------------------------------------------------------------- /packages/primitives/toolbar/src/toolbar-toggle-item.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | import { RdxToggleGroupItemDirective } from '@radix-ng/primitives/toggle-group'; 3 | 4 | @Directive({ 5 | selector: '[rdxToolbarToggleItem]', 6 | hostDirectives: [{ directive: RdxToggleGroupItemDirective, inputs: ['value', 'disabled'] }] 7 | }) 8 | export class RdxToolbarToggleItemDirective {} 9 | -------------------------------------------------------------------------------- /apps/radix-docs/src/components/mdx/a.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { cn } from '@/utils/utils'; 3 | 4 | const { className, ...props } = Astro.props; 5 | --- 6 | 7 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /apps/radix-docs/src/components/tabs/TabsList.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { cn } from '@/utils/utils'; 3 | 4 | export interface Props { 5 | class?: string; 6 | } 7 | --- 8 | 9 |
    16 | 17 |
    18 | -------------------------------------------------------------------------------- /apps/radix-ssr-testing/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "target": "es2016", 7 | "types": ["jest", "node"] 8 | }, 9 | "files": ["src/test-setup.ts"], 10 | "include": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts", "src/**/*.d.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /packages/primitives/accordion/src/accordion-content-presence.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | import { RdxCollapsibleContentPresenceDirective } from '@radix-ng/primitives/collapsible'; 3 | 4 | @Directive({ 5 | selector: 'ng-template[rdxAccordionContentPresence]', 6 | hostDirectives: [RdxCollapsibleContentPresenceDirective] 7 | }) 8 | export class RdxAccordionContentPresenceDirective {} 9 | -------------------------------------------------------------------------------- /packages/primitives/menubar/src/menubar-root.directive.ts: -------------------------------------------------------------------------------- 1 | import { CdkMenuBar } from '@angular/cdk/menu'; 2 | import { Directive } from '@angular/core'; 3 | 4 | @Directive({ 5 | selector: '[RdxMenuBarRoot]', 6 | hostDirectives: [CdkMenuBar], 7 | host: { 8 | tabindex: '0', 9 | '[attr.data-orientation]': '"horizontal"' 10 | } 11 | }) 12 | export class RdxMenuBarRootDirective {} 13 | -------------------------------------------------------------------------------- /packages/primitives/tsconfig.schematics.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "declaration": true, 6 | "resolveJsonModule": true, 7 | "module": "CommonJS", 8 | "types": ["node"] 9 | }, 10 | "exclude": ["**/*.spec.ts", "**/*.test.ts"], 11 | "include": ["./schematics/**/*.ts"] 12 | } 13 | -------------------------------------------------------------------------------- /apps/radix-docs/src/utils/typedoc.ts: -------------------------------------------------------------------------------- 1 | import apiPrimitives from '../api-doc/primitives.json'; 2 | 3 | export const getComponentData = (componentName: string) => { 4 | for (const key in apiPrimitives) { 5 | const components = apiPrimitives[key].components; 6 | if (componentName in components) { 7 | return components[componentName]; 8 | } 9 | } 10 | return null; 11 | }; 12 | -------------------------------------------------------------------------------- /apps/radix-docs/src/components/mdx/TabsContent.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { cn } from '@/utils/utils'; 3 | import { TabsContent as TabsComponent } from '../tabs'; 4 | 5 | const { class: className, ...rest } = Astro.props; 6 | --- 7 | 8 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /apps/radix-docs/src/components/theme/theme-head-script.astro: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /packages/primitives/avatar/src/types.ts: -------------------------------------------------------------------------------- 1 | export type RdxImageLoadingStatus = 'idle' | 'loading' | 'loaded' | 'error'; 2 | 3 | export type HTMLAttributeReferrerPolicy = 4 | | '' 5 | | 'no-referrer' 6 | | 'no-referrer-when-downgrade' 7 | | 'origin' 8 | | 'origin-when-cross-origin' 9 | | 'same-origin' 10 | | 'strict-origin' 11 | | 'strict-origin-when-cross-origin' 12 | | 'unsafe-url'; 13 | -------------------------------------------------------------------------------- /packages/primitives/focus-scope/stories/focus-scope.docs.mdx: -------------------------------------------------------------------------------- 1 | import { Canvas, Meta } from '@storybook/addon-docs/blocks'; 2 | import * as Stories from './focus-scope.stories'; 3 | 4 | 5 | 6 | # Focus Scope 7 | 8 | #### Manages focus within a component boundary with support for trapping and looping focus navigation. 9 | 10 | 11 | -------------------------------------------------------------------------------- /packages/components/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "declaration": true, 6 | "declarationMap": true, 7 | "inlineSources": true, 8 | "types": [] 9 | }, 10 | "exclude": ["src/**/*.spec.ts", "src/test-setup.ts", "jest.config.ts", "src/**/*.test.ts"], 11 | "include": ["src/**/*.ts"] 12 | } 13 | -------------------------------------------------------------------------------- /packages/primitives/stepper/src/stepper-title.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | import { injectStepperItemContext } from './stepper-item-context.token'; 3 | 4 | @Directive({ 5 | selector: '[rdxStepperTitle]', 6 | host: { 7 | '[attr.id]': 'itemContext.titleId' 8 | } 9 | }) 10 | export class RdxStepperTitleDirective { 11 | readonly itemContext = injectStepperItemContext(); 12 | } 13 | -------------------------------------------------------------------------------- /packages/primitives/toolbar/stories/toolbar.docs.mdx: -------------------------------------------------------------------------------- 1 | import { ArgTypes, Canvas, Markdown, Meta } from '@storybook/addon-docs/blocks'; 2 | import * as ToolbarStories from './toolbar.stories'; 3 | 4 | 5 | 6 | # Toolbar 7 | 8 | #### A container for grouping a set of controls, such as buttons, Toolbar groups or dropdown menus. 9 | 10 | 11 | -------------------------------------------------------------------------------- /apps/radix-ssr-testing/src/app/components/switch/page.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { RdxSwitchModule } from '@radix-ng/primitives/switch'; 3 | 4 | @Component({ 5 | selector: 'app-switch', 6 | imports: [RdxSwitchModule], 7 | template: ` 8 | 11 | ` 12 | }) 13 | export default class Page {} 14 | -------------------------------------------------------------------------------- /packages/primitives/core/src/focus-initial.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, ElementRef, inject } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[rdxFocusInitial]' 5 | }) 6 | export class RdxFocusInitialDirective { 7 | /** @ignore */ 8 | private readonly nativeElement = inject(ElementRef).nativeElement; 9 | 10 | /** @ignore */ 11 | focus(): void { 12 | this.nativeElement.focus(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /apps/radix-docs/src/demos/primitives/separator/separator-demo.css: -------------------------------------------------------------------------------- 1 | .SeparatorRoot { 2 | background-color: var(--violet-6); 3 | } 4 | 5 | .SeparatorRoot[data-orientation='horizontal'] { 6 | height: 1px; 7 | width: 100%; 8 | } 9 | 10 | .SeparatorRoot[data-orientation='vertical'] { 11 | height: 100%; 12 | width: 1px; 13 | } 14 | 15 | .Text { 16 | color: white; 17 | font-size: 15px; 18 | line-height: 20px; 19 | } 20 | -------------------------------------------------------------------------------- /packages/primitives/cropper/src/cropper-crop-area.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | import { injectCropperRootContext } from './cropper-context.token'; 3 | 4 | @Directive({ 5 | selector: '[rdxCropperCropArea]', 6 | host: { 7 | '[style]': 'rootContext.getCropAreaStyle()' 8 | } 9 | }) 10 | export class RdxCropperCropAreaDirective { 11 | readonly rootContext = injectCropperRootContext(); 12 | } 13 | -------------------------------------------------------------------------------- /packages/primitives/cropper/src/cropper-description.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | import { injectCropperRootContext } from './cropper-context.token'; 3 | 4 | @Directive({ 5 | selector: '[rdxCropperDescription]', 6 | host: { 7 | '[attr.id]': 'rootContext.descriptionId()' 8 | } 9 | }) 10 | export class RdxCropperDescriptionDirective { 11 | readonly rootContext = injectCropperRootContext(); 12 | } 13 | -------------------------------------------------------------------------------- /packages/primitives/toggle-group/src/toggle-group-item.token.ts: -------------------------------------------------------------------------------- 1 | import { inject, InjectionToken } from '@angular/core'; 2 | import type { RdxToggleGroupItemDirective } from './toggle-group-item.directive'; 3 | 4 | export const RdxToggleGroupItemToken = new InjectionToken('RdxToggleGroupItemToken'); 5 | 6 | export function injectToggleGroupItem(): RdxToggleGroupItemDirective { 7 | return inject(RdxToggleGroupItemToken); 8 | } 9 | -------------------------------------------------------------------------------- /packages/components/.compodocrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../node_modules/@compodoc/compodoc/src/config/schema.json", 3 | "tsconfig": "tsconfig.doc.json", 4 | "output": "../../dist/components/compodoc", 5 | "exportFormat": "json", 6 | "hideGenerator": true, 7 | "disableCoverage": true, 8 | "disablePrivate": true, 9 | "disableInternal": true, 10 | "disableLifeCycleHooks": true, 11 | "disableDependencies": true 12 | } 13 | -------------------------------------------------------------------------------- /packages/primitives/stepper/src/stepper-description.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | import { injectStepperItemContext } from './stepper-item-context.token'; 3 | 4 | @Directive({ 5 | selector: '[rdxStepperDescription]', 6 | host: { 7 | '[attr.id]': 'itemContext.descriptionId' 8 | } 9 | }) 10 | export class RdxStepperDescriptionDirective { 11 | readonly itemContext = injectStepperItemContext(); 12 | } 13 | -------------------------------------------------------------------------------- /tools/scripts/docs-copy.mjs: -------------------------------------------------------------------------------- 1 | import { cpSync, mkdirSync } from 'fs'; 2 | 3 | mkdirSync('apps/radix-docs/node_modules/@radix-ng/primitives', { recursive: true }); 4 | mkdirSync('apps/radix-docs/node_modules/@radix-ng/components', { recursive: true }); 5 | 6 | cpSync('dist/primitives', 'apps/radix-docs/node_modules/@radix-ng/primitives', { recursive: true }); 7 | cpSync('dist/components', 'apps/radix-docs/node_modules/@radix-ng/components', { recursive: true }); 8 | -------------------------------------------------------------------------------- /packages/primitives/README.md: -------------------------------------------------------------------------------- 1 | # Primitives 2 | 3 | > Radix-NG is an unofficial Angular port of [Radix UI](https://www.radix-ui.com/), 4 | > thus we share the same principal and vision when building primitives. 5 | 6 | Radix Primitives is a low-level UI component library with a focus on accessibility, 7 | customization and developer experience. 8 | 9 | You can use these components either as the base layer of your design system, or adopt them incrementally. 10 | -------------------------------------------------------------------------------- /packages/primitives/popover/src/popover.types.ts: -------------------------------------------------------------------------------- 1 | export enum RdxPopoverState { 2 | OPEN = 'open', 3 | CLOSED = 'closed' 4 | } 5 | 6 | export enum RdxPopoverAttachDetachEvent { 7 | ATTACH = 'attach', 8 | DETACH = 'detach' 9 | } 10 | 11 | export enum RdxPopoverAnimationStatus { 12 | OPEN_STARTED = 'open_started', 13 | OPEN_ENDED = 'open_ended', 14 | CLOSED_STARTED = 'closed_started', 15 | CLOSED_ENDED = 'closed_ended' 16 | } 17 | -------------------------------------------------------------------------------- /packages/primitives/tsconfig.typedoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "declaration": true, 6 | "resolveJsonModule": true, 7 | "module": "CommonJS", 8 | "types": ["node"] 9 | }, 10 | "include": ["**/src/**.ts", "**/*.ts"], 11 | "exclude": ["**/*.spec.ts", "**/*.test.ts", "**/stories/**.*", "*.stories.ts", "./schematics/**/*.ts"] 12 | } 13 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 'Question' 3 | about: 'For usage questions or use GitHub Discussions' 4 | --- 5 | 6 | ## Question 7 | 8 | For usage questions, please use Stack Overflow or use [GitHub Discussions](https://github.com/radix-ng/primitives/discussions) instead of posting an issue. 9 | This helps us keep bugs and feature requests prioritized, and it increases the likelihood that more people see your question and can answer it more quickly! 10 | -------------------------------------------------------------------------------- /packages/primitives/menubar/src/menubar-item-radio.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | import { RdxMenuItemRadioDirective } from '@radix-ng/primitives/menu'; 3 | 4 | @Directive({ 5 | selector: '[RdxMenuBarItemRadio]', 6 | hostDirectives: [ 7 | { 8 | directive: RdxMenuItemRadioDirective, 9 | inputs: ['disabled', 'checked'] 10 | } 11 | ] 12 | }) 13 | export class RdxMenubarItemRadioDirective {} 14 | -------------------------------------------------------------------------------- /packages/primitives/menubar/src/menubar-item.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | import { RdxMenuItemDirective } from '@radix-ng/primitives/menu'; 3 | 4 | @Directive({ 5 | selector: '[RdxMenuBarItem]', 6 | hostDirectives: [ 7 | { 8 | directive: RdxMenuItemDirective, 9 | inputs: ['disabled'], 10 | outputs: ['onSelect'] 11 | } 12 | ] 13 | }) 14 | export class RdxMenuBarItemDirective {} 15 | -------------------------------------------------------------------------------- /packages/primitives/toolbar/src/toolbar-toggle-group.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | import { RdxToggleGroupWithoutFocusDirective } from '@radix-ng/primitives/toggle-group'; 3 | 4 | // TODO: set rovingFocus - false 5 | @Directive({ 6 | selector: '[rdxToolbarToggleGroup]', 7 | hostDirectives: [{ directive: RdxToggleGroupWithoutFocusDirective, inputs: ['value', 'type', 'disabled'] }] 8 | }) 9 | export class RdxToolbarToggleGroupDirective {} 10 | -------------------------------------------------------------------------------- /apps/radix-ssr-testing/src/app/components/separator/page.ts: -------------------------------------------------------------------------------- 1 | import { ChangeDetectionStrategy, Component } from '@angular/core'; 2 | import { RdxSeparatorRootDirective } from '@radix-ng/primitives/separator'; 3 | 4 | @Component({ 5 | selector: 'app-separator', 6 | changeDetection: ChangeDetectionStrategy.OnPush, 7 | imports: [RdxSeparatorRootDirective], 8 | template: ` 9 |
    ***
    10 | ` 11 | }) 12 | export default class Page {} 13 | -------------------------------------------------------------------------------- /apps/radix-ssr-testing/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | radix-ssr-testing 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/primitives/menubar/src/menubar-item-checkbox.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | import { RdxMenuItemCheckboxDirective } from '@radix-ng/primitives/menu'; 3 | 4 | @Directive({ 5 | selector: '[RdxMenuBarCheckboxItem]', 6 | hostDirectives: [ 7 | { 8 | directive: RdxMenuItemCheckboxDirective, 9 | inputs: ['checked', 'disabled'] 10 | } 11 | ] 12 | }) 13 | export class RdxMenubarItemCheckboxDirective {} 14 | -------------------------------------------------------------------------------- /packages/primitives/popover/src/utils/types.ts: -------------------------------------------------------------------------------- 1 | export type EventType = 'cdkOverlayOutsideClick' | 'cdkOverlayEscapeKeyDown'; 2 | export type EventTypeCapitalized = Capitalize; 3 | export type EventTypeAsPrimitiveConfigKey = `prevent${EventTypeCapitalized}`; 4 | export type PrimitiveConfig = { 5 | [value in EventTypeAsPrimitiveConfigKey]?: boolean; 6 | }; 7 | export type PrimitiveConfigs = Map; 8 | -------------------------------------------------------------------------------- /packages/primitives/tooltip/src/utils/types.ts: -------------------------------------------------------------------------------- 1 | export type EventType = 'cdkOverlayOutsideClick' | 'cdkOverlayEscapeKeyDown'; 2 | export type EventTypeCapitalized = Capitalize; 3 | export type EventTypeAsPrimitiveConfigKey = `prevent${EventTypeCapitalized}`; 4 | export type PrimitiveConfig = { 5 | [value in EventTypeAsPrimitiveConfigKey]?: boolean; 6 | }; 7 | export type PrimitiveConfigs = Map; 8 | -------------------------------------------------------------------------------- /packages/primitives/hover-card/src/utils/types.ts: -------------------------------------------------------------------------------- 1 | export type EventType = 'cdkOverlayOutsideClick' | 'cdkOverlayEscapeKeyDown'; 2 | export type EventTypeCapitalized = Capitalize; 3 | export type EventTypeAsPrimitiveConfigKey = `prevent${EventTypeCapitalized}`; 4 | export type PrimitiveConfig = { 5 | [value in EventTypeAsPrimitiveConfigKey]?: boolean; 6 | }; 7 | export type PrimitiveConfigs = Map; 8 | -------------------------------------------------------------------------------- /apps/radix-docs/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | declare module '*.analog' { 5 | import type { Type } from '@angular/core'; 6 | const component: Type; 7 | export default component; 8 | } 9 | 10 | declare module '*?includeContent' { 11 | import type { Type } from '@angular/core'; 12 | const component: Type; 13 | export const content: string; 14 | export default component; 15 | } 16 | -------------------------------------------------------------------------------- /packages/primitives/roving-focus/index.ts: -------------------------------------------------------------------------------- 1 | import { RdxRovingFocusGroupDirective } from './src/roving-focus-group.directive'; 2 | import { RdxRovingFocusItemDirective } from './src/roving-focus-item.directive'; 3 | 4 | export * from './src/roving-focus-group.directive'; 5 | export * from './src/roving-focus-item.directive'; 6 | 7 | export type { Direction, Orientation } from './src/utils'; 8 | 9 | export const rovingFocusImports = [RdxRovingFocusGroupDirective, RdxRovingFocusItemDirective]; 10 | -------------------------------------------------------------------------------- /apps/radix-storybook/.storybook/plugins/compodoc.ts: -------------------------------------------------------------------------------- 1 | import { setCompodocJson } from '@storybook/addon-docs/angular'; 2 | import docJson from '../documentation.json'; 3 | 4 | export default { 5 | init() { 6 | const docToCleanup = [...docJson.components, ...docJson.directives]; 7 | 8 | for (const doc of docToCleanup) { 9 | doc.propertiesClass = []; 10 | doc.methodsClass = []; 11 | } 12 | 13 | setCompodocJson(docJson); 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /packages/primitives/tooltip2/src/tooltip-portal.ts: -------------------------------------------------------------------------------- 1 | import { Directive, ElementRef, input } from '@angular/core'; 2 | import { RdxPortal } from '@radix-ng/primitives/portal'; 3 | 4 | @Directive({ 5 | selector: '[rdxTooltipPortal]', 6 | hostDirectives: [ 7 | { 8 | directive: RdxPortal, 9 | inputs: ['container'] 10 | } 11 | ] 12 | }) 13 | export class RdxTooltipPortal { 14 | readonly container = input.required>(); 15 | } 16 | -------------------------------------------------------------------------------- /apps/radix-docs/src/components/tabs/TabsContent.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { cn } from '@/utils/utils'; 3 | 4 | export interface Props { 5 | class?: string; 6 | } 7 | --- 8 | 9 |
    17 | 18 |
    19 | -------------------------------------------------------------------------------- /apps/radix-ssr-testing/src/app/app.config.server.ts: -------------------------------------------------------------------------------- 1 | import { ApplicationConfig, mergeApplicationConfig } from '@angular/core'; 2 | import { provideServerRendering, withRoutes } from '@angular/ssr'; 3 | import { appConfig } from './app.config'; 4 | import { serverRoutes } from './app.routes.server'; 5 | 6 | const serverConfig: ApplicationConfig = { 7 | providers: [provideServerRendering(withRoutes(serverRoutes))] 8 | }; 9 | 10 | export const config = mergeApplicationConfig(appConfig, serverConfig); 11 | -------------------------------------------------------------------------------- /packages/primitives/menubar/src/menubar-trigger.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | import { RdxMenuTriggerDirective } from '@radix-ng/primitives/menu'; 3 | 4 | @Directive({ 5 | selector: '[RdxMenuBarTrigger]', 6 | hostDirectives: [ 7 | { 8 | directive: RdxMenuTriggerDirective, 9 | inputs: ['disabled', 'menuTriggerFor', 'sideOffset', 'side', 'align', 'alignOffset'] 10 | } 11 | ] 12 | }) 13 | export class RdxMenuBarTriggerDirective {} 14 | -------------------------------------------------------------------------------- /apps/radix-docs/src/pages/llms.txt.ts: -------------------------------------------------------------------------------- 1 | import type { APIRoute } from 'astro'; 2 | import { getCollection } from 'astro:content'; 3 | 4 | export const GET: APIRoute = async () => { 5 | const posts = await getCollection('primitives'); 6 | 7 | let content = '# RadixNG Angular\n\n'; 8 | for (const post of posts) { 9 | content += `${post.body}\n\n`; 10 | } 11 | 12 | return new Response(content, { 13 | headers: { 'Content-Type': 'text/plain; charset=utf-8' } 14 | }); 15 | }; 16 | -------------------------------------------------------------------------------- /packages/primitives/context-menu/src/context-menu-separator.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | import { RdxSeparatorRootDirective } from '@radix-ng/primitives/separator'; 3 | 4 | @Directive({ 5 | selector: '[rdxContextMenuSeparator]', 6 | standalone: true, 7 | hostDirectives: [RdxSeparatorRootDirective], 8 | host: { 9 | role: 'separator', 10 | '[attr.aria-orientation]': "'horizontal'" 11 | } 12 | }) 13 | export class RdxContextMenuSeparatorDirective {} 14 | -------------------------------------------------------------------------------- /packages/primitives/dialog/src/dialog-close.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, inject } from '@angular/core'; 2 | import { RdxDialogRef } from './dialog-ref'; 3 | 4 | @Directive({ 5 | selector: '[rdxDialogClose]', 6 | standalone: true, 7 | host: { 8 | '(click)': 'onClick()' 9 | } 10 | }) 11 | export class RdxDialogCloseDirective { 12 | private readonly ref = inject(RdxDialogRef); 13 | 14 | protected onClick(): void { 15 | this.ref.close(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/primitives/toggle-group/src/toggle-group.token.ts: -------------------------------------------------------------------------------- 1 | import { inject, InjectionToken } from '@angular/core'; 2 | 3 | export interface IRdxToggleGroup { 4 | toggle(value: string): void; 5 | disabled: any; 6 | value: any; 7 | type: any; 8 | accessorDisabled: any; 9 | } 10 | 11 | export const RdxToggleGroupToken = new InjectionToken('RdxToggleGroupToken'); 12 | 13 | export function injectToggleGroup(): IRdxToggleGroup { 14 | return inject(RdxToggleGroupToken); 15 | } 16 | -------------------------------------------------------------------------------- /apps/radix-docs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "astro/tsconfigs/base", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "paths": { 6 | "@/*": ["src/*"] 7 | }, 8 | "plugins": [ 9 | { 10 | "name": "@astrojs/ts-plugin" 11 | }, 12 | { 13 | "name": "@angular/language-service" 14 | } 15 | ] 16 | }, 17 | "angularCompilerOptions": { 18 | "strictTemplates": true 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/primitives/core/src/getActiveElement.ts: -------------------------------------------------------------------------------- 1 | export function getActiveElement(): Element | null { 2 | let activeElement = document.activeElement; 3 | if (activeElement == null) { 4 | return null; 5 | } 6 | 7 | while ( 8 | activeElement != null && 9 | activeElement.shadowRoot != null && 10 | activeElement.shadowRoot.activeElement != null 11 | ) { 12 | activeElement = activeElement.shadowRoot.activeElement; 13 | } 14 | 15 | return activeElement; 16 | } 17 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 11 | 12 | ### Description 13 | 14 | 15 | -------------------------------------------------------------------------------- /apps/radix-docs/src/content/config.ts: -------------------------------------------------------------------------------- 1 | import { defineCollection, z } from 'astro:content'; 2 | 3 | const docsSchema = z.object({ 4 | title: z.string(), 5 | section: z.string() 6 | }); 7 | 8 | const themesSchema = z.object({ 9 | title: z.string(), 10 | section: z.string() 11 | }); 12 | 13 | const themes = defineCollection({ 14 | schema: themesSchema 15 | }); 16 | 17 | const primitives = defineCollection({ 18 | schema: docsSchema 19 | }); 20 | 21 | export const collections = { themes, primitives }; 22 | -------------------------------------------------------------------------------- /packages/primitives/avatar/src/avatar-context.token.ts: -------------------------------------------------------------------------------- 1 | import { inject, InjectionToken, WritableSignal } from '@angular/core'; 2 | import { RdxImageLoadingStatus } from './types'; 3 | 4 | export interface AvatarContextToken { 5 | imageLoadingStatus: WritableSignal; 6 | } 7 | 8 | export const AVATAR_ROOT_CONTEXT = new InjectionToken('AVATAR_ROOT_CONTEXT'); 9 | 10 | export function injectAvatarRootContext(): AvatarContextToken { 11 | return inject(AVATAR_ROOT_CONTEXT); 12 | } 13 | -------------------------------------------------------------------------------- /packages/primitives/collection/src/collection-context.ts: -------------------------------------------------------------------------------- 1 | import { InjectionToken, Signal, WritableSignal } from '@angular/core'; 2 | 3 | export interface CollectionItemRecord { 4 | ref: HTMLElement; 5 | value?: any; 6 | } 7 | 8 | export interface CollectionContext { 9 | collectionElementRef: Signal; 10 | itemMap: WritableSignal>; 11 | } 12 | 13 | export const COLLECTION_CONTEXT_TOKEN = new InjectionToken('RDX_COLLECTION_CONTEXT'); 14 | -------------------------------------------------------------------------------- /packages/primitives/tooltip2/src/tooltip-content.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | import { RdxPopperContent } from '@radix-ng/primitives/popper'; 3 | import { injectRdxTooltipContext } from './tooltip'; 4 | 5 | @Directive({ 6 | selector: '[rdxTooltipContent]', 7 | hostDirectives: [RdxPopperContent], 8 | host: { 9 | role: 'tooltip', 10 | '[id]': 'rootContext.contentId' 11 | } 12 | }) 13 | export class RdxTooltipContent { 14 | protected rootContext = injectRdxTooltipContext()!; 15 | } 16 | -------------------------------------------------------------------------------- /packages/primitives/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "declaration": true, 6 | "declarationMap": true, 7 | "inlineSources": true, 8 | "types": [] 9 | }, 10 | "exclude": [ 11 | "**/*.spec.ts", 12 | "test-setup.ts", 13 | "jest.config.ts", 14 | "**/*.test.ts", 15 | "**/*.stories.ts", 16 | "**/*.stories.js" 17 | ], 18 | "include": ["**/*.ts"] 19 | } 20 | -------------------------------------------------------------------------------- /.github/workflows/pr-commitlint.yml: -------------------------------------------------------------------------------- 1 | name: PR Commitlint 2 | 3 | on: 4 | pull_request: 5 | types: [opened, synchronize, edited] 6 | 7 | jobs: 8 | check: 9 | name: Check PR title 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout repository 13 | uses: actions/checkout@v4 14 | with: 15 | fetch-depth: 0 16 | 17 | - uses: ./.github/actions/setup 18 | 19 | - name: Check PR title with commitlint 20 | run: echo "${{ github.event.pull_request.title }}" | npx commitlint 21 | -------------------------------------------------------------------------------- /apps/radix-docs/src/components/code-editor/example-app/index-html.ts: -------------------------------------------------------------------------------- 1 | export const index_html = (componentName: string, componentSelector: string) => ` 2 | 3 | 4 | 5 | 6 | RadixNG ${componentName} 7 | 8 | 9 | 10 | 11 | 12 | <${componentSelector}> 13 | 14 | `; 15 | -------------------------------------------------------------------------------- /packages/components/.storybook/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "emitDecoratorMetadata": true, 5 | "resolveJsonModule": true, 6 | "allowSyntheticDefaultImports": true 7 | }, 8 | "exclude": ["../**/*.spec.ts"], 9 | "include": [ 10 | "../**/*.stories.ts", 11 | "../**/*.stories.js", 12 | "../**/*.stories.jsx", 13 | "../**/*.stories.tsx", 14 | "../**/*.stories.mdx", 15 | "*.js", 16 | "*.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /packages/primitives/dialog/src/dialog-dismiss.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, inject } from '@angular/core'; 2 | import { RdxDialogRef } from './dialog-ref'; 3 | 4 | @Directive({ 5 | selector: 'button[rdxDialogDismiss]', 6 | standalone: true, 7 | host: { 8 | type: 'button', 9 | '(click)': 'onClick()' 10 | } 11 | }) 12 | export class RdxDialogDismissDirective { 13 | private readonly ref = inject(RdxDialogRef); 14 | 15 | protected onClick(): void { 16 | this.ref.dismiss(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/primitives/tooltip/src/tooltip.types.ts: -------------------------------------------------------------------------------- 1 | export enum RdxTooltipState { 2 | OPEN = 'open', 3 | CLOSED = 'closed' 4 | } 5 | 6 | export enum RdxTooltipAction { 7 | OPEN = 'open', 8 | CLOSE = 'close' 9 | } 10 | 11 | export enum RdxTooltipAttachDetachEvent { 12 | ATTACH = 'attach', 13 | DETACH = 'detach' 14 | } 15 | 16 | export enum RdxTooltipAnimationStatus { 17 | OPEN_STARTED = 'open_started', 18 | OPEN_ENDED = 'open_ended', 19 | CLOSED_STARTED = 'closed_started', 20 | CLOSED_ENDED = 'closed_ended' 21 | } 22 | -------------------------------------------------------------------------------- /apps/radix-docs/src/components/layouts/Announcement.astro: -------------------------------------------------------------------------------- 1 | --- 2 | export interface Props { 3 | title: string; 4 | href?: string; 5 | } 6 | 7 | const { title, href } = Astro.props; 8 | --- 9 | 10 | 14 | 🎉{' '} 15 |
    {' '} 16 | {title} 17 | 18 |
    19 | -------------------------------------------------------------------------------- /apps/radix-docs/src/demos/components/kbd/kbd-demo.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { RdxKbdComponent } from '@radix-ng/components/kbd'; 3 | import { RdxThemeDirective } from '@radix-ng/components/theme'; 4 | 5 | @Component({ 6 | selector: 'kbd-demo', 7 | standalone: true, 8 | imports: [RdxThemeDirective, RdxKbdComponent], 9 | template: ` 10 |
    11 | Shift + Tab 12 |
    13 | ` 14 | }) 15 | export class KbdComponent {} 16 | 17 | export default KbdComponent; 18 | -------------------------------------------------------------------------------- /packages/primitives/alert-dialog/src/alert-dialog-cancel.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, inject } from '@angular/core'; 2 | import { RdxAlertDialogService } from './alert-dialog.service'; 3 | 4 | @Directive({ 5 | selector: '[rdxAlertDialogCancel]', 6 | standalone: true, 7 | host: { 8 | '(click)': 'onClick()' 9 | } 10 | }) 11 | export class RdxAlertDialogCancelDirective { 12 | private readonly alertDialogService = inject(RdxAlertDialogService); 13 | 14 | onClick() { 15 | this.alertDialogService.close(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/primitives/hover-card/src/hover-card.types.ts: -------------------------------------------------------------------------------- 1 | export enum RdxHoverCardState { 2 | OPEN = 'open', 3 | CLOSED = 'closed' 4 | } 5 | 6 | export enum RdxHoverCardAction { 7 | OPEN = 'open', 8 | CLOSE = 'close' 9 | } 10 | 11 | export enum RdxHoverCardAttachDetachEvent { 12 | ATTACH = 'attach', 13 | DETACH = 'detach' 14 | } 15 | 16 | export enum RdxHoverCardAnimationStatus { 17 | OPEN_STARTED = 'open_started', 18 | OPEN_ENDED = 'open_ended', 19 | CLOSED_STARTED = 'closed_started', 20 | CLOSED_ENDED = 'closed_ended' 21 | } 22 | -------------------------------------------------------------------------------- /packages/components/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@radix-ng/components", 3 | "version": "0.0.51", 4 | "peerDependencies": { 5 | "@angular/common": "^20.2.3", 6 | "@angular/core": "^20.2.3", 7 | "@radix-ng/primitives": "workspace:*", 8 | "classnames": "^2.5.1" 9 | }, 10 | "devDependencies": { 11 | "@radix-ng/primitives": "workspace:*", 12 | "classnames": "^2.5.1" 13 | }, 14 | "scripts": { 15 | "compodoc": "compodoc --config .compodocrc.json" 16 | }, 17 | "sideEffects": false 18 | } 19 | -------------------------------------------------------------------------------- /packages/primitives/alert-dialog/src/alert-dialog-trigger.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, inject } from '@angular/core'; 2 | import { RdxAlertDialogService } from './alert-dialog.service'; 3 | 4 | @Directive({ 5 | selector: '[rdxAlertDialogTrigger]', 6 | standalone: true, 7 | host: { 8 | '(click)': 'handleClick()' 9 | } 10 | }) 11 | export class RdxAlertDialogTriggerDirective { 12 | private readonly alertDialogService = inject(RdxAlertDialogService); 13 | 14 | handleClick() { 15 | this.alertDialogService.open(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/primitives/core/src/is-equal.ts: -------------------------------------------------------------------------------- 1 | import { serialize } from './serialize'; 2 | /** 3 | * Compare two objects using reference equality and stable deep hashing. 4 | * @param {any} object1 First object 5 | * @param {any} object2 Second object 6 | * @return {boolean} true if equal and false if not 7 | */ 8 | export function isEqual(object1: any, object2: any): boolean { 9 | if (object1 === object2) { 10 | return true; 11 | } 12 | if (serialize(object1) === serialize(object2)) { 13 | return true; 14 | } 15 | return false; 16 | } 17 | -------------------------------------------------------------------------------- /.github/workflows/chromatic.yml: -------------------------------------------------------------------------------- 1 | name: 'Chromatic' 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | chromatic-deployment: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout repository 13 | uses: actions/checkout@v4 14 | with: 15 | fetch-depth: 0 16 | 17 | - uses: ./.github/actions/setup 18 | 19 | - name: Run Chromatic 20 | uses: chromaui/action@latest 21 | with: 22 | projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} 23 | exitZeroOnChanges: true 24 | -------------------------------------------------------------------------------- /apps/radix-docs/src/demos/components/code/code-demo.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { RdxCodeComponent } from '@radix-ng/components/code'; 3 | import { RdxThemeDirective } from '@radix-ng/components/theme'; 4 | 5 | @Component({ 6 | selector: 'kbd-demo', 7 | standalone: true, 8 | imports: [RdxThemeDirective, RdxCodeComponent], 9 | template: ` 10 |
    11 | console.log() 12 |
    13 | ` 14 | }) 15 | export class CodeComponent {} 16 | 17 | export default CodeComponent; 18 | -------------------------------------------------------------------------------- /apps/radix-docs/src/demos/components/switch/switch-demo.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { RdxThemeSwitchComponent } from '@radix-ng/components/switch'; 3 | import { RdxThemeDirective } from '@radix-ng/components/theme'; 4 | 5 | @Component({ 6 | selector: 'switch-demo', 7 | standalone: true, 8 | imports: [RdxThemeSwitchComponent], 9 | hostDirectives: [RdxThemeDirective], 10 | template: ` 11 | 12 | ` 13 | }) 14 | export class SwitchComponent {} 15 | 16 | export default SwitchComponent; 17 | -------------------------------------------------------------------------------- /packages/primitives/select/src/select-item-indicator.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, inject } from '@angular/core'; 2 | import { RdxSelectItemDirective } from './select-item.directive'; 3 | 4 | @Directive({ 5 | selector: '[rdxSelectItemIndicator]', 6 | standalone: true, 7 | exportAs: 'rdxSelectItemIndicator', 8 | host: { 9 | '[attr.aria-hidden]': 'true', 10 | '[style.display]': 'item.selected ? "" : "none"' 11 | } 12 | }) 13 | export class RdxSelectItemIndicatorDirective { 14 | protected item = inject(RdxSelectItemDirective); 15 | } 16 | -------------------------------------------------------------------------------- /apps/radix-docs/src/demos/primitives/collapsible/attrs.ts: -------------------------------------------------------------------------------- 1 | export const attrDataRoot = [ 2 | { name: '[data-state]', value: '"open" | "closed"' }, 3 | { name: '[data-disabled]', value: 'Present when disabled' } 4 | ]; 5 | 6 | export const attrDataTrigger = [ 7 | { name: '[data-state]', value: '"open" | "closed"' }, 8 | { name: '[data-disabled]', value: 'Present when disabled' } 9 | ]; 10 | 11 | export const attrDataContent = [ 12 | { name: '[data-state]', value: '"open" | "closed"' }, 13 | { name: '[data-disabled]', value: 'Present when disabled' } 14 | ]; 15 | -------------------------------------------------------------------------------- /apps/radix-ssr-testing/src/app/components/avatar/page.ts: -------------------------------------------------------------------------------- 1 | import { ChangeDetectionStrategy, Component } from '@angular/core'; 2 | import { RdxAvatarFallbackDirective, RdxAvatarRootDirective } from '@radix-ng/primitives/avatar'; 3 | 4 | @Component({ 5 | selector: 'app-avatar', 6 | changeDetection: ChangeDetectionStrategy.OnPush, 7 | imports: [RdxAvatarRootDirective, RdxAvatarFallbackDirective], 8 | template: ` 9 | 10 | A 11 | 12 | ` 13 | }) 14 | export default class Page {} 15 | -------------------------------------------------------------------------------- /apps/radix-docs/src/content/themes/typography/kbd.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Kbd 3 | slug: kbd 4 | section: typography 5 | description: description 6 | --- 7 | 8 | # Kbd 9 | 10 | Represents keyboard input or a hotkey. 11 | 12 | 13 | 14 | [//]: # (## API Reference) 15 | 16 | [//]: # () 17 | [//]: # () 18 | 19 | ## Examples 20 | 21 | ### Sizes 22 | Use the `size` prop to control text size. 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /packages/primitives/context-menu/src/context-menu-item-indicator.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, inject } from '@angular/core'; 2 | import { RdxContextMenuSelectable } from './context-menu-item-selectable'; 3 | 4 | @Directive({ 5 | selector: '[rdxContextMenuItemIndicator]', 6 | standalone: true, 7 | host: { 8 | '[style.display]': "item.checked ? 'block' : 'none'", 9 | '[attr.data-state]': "item.checked ? 'checked' : 'unchecked'" 10 | } 11 | }) 12 | export class RdxContextMenuItemIndicatorDirective { 13 | item = inject(RdxContextMenuSelectable); 14 | } 15 | -------------------------------------------------------------------------------- /packages/primitives/dropdown-menu/src/dropdown-menu-item-indicator.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, inject } from '@angular/core'; 2 | import { RdxDropdownMenuSelectable } from './dropdown-menu-item-selectable'; 3 | 4 | @Directive({ 5 | selector: '[rdxDropdownMenuItemIndicator]', 6 | standalone: true, 7 | host: { 8 | '[style.display]': "item.checked ? 'block' : 'none'", 9 | '[attr.data-state]': "item.checked ? 'checked' : 'unchecked'" 10 | } 11 | }) 12 | export class RdxDropdownMenuItemIndicatorDirective { 13 | item = inject(RdxDropdownMenuSelectable); 14 | } 15 | -------------------------------------------------------------------------------- /packages/primitives/popover/src/popover-root.inject.ts: -------------------------------------------------------------------------------- 1 | import { assertInInjectionContext, inject, isDevMode } from '@angular/core'; 2 | import { RdxPopoverRootDirective } from './popover-root.directive'; 3 | 4 | export function injectPopoverRoot(optional?: false): RdxPopoverRootDirective; 5 | export function injectPopoverRoot(optional: true): RdxPopoverRootDirective | null; 6 | export function injectPopoverRoot(optional = false): RdxPopoverRootDirective | null { 7 | isDevMode() && assertInInjectionContext(injectPopoverRoot); 8 | return inject(RdxPopoverRootDirective, { optional }); 9 | } 10 | -------------------------------------------------------------------------------- /packages/primitives/slider/src/slider-track.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, inject } from '@angular/core'; 2 | import { RdxSliderRootComponent } from './slider-root.component'; 3 | 4 | @Component({ 5 | selector: 'rdx-slider-track', 6 | host: { 7 | '[attr.data-disabled]': "rootContext.disabled() ? '' : undefined", 8 | '[attr.data-orientation]': 'rootContext.orientation()' 9 | }, 10 | template: ` 11 | 12 | ` 13 | }) 14 | export class RdxSliderTrackComponent { 15 | protected readonly rootContext = inject(RdxSliderRootComponent); 16 | } 17 | -------------------------------------------------------------------------------- /packages/primitives/tooltip/src/tooltip-root.inject.ts: -------------------------------------------------------------------------------- 1 | import { assertInInjectionContext, inject, isDevMode } from '@angular/core'; 2 | import { RdxTooltipRootDirective } from './tooltip-root.directive'; 3 | 4 | export function injectTooltipRoot(optional?: false): RdxTooltipRootDirective; 5 | export function injectTooltipRoot(optional: true): RdxTooltipRootDirective | null; 6 | export function injectTooltipRoot(optional = false): RdxTooltipRootDirective | null { 7 | isDevMode() && assertInInjectionContext(injectTooltipRoot); 8 | return inject(RdxTooltipRootDirective, { optional }); 9 | } 10 | -------------------------------------------------------------------------------- /packages/primitives/tooltip2/src/tooltip-arrow.ts: -------------------------------------------------------------------------------- 1 | import { Directive, inject } from '@angular/core'; 2 | import { RdxPopperArrow } from '@radix-ng/primitives/popper'; 3 | import { RdxVisuallyHiddenDirective } from '@radix-ng/primitives/visually-hidden'; 4 | 5 | @Directive({ 6 | selector: '[rdxTooltipArrow]', 7 | hostDirectives: [RdxPopperArrow], 8 | host: { 9 | '[hidden]': 'isVisuallyHidden' 10 | } 11 | }) 12 | export class RdxTooltipArrow { 13 | protected readonly isVisuallyHidden = !!inject(RdxVisuallyHiddenDirective, { 14 | optional: true 15 | }); 16 | } 17 | -------------------------------------------------------------------------------- /packages/primitives/toolbar/src/toolbar-link.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | import { RdxRovingFocusItemDirective } from '@radix-ng/primitives/roving-focus'; 3 | 4 | @Directive({ 5 | selector: '[rdxToolbarLink]', 6 | hostDirectives: [{ directive: RdxRovingFocusItemDirective, inputs: ['focusable'] }], 7 | host: { 8 | '(keydown)': 'onKeyDown($event)' 9 | } 10 | }) 11 | export class RdxToolbarLinkDirective { 12 | onKeyDown($event: KeyboardEvent) { 13 | if ($event.key === ' ') ($event.currentTarget as HTMLElement)?.click(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /apps/radix-docs/src/contributors.ts: -------------------------------------------------------------------------------- 1 | import contributorNames from './contributor-names.json'; 2 | 3 | export type Contributor = { 4 | name: string; 5 | avatar: string; 6 | }; 7 | 8 | const contributorsAvatars: Record = {}; 9 | 10 | function getAvatarUrl(name: string) { 11 | return `https://github.com/${name}.png`; 12 | } 13 | 14 | export const contributors = (contributorNames as string[]).reduce((acc, name) => { 15 | contributorsAvatars[name] = getAvatarUrl(name); 16 | acc.push({ name, avatar: contributorsAvatars[name] }); 17 | return acc; 18 | }, [] as Contributor[]); 19 | -------------------------------------------------------------------------------- /packages/primitives/core/src/window.ts: -------------------------------------------------------------------------------- 1 | import { inject, InjectionToken } from '@angular/core'; 2 | import { injectDocument } from './document'; 3 | 4 | export const WINDOW = new InjectionToken('An abstraction over global window object', { 5 | factory: () => { 6 | const { defaultView } = injectDocument(); 7 | if (!defaultView) { 8 | throw new Error('Window is not available'); 9 | } 10 | return defaultView; 11 | } 12 | }); 13 | 14 | export function injectWindow(): Window & typeof globalThis { 15 | return inject(WINDOW); 16 | } 17 | -------------------------------------------------------------------------------- /apps/radix-docs/src/content/themes/utilities/theme.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Theme 3 | slug: theme 4 | section: utilities 5 | description: description 6 | --- 7 | 8 | # Theme 9 | 10 | Wraps all or part of a Angular to provide theme configuration. 11 | 12 | ## API Reference 13 | 14 | 15 | ## Examples 16 | 17 | ### Basic configuration 18 | Wrap a component tree in the `Theme` component to provide or modify configuration for all children. 19 | 20 | 21 | 22 | ### Nesting 23 | Nest another theme to modify configuration for a specific subtree. Configuration is inherited from the parent. 24 | 25 | -------------------------------------------------------------------------------- /packages/primitives/calendar/src/calendar-heading.directive.ts: -------------------------------------------------------------------------------- 1 | import { computed, Directive } from '@angular/core'; 2 | import { injectCalendarRootContext } from './сalendar-сontext.token'; 3 | 4 | @Directive({ 5 | selector: 'div[rdxCalendarHeading]', 6 | exportAs: 'rdxCalendarHeading', 7 | host: { 8 | '[attr.data-disabled]': 'rootContext.disabled() ? "" : undefined' 9 | } 10 | }) 11 | export class RdxCalendarHeadingDirective { 12 | protected readonly rootContext = injectCalendarRootContext(); 13 | 14 | readonly headingValue = computed(() => this.rootContext.headingValue()); 15 | } 16 | -------------------------------------------------------------------------------- /apps/radix-docs/src/demos/primitives/progress/progress-demo.css: -------------------------------------------------------------------------------- 1 | .ProgressRoot { 2 | position: relative; 3 | overflow: hidden; 4 | background: var(--black-a9); 5 | border-radius: 99999px; 6 | width: 220px; 7 | display: flex; 8 | height: 25px; 9 | 10 | /* Fix overflow clipping in Safari */ 11 | /* https://gist.github.com/domske/b66047671c780a238b51c51ffde8d3a0 */ 12 | transform: translateZ(0); 13 | } 14 | 15 | .ProgressIndicator { 16 | background-color: white; 17 | width: 100%; 18 | height: 100%; 19 | transition: transform 660ms cubic-bezier(0.65, 0, 0.35, 1); 20 | } 21 | -------------------------------------------------------------------------------- /apps/radix-docs/src/types/index.ts: -------------------------------------------------------------------------------- 1 | import type { MarkdownHeading } from 'astro'; 2 | 3 | export interface Page { 4 | name: string; 5 | url: string; 6 | label?: string; 7 | external?: boolean; 8 | } 9 | 10 | export interface Section { 11 | section: string; 12 | pages: Page[]; 13 | } 14 | 15 | export interface NavigationItem { 16 | name: string; 17 | section: string; 18 | sections: Section[]; 19 | } 20 | 21 | export interface SiteConfig { 22 | navigation: NavigationItem[]; 23 | } 24 | 25 | export interface TocItem extends MarkdownHeading { 26 | children: TocItem[]; 27 | } 28 | -------------------------------------------------------------------------------- /packages/primitives/checkbox/src/checkbox-indicator.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | import { injectCheckboxRootContext } from './checkbox-root'; 3 | 4 | @Directive({ 5 | selector: '[rdxCheckboxIndicator]', 6 | host: { 7 | '[attr.data-state]': 'rootContext.state()', 8 | '[attr.data-disabled]': 'rootContext.disabled() ? "" : undefined', 9 | '[hidden]': '!rootContext.checked()', 10 | '[style.pointer-events]': '"none"' 11 | } 12 | }) 13 | export class RdxCheckboxIndicatorDirective { 14 | protected readonly rootContext = injectCheckboxRootContext()!; 15 | } 16 | -------------------------------------------------------------------------------- /packages/primitives/date-field/index.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RdxDateFieldInputDirective } from './src/date-field-input.directive'; 3 | import { RdxDateFieldRootDirective } from './src/date-field-root.directive'; 4 | 5 | export * from './src/date-field-context.token'; 6 | export * from './src/date-field-input.directive'; 7 | export * from './src/date-field-root.directive'; 8 | 9 | const _imports = [RdxDateFieldRootDirective, RdxDateFieldInputDirective]; 10 | 11 | @NgModule({ 12 | imports: [..._imports], 13 | exports: [..._imports] 14 | }) 15 | export class RdxDateFieldModule {} 16 | -------------------------------------------------------------------------------- /packages/primitives/time-field/index.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RdxTimeFieldInputDirective } from './src/time-field-input.directive'; 3 | import { RdxTimeFieldRootDirective } from './src/time-field-root.directive'; 4 | 5 | export * from './src/time-field-context.token'; 6 | export * from './src/time-field-input.directive'; 7 | export * from './src/time-field-root.directive'; 8 | 9 | const _imports = [RdxTimeFieldRootDirective, RdxTimeFieldInputDirective]; 10 | 11 | @NgModule({ 12 | imports: [..._imports], 13 | exports: [..._imports] 14 | }) 15 | export class RdxTimeFieldModule {} 16 | -------------------------------------------------------------------------------- /packages/primitives/toolbar/src/toolbar-root.token.ts: -------------------------------------------------------------------------------- 1 | import { inject, InjectionToken, Provider } from '@angular/core'; 2 | import { RdxToolbarRootDirective } from './toolbar-root.directive'; 3 | 4 | export const RDX_TOOLBAR_ROOT_TOKEN = new InjectionToken('RdxToolbarRootDirective'); 5 | 6 | export function injectRootContext(): RdxToolbarRootDirective { 7 | return inject(RDX_TOOLBAR_ROOT_TOKEN); 8 | } 9 | 10 | export function provideRootContext(): Provider { 11 | return { 12 | provide: RDX_TOOLBAR_ROOT_TOKEN, 13 | useExisting: RdxToolbarRootDirective 14 | }; 15 | } 16 | -------------------------------------------------------------------------------- /apps/radix-docs/src/demos/primitives/label/label-demo.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | import { RdxLabelDirective } from '@radix-ng/primitives/label'; 4 | 5 | @Component({ 6 | selector: 'primitive-label-demo', 7 | standalone: true, 8 | imports: [RdxLabelDirective], 9 | template: ` 10 | 11 | 12 | `, 13 | styleUrl: 'label-demo.css' 14 | }) 15 | export class LabelDemoComponent {} 16 | 17 | export default LabelDemoComponent; 18 | -------------------------------------------------------------------------------- /packages/primitives/hover-card/src/hover-card-root.inject.ts: -------------------------------------------------------------------------------- 1 | import { assertInInjectionContext, inject, isDevMode } from '@angular/core'; 2 | import { RdxHoverCardRootDirective } from './hover-card-root.directive'; 3 | 4 | export function injectHoverCardRoot(optional?: false): RdxHoverCardRootDirective; 5 | export function injectHoverCardRoot(optional: true): RdxHoverCardRootDirective | null; 6 | export function injectHoverCardRoot(optional = false): RdxHoverCardRootDirective | null { 7 | isDevMode() && assertInInjectionContext(injectHoverCardRoot); 8 | return inject(RdxHoverCardRootDirective, { optional }); 9 | } 10 | -------------------------------------------------------------------------------- /packages/primitives/switch/src/switch-thumb.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | import { injectSwitchRootContext } from './switch-root.directive'; 3 | 4 | /** 5 | * @group Components 6 | */ 7 | @Directive({ 8 | selector: 'span[rdxSwitchThumb]', 9 | exportAs: 'rdxSwitchThumb', 10 | host: { 11 | '[attr.data-disabled]': 'rootContext?.disabled() ? "" : undefined', 12 | '[attr.data-state]': 'rootContext?.checked() ? "checked" : "unchecked"' 13 | } 14 | }) 15 | export class RdxSwitchThumbDirective { 16 | protected readonly rootContext = injectSwitchRootContext(); 17 | } 18 | -------------------------------------------------------------------------------- /apps/radix-ssr-testing/src/app/app.config.ts: -------------------------------------------------------------------------------- 1 | import { ApplicationConfig, provideBrowserGlobalErrorListeners, provideZonelessChangeDetection } from '@angular/core'; 2 | import { provideClientHydration, withEventReplay } from '@angular/platform-browser'; 3 | import { provideRouter } from '@angular/router'; 4 | import { appRoutes } from './app.routes'; 5 | 6 | export const appConfig: ApplicationConfig = { 7 | providers: [ 8 | provideBrowserGlobalErrorListeners(), 9 | provideZonelessChangeDetection(), 10 | provideRouter(appRoutes), 11 | provideClientHydration(withEventReplay()) 12 | ] 13 | }; 14 | -------------------------------------------------------------------------------- /apps/radix-ssr-testing/src/app/components/toggle-group/page.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { RdxToggleGroupDirective, RdxToggleGroupItemDirective } from '@radix-ng/primitives/toggle-group'; 3 | 4 | @Component({ 5 | selector: 'app-toggle-group', 6 | imports: [RdxToggleGroupDirective, RdxToggleGroupItemDirective], 7 | template: ` 8 |
    9 | 10 | 11 |
    12 | ` 13 | }) 14 | export default class Page {} 15 | -------------------------------------------------------------------------------- /apps/radix-storybook/.storybook/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "emitDecoratorMetadata": true, 5 | "resolveJsonModule": true 6 | }, 7 | "exclude": ["../**/*.spec.ts"], 8 | "include": [ 9 | "../../../packages/primitives/**/*.stories.ts", 10 | "../../../packages/primitives/**/*.stories.tsx", 11 | "../../../packages/primitives/**/*.stories.mdx", 12 | "../../../packages/primitives/**/*.directive.ts", 13 | "../../../packages/primitives/**/*.component.ts", 14 | "*.ts", 15 | "*.tsx" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /apps/radix-docs/src/components/mdx/TabsTrigger.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { cn } from '@/utils/utils'; 3 | import { TabsTrigger as TabsComponent } from '../tabs'; 4 | 5 | const { class: className, ...rest } = Astro.props; 6 | --- 7 | 8 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /apps/radix-storybook/.storybook/themes.ts: -------------------------------------------------------------------------------- 1 | import { create } from 'storybook/theming'; 2 | 3 | export const brand = { 4 | brandTitle: 'Radix Angular', 5 | brandUrl: 'https://github.com/radix-ng/primitives', 6 | brandTarget: '_blank', 7 | fontBase: "Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;", 8 | fontCode: "'JetBrains Mono', 'Roboto Mono', 'Consolas', 'Menlo', 'Monaco', monospace;" 9 | }; 10 | 11 | export const light = create({ 12 | ...brand, 13 | base: 'light' 14 | }); 15 | 16 | export const dark = create({ 17 | ...brand, 18 | base: 'dark' 19 | }); 20 | -------------------------------------------------------------------------------- /packages/primitives/dialog/src/dialog.injectors.ts: -------------------------------------------------------------------------------- 1 | import { DIALOG_DATA } from '@angular/cdk/dialog'; 2 | import { inject } from '@angular/core'; 3 | import { RdxDialogRef, RdxDialogSelfRef } from './dialog-ref'; 4 | import { ɵDialogDataFlag, ɵDialogResultFlag } from './dialog.config'; 5 | 6 | export function injectDialogData(): TData & ɵDialogDataFlag { 7 | return inject(DIALOG_DATA); 8 | } 9 | 10 | export function injectDialogRef(): RdxDialogSelfRef & ɵDialogResultFlag { 11 | return inject>(RdxDialogRef) as RdxDialogSelfRef & ɵDialogResultFlag; 12 | } 13 | -------------------------------------------------------------------------------- /packages/primitives/navigation-menu/src/navigation-menu.types.ts: -------------------------------------------------------------------------------- 1 | import { FocusableOption } from '@angular/cdk/a11y'; 2 | 3 | export enum RdxNavigationMenuAnimationStatus { 4 | OPEN_STARTED = 'open_started', 5 | OPEN_ENDED = 'open_ended', 6 | CLOSED_STARTED = 'closed_started', 7 | CLOSED_ENDED = 'closed_ended' 8 | } 9 | 10 | /** 11 | * A stub class solely used to query a single type of focusable element in the navigation menu. 12 | */ 13 | export abstract class RdxNavigationMenuFocusableOption implements FocusableOption { 14 | focus(): void { 15 | throw new Error('Method not implemented.'); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/components/.storybook/main.ts: -------------------------------------------------------------------------------- 1 | import type { StorybookConfig } from '@storybook/angular'; 2 | 3 | const config: StorybookConfig = { 4 | stories: ['../**/*.docs.mdx', '../**/*.stories.@(js|ts)'], 5 | 6 | addons: [ 7 | '@storybook/addon-essentials', 8 | '@storybook/addon-docs', 9 | '@storybook/addon-backgrounds', 10 | '@chromatic-com/storybook' 11 | ], 12 | 13 | framework: { 14 | name: '@storybook/angular', 15 | options: {} 16 | }, 17 | 18 | core: { 19 | disableTelemetry: false 20 | }, 21 | 22 | docs: {} 23 | }; 24 | 25 | export default config; 26 | -------------------------------------------------------------------------------- /packages/primitives/avatar/src/avatar-root.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, signal } from '@angular/core'; 2 | import { provideToken } from '@radix-ng/primitives/core'; 3 | import { AVATAR_ROOT_CONTEXT, AvatarContextToken } from './avatar-context.token'; 4 | import { RdxImageLoadingStatus } from './types'; 5 | 6 | @Directive({ 7 | selector: 'span[rdxAvatarRoot]', 8 | exportAs: 'rdxAvatarRoot', 9 | providers: [provideToken(AVATAR_ROOT_CONTEXT, RdxAvatarRootDirective)] 10 | }) 11 | export class RdxAvatarRootDirective implements AvatarContextToken { 12 | readonly imageLoadingStatus = signal('loading'); 13 | } 14 | -------------------------------------------------------------------------------- /packages/primitives/presence/src/types.ts: -------------------------------------------------------------------------------- 1 | import { Subject } from 'rxjs'; 2 | 3 | type TransitionOptions = { 4 | context?: T; 5 | animation: boolean; 6 | state?: 'continue' | 'stop'; 7 | transitionTimerDelayMs?: number; 8 | }; 9 | 10 | type TransitionContext = { 11 | transition$: Subject; 12 | complete: () => void; 13 | context: T; 14 | }; 15 | 16 | type TransitionStartFn = (element: HTMLElement, animation: boolean, context: T) => TransitionEndFn | void; 17 | 18 | type TransitionEndFn = () => void; 19 | 20 | export { TransitionContext, TransitionEndFn, TransitionOptions, TransitionStartFn }; 21 | -------------------------------------------------------------------------------- /apps/radix-docs/src/components/code-editor/example-app/main.ts: -------------------------------------------------------------------------------- 1 | export const main_ts = ( 2 | componentName: string, 3 | selector: string 4 | ): string => `import { bootstrapApplication } from '@angular/platform-browser'; 5 | import { ${componentName} } from './app/${selector}'; 6 | import { provideAnimationsAsync } from '@angular/platform-browser/animations/async'; 7 | import { ApplicationConfig } from '@angular/core'; 8 | 9 | export const appConfig: ApplicationConfig = { 10 | providers: [ 11 | provideAnimationsAsync(), 12 | ], 13 | }; 14 | 15 | bootstrapApplication(${componentName}, appConfig).catch((err) =>console.error(err));`; 16 | -------------------------------------------------------------------------------- /packages/primitives/progress/index.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RdxProgressIndicatorDirective } from './src/progress-indicator.directive'; 3 | import { RdxProgressRootDirective } from './src/progress-root.directive'; 4 | 5 | export * from './src/progress-indicator.directive'; 6 | export * from './src/progress-root.directive'; 7 | 8 | export type { ProgressProps } from './src/progress-root.directive'; 9 | 10 | const _imports = [RdxProgressRootDirective, RdxProgressIndicatorDirective]; 11 | 12 | @NgModule({ 13 | imports: [..._imports], 14 | exports: [..._imports] 15 | }) 16 | export class RdxProgressModule {} 17 | -------------------------------------------------------------------------------- /packages/primitives/toggle/src/toggle-visually-hidden-input.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | import { RdxVisuallyHiddenInputDirective } from '@radix-ng/primitives/visually-hidden'; 3 | 4 | @Directive({ 5 | selector: 'input[rdxToggleVisuallyHiddenInput]', 6 | exportAs: 'rdxToggleVisuallyHiddenInput', 7 | hostDirectives: [ 8 | { 9 | directive: RdxVisuallyHiddenInputDirective, 10 | inputs: ['name', 'required', 'value', 'disabled'] 11 | } 12 | ], 13 | host: { 14 | type: 'checkbox' 15 | } 16 | }) 17 | export class RdxToggleVisuallyHiddenInputDirective {} 18 | -------------------------------------------------------------------------------- /packages/primitives/tooltip2/src/tooltip-portal-presence.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | import { provideRdxPresenceContext, RdxPresenceDirective } from '@radix-ng/primitives/presence'; 3 | import { injectRdxTooltipContext } from './tooltip'; 4 | 5 | @Directive({ 6 | selector: 'ng-template[rdxTooltipPortalPresence]', 7 | hostDirectives: [RdxPresenceDirective], 8 | providers: [ 9 | provideRdxPresenceContext(() => { 10 | const context = injectRdxTooltipContext()!; 11 | 12 | return { present: context.isOpen }; 13 | }) 14 | ] 15 | }) 16 | export class RdxTooltipPortalPresence {} 17 | -------------------------------------------------------------------------------- /apps/radix-docs/src/content/primitives/components/separator.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Separator 3 | slug: separator 4 | section: components 5 | description: . 6 | --- 7 | 8 | # Separator 9 | 10 | Visually or semantically separates content. 11 | 12 | 13 | 14 | 15 | 16 | ## Anatomy 17 | 18 | ```html 19 |
    20 | ``` 21 | 22 | ## API Reference 23 | 24 | ### Root 25 | 26 | The separator. 27 | `RdxSeparatorRootDirective` 28 | 29 | -------------------------------------------------------------------------------- /packages/primitives/collapsible/src/collapsible-content-presence.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | import { provideRdxPresenceContext, RdxPresenceDirective } from '@radix-ng/primitives/presence'; 3 | import { injectCollapsibleRootContext } from './collapsible-root.directive'; 4 | 5 | @Directive({ 6 | selector: 'ng-template[rdxCollapsibleContentPresence]', 7 | providers: [ 8 | provideRdxPresenceContext(() => ({ 9 | present: injectCollapsibleRootContext()!.open 10 | })) 11 | ], 12 | hostDirectives: [RdxPresenceDirective] 13 | }) 14 | export class RdxCollapsibleContentPresenceDirective {} 15 | -------------------------------------------------------------------------------- /apps/radix-ssr-testing/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["../../.eslintrc.cjs"], 3 | "ignorePatterns": ["!**/*"], 4 | "overrides": [ 5 | { 6 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], 7 | "rules": {} 8 | }, 9 | { 10 | "files": ["*.ts", "*.tsx"], 11 | "rules": {} 12 | }, 13 | { 14 | "files": ["*.js", "*.jsx"], 15 | "rules": {} 16 | }, 17 | { 18 | "files": ["*.ts"], 19 | "rules": { 20 | "@angular-eslint/prefer-standalone": "off" 21 | } 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /packages/primitives/core/src/chunk.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Splits an array into chunks of a given size. 3 | * @param arr The array to split. 4 | * @param size The size of each chunk. 5 | * @returns An array of arrays, where each sub-array has `size` elements from the original array. 6 | * @example ```ts 7 | * const arr = [1, 2, 3, 4, 5, 6, 7, 8]; 8 | * const chunks = chunk(arr, 3); 9 | * // chunks = [[1, 2, 3], [4, 5, 6], [7, 8]] 10 | * ``` 11 | */ 12 | export function chunk(arr: T[], size: number): T[][] { 13 | const result = []; 14 | for (let i = 0; i < arr.length; i += size) result.push(arr.slice(i, i + size)); 15 | 16 | return result; 17 | } 18 | -------------------------------------------------------------------------------- /packages/primitives/cropper/src/cropper-context.token.ts: -------------------------------------------------------------------------------- 1 | import { inject, InjectionToken, InputSignal, WritableSignal } from '@angular/core'; 2 | 3 | export interface CropperContextToken { 4 | image: InputSignal; 5 | getImageProps: () => { [key: string]: any }; 6 | getImageWrapperStyle: () => Record; 7 | getCropAreaStyle: () => Record; 8 | descriptionId: WritableSignal; 9 | } 10 | 11 | export const CROPPER_ROOT_CONTEXT = new InjectionToken('CROPPER_ROOT_CONTEXT'); 12 | 13 | export function injectCropperRootContext() { 14 | return inject(CROPPER_ROOT_CONTEXT); 15 | } 16 | -------------------------------------------------------------------------------- /packages/primitives/alert-dialog/src/alert-dialog-root.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, inject, Input, TemplateRef, ViewContainerRef } from '@angular/core'; 2 | import { RdxAlertDialogService } from './alert-dialog.service'; 3 | 4 | @Directive({ 5 | selector: '[rdxAlertDialogRoot]', 6 | standalone: true 7 | }) 8 | export class RdxAlertDialogRootDirective { 9 | private readonly viewContainerRef = inject(ViewContainerRef); 10 | private readonly alertDialogService = inject(RdxAlertDialogService); 11 | 12 | @Input() set content(template: TemplateRef) { 13 | this.alertDialogService.setDialogContent(this.viewContainerRef, template); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/primitives/core/src/accessor/provide-value-accessor.ts: -------------------------------------------------------------------------------- 1 | import { forwardRef, Provider, Type } from '@angular/core'; 2 | import { NG_VALUE_ACCESSOR } from '@angular/forms'; 3 | 4 | /** 5 | * Include in the providers section of a component which utilizes ControlValueAccessor to redundant code. 6 | * 7 | * ```ts 8 | * @Directive({ 9 | * providers: [provideValueAccessor(ExampleDirective)] 10 | *} 11 | * export class ExampleDirective{} 12 | * ``` 13 | */ 14 | export function provideValueAccessor(type: Type): Provider { 15 | return { 16 | provide: NG_VALUE_ACCESSOR, 17 | useExisting: forwardRef(() => type), 18 | multi: true 19 | }; 20 | } 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 'Feature request' 3 | about: 'Suggest an idea for a feature or a new component' 4 | --- 5 | 6 | ## Feature request 7 | 8 | ### Overview 9 | 10 | 11 | 12 | ### Examples in other libraries 13 | 14 | 15 | 16 | ### Who does this impact? Who is this for? 17 | 18 | 19 | 20 | ### Additional context 21 | 22 | 23 | -------------------------------------------------------------------------------- /.github/actions/setup/action.yml: -------------------------------------------------------------------------------- 1 | name: Setup environment 2 | description: Setup Node.js environment and install dependencies 3 | 4 | runs: 5 | using: composite 6 | steps: 7 | - name: Setup pnpm 8 | uses: pnpm/action-setup@v4 9 | 10 | - name: Setup Node.js 11 | uses: actions/setup-node@v6 12 | with: 13 | node-version-file: .nvmrc 14 | cache: pnpm 15 | registry-url: 'https://registry.npmjs.org' 16 | 17 | - name: Install dependencies 18 | run: pnpm install --frozen-lockfile 19 | shell: bash 20 | 21 | - uses: nrwl/nx-set-shas@v4 22 | 23 | - name: Print Environment Info 24 | run: npx nx report 25 | shell: bash 26 | -------------------------------------------------------------------------------- /packages/primitives/popper/index.ts: -------------------------------------------------------------------------------- 1 | import { RdxPopper } from './src/popper'; 2 | import { RdxPopperAnchor } from './src/popper-anchor'; 3 | import { RdxPopperArrow } from './src/popper-arrow'; 4 | import { RdxPopperContent } from './src/popper-content'; 5 | import { RdxPopperContentWrapper } from './src/popper-content-wrapper'; 6 | 7 | export * from './src/popper'; 8 | export * from './src/popper-anchor'; 9 | export * from './src/popper-arrow'; 10 | export * from './src/popper-content'; 11 | export * from './src/popper-content-wrapper'; 12 | export * from './src/utils'; 13 | 14 | export const popperImports = [RdxPopper, RdxPopperArrow, RdxPopperContentWrapper, RdxPopperContent, RdxPopperAnchor]; 15 | -------------------------------------------------------------------------------- /packages/primitives/switch/index.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RdxSwitchInputDirective } from './src/switch-input.directive'; 3 | import { RdxSwitchRootDirective } from './src/switch-root.directive'; 4 | import { RdxSwitchThumbDirective } from './src/switch-thumb.directive'; 5 | 6 | export * from './src/switch-input.directive'; 7 | export * from './src/switch-root.directive'; 8 | export * from './src/switch-thumb.directive'; 9 | 10 | const switchImports = [RdxSwitchRootDirective, RdxSwitchInputDirective, RdxSwitchThumbDirective]; 11 | 12 | @NgModule({ 13 | imports: [...switchImports], 14 | exports: [...switchImports] 15 | }) 16 | export class RdxSwitchModule {} 17 | -------------------------------------------------------------------------------- /apps/radix-docs/src/content/primitives/components/aspect-ratio.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Aspect Ratio 3 | slug: aspect-ratio 4 | section: components 5 | description: . 6 | --- 7 | 8 | # Aspect Ratio 9 | Displays content within a desired ratio. 10 | 11 | 12 | 13 | 14 | 15 | ## Anatomy 16 | 17 | ```html 18 |
    19 | 20 |
    21 | ``` 22 | 23 | ## API Reference 24 | 25 | ### Root 26 | Contains the content you want to constrain to a given ratio. 27 | 28 | `RdxAspectRatioDirective` 29 | 30 | -------------------------------------------------------------------------------- /packages/primitives/radio/src/radio-tokens.ts: -------------------------------------------------------------------------------- 1 | import { BooleanInput } from '@angular/cdk/coercion'; 2 | import { InjectionToken, InputSignalWithTransform, ModelSignal, Signal } from '@angular/core'; 3 | 4 | export interface RadioGroupProps { 5 | name?: string; 6 | disabled?: InputSignalWithTransform; 7 | defaultValue?: string; 8 | value: ModelSignal; 9 | disableState: Signal; 10 | } 11 | 12 | export interface RadioGroupDirective extends RadioGroupProps { 13 | select(value: string | null): void; 14 | 15 | onTouched(): void; 16 | } 17 | 18 | export const RDX_RADIO_GROUP = new InjectionToken('RdxRadioGroup'); 19 | -------------------------------------------------------------------------------- /tools/scripts/api-doc/constants.mjs: -------------------------------------------------------------------------------- 1 | export const staticMessages = { 2 | methods: "Defines methods that can be accessed by the component's reference.", 3 | emits: 'Defines emit that determine the behavior of the component based on a given condition or report the actions that the component takes.', 4 | events: "Defines the custom events used by the component's emitters.", 5 | interfaces: 'Defines the custom interfaces used by the module.', 6 | types: 'Defines the custom types used by the module.', 7 | props: 'Defines the input properties of the component.', 8 | service: 'Defines the service used by the component', 9 | classes: 'List of class names used in the styled mode.' 10 | }; 11 | -------------------------------------------------------------------------------- /packages/components/types/index.ts: -------------------------------------------------------------------------------- 1 | export type ResponsiveSize = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9; 2 | 3 | export type Variant = 'solid' | 'soft'; 4 | 5 | export type radii = 'none' | 'small' | 'medium' | 'large' | 'full'; 6 | 7 | export type RadixColor = 8 | | 'gray' 9 | | 'gold' 10 | | 'bronze' 11 | | 'brown' 12 | | 'yellow' 13 | | 'amber' 14 | | 'orange' 15 | | 'tomato' 16 | | 'red' 17 | | 'ruby' 18 | | 'crimson' 19 | | 'pink' 20 | | 'plum' 21 | | 'purple' 22 | | 'violet' 23 | | 'iris' 24 | | 'indigo' 25 | | 'blue' 26 | | 'cyan' 27 | | 'teal' 28 | | 'jade' 29 | | 'green' 30 | | 'grass' 31 | | 'lime' 32 | | 'mint'; 33 | -------------------------------------------------------------------------------- /apps/radix-docs/src/content/themes/components/switch.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Switch 3 | slug: switch 4 | Description: Toggle switch alternative to the checkbox. 5 | section: components 6 | --- 7 | # Switch 8 | 9 | Toggle switch alternative to the checkbox. 10 | 11 | 12 | 13 | ## API Reference 14 | 15 | 16 | ## Examples 17 | 18 | ### Size 19 | 20 | Use the `size` prop to control the size of the switch. 21 | 22 | 23 | 24 | ### Radius 25 | 26 | Use the `radius` prop to assign a specific radius value. 27 | 28 | 29 | -------------------------------------------------------------------------------- /packages/primitives/editable/src/editable-submit-trigger.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | import { injectEditableRootContext } from './editable-root'; 3 | 4 | @Directive({ 5 | selector: 'button[rdxEditableSubmitTrigger]', 6 | host: { 7 | type: 'button', 8 | '[attr.aria-label]': '"submit"', 9 | '[attr.aria-disabled]': 'rootContext?.disabled() ? "" : undefined', 10 | '[attr.data-disabled]': 'rootContext?.disabled() ? "" : undefined', 11 | '[disabled]': 'rootContext?.disabled()', 12 | '(click)': 'rootContext?.submit()' 13 | } 14 | }) 15 | export class RdxEditableSubmitTrigger { 16 | protected readonly rootContext = injectEditableRootContext(); 17 | } 18 | -------------------------------------------------------------------------------- /apps/radix-docs/src/components/layouts/DemoNoopContainer.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { DemoLoaderComponent } from '../demo-primitive-preview/demo-loader.component'; 3 | export interface Props { 4 | componentName?: 5 | | 'accordion' 6 | | 'avatar' 7 | | 'alert-dialog' 8 | | 'checkbox' 9 | | 'progress' 10 | | 'collapsible' 11 | | 'dropdown-menu' 12 | | 'default'; 13 | componentFile?: string; 14 | overflow?: boolean; 15 | } 16 | 17 | const { componentName, componentFile } = Astro.props; 18 | --- 19 | 20 |
    21 | 22 |
    23 | -------------------------------------------------------------------------------- /apps/radix-docs/src/components/tabs/TabsTrigger.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { cn } from '@/utils/utils'; 3 | 4 | export interface Props { 5 | class?: string; 6 | } 7 | --- 8 | 9 | 20 | -------------------------------------------------------------------------------- /packages/primitives/accordion/src/accordion-header.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | import { injectAccordionItemContext } from './accordion-item.directive'; 3 | import { injectAccordionRootContext } from './accordion-root.directive'; 4 | 5 | @Directive({ 6 | selector: '[rdxAccordionHeader]', 7 | host: { 8 | '[attr.data-state]': 'itemContext.dataState()', 9 | '[attr.data-disabled]': 'itemContext.dataDisabled()', 10 | '[attr.data-orientation]': 'rootContext.orientation()' 11 | } 12 | }) 13 | export class RdxAccordionHeaderDirective { 14 | protected readonly rootContext = injectAccordionRootContext()!; 15 | protected readonly itemContext = injectAccordionItemContext()!; 16 | } 17 | -------------------------------------------------------------------------------- /apps/radix-docs/src/components/tabs/Tabs.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { cn } from '@/utils/utils'; 3 | 4 | export interface Props { 5 | class?: string; 6 | } 7 | --- 8 | 9 |
    25 | 26 |
    27 | -------------------------------------------------------------------------------- /apps/radix-docs/src/components/demo-component-preview/ComponentThemesPreview.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { DemoThemesLoaderComponent } from './demo-themes-loader.component'; 3 | 4 | export interface Props { 5 | name: string; 6 | file: string; 7 | } 8 | 9 | const { name, file } = Astro.props; 10 | --- 11 | 12 |
    13 |
    14 |
    15 | 16 |
    17 |
    18 |
    19 |

    Not found

    20 |
    21 |
    22 | -------------------------------------------------------------------------------- /apps/radix-docs/src/demos/primitives/toggle/toggle-demo.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | import { RdxToggleDirective } from '@radix-ng/primitives/toggle'; 4 | import { Italic, LucideAngularModule } from 'lucide-angular'; 5 | 6 | @Component({ 7 | selector: 'primitive-toggle-demo', 8 | standalone: true, 9 | imports: [RdxToggleDirective, LucideAngularModule], 10 | template: ` 11 | 14 | `, 15 | styleUrl: 'toggle-demo.css' 16 | }) 17 | export class ToggleDemoComponent { 18 | protected readonly Italic = Italic; 19 | } 20 | 21 | export default ToggleDemoComponent; 22 | -------------------------------------------------------------------------------- /packages/primitives/checkbox/src/checkbox-indicator-presence.ts: -------------------------------------------------------------------------------- 1 | import { computed, Directive } from '@angular/core'; 2 | import { provideRdxPresenceContext, RdxPresenceDirective } from '@radix-ng/primitives/presence'; 3 | import { injectCheckboxRootContext } from './checkbox-root'; 4 | 5 | @Directive({ 6 | selector: 'ng-template[rdxCheckboxIndicatorPresence]', 7 | providers: [ 8 | provideRdxPresenceContext(() => { 9 | const rootContext = injectCheckboxRootContext()!; 10 | 11 | return { 12 | present: computed(() => !!rootContext.checked()) 13 | }; 14 | }) 15 | ], 16 | hostDirectives: [RdxPresenceDirective] 17 | }) 18 | export class RdxCheckboxIndicatorPresenceDirective {} 19 | -------------------------------------------------------------------------------- /packages/primitives/select/src/select-value.directive.ts: -------------------------------------------------------------------------------- 1 | import { Component, inject, Input } from '@angular/core'; 2 | import { RdxSelectComponent } from './select.component'; 3 | 4 | @Component({ 5 | selector: '[rdxSelectValue]', 6 | standalone: true, 7 | exportAs: 'rdxSelectValue', 8 | template: ` 9 | {{ select.selectionModel.isEmpty() ? placeholder : select.selected }} 10 | `, 11 | styles: ` 12 | /* we don't want events from the children to bubble through the item they came from */ 13 | :host { 14 | pointer-events: none; 15 | } 16 | ` 17 | }) 18 | export class RdxSelectValueDirective { 19 | select = inject(RdxSelectComponent); 20 | 21 | @Input() placeholder: string; 22 | } 23 | -------------------------------------------------------------------------------- /apps/radix-docs/src/demos/components/avatar/avatar-variant-demo.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { RdxThemeAvatarComponent } from '@radix-ng/components/avatar'; 3 | import { RdxThemeDirective } from '@radix-ng/components/theme'; 4 | 5 | @Component({ 6 | selector: 'avatar-variant-demo', 7 | standalone: true, 8 | imports: [RdxThemeAvatarComponent], 9 | hostDirectives: [RdxThemeDirective], 10 | template: ` 11 |
    12 | 13 | 14 |
    15 | ` 16 | }) 17 | export class AvatarVariantComponent {} 18 | 19 | export default AvatarVariantComponent; 20 | -------------------------------------------------------------------------------- /packages/primitives/pagination/src/pagination-context.token.ts: -------------------------------------------------------------------------------- 1 | import { computed, inject, InjectionToken, model } from '@angular/core'; 2 | 3 | export interface PaginationRootContext { 4 | page: ReturnType>; 5 | onPageChange: (value: number) => void; 6 | pageCount: ReturnType>; 7 | siblingCount: ReturnType>; 8 | disabled: ReturnType>; 9 | showEdges: ReturnType>; 10 | } 11 | 12 | export const PAGINATION_ROOT_CONTEXT = new InjectionToken('PaginationRootContext'); 13 | 14 | export function injectPaginationRootContext(): PaginationRootContext { 15 | return inject(PAGINATION_ROOT_CONTEXT); 16 | } 17 | -------------------------------------------------------------------------------- /packages/primitives/toolbar/src/toolbar-root.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, input } from '@angular/core'; 2 | import { RdxRovingFocusGroupDirective } from '@radix-ng/primitives/roving-focus'; 3 | import { provideRootContext } from './toolbar-root.token'; 4 | 5 | @Directive({ 6 | selector: '[rdxToolbarRoot]', 7 | hostDirectives: [{ directive: RdxRovingFocusGroupDirective, inputs: ['dir', 'orientation', 'loop'] }], 8 | providers: [provideRootContext()], 9 | host: { 10 | role: 'toolbar', 11 | '[attr.aria-orientation]': 'orientation()' 12 | } 13 | }) 14 | export class RdxToolbarRootDirective { 15 | readonly orientation = input<'horizontal' | 'vertical'>('horizontal'); 16 | readonly dir = input<'ltr' | 'rtl'>('ltr'); 17 | } 18 | -------------------------------------------------------------------------------- /apps/radix-docs/src/content/primitives/components/select.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Select 3 | slug: select 4 | section: components 5 | description: . 6 | --- 7 | 8 | # Select 9 | 10 | Displays a list of options for the user to pick from—triggered by a button. 11 | 12 | 13 | 14 | 20 | 21 | ## Anatomy 22 | 23 | ```html 24 |
    25 |
    26 |
    27 |
    28 |
    29 | ``` 30 | 31 | ## API Reference 32 | 33 | ### Root 34 | -------------------------------------------------------------------------------- /packages/primitives/radio/src/radio-indicator.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, inject } from '@angular/core'; 2 | import { RdxRadioItemDirective } from './radio-item.directive'; 3 | import { RDX_RADIO_GROUP, RadioGroupDirective } from './radio-tokens'; 4 | 5 | @Directive({ 6 | selector: '[rdxRadioIndicator]', 7 | exportAs: 'rdxRadioIndicator', 8 | host: { 9 | '[attr.data-state]': 'radioItem.checkedState() ? "checked" : "unchecked"', 10 | '[attr.data-disabled]': 'radioItem.disabled() ? "" : undefined' 11 | } 12 | }) 13 | export class RdxRadioIndicatorDirective { 14 | protected readonly radioGroup: RadioGroupDirective = inject(RDX_RADIO_GROUP); 15 | protected readonly radioItem: RdxRadioItemDirective = inject(RdxRadioItemDirective); 16 | } 17 | -------------------------------------------------------------------------------- /apps/radix-docs/src/content/themes/theme/overview.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Themes overview 3 | slug: overview 4 | section: theme 5 | description: description 6 | --- 7 | 8 | # Theme overview 9 | 10 | Use the Theme component to change the look and feel of your UI. 11 | 12 | ## Anatomy 13 | 14 | The [Theme component](/themes/utilities/theme) defines the overall visual look of your application. It can be customized by passing a minimal set of configuration options. 15 | 16 | ## Variants 17 | 18 | Variants are visual variations of a component which are used to create visual hierarchies and communicate relative importance. 19 | 20 | Each component offers a different set of variants, though all are designed to be consistent and complimentary with each other. 21 | -------------------------------------------------------------------------------- /apps/radix-docs/src/demos/components/code/code-variants-demo.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { RdxCodeComponent } from '@radix-ng/components/code'; 3 | 4 | @Component({ 5 | selector: 'kbd-variants-demo', 6 | standalone: true, 7 | imports: [RdxCodeComponent], 8 | template: ` 9 |
    10 | console.log() 11 | console.log() 12 | console.log() 13 | console.log() 14 |
    15 | ` 16 | }) 17 | export class CodeVariantsComponent {} 18 | 19 | export default CodeVariantsComponent; 20 | -------------------------------------------------------------------------------- /.github/workflows/algolia-docsearch-crawler.yml: -------------------------------------------------------------------------------- 1 | name: Algolia DocSearch Crawler 2 | 3 | on: 4 | # Trigger the workflow on manual dispatch 5 | workflow_dispatch: 6 | 7 | jobs: 8 | algolia_docsearch_crawler: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Run Algolia DocSearch Crawler 12 | uses: algolia/algoliasearch-crawler-github-actions@v1.1.13 13 | id: algolia_docsearch_crawler 14 | with: 15 | crawler-user-id: ${{ secrets.ALGOLIA_DOCSEARCH_CRAWLER_USER_ID }} 16 | crawler-api-key: ${{ secrets.ALGOLIA_DOCSEARCH_CRAWLER_API_KEY }} 17 | algolia-app-id: KO68VM9HAD 18 | algolia-api-key: ${{ secrets.ALGOLIA_DOCSEARCH_API_KEY }} 19 | site-url: https://radix-ng.com 20 | crawler-name: radix-ng 21 | -------------------------------------------------------------------------------- /packages/primitives/editable/src/editable-edit-trigger.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | import { injectEditableRootContext } from './editable-root'; 3 | 4 | @Directive({ 5 | selector: 'button[rdxEditableEditTrigger]', 6 | host: { 7 | type: 'button', 8 | '[attr.aria-label]': '"edit"', 9 | '[attr.aria-disabled]': 'rootContext?.disabled() ? "" : undefined', 10 | '[attr.data-disabled]': 'rootContext?.disabled() ? "" : undefined', 11 | '[disabled]': 'rootContext?.disabled()', 12 | '[attr.hidden]': 'rootContext?.isEditing() ? "" : undefined', 13 | 14 | '(click)': 'rootContext?.edit()' 15 | } 16 | }) 17 | export class RdxEditableEditTrigger { 18 | protected readonly rootContext = injectEditableRootContext(); 19 | } 20 | -------------------------------------------------------------------------------- /packages/primitives/avatar/index.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RdxAvatarFallbackDirective } from './src/avatar-fallback.directive'; 3 | import { RdxAvatarImageDirective } from './src/avatar-image.directive'; 4 | import { RdxAvatarRootDirective } from './src/avatar-root.directive'; 5 | 6 | export * from './src/avatar-fallback.directive'; 7 | export * from './src/avatar-image.directive'; 8 | export * from './src/avatar-root.directive'; 9 | export * from './src/avatar.config'; 10 | export type { RdxImageLoadingStatus } from './src/types'; 11 | 12 | const _imports = [RdxAvatarRootDirective, RdxAvatarFallbackDirective, RdxAvatarImageDirective]; 13 | 14 | @NgModule({ 15 | imports: [..._imports], 16 | exports: [..._imports] 17 | }) 18 | export class RdxCheckboxModule {} 19 | -------------------------------------------------------------------------------- /apps/radix-docs/src/demos/primitives/slider/slider-demo.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | import { RdxSliderModule } from '@radix-ng/primitives/slider'; 4 | 5 | @Component({ 6 | selector: 'radix-slider-demo', 7 | standalone: true, 8 | imports: [RdxSliderModule], 9 | styleUrl: 'slider-demo.css', 10 | template: ` 11 | 12 | 13 | 14 | 15 | 16 | 17 | ` 18 | }) 19 | export class SliderDemoComponent {} 20 | 21 | export default SliderDemoComponent; 22 | -------------------------------------------------------------------------------- /packages/primitives/arrow/src/arrow.ts: -------------------------------------------------------------------------------- 1 | import { NumberInput } from '@angular/cdk/coercion'; 2 | import { ChangeDetectionStrategy, Component, input, numberAttribute } from '@angular/core'; 3 | 4 | @Component({ 5 | selector: 'rdx-arrow', 6 | changeDetection: ChangeDetectionStrategy.OnPush, 7 | template: ` 8 | 9 | 10 | 11 | 12 | 13 | ` 14 | }) 15 | export class RdxArrow { 16 | readonly width = input(10, { transform: numberAttribute }); 17 | 18 | readonly height = input(5, { transform: numberAttribute }); 19 | } 20 | -------------------------------------------------------------------------------- /packages/primitives/editable/src/editable-cancel-trigger.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | import { injectEditableRootContext } from './editable-root'; 3 | 4 | @Directive({ 5 | selector: 'button[rdxEditableCancelTrigger]', 6 | host: { 7 | type: 'button', 8 | '[attr.aria-label]': '"cancel"', 9 | '[attr.aria-disabled]': 'rootContext?.disabled() ? "" : undefined', 10 | '[attr.data-disabled]': 'rootContext?.disabled() ? "" : undefined', 11 | '[disabled]': 'rootContext?.disabled()', 12 | '[attr.hidden]': 'rootContext?.isEditing() ? "" : undefined', 13 | 14 | '(click)': 'rootContext?.cancel()' 15 | } 16 | }) 17 | export class RdxEditableCancelTrigger { 18 | protected readonly rootContext = injectEditableRootContext(); 19 | } 20 | -------------------------------------------------------------------------------- /packages/primitives/pagination/src/pagination-first.directive.ts: -------------------------------------------------------------------------------- 1 | import { computed, Directive } from '@angular/core'; 2 | import { injectPaginationRootContext } from './pagination-context.token'; 3 | 4 | // as Button 5 | @Directive({ 6 | selector: '[rdxPaginationFirst]', 7 | host: { 8 | '[attr.aria-label]': '"First Page"', 9 | 10 | '[disabled]': 'disabled()', 11 | '(click)': 'onClick()' 12 | } 13 | }) 14 | export class RdxPaginationFirstDirective { 15 | private readonly rootContext = injectPaginationRootContext(); 16 | 17 | readonly disabled = computed(() => this.rootContext.page() === 1 || this.rootContext.disabled()); 18 | 19 | onClick() { 20 | if (!this.disabled()) { 21 | this.rootContext.onPageChange(1); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/primitives/stepper/src/stepper-item-context.token.ts: -------------------------------------------------------------------------------- 1 | import { BooleanInput, NumberInput } from '@angular/cdk/coercion'; 2 | import { inject, InjectionToken, InputSignalWithTransform, Signal } from '@angular/core'; 3 | import { StepperState } from './types'; 4 | 5 | export interface StepperItemContext { 6 | titleId: string; 7 | descriptionId: string; 8 | step: InputSignalWithTransform; 9 | disabled: InputSignalWithTransform; 10 | isFocusable: Signal; 11 | itemState: Signal; 12 | } 13 | 14 | export const STEPPER_ITEM_CONTEXT = new InjectionToken('StepperItemContext'); 15 | 16 | export function injectStepperItemContext(): StepperItemContext { 17 | return inject(STEPPER_ITEM_CONTEXT); 18 | } 19 | -------------------------------------------------------------------------------- /apps/radix-docs/src/demos/components/avatar/avatar-radius-demo.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { RdxThemeAvatarComponent } from '@radix-ng/components/avatar'; 3 | import { RdxThemeDirective } from '@radix-ng/components/theme'; 4 | 5 | @Component({ 6 | selector: 'avatar-radius-demo', 7 | standalone: true, 8 | imports: [RdxThemeAvatarComponent], 9 | hostDirectives: [RdxThemeDirective], 10 | template: ` 11 |
    12 | 13 | 14 | 15 |
    16 | ` 17 | }) 18 | export class AvatarRadiusComponent {} 19 | 20 | export default AvatarRadiusComponent; 21 | -------------------------------------------------------------------------------- /apps/radix-docs/src/demos/primitives/avatar/avatar-demo.css: -------------------------------------------------------------------------------- 1 | .AvatarRoot { 2 | display: inline-flex; 3 | align-items: center; 4 | justify-content: center; 5 | vertical-align: middle; 6 | overflow: hidden; 7 | user-select: none; 8 | width: 45px; 9 | height: 45px; 10 | border-radius: 100%; 11 | background-color: var(--black-a3); 12 | } 13 | 14 | .AvatarImage { 15 | width: 100%; 16 | height: 100%; 17 | object-fit: cover; 18 | border-radius: inherit; 19 | } 20 | 21 | .AvatarFallback { 22 | width: 100%; 23 | height: 100%; 24 | display: flex; 25 | align-items: center; 26 | justify-content: center; 27 | background-color: white; 28 | color: var(--violet-11); 29 | font-size: 15px; 30 | line-height: 1; 31 | font-weight: 500; 32 | } 33 | -------------------------------------------------------------------------------- /packages/primitives/collapsible/src/collapsible-trigger.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | import { injectCollapsibleRootContext } from './collapsible-root.directive'; 3 | 4 | @Directive({ 5 | selector: '[rdxCollapsibleTrigger]', 6 | host: { 7 | '[attr.aria-controls]': 'rootContext.contentId()', 8 | '[attr.aria-expanded]': 'rootContext.open()', 9 | '[attr.data-state]': 'rootContext.open() ? "open" : "closed"', 10 | '[attr.data-disabled]': 'rootContext.disabled() ? "true" : undefined', 11 | '[attr.disabled]': 'rootContext.disabled() || undefined', 12 | 13 | '(click)': 'rootContext.toggle()' 14 | } 15 | }) 16 | export class RdxCollapsibleTriggerDirective { 17 | protected readonly rootContext = injectCollapsibleRootContext()!; 18 | } 19 | -------------------------------------------------------------------------------- /packages/primitives/tabs/index.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RdxTabsContentDirective } from './src/tabs-content.directive'; 3 | import { RdxTabsListDirective } from './src/tabs-list.directive'; 4 | import { RdxTabsRootDirective } from './src/tabs-root.directive'; 5 | import { RdxTabsTriggerDirective } from './src/tabs-trigger.directive'; 6 | 7 | export * from './src/tabs-content.directive'; 8 | export * from './src/tabs-list.directive'; 9 | export * from './src/tabs-root.directive'; 10 | export * from './src/tabs-trigger.directive'; 11 | 12 | const tabsImports = [RdxTabsRootDirective, RdxTabsContentDirective, RdxTabsListDirective, RdxTabsTriggerDirective]; 13 | 14 | @NgModule({ 15 | imports: [...tabsImports], 16 | exports: [...tabsImports] 17 | }) 18 | export class RdxTabsModule {} 19 | -------------------------------------------------------------------------------- /packages/primitives/core/src/mount.ts: -------------------------------------------------------------------------------- 1 | import { AfterViewInit, Directive } from '@angular/core'; 2 | 3 | const callAll = 4 | void>(...fns: (T | undefined)[]) => 5 | (...a: Parameters) => { 6 | fns.forEach(function (fn) { 7 | fn?.(...a); 8 | }); 9 | }; 10 | 11 | @Directive({ 12 | standalone: true 13 | }) 14 | export class OnMountDirective implements AfterViewInit { 15 | #onMountFns?: () => void; 16 | 17 | onMount(fn: () => void) { 18 | this.#onMountFns = callAll(this.#onMountFns, fn); 19 | } 20 | 21 | ngAfterViewInit() { 22 | if (!this.#onMountFns) { 23 | throw new Error('The onMount function must be called before the component is mounted.'); 24 | } 25 | this.#onMountFns(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /apps/radix-docs/src/demos/primitives/toggle/toggle-demo.css: -------------------------------------------------------------------------------- 1 | :host { 2 | button { 3 | all: unset; 4 | } 5 | } 6 | 7 | .Toggle { 8 | background-color: white; 9 | color: var(--mauve-11); 10 | height: 35px; 11 | width: 35px; 12 | border-radius: 4px; 13 | display: flex; 14 | font-size: 15px; 15 | line-height: 1; 16 | align-items: center; 17 | justify-content: center; 18 | box-shadow: 0 2px 10px var(--black-a7); 19 | } 20 | 21 | .Toggle:hover { 22 | background-color: var(--violet-3); 23 | } 24 | 25 | .Toggle[disabled] { 26 | pointer-events: none; 27 | opacity: 0.5; 28 | } 29 | 30 | .Toggle[data-state='on'] { 31 | background-color: var(--violet-6); 32 | color: var(--violet-12); 33 | } 34 | 35 | .Toggle:focus { 36 | box-shadow: 0 0 0 2px black; 37 | } 38 | -------------------------------------------------------------------------------- /packages/primitives/pagination/src/pagination-list.directive.ts: -------------------------------------------------------------------------------- 1 | import { computed, Directive } from '@angular/core'; 2 | import { injectPaginationRootContext } from './pagination-context.token'; 3 | import { getRange, transform } from './utils'; 4 | 5 | @Directive({ 6 | selector: '[rdxPaginationList]', 7 | exportAs: 'rdxPaginationList' 8 | }) 9 | export class RdxPaginationListDirective { 10 | private readonly rootContext = injectPaginationRootContext(); 11 | 12 | readonly transformedRange = computed(() => { 13 | return transform( 14 | getRange( 15 | this.rootContext.page(), 16 | this.rootContext.pageCount(), 17 | this.rootContext.siblingCount(), 18 | this.rootContext.showEdges() 19 | ) 20 | ); 21 | }); 22 | } 23 | -------------------------------------------------------------------------------- /apps/radix-docs/plugins/unist.ts: -------------------------------------------------------------------------------- 1 | import type { Node } from 'unist'; 2 | 3 | export interface UnistNode extends Node { 4 | type: string; 5 | name?: string; 6 | tagName?: string; 7 | value?: string; 8 | properties?: { 9 | __rawString__?: string; 10 | __className__?: string; 11 | __event__?: string; 12 | [key: string]: unknown; 13 | } & NpmCommands; 14 | attributes?: { 15 | name: string; 16 | value: unknown; 17 | type?: string; 18 | }[]; 19 | children?: UnistNode[]; 20 | } 21 | 22 | export interface UnistTree extends Node { 23 | children: UnistNode[]; 24 | } 25 | 26 | export interface NpmCommands { 27 | __npmCommand__?: string; 28 | __yarnCommand__?: string; 29 | __pnpmCommand__?: string; 30 | __bunCommand__?: string; 31 | } 32 | -------------------------------------------------------------------------------- /apps/radix-docs/src/demos/primitives/label/label-demo.css: -------------------------------------------------------------------------------- 1 | :host { 2 | input { 3 | all: unset; 4 | } 5 | } 6 | 7 | .Input { 8 | width: 200px; 9 | display: inline-flex; 10 | align-items: center; 11 | justify-content: center; 12 | border-radius: 4px; 13 | padding: 0 10px; 14 | margin-left: 10px; 15 | height: 35px; 16 | font-size: 15px; 17 | line-height: 1; 18 | color: white; 19 | background-color: var(--black-a2); 20 | box-shadow: 0 0 0 1px var(--black-a6); 21 | } 22 | 23 | .Input:focus { 24 | box-shadow: 0 0 0 2px black; 25 | } 26 | 27 | .Input::selection { 28 | background-color: var(--black-a6); 29 | color: white; 30 | } 31 | 32 | .LabelRoot { 33 | color: white; 34 | font-size: 15px; 35 | font-weight: 500; 36 | line-height: 35px; 37 | } 38 | -------------------------------------------------------------------------------- /packages/primitives/collection/src/collection-provider.ts: -------------------------------------------------------------------------------- 1 | import { Directive, ElementRef, forwardRef, inject, signal, WritableSignal } from '@angular/core'; 2 | import { COLLECTION_CONTEXT_TOKEN, CollectionContext } from './collection-context'; 3 | 4 | @Directive({ 5 | selector: '[rdxCollectionProvider]', 6 | providers: [ 7 | { 8 | provide: COLLECTION_CONTEXT_TOKEN, 9 | useExisting: forwardRef(() => RdxCollectionProvider) 10 | } 11 | ] 12 | }) 13 | export class RdxCollectionProvider implements CollectionContext { 14 | private readonly elementRef = inject(ElementRef).nativeElement; 15 | 16 | readonly collectionElementRef = signal(this.elementRef); 17 | 18 | readonly itemMap: WritableSignal> = signal(new Map()); 19 | } 20 | -------------------------------------------------------------------------------- /packages/primitives/pagination/src/pagination-prev.directive.ts: -------------------------------------------------------------------------------- 1 | import { computed, Directive } from '@angular/core'; 2 | import { injectPaginationRootContext } from './pagination-context.token'; 3 | 4 | // as Button 5 | @Directive({ 6 | selector: '[rdxPaginationPrev]', 7 | host: { 8 | '[attr.aria-label]': '"Previous Page"', 9 | 10 | '[disabled]': 'disabled()', 11 | '(click)': 'onClick()' 12 | } 13 | }) 14 | export class RdxPaginationPrevDirective { 15 | private readonly rootContext = injectPaginationRootContext(); 16 | 17 | readonly disabled = computed(() => this.rootContext.page() === 1 || this.rootContext.disabled()); 18 | 19 | onClick() { 20 | if (!this.disabled()) { 21 | this.rootContext.onPageChange(this.rootContext.page() - 1); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/primitives/slider/src/slider-orientation-context.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, signal } from '@angular/core'; 2 | 3 | export interface OrientationContext { 4 | startEdge: string; 5 | endEdge: string; 6 | direction: number; 7 | size: string; 8 | } 9 | 10 | @Injectable() 11 | export class RdxSliderOrientationContextService { 12 | private contextSignal = signal({ 13 | startEdge: 'left', 14 | endEdge: 'right', 15 | direction: 1, 16 | size: 'width' 17 | }); 18 | 19 | get context() { 20 | return this.contextSignal(); 21 | } 22 | 23 | updateContext(context: Partial) { 24 | this.contextSignal.update((current) => ({ 25 | ...current, 26 | ...context 27 | })); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /apps/radix-docs/src/demos/components/switch/switch-sizes-demo.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { RdxThemeSwitchComponent } from '@radix-ng/components/switch'; 3 | import { RdxThemeDirective } from '@radix-ng/components/theme'; 4 | 5 | @Component({ 6 | selector: 'switch-sizes-demo', 7 | standalone: true, 8 | imports: [RdxThemeDirective, RdxThemeSwitchComponent], 9 | hostDirectives: [RdxThemeDirective], 10 | template: ` 11 |
    12 | 13 | 14 | 15 |
    16 | ` 17 | }) 18 | export class SwitchSizedComponent {} 19 | 20 | export default SwitchSizedComponent; 21 | -------------------------------------------------------------------------------- /apps/radix-docs/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | import type { TocItem } from '@/types'; 2 | import type { MarkdownHeading } from 'astro'; 3 | 4 | export function generateToc(headings: MarkdownHeading[], maxDepth = 3): TocItem[] { 5 | const toc: TocItem[] = []; 6 | const parentHeadings = new Map(); 7 | 8 | headings.forEach((h) => { 9 | const heading = { ...h, children: [] }; 10 | parentHeadings.set(heading.depth, heading); 11 | 12 | if (heading.depth === 2 || heading.depth === 3) { 13 | toc.push(heading); 14 | } else if (heading.depth <= maxDepth) { 15 | const parent = parentHeadings.get(heading.depth - 1); 16 | if (parent) { 17 | parent.children.push(heading); 18 | } 19 | } 20 | }); 21 | 22 | return toc; 23 | } 24 | -------------------------------------------------------------------------------- /packages/primitives/context-menu/src/context-menu-item-selectable.ts: -------------------------------------------------------------------------------- 1 | import { booleanAttribute, Directive, EventEmitter, Input, Output } from '@angular/core'; 2 | import { RdxContextMenuItemDirective } from './context-menu-item.directive'; 3 | 4 | /** Base class providing checked state for selectable ContextMenuItems. */ 5 | @Directive({ 6 | standalone: true, 7 | host: { 8 | '[attr.aria-checked]': '!!checked', 9 | '[attr.aria-disabled]': 'disabled || null', 10 | '[attr.data-state]': 'checked ? "checked" : "unchecked"' 11 | } 12 | }) 13 | export class RdxContextMenuSelectable extends RdxContextMenuItemDirective { 14 | /** Whether the element is checked */ 15 | @Input({ transform: booleanAttribute }) checked = false; 16 | 17 | @Output() readonly checkedChange = new EventEmitter(); 18 | } 19 | -------------------------------------------------------------------------------- /packages/primitives/editable/stories/editable.stories.ts: -------------------------------------------------------------------------------- 1 | import { componentWrapperDecorator, Meta, moduleMetadata, StoryObj } from '@storybook/angular'; 2 | import { Editable } from './editable'; 3 | 4 | const html = String.raw; 5 | 6 | export default { 7 | title: 'Primitives/Editable', 8 | decorators: [ 9 | moduleMetadata({ 10 | imports: [Editable] 11 | }), 12 | componentWrapperDecorator( 13 | (story) => html` 14 |
    ${story}
    15 | ` 16 | ) 17 | ] 18 | } as Meta; 19 | 20 | type Story = StoryObj; 21 | 22 | export const Default: Story = { 23 | render: () => ({ 24 | template: html` 25 | 26 | ` 27 | }) 28 | }; 29 | -------------------------------------------------------------------------------- /.github/DISCUSSION_TEMPLATE/example-request.yml: -------------------------------------------------------------------------------- 1 | title: '[Example]: ' 2 | labels: [Example Request] 3 | body: 4 | - type: markdown 5 | attributes: 6 | value: | 7 | ### Thanks for taking the time to create an example request! Please search open/closed requests before submitting, as the block or a similar one may have already been requested. 8 | 9 | - type: textarea 10 | id: example-description 11 | attributes: 12 | label: Description 13 | description: Tell us about your example request 14 | placeholder: A modal with tooltip 15 | validations: 16 | required: true 17 | 18 | - type: input 19 | id: example-url 20 | attributes: 21 | label: Example 22 | description: Link to an example 23 | placeholder: ex. https://example.com 24 | validations: 25 | required: false 26 | -------------------------------------------------------------------------------- /packages/primitives/alert-dialog/src/alert-dialog-content.directive.ts: -------------------------------------------------------------------------------- 1 | import { CdkTrapFocus } from '@angular/cdk/a11y'; 2 | import { Directive, ElementRef, inject, Input, Renderer2 } from '@angular/core'; 3 | 4 | @Directive({ 5 | selector: '[rdxAlertDialogContent]', 6 | standalone: true, 7 | hostDirectives: [ 8 | { 9 | directive: CdkTrapFocus 10 | } 11 | ], 12 | host: { 13 | '[attr.data-state]': '"open"', 14 | '[attr.cdkTrapFocusAutoCapture]': 'true' 15 | } 16 | }) 17 | export class RdxAlertDialogContentDirective { 18 | private readonly renderer = inject(Renderer2); 19 | private readonly elementRef = inject(ElementRef); 20 | 21 | @Input() set maxWidth(value: string) { 22 | this.renderer.setStyle(this.elementRef.nativeElement, 'maxWidth', value); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/primitives/jest.config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | displayName: 'primitives', 3 | preset: '../../jest.preset.cjs', 4 | setupFilesAfterEnv: ['/test-setup.ts'], 5 | coverageDirectory: '../../coverage/packages/primitives', 6 | transform: { 7 | '^.+\\.(ts|mjs|js|html)$': [ 8 | 'jest-preset-angular', 9 | { 10 | tsconfig: '/tsconfig.spec.json', 11 | stringifyContentPathRegex: '\\.(html|svg)$' 12 | } 13 | ] 14 | }, 15 | transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], 16 | snapshotSerializers: [ 17 | 'jest-preset-angular/build/serializers/no-ng-attributes', 18 | 'jest-preset-angular/build/serializers/ng-snapshot', 19 | 'jest-preset-angular/build/serializers/html-comment' 20 | ] 21 | }; 22 | -------------------------------------------------------------------------------- /packages/primitives/presence/src/transitions/transition.toast.ts: -------------------------------------------------------------------------------- 1 | import { TransitionStartFn } from '../types'; 2 | import { triggerReflow } from '../utils'; 3 | 4 | export const toastFadeInTransition: TransitionStartFn = (element: HTMLElement, animation: boolean) => { 5 | const { classList } = element; 6 | 7 | if (animation) { 8 | classList.add('fade'); 9 | } else { 10 | classList.add('show'); 11 | return; 12 | } 13 | 14 | triggerReflow(element); 15 | classList.add('show', 'showing'); 16 | 17 | return () => { 18 | classList.remove('showing'); 19 | }; 20 | }; 21 | 22 | export const toastFadeOutTransition: TransitionStartFn = ({ classList }: HTMLElement) => { 23 | classList.add('showing'); 24 | return () => { 25 | classList.remove('show', 'showing'); 26 | }; 27 | }; 28 | -------------------------------------------------------------------------------- /tools/scripts/api-doc/utility/get-types.mjs: -------------------------------------------------------------------------------- 1 | import { staticMessages } from '../constants.mjs'; 2 | import { getCommentSummary, getDeprecatedText, parameters } from '../utils.mjs'; 3 | 4 | /** 5 | * 6 | * @param {Array} typesChildren 7 | * @returns {{description: string, values: Array}} 8 | */ 9 | export const processComponentTypes = (typesChildren) => { 10 | const types = { 11 | description: staticMessages['types'], 12 | values: [] 13 | }; 14 | 15 | typesChildren.forEach((type) => { 16 | types.values.push({ 17 | name: type.name, 18 | description: getCommentSummary(type.comment), 19 | type: type.type?.toString(), 20 | parameters: parameters(type), 21 | deprecated: getDeprecatedText(type) 22 | }); 23 | }); 24 | 25 | return types; 26 | }; 27 | -------------------------------------------------------------------------------- /packages/components/jest.config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | displayName: 'components', 3 | preset: '../../jest.preset.cjs', 4 | setupFilesAfterEnv: ['/src/test-setup.ts'], 5 | coverageDirectory: '../../coverage/packages/components', 6 | transform: { 7 | '^.+\\.(ts|mjs|js|html)$': [ 8 | 'jest-preset-angular', 9 | { 10 | tsconfig: '/tsconfig.spec.json', 11 | stringifyContentPathRegex: '\\.(html|svg)$' 12 | } 13 | ] 14 | }, 15 | transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], 16 | snapshotSerializers: [ 17 | 'jest-preset-angular/build/serializers/no-ng-attributes', 18 | 'jest-preset-angular/build/serializers/ng-snapshot', 19 | 'jest-preset-angular/build/serializers/html-comment' 20 | ] 21 | }; 22 | -------------------------------------------------------------------------------- /apps/radix-docs/src/demos/components/switch/switch-radius-demo.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { RdxThemeSwitchComponent } from '@radix-ng/components/switch'; 3 | import { RdxThemeDirective } from '@radix-ng/components/theme'; 4 | 5 | @Component({ 6 | selector: 'switch-radius-demo', 7 | standalone: true, 8 | imports: [RdxThemeDirective, RdxThemeSwitchComponent], 9 | hostDirectives: [RdxThemeDirective], 10 | template: ` 11 |
    12 | 13 | 14 | 15 |
    16 | ` 17 | }) 18 | export class SwitchRadiusComponent {} 19 | 20 | export default SwitchRadiusComponent; 21 | -------------------------------------------------------------------------------- /packages/primitives/calendar/src/calendar-grid.directive.ts: -------------------------------------------------------------------------------- 1 | import { computed, Directive } from '@angular/core'; 2 | import { injectCalendarRootContext } from './сalendar-сontext.token'; 3 | 4 | @Directive({ 5 | selector: 'table[rdxCalendarGrid]', 6 | host: { 7 | tabindex: '-1', 8 | role: 'grid', 9 | '[attr.aria-readonly]': 'readonly()', 10 | '[attr.aria-disabled]': 'disabled()', 11 | '[attr.data-readonly]': 'readonly() && ""', 12 | '[attr.data-disabled]': 'disabled() && ""' 13 | } 14 | }) 15 | export class RdxCalendarGridDirective { 16 | private readonly rootContext = injectCalendarRootContext(); 17 | 18 | readonly disabled = computed(() => (this.rootContext.disabled() ? true : undefined)); 19 | readonly readonly = computed(() => (this.rootContext.readonly ? true : undefined)); 20 | } 21 | -------------------------------------------------------------------------------- /packages/primitives/dropdown-menu/src/dropdown-menu-item-selectable.ts: -------------------------------------------------------------------------------- 1 | import { booleanAttribute, Directive, EventEmitter, Input, Output } from '@angular/core'; 2 | import { RdxDropdownMenuItemDirective } from './dropdown-menu-item.directive'; 3 | 4 | /** Base class providing checked state for selectable DropdownMenuItems. */ 5 | @Directive({ 6 | standalone: true, 7 | host: { 8 | '[attr.aria-checked]': '!!checked', 9 | '[attr.aria-disabled]': 'disabled || null', 10 | '[attr.data-state]': 'checked ? "checked" : "unchecked"' 11 | } 12 | }) 13 | export class RdxDropdownMenuSelectable extends RdxDropdownMenuItemDirective { 14 | /** Whether the element is checked */ 15 | @Input({ transform: booleanAttribute }) checked: boolean = false; 16 | 17 | @Output() readonly checkedChange = new EventEmitter(); 18 | } 19 | -------------------------------------------------------------------------------- /apps/radix-docs/src/components/layouts/TocHeading.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import type { TocItem } from '@/types'; 3 | 4 | interface Props { 5 | heading: TocItem; 6 | } 7 | 8 | const { heading } = Astro.props; 9 | --- 10 | 11 |
  • 12 | 23 | {heading.text} 24 | 25 | { 26 | heading.children.length > 0 && ( 27 |
      28 | {heading.children.map((subheading) => ( 29 | 30 | ))} 31 |
    32 | ) 33 | } 34 |
  • 35 | -------------------------------------------------------------------------------- /apps/radix-ssr-testing/jest.config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | displayName: 'radix-ssr-testing', 3 | preset: '../../jest.preset.cjs', 4 | setupFilesAfterEnv: ['/src/test-setup.ts'], 5 | coverageDirectory: '../../coverage/apps/radix-ssr-testing', 6 | transform: { 7 | '^.+\\.(ts|mjs|js|html)$': [ 8 | 'jest-preset-angular', 9 | { 10 | tsconfig: '/tsconfig.spec.json', 11 | stringifyContentPathRegex: '\\.(html|svg)$' 12 | } 13 | ] 14 | }, 15 | transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], 16 | snapshotSerializers: [ 17 | 'jest-preset-angular/build/serializers/no-ng-attributes', 18 | 'jest-preset-angular/build/serializers/ng-snapshot', 19 | 'jest-preset-angular/build/serializers/html-comment' 20 | ] 21 | }; 22 | -------------------------------------------------------------------------------- /packages/components/kbd/src/kbd.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, computed, input, Input, InputSignal, numberAttribute } from '@angular/core'; 2 | import { ResponsiveSize } from '@radix-ng/components/types'; 3 | import classNames from 'classnames'; 4 | 5 | @Component({ 6 | selector: 'rdx-kbd', 7 | standalone: true, 8 | template: ` 9 | 10 | `, 11 | host: { 12 | '[class]': 'computedClass()' 13 | } 14 | }) 15 | export class RdxKbdComponent { 16 | @Input({ transform: numberAttribute }) size?: ResponsiveSize; 17 | 18 | readonly class: InputSignal = input(); 19 | 20 | /** 21 | * 22 | * @ignore 23 | */ 24 | protected computedClass = computed(() => 25 | classNames('rt-reset', 'rt-Kbd', this.size && `rt-r-size-${this.size}`, this.class()) 26 | ); 27 | } 28 | -------------------------------------------------------------------------------- /apps/radix-docs/src/components/code-editor/example-app/styles-css.ts: -------------------------------------------------------------------------------- 1 | export const stylesCss = ` 2 | @import '@radix-ui/colors/black-alpha.css'; 3 | @import '@radix-ui/colors/mauve.css'; 4 | @import '@radix-ui/colors/violet.css'; 5 | 6 | @import '@angular/cdk/overlay-prebuilt.css'; 7 | 8 | html, 9 | body { 10 | height: 100%; 11 | margin: 10px; 12 | padding: 0; 13 | } 14 | 15 | body { 16 | background: linear-gradient(to bottom right, #3730a3, #6b21a8, #be185d); 17 | background-repeat: no-repeat; 18 | background-attachment: fixed; 19 | 20 | --default-font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', 21 | Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji'; 22 | 23 | --code-font-family: 'JetBrains Mono', 'Menlo', monospace, 'Apple Color Emoji', 24 | 'Segoe UI Emoji'; 25 | 26 | font-family: var(--default-font-family); 27 | }`; 28 | -------------------------------------------------------------------------------- /packages/primitives/pagination/src/pagination-last.directive.ts: -------------------------------------------------------------------------------- 1 | import { computed, Directive } from '@angular/core'; 2 | import { injectPaginationRootContext } from './pagination-context.token'; 3 | 4 | // as Button 5 | @Directive({ 6 | selector: '[rdxPaginationLast]', 7 | host: { 8 | '[attr.aria-label]': '"Last Page"', 9 | 10 | '[disabled]': 'disabled()', 11 | '(click)': 'onClick()' 12 | } 13 | }) 14 | export class RdxPaginationLastDirective { 15 | private readonly rootContext = injectPaginationRootContext(); 16 | 17 | readonly disabled = computed( 18 | () => this.rootContext.page() === this.rootContext.pageCount() || this.rootContext.disabled() 19 | ); 20 | 21 | onClick() { 22 | if (!this.disabled()) { 23 | this.rootContext.onPageChange(this.rootContext.pageCount()); 24 | } 25 | } 26 | } 27 | --------------------------------------------------------------------------------