@alacris/ui 0.5.2 → 0.6.1

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.
package/README.md CHANGED
@@ -47,9 +47,9 @@ The published package is plain ESM. Point an import map at a pinned CDN build of
47
47
  {
48
48
  "imports": {
49
49
  "@alacris/core": "https://cdn.jsdelivr.net/npm/@alacris/core@0.11.5/dist/alacris.js",
50
- "@alacris/ui": "https://cdn.jsdelivr.net/npm/@alacris/ui@0.5.2/src/index.js",
51
- "@alacris/ui/theme": "https://cdn.jsdelivr.net/npm/@alacris/ui@0.5.2/src/theme/index.js",
52
- "@alacris/ui/components/": "https://cdn.jsdelivr.net/npm/@alacris/ui@0.5.2/src/components/"
50
+ "@alacris/ui": "https://cdn.jsdelivr.net/npm/@alacris/ui@0.6.1/src/index.js",
51
+ "@alacris/ui/theme": "https://cdn.jsdelivr.net/npm/@alacris/ui@0.6.1/src/theme/index.js",
52
+ "@alacris/ui/components/": "https://cdn.jsdelivr.net/npm/@alacris/ui@0.6.1/src/components/"
53
53
  }
54
54
  }
55
55
  </script>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alacris/ui",
3
- "version": "0.5.2",
3
+ "version": "0.6.1",
4
4
  "description": "Themeable design system for Alacris — Material defaults, sixty-nine custom elements, ESM-only, no build step.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -21,6 +21,79 @@ export const base = css`
21
21
  animation-iteration-count: 1;
22
22
  }
23
23
  }
24
+ @media (hover: hover) and (pointer: fine) {
25
+ :host, *, *::before, *::after {
26
+ scrollbar-width: thin;
27
+ scrollbar-color: ${sys.scrollbar.thumb} ${sys.scrollbar.track};
28
+ }
29
+ ::-webkit-scrollbar {
30
+ inline-size: ${sys.scrollbar.size};
31
+ block-size: ${sys.scrollbar.size};
32
+ }
33
+ ::-webkit-scrollbar-track {
34
+ background: ${sys.scrollbar.track};
35
+ }
36
+ ::-webkit-scrollbar-thumb {
37
+ background-color: ${sys.scrollbar.thumb};
38
+ border-radius: ${sys.scrollbar.radius};
39
+ border: 2px solid transparent;
40
+ background-clip: content-box;
41
+ }
42
+ ::-webkit-scrollbar-thumb:hover {
43
+ background-color: ${sys.scrollbar.thumbHover};
44
+ }
45
+ ::-webkit-scrollbar-thumb:active {
46
+ background-color: ${sys.scrollbar.thumbActive};
47
+ }
48
+ ::-webkit-scrollbar-corner {
49
+ background: transparent;
50
+ }
51
+ ::-webkit-scrollbar-button {
52
+ display: none;
53
+ inline-size: 0;
54
+ block-size: 0;
55
+ }
56
+ }
57
+ `;
58
+
59
+ /**
60
+ * Custom scrollbar rules for a specific selector.
61
+ * Interpolate into a component's css template.
62
+ */
63
+ export const scrollbarOn = (selector) => `
64
+ @media (hover: hover) and (pointer: fine) {
65
+ ${selector} {
66
+ scrollbar-width: thin;
67
+ scrollbar-color: var(--ui-scrollbar-thumb) var(--ui-scrollbar-track);
68
+ }
69
+ ${selector}::-webkit-scrollbar {
70
+ inline-size: var(--ui-scrollbar-size);
71
+ block-size: var(--ui-scrollbar-size);
72
+ }
73
+ ${selector}::-webkit-scrollbar-track {
74
+ background: var(--ui-scrollbar-track);
75
+ }
76
+ ${selector}::-webkit-scrollbar-thumb {
77
+ background-color: var(--ui-scrollbar-thumb);
78
+ border-radius: var(--ui-scrollbar-radius);
79
+ border: 2px solid transparent;
80
+ background-clip: content-box;
81
+ }
82
+ ${selector}::-webkit-scrollbar-thumb:hover {
83
+ background-color: var(--ui-scrollbar-thumb-hover);
84
+ }
85
+ ${selector}::-webkit-scrollbar-thumb:active {
86
+ background-color: var(--ui-scrollbar-thumb-active);
87
+ }
88
+ ${selector}::-webkit-scrollbar-corner {
89
+ background: transparent;
90
+ }
91
+ ${selector}::-webkit-scrollbar-button {
92
+ display: none;
93
+ inline-size: 0;
94
+ block-size: 0;
95
+ }
96
+ }
24
97
  `;
25
98
 
26
99
  /**
@@ -44,3 +117,4 @@ export const stateLayerOn = (host, { focus = host } = {}) => `
44
117
  ${focus}:focus-visible .layer { opacity: var(--ui-state-focus); }
45
118
  ${host}:active .layer { opacity: var(--ui-state-pressed); }
46
119
  `;
120
+
@@ -9,7 +9,8 @@
9
9
  // Distinct from <ui-drawer> (navigation) and <ui-sheet> (bottom). Modal
10
10
  // (default): a scrim plus a panel that slides in from the end edge. Focus is
11
11
  // trapped and page scroll locked while open. The PARENT owns `open`. Standard:
12
- // an in-flow panel that animates its inline size — no scrim, no trap.
12
+ // an in-flow panel that animates its inline size — no scrim, no trap — with
13
+ // the same headline, close button and actions area as the modal sheet.
13
14
  //
14
15
  // @prop {boolean} open=false
15
16
  // @prop {string} variant='modal' — modal | standard
@@ -119,6 +120,7 @@ const styles = css`
119
120
 
120
121
  .std {
121
122
  display: block;
123
+ block-size: 100%;
122
124
  inline-size: 0;
123
125
  overflow: hidden;
124
126
  background: ${t.bg};
@@ -126,7 +128,12 @@ const styles = css`
126
128
  transition: inline-size ${sys.duration.medium2} ${sys.easing.emphasized};
127
129
  }
128
130
  .std.open { inline-size: ${t.width}; }
129
- .std-inner { inline-size: ${t.width}; }
131
+ .std-inner {
132
+ display: flex;
133
+ flex-direction: column;
134
+ inline-size: ${t.width};
135
+ block-size: 100%;
136
+ }
130
137
  `;
131
138
 
132
139
  define('ui-side-sheet', {
@@ -306,8 +313,13 @@ define('ui-side-sheet', {
306
313
  ref=${(el) => hasSlot(el.querySelector('slot'), (has) => hasHeadline.set(has))}>
307
314
  <slot name="headline"></slot>
308
315
  </div>
316
+ <ui-icon-button icon="close" label="Close" @click=${() => requestClose('method')}></ui-icon-button>
309
317
  </div>
310
318
  <div class="body" part="body"><slot></slot></div>
319
+ <div class="actions" part="actions"
320
+ ref=${(el) => hasSlot(el.querySelector('slot'), (has) => el.classList.toggle('has', has))}>
321
+ <slot name="actions"></slot>
322
+ </div>
311
323
  </div>
312
324
  </aside>`
313
325
  : null}
package/src/index.js CHANGED
@@ -36,6 +36,7 @@ export {
36
36
  processTable, filterRows, sortRows, groupRows, paginate,
37
37
  aggregateRow, toCsv, downloadText, inferColumns, visibleColumns,
38
38
  } from './util/table.js';
39
+ export { base, scrollbarOn, focusRingOn, stateLayerOn } from './components/base.js';
39
40
 
40
41
  // Components — importing registers the custom element.
41
42
  import './components/ui-icon.js';
@@ -27,12 +27,49 @@ const block = (tokens) => {
27
27
  // plain typeface. Components then set a type-role shorthand on top.
28
28
  const FACE = 'font-family:var(--ui-font-plain);font-optical-sizing:auto;font-synthesis:none;';
29
29
 
30
+ const SCROLLBAR = [
31
+ '@media (hover: hover) and (pointer: fine) {',
32
+ ' :root, html, body {',
33
+ ' scrollbar-width: thin;',
34
+ ' scrollbar-color: var(--ui-scrollbar-thumb) var(--ui-scrollbar-track);',
35
+ ' }',
36
+ ' ::-webkit-scrollbar {',
37
+ ' inline-size: var(--ui-scrollbar-size);',
38
+ ' block-size: var(--ui-scrollbar-size);',
39
+ ' }',
40
+ ' ::-webkit-scrollbar-track {',
41
+ ' background: var(--ui-scrollbar-track);',
42
+ ' }',
43
+ ' ::-webkit-scrollbar-thumb {',
44
+ ' background-color: var(--ui-scrollbar-thumb);',
45
+ ' border-radius: var(--ui-scrollbar-radius);',
46
+ ' border: 2px solid transparent;',
47
+ ' background-clip: content-box;',
48
+ ' }',
49
+ ' ::-webkit-scrollbar-thumb:hover {',
50
+ ' background-color: var(--ui-scrollbar-thumb-hover);',
51
+ ' }',
52
+ ' ::-webkit-scrollbar-thumb:active {',
53
+ ' background-color: var(--ui-scrollbar-thumb-active);',
54
+ ' }',
55
+ ' ::-webkit-scrollbar-corner {',
56
+ ' background: transparent;',
57
+ ' }',
58
+ ' ::-webkit-scrollbar-button {',
59
+ ' display: none;',
60
+ ' inline-size: 0;',
61
+ ' block-size: 0;',
62
+ ' }',
63
+ '}',
64
+ ].join('\n');
65
+
30
66
  export function themeCss(theme) {
31
67
  const { common, schemes } = theme;
32
68
  return [
33
69
  `:root{${FACE}${block(common)}${block(schemes.light)}}`,
34
70
  `:root[data-ui-scheme="dark"]{${block(schemes.dark)}}`,
35
71
  `@media (prefers-color-scheme: dark){:root:not([data-ui-scheme="light"]){${block(schemes.dark)}}}`,
72
+ SCROLLBAR,
36
73
  ].join('\n');
37
74
  }
38
75
 
@@ -11,7 +11,7 @@ import { makePalettes, makeScheme, COLOR_ROLES } from '../tokens/color.js';
11
11
  import { typographyTokens, resolveTypography } from '../tokens/typography.js';
12
12
  import {
13
13
  shapeTokens, elevationTokens, motionTokens, spacingTokens,
14
- stateTokens, focusTokens, zTokens, densityTokens,
14
+ stateTokens, focusTokens, zTokens, densityTokens, scrollbarTokens,
15
15
  } from '../tokens/system.js';
16
16
 
17
17
  const kebab = (s) => s.replace(/[A-Z]/g, (c) => '-' + c.toLowerCase());
@@ -47,6 +47,7 @@ export function createTheme(config = {}) {
47
47
  ...focusTokens(),
48
48
  ...zTokens(),
49
49
  ...densityTokens(config),
50
+ ...scrollbarTokens(),
50
51
  ...(config.overrides?.common || {}),
51
52
  };
52
53
 
@@ -9,6 +9,7 @@ export {
9
9
  } from './typography.js';
10
10
  export {
11
11
  shapeTokens, elevationTokens, motionTokens, spacingTokens, stateTokens,
12
- focusTokens, zTokens, densityTokens, RADIUS_KEYS, ELEVATION_LEVELS,
12
+ focusTokens, zTokens, densityTokens, scrollbarTokens, RADIUS_KEYS, ELEVATION_LEVELS,
13
13
  DURATIONS, EASINGS, SPACE_STEPS,
14
14
  } from './system.js';
15
+
package/src/tokens/sys.js CHANGED
@@ -69,6 +69,14 @@ export const sys = {
69
69
  snackbar: v('z-snackbar'),
70
70
  tooltip: v('z-tooltip'),
71
71
  },
72
+ scrollbar: {
73
+ thumb: v('scrollbar-thumb'),
74
+ thumbHover: v('scrollbar-thumb-hover'),
75
+ thumbActive: v('scrollbar-thumb-active'),
76
+ track: v('scrollbar-track'),
77
+ size: v('scrollbar-size'),
78
+ radius: v('scrollbar-radius'),
79
+ },
72
80
  density: 'var(--ui-density, 0)',
73
81
  };
74
82
 
@@ -113,3 +113,17 @@ export function zTokens() {
113
113
  export function densityTokens({ density = 0 } = {}) {
114
114
  return { density: String(Math.max(-2, Math.min(0, density))) };
115
115
  }
116
+
117
+ // ---------------------------------------------------------------- scrollbar
118
+
119
+ export function scrollbarTokens() {
120
+ return {
121
+ 'scrollbar-size': '8px',
122
+ 'scrollbar-radius': 'var(--ui-radius-full)',
123
+ 'scrollbar-track': 'transparent',
124
+ 'scrollbar-thumb': 'var(--ui-color-outline-variant)',
125
+ 'scrollbar-thumb-hover': 'var(--ui-color-outline)',
126
+ 'scrollbar-thumb-active': 'var(--ui-color-on-surface-variant)',
127
+ };
128
+ }
129
+
package/types/index.d.ts CHANGED
@@ -1,6 +1,4 @@
1
- // Hand-written types for @alacris/ui. They track starter/src/index.js and the
2
- // theme / motion / token / util entry points — not generated.
3
- import type { Signal, Computed, Template } from '@alacris/core';
1
+ import type { Signal, Computed, Template, Sheet } from '@alacris/core';
4
2
  import './elements.js';
5
3
 
6
4
  export type Scheme = 'light' | 'dark';
@@ -60,6 +58,7 @@ export const sys: {
60
58
  state: Record<string, string>;
61
59
  focus: Record<string, string>;
62
60
  z: Record<string, string>;
61
+ scrollbar: Record<string, string>;
63
62
  density: string;
64
63
  };
65
64
  export function typeRule(role: string): string;
@@ -190,3 +189,10 @@ export function showSnackbar(
190
189
  message: string,
191
190
  opts?: { action?: string; duration?: number; closeButton?: boolean }
192
191
  ): { close: () => void; closed: Promise<void> };
192
+
193
+ export const base: Sheet;
194
+ export function scrollbarOn(selector: string): string;
195
+ export function focusRingOn(selector: string): string;
196
+ export function stateLayerOn(host: string, opts?: { focus?: string }): string;
197
+ export function scrollbarTokens(): Record<string, string>;
198
+