@carissa-io/theme-default

中文文档
0.3.24发布于 2026/11/09UNLICENSEDES Module零依赖近 30 天下载 2694

Carissa UI: the default theme (Swiss minimalism) as SCSS variable overrides of the Carissa components, with a compiled CSS build

原始使用文档
文档目录8 节
  1. Install
  2. Use it
  3. Color modes
  4. Scrollbars
  5. Tokens
  6. What it configures
  7. Change a value
  8. Develop

@carissa-io/theme-default

The Carissa Default theme: Swiss minimalism (square corners, absolute black for primary actions and focus, a neutral grey scale, a neutral grotesque type stack). The Carissa components ship neutral defaults and no look of their own; this package gives them one by overriding their SCSS variables. The decisions behind the values are in DESIGN.md.

Install

npm install @carissa-io/theme-default

The compiled CSS needs nothing else. To compile the SCSS yourself, also install the components you use (they are optional peer dependencies).

Use it

  1. Compiled CSS (nothing to compile; the components must still be installed to render):
    import '@carissa-io/theme-default/css'
    
    It is also the package's main export, so import '@carissa-io/theme-default' works with a bundler that handles CSS.
  2. SCSS source: forward or @use it from your own Sass entry, with @carissa-io/* resolvable (node_modules on the load path):
    @use '@carissa-io/theme-default/scss';
    
  3. Tokens (Sass variables only, no CSS): see Tokens.
  4. A starting point for a new theme: copy scss/index.scss and scss/_tokens.scss and change the values. In the Carissa workspace, scripts/new-theme.sh <name> "<description>" does this and sets up the repo.

Color modes

The theme has a light and a dark palette in one package. The palette is a set of CSS custom properties (--c-background, --c-text, --c-muted, --c-surface, --c-surface-active, --c-primary, --c-on-primary, --c-primary-hover, --c-primary-active, --c-disabled-text, --c-disabled-border, --c-error, --c-success, --c-warning, --c-info, --c-focus, --c-scrollbar-thumb, --c-scrollbar-track) that every component reads. Dark is opt-in per app: without the attribute below the app is light, exactly as before.

An app opts in with one line in the file where it imports the theme (App/theme.js), setting the mode on <html>:

import '@carissa-io/theme-default/css'

document.documentElement.dataset.mode = 'auto' // 'auto' | 'dark' | 'light'
data-mode on <html>Result
nonelight
lightlight
darkdark
autolight, and dark while the system asks for it (prefers-color-scheme: dark)

color-scheme follows the mode, so native controls and scrollbars match. To avoid a flash of the wrong mode, set the attribute before the first paint: put this in the <head> of the page, before the stylesheet, with the choice the app remembers (here in localStorage):

<script>
    try {
        document.documentElement.dataset.mode = localStorage.getItem('mode') || 'auto'
    } catch {
        document.documentElement.dataset.mode = 'auto'
    }
</script>

The Sass tokens above stay the static light values (for Sass consumers); the dark values are in scss/_modes.scss. The page background and text color are the app's: give body background: var(--c-background); color: var(--c-text).

Scrollbars

The theme styles every scroll container with no change in any component: the page (the viewport bar follows), the message list, the table wrapper, the modal and drawer bodies, the select, combobox and listbox popups, the sidebar and code blocks. The two palette roles --c-scrollbar-thumb and --c-scrollbar-track follow data-mode.

  • Chrome, Edge, Safari and other Blink / WebKit browsers get an 8px bar ($scrollbar-size) with a square thumb ($scrollbar-radius, which is the shared $radius, so a theme with rounded corners gets a rounded thumb) and no arrow buttons, drawn with the *::-webkit-scrollbar pseudo-elements. The standard scrollbar-color and scrollbar-width are deliberately not used there: from Chrome 121 they switch the bar to the standardized rendering (rounded thumb, arrows can remain) and make the pseudo-elements ignored.
  • Firefox has no such pseudo-elements, so it gets the standard properties (scrollbar-color on :root, scrollbar-width: thin from $scrollbar-width on *), coloured with the same roles. Their shape cannot be styled: the thumb ends are not square there.
  • Older engines keep the native bar.

All the rules have zero or near-zero specificity (* and *::-webkit-scrollbar...), so any component rule or your own rule wins over them; the carousel already hides its own bar.

To change them in your own theme, set $scrollbar-thumb, $scrollbar-track, $scrollbar-size, $scrollbar-radius and $scrollbar-width in your scss/_tokens.scss (and the dark values of the two roles in scss/_modes.scss); keep the thumb at 3:1 or more against the track and against the background. The default track is the page background, so inside a surface-coloured container (the sidebar, a card) it shows as a strip of the page colour; a theme that prefers it quieter there sets $scrollbar-track to its surface value. An app that only needs one scroller to look different overrides ::-webkit-scrollbar-thumb (and scrollbar-color for Firefox) on that element. See DESIGN.md for the values and limits.

Tokens

The palette and the values shared by every component are Sass variables in scss/_tokens.scss, the single source of the theme's values (scss/index.scss reads them with @use 'tokens' as *). The file emits no CSS, so an app can read the values without pulling any rule in. The names are the public token API: renaming or removing one is a breaking change.

@use '@carissa-io/theme-default/scss/tokens' as theme;
TokenValueUse
$black#000primary, hover and focus
$white#fffsurfaces
$text#171717body text
$muted#666666labels, field borders, placeholders
$surface#f5f5f5hover surface, disabled background
$surface-active#e5e5e5pressed surface, dividers
$primary-hover#262626primary action on hover
$primary-active#404040primary action while pressed
$disabled-text#a3a3a3disabled text and marks
$disabled-border#d4d4d4disabled borders
$error#dc3545error text and borders
$success#15803dsuccess accent and icon (Alert)
$warning#a16207warning accent and icon (Alert)
$info#1d4ed8info accent and icon (Alert)
$scrollbar-thumb#737373scrollbar thumb
$scrollbar-track$whitescrollbar track (the page ground)
$scrollbar-widththinscrollbar thickness where the standard property is used (Firefox)
$scrollbar-size0.5remscrollbar thickness in Blink and WebKit
$scrollbar-radius$radiusscrollbar thumb radius in Blink and WebKit (square here)
$font-family'Helvetica Neue', Helvetica, Arial, 'Liberation Sans', sans-seriftype stack
$font-family-monoui-monospace, 'SFMono-Regular', Menlo, Consolas, 'Liberation Mono', monospacemonospace stack for system data and code
$radius0corner radius
$min-height2.75remtouch target
$focus-color$blackfocus color
$focus-width1pxfocus ring width
$transition-duration0.2scolor and border transitions
$motion-duration-short0.25squick entrances and small moves (scramble settle, four of them make the typewriter cursor blink)
$motion-duration-medium0.5sthe default entrance (animate) and the highlight-sweep
$motion-duration-long0.9scounts (counter), reveals and other slow moves
$motion-easingcubic-bezier(0.16, 1, 0.3, 1)the one decelerating easing of the motion components
$motion-stagger0.15sgap between the items of a sequence or a stagger-list
$label-font-size0.6875remfield label size
$label-font-weight700field label weight
$label-letter-spacing0.1emfield label tracking
$font-size-display3.5remHeading display
$font-size-h12.5remHeading 1
$font-size-h21.75remHeading 2
$font-size-h31.25remHeading 3
$font-size-h41.125remHeading 4
$font-size-h51remHeading 5
$font-size-h60.875remHeading 6, Text mono
$font-size-lead1.25remText lead
$font-size-body1rembody text, and the text of every field and option (16px)
$font-size-small0.875remText small
$font-size-caption0.75remText caption
$font-size-overline$label-font-sizeText overline
$font-weight-regular400body text
$font-weight-bold700titles from h3, selected option
$font-weight-black900display, h1 and h2
$line-height-tight1.3h3 and h4
$line-height-normal1.5running text
$arrow-size1remdropdown arrow size
$arrow-offset0.75remdropdown arrow inset
$arrow-color$muteddropdown arrow color
$arrow-color-active$blackdropdown arrow on hover and when open
$arrow-color-disabled$disabled-textdropdown arrow when disabled
$arrow-transitionrotate and color, $transition-durationdropdown arrow motion
$arrow-rotate-open180degdropdown arrow rotation when open

Recommended for apps: configure Bootstrap from the tokens, so the app and the Carissa components share one palette. Needs sass-embedded (or sass) and a bundler whose Sass importer respects package exports (Vite does):

@use '@carissa-io/theme-default/scss/tokens' as theme;
@use 'bootstrap/scss/bootstrap' with (
    $primary: theme.$black,
    $font-family-sans-serif: theme.$font-family,
    $body-bg: theme.$surface
);

Outside a bundler, put node_modules on the Sass load path (sass --load-path=node_modules).

Every theme repo has its own tokens, with the same names. Switching theme means the same @use path with another package name (@carissa-io/theme-<name>/scss/tokens). A theme that does not define a token must not be used with code that expects it: check the names against the theme's scss/_tokens.scss before you switch.

What it configures

components-input, -button, -checkbox, -switch, -radio-group, -slider, -popover, -listbox, -select, -combobox, -upload, -calendar, -date-picker, -search, -typography, -card, -alert, -spinner, -modal, -toast, -divider, -badge, -tag, -link, -avatar, -skeleton, -progress, -tooltip, -prose, -tabs, -accordion, -breadcrumb, -pagination, -stepper, -sidebar, -navbar, -drawer, -menu, -table, -list, -description-list, -stat, -empty-state, -timeline, -tree, -code, -field, -number-input, -otp-input, -phone, -tag-input, -time-picker, -date-range, -rating, -color-picker, -async-autocomplete, -section, -faq, -carousel, -visually-hidden, -live-region, -theme-switch, -icon, -ai-label, -thinking-indicator, -streaming-text, -message, -message-list, -prompt-input, -suggested-prompts, -message-actions, -animate, -sequence, -typewriter, -scramble, -counter, -highlight-sweep, -ticker, -stagger-list, -demo, -feature-card and -device-frame. components-email, -password, -url and -textarea are styled through the input.

The checkbox's mixed state (indeterminate, from the next components-checkbox release, class c-checkbox--indeterminate) is the checked box with a 10px dash in --c-on-primary; on an older checkbox the rule is simply unused.

Change a value

The palette and the values shared by every component (fonts, radius, minimum height, focus ring, transition, label style, dropdown arrow) are the Sass variables of scss/_tokens.scss (the tokens); each component has one @use ... with (...) block of overrides below. Change the value, run npm run build, and update DESIGN.md if the decision changes.

Develop

npm install
npm run lint    # compile, fail on any Sass error or warning
npm test        # builds, then checks every component root has rules and dist/ is current
npm run build   # dist/index.css

dist/ is not committed; it is built before every publish. The package ships dist, scss and DESIGN.md. Releases follow the Carissa project rules: branch and pull request, CI publishes when the version on main is new.

版本与发布记录

@carissa-io/theme-default 共发布 31 个版本,首次发布于 2026/10/13;过去 12 个月发布了 31 个版本。

版本发布日期距今
0.3.24latest2026/11/09今天
0.3.232026/11/09今天
0.3.222026/11/08今天
0.3.212026/11/071 天前
0.3.202026/11/054 天前
0.3.192026/11/044 天前

关于 @carissa-io/theme-default 的常见问题

@carissa-io/theme-default 是什么?

Carissa UI: the default theme (Swiss minimalism) as SCSS variable overrides of the Carissa components, with a compiled CSS build

如何安装 @carissa-io/theme-default?

在项目目录运行 npm install @carissa-io/theme-default,或使用 pnpm add / yarn add / bun add。

@carissa-io/theme-default 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/carissa-io__theme-default 是否存在。

@carissa-io/theme-default 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@carissa-io/theme-default 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=24。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@carissa-io/theme-default 可以商用吗?

@carissa-io/theme-default 使用 UNLICENSED 许可。作者声明为 UNLICENSED,即不授予公开使用许可(与公共领域的 Unlicense 不同)。使用前需获得作者授权。以上为概括,不构成法律意见,请以许可原文为准。

@carissa-io/theme-default 的下载量有多少?

根据 npm 官方下载统计,@carissa-io/theme-default 在 2026/10/09 – 2026/11/07 这 30 天内被下载 2,694 次,日均约 90 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@carissa-io/theme-default 还在维护吗?

最新版本 0.3.24 发布于 2026/11/09(今天);至今共发布 31 个版本,其中过去 12 个月发布了 31 个;首次发布于 2026/10/13。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。