npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@bloc-ui/core

v0.0.12

Published

> **Latest:** v0.0.12

Readme

@bloc-ui/core

Latest: v0.0.12

Lightweight, accessible Angular component library. Barebone structure and behaviour — no hard-coded colours, no design opinions. Pair with @bloc-ui/theme to add a visual layer, or bring your own styles via CSS custom properties.

Live Documentation & Demos

Tip: Need modal, table, toast, date-picker, or tab components too? Install @bloc-ui/kit for a single all-in-one import, or install each standalone package individually.


Installation

npm install @bloc-ui/core

Peer dependencies: @angular/common and @angular/core ≥ 21.

Each component ships as a secondary entry point for optimal tree-shaking:

import { BlocButtonComponent } from '@bloc-ui/core/button';
import { BlocSpinnerDirective } from '@bloc-ui/core/spinner';

You can also import everything from the primary entry point (@bloc-ui/core) for convenience.


Components & Directives

| Export | Selector | Entry Point | Type | | ------------------------- | -------------------------------------- | ------------------------ | --------- | | BlocButtonComponent | button[blocButton] | @bloc-ui/core/button | Component | | BlocCheckboxComponent | bloc-checkbox | @bloc-ui/core/checkbox | Component | | BlocInputDirective | input[blocInput] | @bloc-ui/core/input | Directive | | BlocInputGroupDirective | bloc-input-group, [blocInputGroup] | @bloc-ui/core/input | Directive | | BlocPrefixDirective | bloc-prefix, [blocPrefix] | @bloc-ui/core/input | Directive | | BlocSuffixDirective | bloc-suffix, [blocSuffix] | @bloc-ui/core/input | Directive | | BlocInputErrorDirective | [blocInputError], bloc-input-error | @bloc-ui/core/input | Directive | | BlocRadioGroupComponent | bloc-radio-group | @bloc-ui/core/radio | Component | | BlocRadioComponent | bloc-radio | @bloc-ui/core/radio | Component | | BlocSpinnerDirective | bloc-spinner, [blocSpinner] | @bloc-ui/core/spinner | Directive | | BlocToggleComponent | bloc-toggle | @bloc-ui/core/toggle | Component |

NgModule wrappers (BlocButtonModule, BlocCheckboxModule, BlocInputModule, BlocRadioModule, BlocSpinnerModule, BlocToggleModule) are also exported for NgModule-based applications.


Usage

All components are standalone: true. Import them directly or via their companion Module.

Button

import { BlocButtonComponent } from '@bloc-ui/core/button';
<button blocButton>Default</button>
<button blocButton variant="secondary">Secondary</button>
<button blocButton variant="outline">Outline</button>
<button blocButton [loading]="isSaving">Save</button>
<button blocButton [disabled]="true">Disabled</button>

Inputs

| Input | Type | Default | Description | | ---------- | --------------------------------------- | ----------- | ------------------------------------------------ | | variant | 'primary' \| 'secondary' \| 'outline' | 'primary' | Visual variant | | disabled | boolean | false | Disables the button | | loading | boolean | false | Shows an inline spinner and prevents interaction |

Outputs

| Output | Type | Description | | --------- | ------------ | ------------------------------------------------- | | clicked | MouseEvent | Emits on click (skipped when disabled or loading) |

CSS tokens

| Token | Fallback | Description | | ------------------ | --------- | ----------------------------------- | | --bloc-primary | #3b82f6 | Primary background / outline colour | | --bloc-secondary | #64748b | Secondary background colour |


Checkbox

import { BlocCheckboxComponent } from '@bloc-ui/core/checkbox';
<bloc-checkbox [(ngModel)]="agreed">I agree to the terms</bloc-checkbox>
<bloc-checkbox [formControl]="acceptCtrl" size="lg">Accept</bloc-checkbox>
<bloc-checkbox [disabled]="true">Disabled</bloc-checkbox>
<bloc-checkbox labelPosition="before">Label before</bloc-checkbox>

Implements ControlValueAccessor — works with both template-driven and reactive forms.

Inputs

| Input | Type | Default | Description | | --------------- | ---------------------- | --------- | ------------------------------- | | size | 'sm' \| 'md' \| 'lg' | 'md' | Checkbox size | | labelPosition | 'before' \| 'after' | 'after' | Label placement relative to box | | disabled | boolean | false | Disables the checkbox |

CSS tokens

| Token | Fallback | Description | | -------------------------------- | ------------------------------ | --------------------- | | --bloc-checkbox-border | #aaafb7 | Default border colour | | --bloc-checkbox-bg | #ffffff | Default background | | --bloc-checkbox-checked-border | var(--bloc-primary, #6b7280) | Checked border colour | | --bloc-checkbox-checked-bg | var(--bloc-primary, #6b7280) | Checked background | | --bloc-checkbox-check-color | #ffffff | Checkmark colour | | --bloc-checkbox-focus-ring | var(--bloc-primary, #6b7280) | Focus ring colour |

Keyboard: Space to toggle. ARIA: role="checkbox", aria-checked, aria-disabled.


Input

import {
    BlocInputDirective,
    BlocInputGroupDirective,
    BlocPrefixDirective,
    BlocSuffixDirective,
    BlocInputErrorDirective,
} from '@bloc-ui/core/input';

Standalone input:

<input blocInput type="text" placeholder="Email" />

With Angular reactive forms — validation error shown on touch:

<input blocInput [formControl]="emailCtrl" type="email" />

Input group with prefix / suffix:

<bloc-input-group>
    <span blocPrefix>@</span>
    <input blocInput type="text" placeholder="username" />
    <span blocSuffix>.com</span>
</bloc-input-group>

With error message:

<input blocInput [formControl]="emailCtrl" type="email" />
<span blocInputError>Please enter a valid email.</span>

BlocInputDirective inputs

| Input | Type | Default | Description | | -------------- | ---------------- | ------- | -------------------------------------------------------------------------------------------------- | | error | boolean | false | Forces error styling. Also applied automatically when a bound FormControl is invalid and touched | | autocomplete | string \| null | null | Sets autocomplete attribute. Pass "off" to disable browser suggestions |

CSS tokens

| Token | Fallback | Description | | -------------------------------------- | ------------------------------ | --------------------------- | | --bloc-input-border | var(--bloc-border, #cbd5e1) | Default border colour | | --bloc-input-focus-border | var(--bloc-primary, #6b7280) | Focus border colour | | --bloc-input-error-border | var(--bloc-error, #f87171) | Error border colour | | --bloc-input-bg | #ffffff | Input background | | --bloc-input-color | #374151 | Input text colour | | --bloc-input-radius | 4px | Border radius | | --bloc-input-padding | 8px 12px | Inner padding | | --bloc-input-font-size | 14px | Font size | | --bloc-input-group-border | var(--bloc-border, #cbd5e1) | Group border colour | | --bloc-input-group-radius | 4px | Group border radius | | --bloc-input-group-bg | #ffffff | Group background | | --bloc-input-group-focus-border | var(--bloc-primary, #6b7280) | Group focus border colour | | --bloc-input-group-adornment-padding | 0 8px | Prefix / suffix padding | | --bloc-input-group-adornment-color | #9ca3af | Prefix / suffix text colour | | --bloc-input-error-color | var(--bloc-error, #f87171) | Error message text colour | | --bloc-input-error-font-size | 0.75rem | Error message font size |


Radio

import { BlocRadioGroupComponent, BlocRadioComponent } from '@bloc-ui/core/radio';
<bloc-radio-group [(ngModel)]="colour">
    <bloc-radio value="red">Red</bloc-radio>
    <bloc-radio value="green">Green</bloc-radio>
    <bloc-radio value="blue">Blue</bloc-radio>
</bloc-radio-group>

<bloc-radio-group [formControl]="sizeCtrl" labelPosition="before">
    <bloc-radio value="sm" size="sm">Small</bloc-radio>
    <bloc-radio value="md">Medium</bloc-radio>
    <bloc-radio value="lg" size="lg">Large</bloc-radio>
</bloc-radio-group>

BlocRadioGroupComponent implements ControlValueAccessor — works with both template-driven and reactive forms. Each <bloc-radio> must be placed inside a <bloc-radio-group>.

bloc-radio-group inputs

| Input | Type | Default | Description | | --------------- | --------------------- | --------- | ---------------------------------------- | | disabled | boolean | false | Disables the entire group | | labelPosition | 'before' \| 'after' | 'after' | Default label placement for all children |

bloc-radio inputs

| Input | Type | Default | Description | | --------------- | ----------------------------- | ------- | --------------------------------------------- | | value | unknown | — | Required. The value this radio represents | | disabled | boolean | false | Disables this radio | | size | 'sm' \| 'md' \| 'lg' | 'md' | Radio button size | | labelPosition | 'before' \| 'after' \| null | null | Label placement (null = inherit from group) |

CSS tokens

| Token | Fallback | Description | | ----------------------------- | ------------------------------ | ----------------------- | | --bloc-radio-border | #aaafb7 | Default border colour | | --bloc-radio-bg | #ffffff | Default background | | --bloc-radio-checked-border | var(--bloc-primary, #6b7280) | Checked border colour | | --bloc-radio-dot-color | var(--bloc-primary, #6b7280) | Dot colour when checked | | --bloc-radio-focus-ring | var(--bloc-primary, #6b7280) | Focus ring colour | | --bloc-radio-group-gap | 8px | Spacing between radios |

Keyboard: Space to select, Arrow keys for roving focus (WAI-ARIA radio group pattern). ARIA: role="radiogroup" / role="radio", aria-checked, aria-disabled.


Spinner

import { BlocSpinnerDirective } from '@bloc-ui/core/spinner';
<!-- element form -->
<bloc-spinner />
<bloc-spinner size="lg" />

<!-- attribute form — on any element -->
<span blocSpinner size="sm"></span>

<!-- custom size -->
<bloc-spinner [width]="'40px'" [height]="'40px'" />

Inputs

| Input | Type | Default | Description | | -------- | ---------------------------------------------- | ------- | ----------------------------------------------------- | | size | 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| null | 'md' | Preset size. Pass null to size manually | | width | string | '' | Explicit width (e.g. '40px'). Overrides size preset | | height | string | '' | Explicit height. Overrides size preset |

Preset dimensions: xs 12 px · sm 16 px · md 24 px · lg 32 px · xl 48 px.

CSS tokens

| Token | Fallback | Description | | ---------------------- | --------- | ------------------------------------- | | --bloc-spinner-color | #6b7280 | Spinner colour (drives arc and track) |

The spinner colour can also be set with a Tailwind text colour class (e.g. class="text-blue-500").


Toggle

import { BlocToggleComponent } from '@bloc-ui/core/toggle';
<bloc-toggle [(ngModel)]="darkMode">Dark mode</bloc-toggle>
<bloc-toggle [formControl]="notificationsCtrl" size="sm">Notifications</bloc-toggle>
<bloc-toggle [disabled]="true">Disabled</bloc-toggle>
<bloc-toggle labelPosition="before" size="lg">Label before</bloc-toggle>

Implements ControlValueAccessor — works with both template-driven and reactive forms.

Inputs

| Input | Type | Default | Description | | --------------- | ---------------------- | --------- | --------------------------------- | | size | 'sm' \| 'md' \| 'lg' | 'md' | Toggle size | | labelPosition | 'before' \| 'after' | 'after' | Label placement relative to track | | disabled | boolean | false | Disables the toggle |

CSS tokens

| Token | Fallback | Description | | -------------------------------- | ------------------------------ | ---------------------- | | --bloc-toggle-track-bg | #d1d5db | Track background (off) | | --bloc-toggle-track-checked-bg | var(--bloc-primary, #6b7280) | Track background (on) | | --bloc-toggle-thumb-bg | #ffffff | Thumb background | | --bloc-toggle-thumb-shadow | rgba(0,0,0,0.2) | Thumb shadow | | --bloc-toggle-focus-ring | var(--bloc-primary, #6b7280) | Focus ring colour | | --bloc-toggle-width | 44px (md) | Track width override | | --bloc-toggle-height | 24px (md) | Track height override |

Keyboard: Space to toggle. ARIA: role="switch", aria-checked, aria-disabled.


Tailwind CSS integration

If you use Tailwind CSS, declare the bloc-* cascade layers before @import "tailwindcss" so that Tailwind's utilities layer always has priority over bloc-ui defaults:

/* tailwind.css */
@layer theme, base, bloc-input, bloc-input-group, bloc-input-error, bloc-spinner, components, utilities;
@import 'tailwindcss';

Add one entry per bloc-ui directive you use (bloc-input, bloc-input-group, bloc-input-error, bloc-spinner, etc.).


Theming

All visual tokens (--bloc-primary, --bloc-error, colour scales, dark-mode) are provided by the optional @bloc-ui/theme package. Components work without it — neutral fallbacks are applied automatically.


License

MIT