@kanso-labs/kanso-ui 0.38.0 → 0.39.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/README.md +157 -27
  2. package/dist/button/hooks.js +1 -1
  3. package/dist/button/index.js +1 -1
  4. package/dist/button/index.js.map +1 -1
  5. package/dist/collection/index.js +4 -4
  6. package/dist/collection/index.js.map +1 -1
  7. package/dist/color-scheme.d.ts +19 -12
  8. package/dist/color-scheme.js +22 -15
  9. package/dist/color-scheme.js.map +1 -1
  10. package/dist/components/app-bar/index.d.ts +10 -14
  11. package/dist/components/app-bar/index.js +12 -12
  12. package/dist/components/app-bar/index.js.map +1 -1
  13. package/dist/components/avatar/index.d.ts +15 -1
  14. package/dist/components/avatar/index.js +43 -145
  15. package/dist/components/avatar/index.js.map +1 -1
  16. package/dist/components/breadcrumbs/index.d.ts +1 -1
  17. package/dist/components/breadcrumbs/index.js.map +1 -1
  18. package/dist/components/button/index.js +3 -3
  19. package/dist/components/button/index.js.map +1 -1
  20. package/dist/components/chip/index.js +27 -25
  21. package/dist/components/chip/index.js.map +1 -1
  22. package/dist/components/chip-group/index.d.ts +22 -1
  23. package/dist/components/chip-group/index.js +3 -3
  24. package/dist/components/chip-group/index.js.map +1 -1
  25. package/dist/components/code/index.js +1 -1
  26. package/dist/components/code/index.js.map +1 -1
  27. package/dist/components/color-picker/index.d.ts +5 -5
  28. package/dist/components/color-picker/index.js +46 -51
  29. package/dist/components/color-picker/index.js.map +1 -1
  30. package/dist/components/color-swatch-picker/index.d.ts +1 -1
  31. package/dist/components/color-swatch-picker/index.js.map +1 -1
  32. package/dist/components/combo-box/index.d.ts +5 -5
  33. package/dist/components/combo-box/index.js +33 -35
  34. package/dist/components/combo-box/index.js.map +1 -1
  35. package/dist/components/copy-field/index.js +1 -1
  36. package/dist/components/copy-field/index.js.map +1 -1
  37. package/dist/components/currency/index.d.ts +16 -0
  38. package/dist/components/currency/index.js +16 -0
  39. package/dist/components/currency/index.js.map +1 -1
  40. package/dist/components/date-picker/index.d.ts +5 -5
  41. package/dist/components/date-picker/index.js +35 -40
  42. package/dist/components/date-picker/index.js.map +1 -1
  43. package/dist/components/date-range-picker/index.d.ts +5 -5
  44. package/dist/components/date-range-picker/index.js +35 -40
  45. package/dist/components/date-range-picker/index.js.map +1 -1
  46. package/dist/components/dialog/index.d.ts +9 -9
  47. package/dist/components/dialog/index.js +29 -22
  48. package/dist/components/dialog/index.js.map +1 -1
  49. package/dist/components/disclosure/index.d.ts +1 -1
  50. package/dist/components/disclosure/index.js.map +1 -1
  51. package/dist/components/fab-menu/index.d.ts +4 -2
  52. package/dist/components/fab-menu/index.js.map +1 -1
  53. package/dist/components/index.d.ts +4 -2
  54. package/dist/components/list/index.d.ts +3 -3
  55. package/dist/components/list/index.js +2 -2
  56. package/dist/components/list/index.js.map +1 -1
  57. package/dist/components/list-box/index.d.ts +3 -3
  58. package/dist/components/list-box/index.js +2 -2
  59. package/dist/components/list-box/index.js.map +1 -1
  60. package/dist/components/list-item/index.js +1 -1
  61. package/dist/components/loading-indicator/index.d.ts +30 -0
  62. package/dist/components/loading-indicator/index.js +71 -0
  63. package/dist/components/loading-indicator/index.js.map +1 -0
  64. package/dist/components/menu/index.d.ts +8 -8
  65. package/dist/components/menu/index.js +2 -2
  66. package/dist/components/menu/index.js.map +1 -1
  67. package/dist/components/navigation-tree/index.d.ts +2 -2
  68. package/dist/components/navigation-tree/index.js.map +1 -1
  69. package/dist/components/popover/index.d.ts +7 -7
  70. package/dist/components/popover/index.js.map +1 -1
  71. package/dist/components/product-icon/index.d.ts +1 -1
  72. package/dist/components/product-icon/index.js +28 -142
  73. package/dist/components/product-icon/index.js.map +1 -1
  74. package/dist/components/progress-indicator/index.d.ts +21 -15
  75. package/dist/components/progress-indicator/index.js +485 -185
  76. package/dist/components/progress-indicator/index.js.map +1 -1
  77. package/dist/components/search-view/index.d.ts +5 -5
  78. package/dist/components/search-view/index.js.map +1 -1
  79. package/dist/components/segmented-button/index.d.ts +1 -1
  80. package/dist/components/segmented-button/index.js.map +1 -1
  81. package/dist/components/select/index.d.ts +5 -5
  82. package/dist/components/select/index.js +5 -2
  83. package/dist/components/select/index.js.map +1 -1
  84. package/dist/components/sheet/index.d.ts +10 -10
  85. package/dist/components/sheet/index.js +27 -20
  86. package/dist/components/sheet/index.js.map +1 -1
  87. package/dist/components/slider/index.js +1 -1
  88. package/dist/components/slider/index.js.map +1 -1
  89. package/dist/components/split-button/index.d.ts +4 -2
  90. package/dist/components/split-button/index.js.map +1 -1
  91. package/dist/components/stack/index.d.ts +4 -1
  92. package/dist/components/stack/index.js +7 -1
  93. package/dist/components/stack/index.js.map +1 -1
  94. package/dist/components/table/index.d.ts +7 -7
  95. package/dist/components/table/index.js +39 -26
  96. package/dist/components/table/index.js.map +1 -1
  97. package/dist/components/tabs/index.d.ts +4 -4
  98. package/dist/components/tabs/index.js +59 -27
  99. package/dist/components/tabs/index.js.map +1 -1
  100. package/dist/components/text/index.d.ts +22 -9
  101. package/dist/components/text/index.js +22 -5
  102. package/dist/components/text/index.js.map +1 -1
  103. package/dist/components/time-picker/index.d.ts +110 -0
  104. package/dist/components/time-picker/index.js +954 -0
  105. package/dist/components/time-picker/index.js.map +1 -0
  106. package/dist/components/tooltip/index.d.ts +5 -5
  107. package/dist/components/tooltip/index.js +1 -0
  108. package/dist/components/tooltip/index.js.map +1 -1
  109. package/dist/components/tree/index.d.ts +2 -2
  110. package/dist/components/tree/index.js +2 -2
  111. package/dist/components/tree/index.js.map +1 -1
  112. package/dist/glyphs/index.js +37 -1
  113. package/dist/glyphs/index.js.map +1 -1
  114. package/dist/i18n/index.js +4 -0
  115. package/dist/i18n/index.js.map +1 -1
  116. package/dist/i18n/messages.js +136 -0
  117. package/dist/i18n/messages.js.map +1 -1
  118. package/dist/index.d.ts +6 -3
  119. package/dist/index.js +5 -2
  120. package/dist/indicator/index.js +38 -35
  121. package/dist/indicator/index.js.map +1 -1
  122. package/dist/mark/index.js +137 -0
  123. package/dist/mark/index.js.map +1 -0
  124. package/dist/mark/initials.js +42 -0
  125. package/dist/mark/initials.js.map +1 -0
  126. package/dist/mark/styles.js +91 -0
  127. package/dist/mark/styles.js.map +1 -0
  128. package/dist/render/ref.js +35 -1
  129. package/dist/render/ref.js.map +1 -1
  130. package/dist/render/useRender.js +1 -30
  131. package/dist/render/useRender.js.map +1 -1
  132. package/dist/styles/picker.js +29 -1
  133. package/dist/styles/picker.js.map +1 -1
  134. package/dist/styles.css +685 -231
  135. package/dist/theme-scope.d.ts +40 -0
  136. package/dist/theme-scope.js +112 -0
  137. package/dist/theme-scope.js.map +1 -0
  138. package/dist/tokens/design.tokens.stylex.js +39 -5
  139. package/dist/tokens/design.tokens.stylex.js.map +1 -1
  140. package/package.json +2 -1
package/README.md CHANGED
@@ -20,6 +20,9 @@ Every component is documented in Storybook, published from the latest release at
20
20
  npm install @kanso-labs/kanso-ui
21
21
  ```
22
22
 
23
+ Coming from an earlier 0.x release? [`UPGRADING.md`](UPGRADING.md) lists every
24
+ breaking change on the way to 1.0, with the edit each one asks for.
25
+
23
26
  ## Usage
24
27
 
25
28
  ```tsx
@@ -36,13 +39,19 @@ default, in both light and dark (respecting the OS-level
36
39
  `prefers-color-scheme`), and every component sizes itself with
37
40
  `box-sizing: border-box` rather than leaving that to a reset you supply.
38
41
 
39
- A bundler is what resolves that stylesheet. In an environment that cannot import
40
- CSS from JavaScript — some server-side renderers, or a plain Node process —
41
- import it yourself instead and the components style themselves the same way:
42
+ A bundler is what resolves that stylesheet, so the package always loads through
43
+ one. The main entry imports `./styles.css` itself and Node has no loader for
44
+ CSS, so in plain Node an `import` or a `require()` of `@kanso-labs/kanso-ui`
45
+ throws `ERR_UNKNOWN_FILE_EXTENSION`; `@kanso-labs/kanso-ui/date` is the one
46
+ entry plain Node can load. A server renderer or a test runner that leaves
47
+ dependencies to Node takes one setting to hand this package to its bundler
48
+ instead, and [Server rendering and tests](#server-rendering-and-tests) gives it
49
+ for Vite, Vitest and Jest.
42
50
 
43
- ```ts
44
- import '@kanso-labs/kanso-ui/styles.css'
45
- ```
51
+ The same stylesheet is published on its own, as
52
+ `@kanso-labs/kanso-ui/styles.css`, for CSS that loads it apart from the
53
+ JavaScript: an `@import` in a stylesheet of your own, or a `<link>`. It adds the
54
+ rules and nothing else, so it is not a way round the main entry's own import.
46
55
 
47
56
  `className` and `style` reach the element a component renders, so a component is
48
57
  positioned from the call site like any other element:
@@ -203,7 +212,7 @@ the page scrolls, becoming the small bar:
203
212
  contentMaxInlineSize="960px"
204
213
  headline="Headline"
205
214
  scrolled={scrollTop > 0}
206
- size="large"
215
+ size="lg"
207
216
  />
208
217
  {page}
209
218
  </div>
@@ -367,13 +376,70 @@ Four things follow from where that boundary falls.
367
376
  ```
368
377
 
369
378
  - **The React Aria utilities the package re-exports are client-only** —
370
- `I18nProvider`, `useListData`, `parseColor` and the rest. `collectionSizes` is
371
- a plain value and works on either side.
379
+ `I18nProvider`, `useListData`, `parseColor` and the rest. `collectionSizes`,
380
+ `colorScheme` and `themeScope` are plain values and work on either side.
372
381
  - **A server-rendered app wraps its tree in `I18nProvider`** with the request's
373
382
  locale. React Aria reads the browser's locale on the client and has none on
374
383
  the server, so without it a date or a number can render differently on the two
375
384
  and fail hydration.
376
385
 
386
+ ### Server rendering and tests
387
+
388
+ The main entry imports its own stylesheet, so the package has to reach a bundler
389
+ wherever it runs. Three tools hand dependencies to Node by default, and each has
390
+ a setting that sends this package through its bundler instead.
391
+
392
+ **Vite's server rendering** leaves dependencies to Node, in `vite dev` and in a
393
+ built server alike, so the server of a Vite-based framework — React Router's
394
+ framework mode, TanStack Start, Astro, Vike — throws
395
+ `ERR_UNKNOWN_FILE_EXTENSION` for `dist/styles.css` as it starts. Name the
396
+ package in `ssr.noExternal`, wherever the framework takes its Vite settings
397
+ (Astro's sit under `vite` in `astro.config.mjs`):
398
+
399
+ ```ts
400
+ // vite.config.ts
401
+ import { defineConfig } from 'vite'
402
+
403
+ export default defineConfig({
404
+ ssr: { noExternal: ['@kanso-labs/kanso-ui'] },
405
+ })
406
+ ```
407
+
408
+ **Vitest** leaves dependencies to Node too, so the first test that imports a
409
+ component fails with `Unknown file extension ".css"`. Inline the package:
410
+
411
+ ```ts
412
+ // vitest.config.ts
413
+ import { defineConfig } from 'vitest/config'
414
+
415
+ export default defineConfig({
416
+ test: { server: { deps: { inline: ['@kanso-labs/kanso-ui'] } } },
417
+ })
418
+ ```
419
+
420
+ **Jest** wants a stand-in for the stylesheet, since it has no loader for CSS,
421
+ and a transform for the package, since the package is ES modules:
422
+
423
+ ```js
424
+ // jest.config.cjs
425
+ module.exports = {
426
+ moduleNameMapper: { '\\.css$': '<rootDir>/style-stub.cjs' },
427
+ transformIgnorePatterns: [
428
+ '^(?!.*/node_modules/@kanso-labs/kanso-ui/).*/node_modules/',
429
+ ],
430
+ }
431
+ ```
432
+
433
+ `style-stub.cjs` is `module.exports = {}`, and the transform needs a Babel
434
+ config that compiles modules to CommonJS, such as `@babel/preset-env`. The
435
+ pattern is written to let in everything under the package, its own
436
+ `dist/node_modules` included, which carries StyleX's runtime: the shorter
437
+ `/node_modules/(?!@kanso-labs/kanso-ui/)` matches again at that second
438
+ `node_modules` and leaves the runtime untransformed. On Node 24.9 or newer, Jest
439
+ 30 can load the package as ES modules instead, under
440
+ `NODE_OPTIONS=--experimental-vm-modules`, and then needs the `moduleNameMapper`
441
+ alone.
442
+
377
443
  ## Theming
378
444
 
379
445
  Every design token — color, spacing, radii, sizing, shadows, typography,
@@ -395,10 +461,8 @@ component, independent of your app's build tooling:
395
461
  }
396
462
  ```
397
463
 
398
- Overrides must target `:root` (or another selector matching the `<html>`
399
- element) — components resolve their tokens once, at the root, so redeclaring a
400
- `--kui-*` property on a smaller scope (e.g. a wrapping `<div>`) doesn't reach
401
- them.
464
+ Overrides on `:root` reach the whole page. To theme part of one, declare them on
465
+ a `ThemeScope` instead — see [Theming part of a page](#theming-part-of-a-page).
402
466
 
403
467
  [`@kanso-labs/kanso-ui/tokens.css`](src/tokens/design.tokens.css) is the
404
468
  canonical, generated reference for every available variable and its current
@@ -409,41 +473,107 @@ default value — useful for discovering names, not required at runtime
409
473
  import '@kanso-labs/kanso-ui/tokens.css'
410
474
  ```
411
475
 
476
+ ### Theming part of a page
477
+
478
+ The tokens resolve once, on `:root`, and every component inherits them already
479
+ resolved, so a `--kui-*` property redeclared on a smaller element — a wrapping
480
+ `<div>` — reaches nothing on its own. `ThemeScope` resolves them again on an
481
+ element of its own. An override declared on the scope, through `className` or
482
+ `style`, or on any element around it, reaches every component inside, and the
483
+ rest of the page keeps its own tokens:
484
+
485
+ ```css
486
+ .accent {
487
+ --kui-color-primary: #7d5260;
488
+ --kui-color-on-primary: #ffffff;
489
+ }
490
+ ```
491
+
492
+ ```tsx
493
+ import { Select, ThemeScope } from '@kanso-labs/kanso-ui'
494
+
495
+ function Section() {
496
+ return (
497
+ <ThemeScope className="accent">
498
+ <Select label="Label">…</Select>
499
+ </ThemeScope>
500
+ )
501
+ }
502
+ ```
503
+
504
+ `scheme` pins the scope to `'light'` or `'dark'`, whatever the OS asks for. Left
505
+ unset, the scope keeps the scheme around it, so a scope inside a dark page stays
506
+ dark.
507
+
508
+ Overlays come along. React Aria portals a popover, a sheet, a tooltip or a
509
+ snackbar to the end of `<body>`, outside any wrapper; one opened inside a
510
+ `ThemeScope` portals into the scope instead, and takes its tokens with it. The
511
+ cost is that an ancestor confining its descendants confines those overlays too —
512
+ a `transform` or a `filter` makes a sheet's scrim cover that ancestor rather
513
+ than the viewport, and `overflow: hidden` clips a popover — so put the scope
514
+ around such an element rather than inside it.
515
+
516
+ `themeScope` is the same thing as a class name, for an element you render
517
+ yourself. Overlays opened under it still portal to the body and keep the page's
518
+ tokens, since nothing tells them otherwise.
519
+
412
520
  ### Pinning light or dark
413
521
 
414
522
  The colours follow the reader's OS through `prefers-color-scheme` unless the app
415
523
  says otherwise. An app with a theme switch of its own pins a scheme with
416
- `colorScheme`, two class names: put `colorScheme.light` or `colorScheme.dark` on
417
- the `<html>` element, and remove both to follow the OS again. The `<html>`
418
- element is the place for it, since overlays are portalled to the body and still
419
- sit inside it.
524
+ `colorScheme`: put `colorScheme.light` or `colorScheme.dark` on the `<html>`
525
+ element, and remove it to follow the OS again. The `<html>` element is the place
526
+ for it, since overlays are portalled to the body and still sit inside it. Either
527
+ also works on a smaller element, as a `themeScope` that pins.
420
528
 
421
- Its shape is the one next-themes takes for class names, so a provider is all it
422
- needs:
529
+ Each is several class names separated by spaces, so set it through `className`,
530
+ or spread `name.split(' ')` into `classList.add`. A provider that adds one class
531
+ per scheme throws on it — next-themes' `value` option is one. With a provider of
532
+ that kind, render a `ThemeScope` around the app instead and hand it the
533
+ provider's scheme:
423
534
 
424
535
  ```tsx
425
- import { ThemeProvider } from 'next-themes'
426
- import { colorScheme } from '@kanso-labs/kanso-ui'
536
+ 'use client'
537
+
538
+ import { ThemeProvider, useTheme } from 'next-themes'
539
+ import { useEffect, useState } from 'react'
540
+ import { ThemeScope } from '@kanso-labs/kanso-ui'
541
+
542
+ function Scheme({ children }: { children: React.ReactNode }) {
543
+ const { resolvedTheme } = useTheme()
544
+ const [mounted, setMounted] = useState(false)
545
+ useEffect(() => setMounted(true), [])
546
+ const scheme =
547
+ mounted && (resolvedTheme === 'dark' || resolvedTheme === 'light')
548
+ ? resolvedTheme
549
+ : undefined
550
+
551
+ return <ThemeScope scheme={scheme}>{children}</ThemeScope>
552
+ }
427
553
 
428
554
  function Providers({ children }: { children: React.ReactNode }) {
429
555
  return (
430
- <ThemeProvider attribute="class" value={colorScheme}>
431
- {children}
556
+ <ThemeProvider attribute="data-theme">
557
+ <Scheme>{children}</Scheme>
432
558
  </ThemeProvider>
433
559
  )
434
560
  }
435
561
  ```
436
562
 
563
+ The server cannot know the stored choice, so the scope takes it only once the
564
+ page has mounted, which keeps the first client render matching the server's. The
565
+ first paint follows the OS until then.
566
+
437
567
  A `--kui-color-*` override on `:root` still applies under a pinned scheme. To
438
568
  give one scheme a value of its own, key the override on an attribute your switch
439
569
  sets beside the class, since the class names are generated.
440
570
 
441
571
  ### For StyleX consumers
442
572
 
443
- If your app also uses StyleX, theme with
444
- [`stylex.createTheme()`](https://stylexjs.com/docs/learn/theming/) instead — it
445
- produces a scoped override class rather than a global one. The token objects
446
- themselves (`colors`, `typography`, `spacing`, `radii`, `sizing`, `shadows`,
573
+ An app that also uses StyleX themes the same way, through the `--kui-*`
574
+ properties and `ThemeScope`. The token objects
575
+ [`stylex.createTheme()`](https://stylexjs.com/docs/learn/theming/) would take
576
+ (`colors`, `typography`, `spacing`, `radii`, `sizing`, `shadows`,
447
577
  `stateLayerOpacity` and `motion`) aren't part of the public API yet; open an
448
578
  issue if you need them exported.
449
579
 
@@ -1,6 +1,6 @@
1
+ import { refCallback } from "../render/ref.js";
1
2
  import { ariaAttributesOf } from "../render/aria.js";
2
3
  import { useRipple } from "../hooks/useRipple.js";
3
- import { refCallback } from "../render/ref.js";
4
4
  import { c } from "react/compiler-runtime";
5
5
  import { ButtonContext, useSlottedContext } from "react-aria-components";
6
6
  //#region src/button/hooks.ts
@@ -146,8 +146,8 @@ function buttonContent(children, pendingLabel, surface) {
146
146
  ...props(buttonBaseStyles.pending),
147
147
  children: /* @__PURE__ */ jsx(ProgressIndicator, {
148
148
  "aria-label": pendingLabel,
149
+ diameter: "1em",
149
150
  isIndeterminate: true,
150
- size: "1em",
151
151
  tone: "inherit",
152
152
  variant: "circular"
153
153
  })
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["DOMAttributes","ReactNode","RefAttributes","ButtonRenderProps","ClassNameOrFunction","ButtonProps","RACButtonProps","ToggleButtonProps","RACToggleButtonProps","StyleOrFunction","stylex","Button","RACButton","Link","RACLink","ToggleButton","RACToggleButton","ProgressIndicator","useToggleGroupDisabled","useMessages","buttonRenderer","linkRenderer","toggleButtonRenderer","mergeStatefulStyles","useButtonBase","buttonBaseStyles","ButtonBaseProps","children","classes","state","ButtonState","ReturnType","props","className","disableRipple","href","pendingLabel","rel","style","target","ButtonDOMProps","HTMLAnchorElement","HTMLButtonElement","Omit","GlobalEventKey","Pick","HTMLElement","isSelected","Exclude","ToggleButtonBaseProps","defaultSelected","onChange","ButtonBase","t0","$","_c","input","render","t1","isPending","undefined","messages","disabled","element","ref","ripple","t2","styleProps","t3","t4","handlers","surface","t5","loading","t6","buttonContent","t7","label","labelPending","pending","ToggleButtonBase","disabledByGroup","id","isDisabled","toggleRender","toggleContent","_c","RACLink","RACButton","stylex.props","RACToggleButton"],"sources":["../../src/button/index.tsx"],"sourcesContent":["import type { DOMAttributes, ReactNode, RefAttributes } from 'react';\nimport type { ButtonRenderProps, ClassNameOrFunction, ButtonProps as RACButtonProps, ToggleButtonProps as RACToggleButtonProps, StyleOrFunction } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { Button as RACButton, Link as RACLink, ToggleButton as RACToggleButton } from 'react-aria-components';\nimport ProgressIndicator from '../components/progress-indicator';\nimport { useToggleGroupDisabled } from '../hooks/useToggleGroupDisabled';\nimport { useMessages } from '../i18n';\nimport { buttonRenderer, linkRenderer, toggleButtonRenderer } from '../render/aria';\nimport { mergeStatefulStyles } from '../styles/merge';\nimport { useButtonBase } from './hooks';\nimport { buttonBaseStyles } from './styles';\n\n// The press-button core Button and IconButton both render through. A button\n// is React Aria's `Button`, its `Link` once given `href`, or its\n// `ToggleButton` once it reports a state, and around each this adds what\n// React Aria leaves out: the ripple, the disabled state a parent's context\n// sets, the `aria-*` props and keyboard handlers it would drop or wrap, and\n// the ring drawn over the label while the button is pending. Each component\n// brings its own classes, as a function of the render state, and the call\n// site's `className` and `style` are merged over them.\n//\n// One module rather than a copy in each, since the copies had already drifted\n// once: IconButton read `ButtonContext` for a parent's disabled state and\n// Button did not. Not a component of the library's own and not exported from\n// the package; see `src/row` for the same arrangement around a list's row.\n\ntype ButtonBaseProps = {\n children?: ReactNode;\n /**\n * The component's own classes, from the render state. The call site's\n * `className` and `style` are merged over them.\n */\n classes: (state: ButtonState) => ReturnType<typeof stylex.props>;\n className?: ClassNameOrFunction<ButtonState>;\n disableRipple?: boolean;\n href?: string;\n pendingLabel?: string;\n rel?: string;\n style?: StyleOrFunction<ButtonState>;\n target?: string;\n} & ButtonDOMProps & RefAttributes<HTMLAnchorElement | HTMLButtonElement>;\n\n// The props a button hands React Aria. React Aria types the global DOM events\n// — pointer, mouse, touch, wheel and the rest — against the element each\n// component renders, and a handler written for a <button> does not type-check\n// against an <a>. The keys are retyped against HTMLElement here so one set of\n// props serves both forms; the events React Aria defines itself (press,\n// focus, keyboard) keep its types, since it hands those its own event objects.\ntype ButtonDOMProps = Omit<RACButtonProps, 'children' | 'className' | 'style' | GlobalEventKey> & Pick<DOMAttributes<HTMLElement>, GlobalEventKey>;\n\n// The render state React Aria's three elements share. A className or style\n// function written against it serves the button, the link and the toggle\n// alike; `isPending` belongs to the button alone, and `isCurrent` to the\n// link, so neither is here. What the button draws while pending is decided\n// in `buttonContent`, which sees React Aria's own state rather than this one.\n//\n// `isSelected` is optional because only the toggle has one: React Aria hands\n// the button and the link a state without it and the toggle a state with\n// it, and a parameter type this wide accepts either.\ntype ButtonState = Pick<ButtonRenderProps, 'isDisabled' | 'isFocused' | 'isFocusVisible' | 'isHovered' | 'isPressed'> & {\n isSelected?: boolean;\n};\ntype GlobalEventKey = Exclude<keyof DOMAttributes<HTMLElement> & keyof RACButtonProps, 'onBlur' | 'onClick' | 'onFocus'>;\ntype ToggleButtonBaseProps = {\n children?: ReactNode;\n /** As for ButtonBase, handed `isSelected` as well. */\n classes: (state: ButtonState) => ReturnType<typeof stylex.props>;\n className?: ClassNameOrFunction<ButtonState>;\n defaultSelected?: boolean;\n disableRipple?: boolean;\n isSelected?: boolean;\n onChange?: (isSelected: boolean) => void;\n style?: StyleOrFunction<ButtonState>;\n} & ButtonDOMProps & RefAttributes<HTMLAnchorElement | HTMLButtonElement>;\n\n/**\n * A button drawn with the classes a component hands it: React Aria's\n * `Button`, or its `Link` given `href`. See the header.\n */\nfunction ButtonBase({\n children,\n classes,\n href,\n isPending = false,\n pendingLabel,\n rel,\n render,\n target,\n ...input\n}: ButtonBaseProps) {\n const messages = useMessages();\n const {\n disabled,\n element,\n props,\n ref,\n ripple\n } = useButtonBase(input, isPending);\n const styleProps = mergeStatefulStyles(classes, props);\n if (href !== undefined) {\n return <RACLink href={href} isDisabled={disabled} ref={ref} rel={rel} render={linkRenderer(element)} target={target} {...ripple.handlers} {...props} {...styleProps}>\n {children}\n {ripple.surface}\n </RACLink>;\n }\n return <RACButton isDisabled={disabled} isPending={isPending} ref={ref} render={buttonRenderer(element, render)} {...ripple.handlers} {...props} {...styleProps}>\n {buttonContent(children, pendingLabel ?? messages.loading, ripple.surface)}\n </RACButton>;\n}\n\n// What the button draws: its label, hidden while the button is pending, with\n// the ring over it. The ring takes the button's own content colour rather\n// than the progress page's primary, which on a filled button is the fill\n// itself and so invisible. The label stays in the flow so the button keeps its\n// width, which is what stops a form jumping the moment it is submitted.\n// React Aria wants the progress bar in the accessibility tree as soon as the\n// button goes pending, so it is rendered from the render state rather than\n// after a delay.\n//\n// Built by a call rather than written inline at the prop, which is what\n// react-perf's no-new-function-as-prop is after; the React Compiler\n// memoises the result on its inputs.\nfunction buttonContent(children: ReactNode, pendingLabel: string, surface: ReactNode) {\n return (state: ButtonRenderProps) => <>\n <span {...stylex.props(buttonBaseStyles.label, state.isPending && buttonBaseStyles.labelPending)}>\n {children}\n </span>\n {state.isPending ? <span {...stylex.props(buttonBaseStyles.pending)}>\n <ProgressIndicator aria-label={pendingLabel} isIndeterminate size=\"1em\" tone=\"inherit\" variant=\"circular\" />\n </span> : null}\n {surface}\n </>;\n}\n\n/**\n * A toggle drawn with the classes a component hands it: React Aria's\n * `ToggleButton`, which reports its state through `aria-pressed`. It is never\n * a link and never pending — React Aria's toggle takes neither, and neither\n * means anything for a control whose whole job is to report which of two\n * states it is in — so `isPending` reaches it only to keep the ripple off,\n * as it does for the plain button.\n */\nfunction ToggleButtonBase({\n children,\n classes,\n defaultSelected,\n isPending = false,\n isSelected,\n onChange,\n render,\n ...input\n}: ToggleButtonBaseProps) {\n // A selecting ButtonGroup disables its toggles through React Aria's group\n // state, which no prop here carries, so the ripple would stay on in a\n // disabled group and answer a press with an animation. Handed on as the\n // toggle's own `isDisabled`, which is what React Aria makes of it anyway.\n const disabledByGroup = useToggleGroupDisabled(input.id);\n const {\n disabled,\n element,\n props,\n ref,\n ripple\n } = useButtonBase(disabledByGroup ? {\n ...input,\n isDisabled: true\n } : input, isPending);\n return <RACToggleButton defaultSelected={defaultSelected} isDisabled={disabled} isSelected={isSelected} onChange={onChange} ref={ref} render={toggleButtonRenderer(element, toggleRender(render))} {...ripple.handlers} {...props} {...mergeStatefulStyles(classes, props)}>\n {toggleContent(children, ripple.surface)}\n </RACToggleButton>;\n}\n\n// What a toggle draws: its label and the ripple. No pending ring — see\n// ToggleButtonBase. Built by a call for the reason `buttonContent` is.\nfunction toggleContent(children: ReactNode, surface: ReactNode) {\n return () => <>\n {children}\n {surface}\n </>;\n}\n\n// A call site's `render` is written for React Aria's button, whose render\n// state says whether it is pending; a toggle's says nothing of it, and a\n// toggle never is. So the toggle hands that function its own state with\n// `isPending` filled in, which is what lets one `render` prop serve a button\n// whichever element it turns out to be.\nfunction toggleRender(render: RACButtonProps['render']): RACToggleButtonProps['render'] {\n if (render === undefined) {\n return undefined;\n }\n return (props, state) => render(props, {\n ...state,\n isPending: false\n });\n}\nexport type { ButtonDOMProps, ButtonState };\nexport { ButtonBase, ToggleButtonBase };"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["DOMAttributes","ReactNode","RefAttributes","ButtonRenderProps","ClassNameOrFunction","ButtonProps","RACButtonProps","ToggleButtonProps","RACToggleButtonProps","StyleOrFunction","stylex","Button","RACButton","Link","RACLink","ToggleButton","RACToggleButton","ProgressIndicator","useToggleGroupDisabled","useMessages","buttonRenderer","linkRenderer","toggleButtonRenderer","mergeStatefulStyles","useButtonBase","buttonBaseStyles","ButtonBaseProps","children","classes","state","ButtonState","ReturnType","props","className","disableRipple","href","pendingLabel","rel","style","target","ButtonDOMProps","HTMLAnchorElement","HTMLButtonElement","Omit","GlobalEventKey","Pick","HTMLElement","isSelected","Exclude","ToggleButtonBaseProps","defaultSelected","onChange","ButtonBase","t0","$","_c","input","render","t1","isPending","undefined","messages","disabled","element","ref","ripple","t2","styleProps","t3","t4","handlers","surface","t5","loading","t6","buttonContent","t7","label","labelPending","pending","ToggleButtonBase","disabledByGroup","id","isDisabled","toggleRender","toggleContent","_c","RACLink","RACButton","stylex.props","RACToggleButton"],"sources":["../../src/button/index.tsx"],"sourcesContent":["import type { DOMAttributes, ReactNode, RefAttributes } from 'react';\nimport type { ButtonRenderProps, ClassNameOrFunction, ButtonProps as RACButtonProps, ToggleButtonProps as RACToggleButtonProps, StyleOrFunction } from 'react-aria-components';\nimport * as stylex from '@stylexjs/stylex';\nimport { Button as RACButton, Link as RACLink, ToggleButton as RACToggleButton } from 'react-aria-components';\nimport ProgressIndicator from '../components/progress-indicator';\nimport { useToggleGroupDisabled } from '../hooks/useToggleGroupDisabled';\nimport { useMessages } from '../i18n';\nimport { buttonRenderer, linkRenderer, toggleButtonRenderer } from '../render/aria';\nimport { mergeStatefulStyles } from '../styles/merge';\nimport { useButtonBase } from './hooks';\nimport { buttonBaseStyles } from './styles';\n\n// The press-button core Button and IconButton both render through. A button\n// is React Aria's `Button`, its `Link` once given `href`, or its\n// `ToggleButton` once it reports a state, and around each this adds what\n// React Aria leaves out: the ripple, the disabled state a parent's context\n// sets, the `aria-*` props and keyboard handlers it would drop or wrap, and\n// the ring drawn over the label while the button is pending. Each component\n// brings its own classes, as a function of the render state, and the call\n// site's `className` and `style` are merged over them.\n//\n// One module rather than a copy in each, since the copies had already drifted\n// once: IconButton read `ButtonContext` for a parent's disabled state and\n// Button did not. Not a component of the library's own and not exported from\n// the package; see `src/row` for the same arrangement around a list's row.\n\ntype ButtonBaseProps = {\n children?: ReactNode;\n /**\n * The component's own classes, from the render state. The call site's\n * `className` and `style` are merged over them.\n */\n classes: (state: ButtonState) => ReturnType<typeof stylex.props>;\n className?: ClassNameOrFunction<ButtonState>;\n disableRipple?: boolean;\n href?: string;\n pendingLabel?: string;\n rel?: string;\n style?: StyleOrFunction<ButtonState>;\n target?: string;\n} & ButtonDOMProps & RefAttributes<HTMLAnchorElement | HTMLButtonElement>;\n\n// The props a button hands React Aria. React Aria types the global DOM events\n// — pointer, mouse, touch, wheel and the rest — against the element each\n// component renders, and a handler written for a <button> does not type-check\n// against an <a>. The keys are retyped against HTMLElement here so one set of\n// props serves both forms; the events React Aria defines itself (press,\n// focus, keyboard) keep its types, since it hands those its own event objects.\ntype ButtonDOMProps = Omit<RACButtonProps, 'children' | 'className' | 'style' | GlobalEventKey> & Pick<DOMAttributes<HTMLElement>, GlobalEventKey>;\n\n// The render state React Aria's three elements share. A className or style\n// function written against it serves the button, the link and the toggle\n// alike; `isPending` belongs to the button alone, and `isCurrent` to the\n// link, so neither is here. What the button draws while pending is decided\n// in `buttonContent`, which sees React Aria's own state rather than this one.\n//\n// `isSelected` is optional because only the toggle has one: React Aria hands\n// the button and the link a state without it and the toggle a state with\n// it, and a parameter type this wide accepts either.\ntype ButtonState = Pick<ButtonRenderProps, 'isDisabled' | 'isFocused' | 'isFocusVisible' | 'isHovered' | 'isPressed'> & {\n isSelected?: boolean;\n};\ntype GlobalEventKey = Exclude<keyof DOMAttributes<HTMLElement> & keyof RACButtonProps, 'onBlur' | 'onClick' | 'onFocus'>;\ntype ToggleButtonBaseProps = {\n children?: ReactNode;\n /** As for ButtonBase, handed `isSelected` as well. */\n classes: (state: ButtonState) => ReturnType<typeof stylex.props>;\n className?: ClassNameOrFunction<ButtonState>;\n defaultSelected?: boolean;\n disableRipple?: boolean;\n isSelected?: boolean;\n onChange?: (isSelected: boolean) => void;\n style?: StyleOrFunction<ButtonState>;\n} & ButtonDOMProps & RefAttributes<HTMLAnchorElement | HTMLButtonElement>;\n\n/**\n * A button drawn with the classes a component hands it: React Aria's\n * `Button`, or its `Link` given `href`. See the header.\n */\nfunction ButtonBase({\n children,\n classes,\n href,\n isPending = false,\n pendingLabel,\n rel,\n render,\n target,\n ...input\n}: ButtonBaseProps) {\n const messages = useMessages();\n const {\n disabled,\n element,\n props,\n ref,\n ripple\n } = useButtonBase(input, isPending);\n const styleProps = mergeStatefulStyles(classes, props);\n if (href !== undefined) {\n return <RACLink href={href} isDisabled={disabled} ref={ref} rel={rel} render={linkRenderer(element)} target={target} {...ripple.handlers} {...props} {...styleProps}>\n {children}\n {ripple.surface}\n </RACLink>;\n }\n return <RACButton isDisabled={disabled} isPending={isPending} ref={ref} render={buttonRenderer(element, render)} {...ripple.handlers} {...props} {...styleProps}>\n {buttonContent(children, pendingLabel ?? messages.loading, ripple.surface)}\n </RACButton>;\n}\n\n// What the button draws: its label, hidden while the button is pending, with\n// the ring over it. The ring takes the button's own content colour rather\n// than the progress page's primary, which on a filled button is the fill\n// itself and so invisible. The label stays in the flow so the button keeps its\n// width, which is what stops a form jumping the moment it is submitted.\n// React Aria wants the progress bar in the accessibility tree as soon as the\n// button goes pending, so it is rendered from the render state rather than\n// after a delay.\n//\n// Built by a call rather than written inline at the prop, which is what\n// react-perf's no-new-function-as-prop is after; the React Compiler\n// memoises the result on its inputs.\nfunction buttonContent(children: ReactNode, pendingLabel: string, surface: ReactNode) {\n return (state: ButtonRenderProps) => <>\n <span {...stylex.props(buttonBaseStyles.label, state.isPending && buttonBaseStyles.labelPending)}>\n {children}\n </span>\n {state.isPending ? <span {...stylex.props(buttonBaseStyles.pending)}>\n <ProgressIndicator aria-label={pendingLabel} diameter=\"1em\" isIndeterminate tone=\"inherit\" variant=\"circular\" />\n </span> : null}\n {surface}\n </>;\n}\n\n/**\n * A toggle drawn with the classes a component hands it: React Aria's\n * `ToggleButton`, which reports its state through `aria-pressed`. It is never\n * a link and never pending — React Aria's toggle takes neither, and neither\n * means anything for a control whose whole job is to report which of two\n * states it is in — so `isPending` reaches it only to keep the ripple off,\n * as it does for the plain button.\n */\nfunction ToggleButtonBase({\n children,\n classes,\n defaultSelected,\n isPending = false,\n isSelected,\n onChange,\n render,\n ...input\n}: ToggleButtonBaseProps) {\n // A selecting ButtonGroup disables its toggles through React Aria's group\n // state, which no prop here carries, so the ripple would stay on in a\n // disabled group and answer a press with an animation. Handed on as the\n // toggle's own `isDisabled`, which is what React Aria makes of it anyway.\n const disabledByGroup = useToggleGroupDisabled(input.id);\n const {\n disabled,\n element,\n props,\n ref,\n ripple\n } = useButtonBase(disabledByGroup ? {\n ...input,\n isDisabled: true\n } : input, isPending);\n return <RACToggleButton defaultSelected={defaultSelected} isDisabled={disabled} isSelected={isSelected} onChange={onChange} ref={ref} render={toggleButtonRenderer(element, toggleRender(render))} {...ripple.handlers} {...props} {...mergeStatefulStyles(classes, props)}>\n {toggleContent(children, ripple.surface)}\n </RACToggleButton>;\n}\n\n// What a toggle draws: its label and the ripple. No pending ring — see\n// ToggleButtonBase. Built by a call for the reason `buttonContent` is.\nfunction toggleContent(children: ReactNode, surface: ReactNode) {\n return () => <>\n {children}\n {surface}\n </>;\n}\n\n// A call site's `render` is written for React Aria's button, whose render\n// state says whether it is pending; a toggle's says nothing of it, and a\n// toggle never is. So the toggle hands that function its own state with\n// `isPending` filled in, which is what lets one `render` prop serve a button\n// whichever element it turns out to be.\nfunction toggleRender(render: RACButtonProps['render']): RACToggleButtonProps['render'] {\n if (render === undefined) {\n return undefined;\n }\n return (props, state) => render(props, {\n ...state,\n isPending: false\n });\n}\nexport type { ButtonDOMProps, ButtonState };\nexport { ButtonBase, ToggleButtonBase };"],"mappings":"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"}
@@ -11,18 +11,18 @@ import { jsx } from "react/jsx-runtime";
11
11
  */
12
12
  function CollectionLoadMore(t0) {
13
13
  const $ = c(3);
14
- const { label, size } = t0;
14
+ const { diameter, label } = t0;
15
15
  const messages = useMessages();
16
16
  const t1 = label ?? messages.loadingMore;
17
17
  let t2;
18
- if ($[0] !== size || $[1] !== t1) {
18
+ if ($[0] !== diameter || $[1] !== t1) {
19
19
  t2 = /* @__PURE__ */ jsx(ProgressIndicator, {
20
20
  "aria-label": t1,
21
+ diameter,
21
22
  isIndeterminate: true,
22
- size,
23
23
  variant: "circular"
24
24
  });
25
- $[0] = size;
25
+ $[0] = diameter;
26
26
  $[1] = t1;
27
27
  $[2] = t2;
28
28
  } else t2 = $[2];
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["ProgressIndicator","useMessages","CollectionLoadMoreProps","label","size","CollectionLoadMore","t0","$","_c","messages","t1","loadingMore","t2","_c"],"sources":["../../src/collection/index.tsx"],"sourcesContent":["import ProgressIndicator from '../components/progress-indicator'\nimport { useMessages } from '../i18n'\n\ntype CollectionLoadMoreProps = {\n /**\n * What a screen reader announces while the next page is on its way. Left\n * out, it is the I18nProvider's locale's word for it.\n */\n label: string | undefined\n /** The ring's diameter, which follows the row it sits in. */\n size: string\n}\n\n/**\n * The ring a collection shows while it loads more items.\n *\n * Indeterminate and circular in every collection that has one, since none of\n * them knows how many items are still to come.\n */\nfunction CollectionLoadMore({ label, size }: CollectionLoadMoreProps) {\n const messages = useMessages()\n\n return (\n <ProgressIndicator\n aria-label={label ?? messages.loadingMore}\n isIndeterminate\n size={size}\n variant=\"circular\"\n />\n )\n}\n\nexport type { CollectionLoadMoreProps }\nexport { CollectionLoadMore }\n"],"mappings":";;;;;;;;;;;AAmBA,SAAAK,mBAAAC,IAAA;CAAA,MAAAC,IAAAC,EAAA,CAAA;CAA4B,MAAA,EAAAL,OAAAC,SAAAE;CAC1B,MAAAG,WAAiBR,YAAY;CAIb,MAAAS,KAAAP,SAASM,SAAQE;CAAY,IAAAC;CAAA,IAAAL,EAAA,OAAAH,QAAAG,EAAA,OAAAG,IAAA;EAD3CE,KAAA,oBAAC,mBAAD;GACc,cAAAF;GACZ,iBAAA;GACMN;GACE,SAAA;EAAU,CAAA;EAClBG,EAAA,KAAAH;EAAAG,EAAA,KAAAG;EAAAH,EAAA,KAAAK;CAAA,OAAAA,KAAAL,EAAA;CAAA,OALFK;AAKE"}
1
+ {"version":3,"file":"index.js","names":["ProgressIndicator","useMessages","CollectionLoadMoreProps","diameter","label","CollectionLoadMore","t0","$","_c","messages","t1","loadingMore","t2","_c"],"sources":["../../src/collection/index.tsx"],"sourcesContent":["import ProgressIndicator from '../components/progress-indicator'\nimport { useMessages } from '../i18n'\n\ntype CollectionLoadMoreProps = {\n /** The ring's diameter, which follows the row it sits in. */\n diameter: string\n /**\n * What a screen reader announces while the next page is on its way. Left\n * out, it is the I18nProvider's locale's word for it.\n */\n label: string | undefined\n}\n\n/**\n * The ring a collection shows while it loads more items.\n *\n * Indeterminate and circular in every collection that has one, since none of\n * them knows how many items are still to come.\n */\nfunction CollectionLoadMore({ diameter, label }: CollectionLoadMoreProps) {\n const messages = useMessages()\n\n return (\n <ProgressIndicator\n aria-label={label ?? messages.loadingMore}\n diameter={diameter}\n isIndeterminate\n variant=\"circular\"\n />\n )\n}\n\nexport type { CollectionLoadMoreProps }\nexport { CollectionLoadMore }\n"],"mappings":";;;;;;;;;;;AAmBA,SAAAK,mBAAAC,IAAA;CAAA,MAAAC,IAAAC,EAAA,CAAA;CAA4B,MAAA,EAAAL,UAAAC,UAAAE;CAC1B,MAAAG,WAAiBR,YAAY;CAIb,MAAAS,KAAAN,SAASK,SAAQE;CAAY,IAAAC;CAAA,IAAAL,EAAA,OAAAJ,YAAAI,EAAA,OAAAG,IAAA;EAD3CE,KAAA,oBAAC,mBAAD;GACc,cAAAF;GACFP;GACV,iBAAA;GACQ,SAAA;EAAU,CAAA;EAClBI,EAAA,KAAAJ;EAAAI,EAAA,KAAAG;EAAAH,EAAA,KAAAK;CAAA,OAAAA,KAAAL,EAAA;CAAA,OALFK;AAKE"}
@@ -1,21 +1,28 @@
1
1
  //#region src/color-scheme.d.ts
2
+ /**
3
+ * The class that lets an element theme what is inside it. A `--kui-*`
4
+ * override declared on that element, or on one around it, reaches every
5
+ * component rendered inside, where on any element but `<html>` it would
6
+ * otherwise reach none — the tokens resolve on `:root` and are inherited from
7
+ * there already resolved. The scheme is inherited from around it, so a scope
8
+ * inside a dark page stays dark.
9
+ *
10
+ * Overlays are portalled to the body, outside the element, so they keep the
11
+ * page's tokens; `ThemeScope` is the same class with a portal container of
12
+ * its own, which takes them along.
13
+ */
14
+ declare const themeScope: string;
2
15
  /**
3
16
  * The classes that pin the library's colours to its light or its dark
4
17
  * scheme, whatever the reader's OS asks for — for an app with a theme switch
5
18
  * of its own. Put one on the `<html>` element, where overlays portalled to
6
19
  * the body still sit inside it; with neither there, the colours follow the
7
- * OS as they always have.
8
- *
9
- * Shaped as next-themes takes its class names:
10
- *
11
- * ```tsx
12
- * import { ThemeProvider } from 'next-themes'
13
- * import { colorScheme } from '@kanso-labs/kanso-ui'
20
+ * OS as they always have. Each is also a {@link themeScope}, so either on a
21
+ * smaller element pins and scopes the subtree under it.
14
22
  *
15
- * <ThemeProvider attribute="class" value={colorScheme}>
16
- * {children}
17
- * </ThemeProvider>
18
- * ```
23
+ * Shaped as an object of class names, one per scheme. Each name is several
24
+ * classes separated by spaces, so add them with `className` rather than
25
+ * `classList.add`, which takes one class per argument.
19
26
  *
20
27
  * A `--kui-color-*` override still applies under either, declared on the
21
28
  * same element or above it.
@@ -25,5 +32,5 @@ declare const colorScheme: {
25
32
  light: string;
26
33
  };
27
34
  //#endregion
28
- export { colorScheme };
35
+ export { colorScheme, themeScope };
29
36
  //# sourceMappingURL=color-scheme.d.ts.map
@@ -1,32 +1,39 @@
1
1
  import { props } from "./node_modules/@stylexjs/stylex/lib/es/stylex.js";
2
- import { colorsDarkTheme, colorsLightTheme } from "./tokens/design.tokens.stylex.js";
2
+ import { colorDefaultsDarkTheme, colorDefaultsLightTheme, tokenScope } from "./tokens/design.tokens.stylex.js";
3
3
  //#region src/color-scheme.ts
4
4
  /**
5
+ * The class that lets an element theme what is inside it. A `--kui-*`
6
+ * override declared on that element, or on one around it, reaches every
7
+ * component rendered inside, where on any element but `<html>` it would
8
+ * otherwise reach none — the tokens resolve on `:root` and are inherited from
9
+ * there already resolved. The scheme is inherited from around it, so a scope
10
+ * inside a dark page stays dark.
11
+ *
12
+ * Overlays are portalled to the body, outside the element, so they keep the
13
+ * page's tokens; `ThemeScope` is the same class with a portal container of
14
+ * its own, which takes them along.
15
+ */
16
+ const themeScope = props(tokenScope).className ?? "";
17
+ /**
5
18
  * The classes that pin the library's colours to its light or its dark
6
19
  * scheme, whatever the reader's OS asks for — for an app with a theme switch
7
20
  * of its own. Put one on the `<html>` element, where overlays portalled to
8
21
  * the body still sit inside it; with neither there, the colours follow the
9
- * OS as they always have.
10
- *
11
- * Shaped as next-themes takes its class names:
12
- *
13
- * ```tsx
14
- * import { ThemeProvider } from 'next-themes'
15
- * import { colorScheme } from '@kanso-labs/kanso-ui'
22
+ * OS as they always have. Each is also a {@link themeScope}, so either on a
23
+ * smaller element pins and scopes the subtree under it.
16
24
  *
17
- * <ThemeProvider attribute="class" value={colorScheme}>
18
- * {children}
19
- * </ThemeProvider>
20
- * ```
25
+ * Shaped as an object of class names, one per scheme. Each name is several
26
+ * classes separated by spaces, so add them with `className` rather than
27
+ * `classList.add`, which takes one class per argument.
21
28
  *
22
29
  * A `--kui-color-*` override still applies under either, declared on the
23
30
  * same element or above it.
24
31
  */
25
32
  const colorScheme = {
26
- dark: props(colorsDarkTheme).className ?? "",
27
- light: props(colorsLightTheme).className ?? ""
33
+ dark: props(tokenScope, colorDefaultsDarkTheme).className ?? "",
34
+ light: props(tokenScope, colorDefaultsLightTheme).className ?? ""
28
35
  };
29
36
  //#endregion
30
- export { colorScheme };
37
+ export { colorScheme, themeScope };
31
38
 
32
39
  //# sourceMappingURL=color-scheme.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"color-scheme.js","names":["stylex","colorsDarkTheme","colorsLightTheme","colorScheme","dark","props","className","light","stylex.props"],"sources":["../src/color-scheme.ts"],"sourcesContent":["import * as stylex from '@stylexjs/stylex';\nimport { colorsDarkTheme, colorsLightTheme } from './tokens/design.tokens.stylex';\n\n// The library's colours follow the reader's OS through `prefers-color-scheme`\n// unless something says otherwise, and these are what say otherwise. Both\n// classes have always been generated and shipped in the stylesheet, for\n// Storybook's Theme control; nothing in the package named them, so an app\n// with a switch of its own had to restate every colour token under its own\n// selector, twice — dark for a light OS, light for a dark one.\n//\n// A server module like the entry, since it is two strings.\n\n/**\n * The classes that pin the library's colours to its light or its dark\n * scheme, whatever the reader's OS asks for — for an app with a theme switch\n * of its own. Put one on the `<html>` element, where overlays portalled to\n * the body still sit inside it; with neither there, the colours follow the\n * OS as they always have.\n *\n * Shaped as next-themes takes its class names:\n *\n * ```tsx\n * import { ThemeProvider } from 'next-themes'\n * import { colorScheme } from '@kanso-labs/kanso-ui'\n *\n * <ThemeProvider attribute=\"class\" value={colorScheme}>\n * {children}\n * </ThemeProvider>\n * ```\n *\n * A `--kui-color-*` override still applies under either, declared on the\n * same element or above it.\n */\nconst colorScheme = {\n dark: stylex.props(colorsDarkTheme).className ?? '',\n light: stylex.props(colorsLightTheme).className ?? ''\n};\nexport { colorScheme };"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAiCA,MAAMG,cAAc;CAClBC,MAAMJ,MAAaC,eAAe,CAAC,CAACK,aAAa;CACjDC,OAAOP,MAAaE,gBAAgB,CAAC,CAACI,aAAa;AACrD"}
1
+ {"version":3,"file":"color-scheme.js","names":["stylex","colorDefaultsDarkTheme","colorDefaultsLightTheme","tokenScope","themeScope","props","className","colorScheme","dark","light","stylex.props"],"sources":["../src/color-scheme.ts"],"sourcesContent":["import * as stylex from '@stylexjs/stylex';\nimport { colorDefaultsDarkTheme, colorDefaultsLightTheme, tokenScope } from './tokens/design.tokens.stylex';\n\n// The library's tokens resolve once, on `:root`, and follow the reader's OS\n// through `prefers-color-scheme` unless something says otherwise. These are\n// the classes that say otherwise, for a page that cannot or would rather not\n// render `ThemeScope`: `themeScope` resolves every token again on the element\n// it lands on, and each `colorScheme` class does that and pins the scheme\n// too. All three were generated for Storybook first, where the Theme control\n// uses the scheme pair; nothing in the package named them, so an app with a\n// switch of its own had to restate every colour token under its own\n// selector, twice — dark for a light OS, light for a dark one.\n//\n// A server module like the entry, since it is three strings.\n\n/**\n * The class that lets an element theme what is inside it. A `--kui-*`\n * override declared on that element, or on one around it, reaches every\n * component rendered inside, where on any element but `<html>` it would\n * otherwise reach none — the tokens resolve on `:root` and are inherited from\n * there already resolved. The scheme is inherited from around it, so a scope\n * inside a dark page stays dark.\n *\n * Overlays are portalled to the body, outside the element, so they keep the\n * page's tokens; `ThemeScope` is the same class with a portal container of\n * its own, which takes them along.\n */\nconst themeScope = stylex.props(tokenScope).className ?? '';\n\n/**\n * The classes that pin the library's colours to its light or its dark\n * scheme, whatever the reader's OS asks for — for an app with a theme switch\n * of its own. Put one on the `<html>` element, where overlays portalled to\n * the body still sit inside it; with neither there, the colours follow the\n * OS as they always have. Each is also a {@link themeScope}, so either on a\n * smaller element pins and scopes the subtree under it.\n *\n * Shaped as an object of class names, one per scheme. Each name is several\n * classes separated by spaces, so add them with `className` rather than\n * `classList.add`, which takes one class per argument.\n *\n * A `--kui-color-*` override still applies under either, declared on the\n * same element or above it.\n */\nconst colorScheme = {\n dark: stylex.props(tokenScope, colorDefaultsDarkTheme).className ?? '',\n light: stylex.props(tokenScope, colorDefaultsLightTheme).className ?? ''\n};\nexport { colorScheme, themeScope };"],"mappings":";;;;;;;;;;;;;;;AA2BA,MAAMI,aAAaJ,MAAaG,UAAU,CAAC,CAACG,aAAa;;;;;;;;;;;;;;;;AAiBzD,MAAMC,cAAc;CAClBC,MAAMR,MAAaG,YAAYF,sBAAsB,CAAC,CAACK,aAAa;CACpEG,OAAOT,MAAaG,YAAYD,uBAAuB,CAAC,CAACI,aAAa;AACxE"}
@@ -11,14 +11,14 @@ type AppBarProps = Omit<RenderComponentProps<'header'>, 'children'> & {
11
11
  /**
12
12
  * Collapses a flexible bar to the height and headline of the small one, for
13
13
  * a pinned bar over content that has been scrolled. Material Design
14
- * specifies it for the flexible sizes, and without it a pinned `large` costs
14
+ * specifies it for the flexible sizes, and without it a pinned `lg` costs
15
15
  * 152px of the viewport for as long as the page is open.
16
16
  *
17
17
  * Controlled, and for the same reason `scrolled` is: only the app knows
18
18
  * which element scrolls, and how far into it the bar should have finished
19
19
  * collapsing. Usually set from the same handler.
20
20
  *
21
- * Ignored on `small`, which is already the height this collapses to. The
21
+ * Ignored on `sm`, which is already the height this collapses to. The
22
22
  * subtitle goes with the height, since there is no room for a second line
23
23
  * in the small bar.
24
24
  *
@@ -85,17 +85,13 @@ type AppBarProps = Omit<RenderComponentProps<'header'>, 'children'> & {
85
85
  */
86
86
  scrolled?: boolean;
87
87
  /**
88
- * Height and headline size. `medium` and `large` are Material Design's
89
- * flexible bars, which hug their text.
90
- *
91
- * Spelled out rather than the `sm`/`md`/`lg` the rest of the library takes
92
- * — see AGENTS.md, under Prop vocabularies. It predates that rule, and
93
- * renaming a public prop's values is a breaking change of its own rather
94
- * than something to fold into other work.
95
- * @default 'small'
88
+ * Height and headline size, as steps of the library's size scale. `sm` is
89
+ * Material Design's small bar, a fixed 64px; `md` and `lg` are its medium
90
+ * and large flexible bars, which hug their text.
91
+ * @default 'sm'
96
92
  */
97
- size?: 'large' | 'medium' | 'small';
98
- /** A second line under the headline. Makes `medium` and `large` taller. */
93
+ size?: 'lg' | 'md' | 'sm';
94
+ /** A second line under the headline. Makes `md` and `lg` taller. */
99
95
  subtitle?: ReactNode;
100
96
  /** Actions, at the far end. Usually icon buttons. */
101
97
  trailing?: ReactNode;
@@ -104,8 +100,8 @@ type AppBarProps = Omit<RenderComponentProps<'header'>, 'children'> & {
104
100
  * Material Design's app bar: the container at the top of a page carrying its
105
101
  * title, one or two actions, and the way back out.
106
102
  *
107
- * Three sizes. `small` is a fixed 64px bar for a page whose title is a label;
108
- * `medium` and `large` are the flexible bars, which give the headline a larger
103
+ * Three sizes. `sm` is a fixed 64px bar for a page whose title is a label;
104
+ * `md` and `lg` are the flexible bars, which give the headline a larger
109
105
  * type role and grow to fit a subtitle or a headline that wraps.
110
106
  *
111
107
  * It paints its own surface, unlike the layout components, because separating
@@ -10,20 +10,20 @@ import { jsx, jsxs } from "react/jsx-runtime";
10
10
  const HEADLINE_OFFSET = "12px";
11
11
  const DEFAULT_CONTENT_INSET = "16px";
12
12
  const HEIGHTS = {
13
- large: {
13
+ lg: {
14
14
  plain: "120px",
15
15
  withSubtitle: "152px"
16
16
  },
17
- medium: {
17
+ md: {
18
18
  plain: "112px",
19
19
  withSubtitle: "136px"
20
20
  },
21
- small: {
21
+ sm: {
22
22
  plain: "64px",
23
23
  withSubtitle: "64px"
24
24
  }
25
25
  };
26
- const COLLAPSED_HEIGHT = HEIGHTS.small.plain;
26
+ const COLLAPSED_HEIGHT = HEIGHTS.sm.plain;
27
27
  const styles = {
28
28
  root: {
29
29
  k6CgDc: "x12w9bfk",
@@ -52,9 +52,9 @@ const styles = {
52
52
  }
53
53
  };
54
54
  const HEADLINE_VARIANT = {
55
- large: "headlineMedium",
56
- medium: "headlineSmall",
57
- small: "titleLarge"
55
+ lg: "headlineMedium",
56
+ md: "headlineSmall",
57
+ sm: "titleLarge"
58
58
  };
59
59
  const HEADINGS = [
60
60
  "h1",
@@ -87,8 +87,8 @@ const rowStyles = { root: (contentInset, maxInlineSize) => [_temp2, {
87
87
  * Material Design's app bar: the container at the top of a page carrying its
88
88
  * title, one or two actions, and the way back out.
89
89
  *
90
- * Three sizes. `small` is a fixed 64px bar for a page whose title is a label;
91
- * `medium` and `large` are the flexible bars, which give the headline a larger
90
+ * Three sizes. `sm` is a fixed 64px bar for a page whose title is a label;
91
+ * `md` and `lg` are the flexible bars, which give the headline a larger
92
92
  * type role and grow to fit a subtitle or a headline that wraps.
93
93
  *
94
94
  * It paints its own surface, unlike the layout components, because separating
@@ -113,8 +113,8 @@ function AppBar(t0) {
113
113
  const contentMaxInlineSize = t9 === void 0 ? "none" : t9;
114
114
  const headingLevel = t10 === void 0 ? 1 : t10;
115
115
  const scrolled = t12 === void 0 ? false : t12;
116
- const size = t13 === void 0 ? "small" : t13;
117
- const collapse = collapsed && size !== "small";
116
+ const size = t13 === void 0 ? "sm" : t13;
117
+ const collapse = collapsed && size !== "sm";
118
118
  const expandedHeight = subtitle === void 0 || subtitle === null ? HEIGHTS[size].plain : HEIGHTS[size].withSubtitle;
119
119
  const height = collapse ? COLLAPSED_HEIGHT : expandedHeight;
120
120
  t5 = useRender;
@@ -150,7 +150,7 @@ function AppBar(t0) {
150
150
  t18 = headline === void 0 ? null : /* @__PURE__ */ jsx(Text, {
151
151
  className: "x12w9bfk xioksi3 x1nxaspg x1seskgd",
152
152
  render: heading(headingLevel),
153
- variant: collapse ? HEADLINE_VARIANT.small : HEADLINE_VARIANT[size],
153
+ variant: collapse ? HEADLINE_VARIANT.sm : HEADLINE_VARIANT[size],
154
154
  children: headline
155
155
  });
156
156
  $[13] = collapse;