@zylem/ui 0.9.5 → 0.9.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zylem/ui",
3
- "version": "0.9.5",
3
+ "version": "0.9.6",
4
4
  "description": "Design tokens, global styles, and Solid components for Zylem, built with vanilla-extract",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -1,8 +1,8 @@
1
1
  import { Show } from 'solid-js';
2
2
  import ChevronDown from 'lucide-solid/icons/chevron-down';
3
3
  import ChevronUp from 'lucide-solid/icons/chevron-up';
4
- import Dock from 'lucide-solid/icons/dock';
5
4
  import X from 'lucide-solid/icons/x';
5
+ import { Dock } from '../../icons';
6
6
  import { DropdownMenu } from '../DropdownMenu/DropdownMenu';
7
7
 
8
8
  /** Where a panel sits. `float` leaves it free of the top and bottom edges. */
@@ -45,7 +45,7 @@ export function WindowControls(props: WindowControlsProps) {
45
45
  triggerLabel="Dock panel"
46
46
  triggerClass="zylem-window-control zylem-window-control--dock"
47
47
  placement="bottom-end"
48
- trigger={<Dock size={11} strokeWidth={2.5} aria-hidden="true" />}
48
+ trigger={<Dock size={11} aria-hidden="true" />}
49
49
  items={DOCK_OPTIONS.map((option) => ({
50
50
  id: option.id,
51
51
  label: option.label,
@@ -237,10 +237,12 @@ export {
237
237
  Perspective,
238
238
  SideviewPerspective,
239
239
  TopDownPerspective,
240
+ Dock,
240
241
  cameraIconNodes,
241
242
  createZylemIcon,
242
243
  type CameraIcon,
243
244
  type CameraIconName,
244
245
  type IconNode,
246
+ type ZylemIconOptions,
245
247
  type ZylemIconProps,
246
248
  } from '../icons';
@@ -21,6 +21,19 @@ function kebab(name: string): string {
21
21
  return name.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
22
22
  }
23
23
 
24
+ export interface ZylemIconOptions {
25
+ /**
26
+ * Replaces the `zylem-icon` class. Toolbar icons keep that class, which
27
+ * sizes them to 18px; chrome glyphs omit it so `size` wins, the way a
28
+ * Lucide chevron does.
29
+ */
30
+ className?: string;
31
+ /** Draw with `currentColor` fill instead of a stroke. */
32
+ filled?: boolean;
33
+ /** Defaults to the 24×24 Lucide grid. */
34
+ viewBox?: string;
35
+ }
36
+
24
37
  /**
25
38
  * Solid icon factory matching lucide-solid's size / color / strokeWidth
26
39
  * props so these glyphs drop into the same toolbar buttons and CSS.
@@ -28,6 +41,7 @@ function kebab(name: string): string {
28
41
  export function createZylemIcon(
29
42
  name: string,
30
43
  iconNode: IconNode,
44
+ options?: ZylemIconOptions,
31
45
  ): Component<ZylemIconProps> {
32
46
  const Icon: Component<ZylemIconProps> = (props) => {
33
47
  const [local, rest] = splitProps(props, [
@@ -46,17 +60,22 @@ export function createZylemIcon(
46
60
  return width;
47
61
  };
48
62
  const classes = () =>
49
- ['zylem-icon', `zylem-icon-${kebab(name)}`, local.class]
63
+ [options?.className ?? 'zylem-icon', `zylem-icon-${kebab(name)}`, local.class]
50
64
  .filter((value) => Boolean(value))
51
65
  .join(' ');
52
66
 
67
+ const filled = options?.filled === true;
68
+ const paint = () => local.color ?? 'currentColor';
69
+
53
70
  return (
54
71
  <svg
55
72
  {...DEFAULTS}
73
+ viewBox={options?.viewBox ?? DEFAULTS.viewBox}
56
74
  width={size()}
57
75
  height={size()}
58
- stroke={local.color ?? 'currentColor'}
59
- stroke-width={strokeWidth()}
76
+ fill={filled ? paint() : 'none'}
77
+ stroke={filled ? 'none' : paint()}
78
+ stroke-width={filled ? 0 : strokeWidth()}
60
79
  class={classes()}
61
80
  aria-hidden="true"
62
81
  {...rest}
@@ -63,6 +63,16 @@ export const GameCameraNode: IconNode = [
63
63
  ['path', { d: 'M14 10h.01M14 14h.01' }],
64
64
  ];
65
65
 
66
+ /** Filled window frame for the dock control. 16×16, not the 24 stroke grid. */
67
+ export const DockNode: IconNode = [
68
+ [
69
+ 'path',
70
+ {
71
+ d: 'M0 2.75C0 1.784.784 1 1.75 1h12.5c.966 0 1.75.784 1.75 1.75v10.5A1.75 1.75 0 0 1 14.25 15H1.75A1.75 1.75 0 0 1 0 13.25ZM14.5 6h-13v7.25c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25Zm-6-3.5v2h6V2.75a.25.25 0 0 0-.25-.25ZM5 2.5v2h2v-2Zm-3.25 0a.25.25 0 0 0-.25.25V4.5h2v-2Z',
72
+ },
73
+ ],
74
+ ];
75
+
66
76
  export const cameraIconNodes = {
67
77
  perspective: PerspectiveNode,
68
78
  'sideview-perspective': SideviewPerspectiveNode,
@@ -1,6 +1,7 @@
1
1
  import type { Component } from 'solid-js';
2
2
  import { createZylemIcon, type ZylemIconProps } from './create-icon';
3
3
  import {
4
+ DockNode,
4
5
  FreePerspectiveNode,
5
6
  GameCameraNode,
6
7
  IsometricPerspectiveNode,
@@ -19,7 +20,7 @@ export {
19
20
  SideviewPerspectiveNode,
20
21
  TopDownPerspectiveNode,
21
22
  } from './icon-nodes';
22
- export { createZylemIcon, type ZylemIconProps } from './create-icon';
23
+ export { createZylemIcon, type ZylemIconOptions, type ZylemIconProps } from './create-icon';
23
24
 
24
25
  export type CameraIcon = Component<ZylemIconProps>;
25
26
 
@@ -44,6 +45,13 @@ export const FreePerspective = createZylemIcon('FreePerspective', FreePerspectiv
44
45
  /** Recorder with controller buttons (game camera). */
45
46
  export const GameCamera = createZylemIcon('GameCamera', GameCameraNode);
46
47
 
48
+ /** Filled window frame. Skips the 18px toolbar metric so `size` matches a chevron. */
49
+ export const Dock = createZylemIcon('Dock', DockNode, {
50
+ className: 'zylem-dock',
51
+ filled: true,
52
+ viewBox: '0 0 16 16',
53
+ });
54
+
47
55
  export const CAMERA_ICONS = [
48
56
  { name: 'perspective', label: 'Perspective', Icon: Perspective },
49
57
  { name: 'sideview-perspective', label: 'Side view', Icon: SideviewPerspective },