@alexandregme/zljs 1.19.0 → 2.0.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.
package/CHANGELOG.md CHANGED
@@ -8,6 +8,47 @@ A change that needs action in an app has a **Migration** note. When updating, re
8
8
 
9
9
  ## [Unreleased]
10
10
 
11
+ ## [2.0.0] - 2026-11-03
12
+
13
+ ### Added
14
+
15
+ - Auxiliary colors `orange`, `pink` and `purple`, with the `AuxiliaryColor` type and the `--color-zl-<color>` and `--color-zl-<color>-strong` theme values. They have no meaning of their own and only `Tag` takes them
16
+ - `TagColor` type, and `Tag` takes `primary`, `success`, `danger`, `warning`, `info` and `muted`
17
+ - `removeLabel` on `Tag`, to name the remove button when several tags show at once. It defaults to `Remover`
18
+
19
+ ### Changed
20
+
21
+ - `Tag` follows the `--color-zl-*` theme values: its background is the color at 15% and its text is the `-strong` value. Its default color is `primary`, no longer `blue`
22
+ - The remove button of `Tag` takes the text color of the `Tag`, for its icon and its focus outline
23
+
24
+ ### Removed
25
+
26
+ - The `blue`, `green`, `red`, `yellow` and `gray` colors of `Tag`. `orange` stays. `StatsCard` and `DataColor` keep them
27
+
28
+ #### Migration
29
+
30
+ Search the app for `<Tag` and read its props, which can sit on the next lines (`grep -rn -A3 "<Tag"`). Replace `color`: `blue` → `primary`, `green` → `success`, `red` → `danger`, `yellow` → `warning`, `gray` → `muted`. A variable typed `DataColor` that reaches a `Tag` becomes `TagColor`. A test that asserts `bg-*-100` or `text-*-700` on a `Tag` moves to `bg-zl-<color>/15` and `text-zl-<color>-strong`. Don't change `StatsCard`.
31
+
32
+ ## [1.19.1] - 2026-11-03
33
+
34
+ ### Changed
35
+
36
+ - Collapsed `Sidebar` shows only the logout button in its footer. The avatar, name and email come back when it expands, and the footer and the collapse button keep their height in both states, at 64px and 56px
37
+ - The collapse button of `Sidebar` is named by `collapseLabel` while expanded, no longer `Collapse sidebar`, and shows only its icon when collapsed
38
+ - `Sidebar` links have fewer elements and look the same: the `Icon` is a direct child of the link, and the home link has no empty `span` when there is no `homeLabel`
39
+
40
+ #### Migration
41
+
42
+ Search the app's tests for `Collapse sidebar` and replace it with the value the app passes in `collapseLabel`. `Expand sidebar` stays.
43
+
44
+ ### Fixed
45
+
46
+ - Collapsed `Sidebar` can log out with a mouse. The button sat outside the visible area, and focusing it with the keyboard scrolled the sidebar sideways, out of view
47
+ - `Sidebar` links draw their own focus outline in the text color. They relied on the browser's default, which was 2.53:1 in Chromium
48
+ - The active home link of `Sidebar` has `aria-current="page"`, its link is styled like the others, and the avatar initials are hidden from screen readers
49
+ - A long email in `Sidebar` is cut with an ellipsis. It ran under the logout button
50
+ - The icon of the `Sidebar` collapse button lines up with the link icons, so it is centered when collapsed and doesn't move on toggle. It sat 4px to the right
51
+
11
52
  ## [1.19.0] - 2026-11-02
12
53
 
13
54
  ### Added
@@ -282,7 +323,9 @@ Replace the shade with the class of the `color` being tested, for example `/(^|\
282
323
 
283
324
  The message of `Error` is `text-zl-danger`. `none` and `ghost` didn't change.
284
325
 
285
- [Unreleased]: https://github.com/alexandregme/zljs/compare/v1.19.0...HEAD
326
+ [Unreleased]: https://github.com/alexandregme/zljs/compare/v2.0.0...HEAD
327
+ [2.0.0]: https://github.com/alexandregme/zljs/compare/v1.19.1...v2.0.0
328
+ [1.19.1]: https://github.com/alexandregme/zljs/compare/v1.19.0...v1.19.1
286
329
  [1.19.0]: https://github.com/alexandregme/zljs/compare/v1.18.1...v1.19.0
287
330
  [1.18.1]: https://github.com/alexandregme/zljs/compare/v1.18.0...v1.18.1
288
331
  [1.18.0]: https://github.com/alexandregme/zljs/compare/v1.17.0...v1.18.0
package/README.md CHANGED
@@ -58,12 +58,14 @@ The components work with no setup, using the default colors. To use your own, re
58
58
 
59
59
  `primary`, `success`, `danger`, `warning`, `info` and `muted` each take one value (`--color-zl-<color>`), used for text and the focus outline. The others follow it, and you can redefine them too:
60
60
 
61
- | Value | Used for | Default |
62
- | --------------------------- | ---------------------- | ------------------------------------------ |
63
- | `--color-zl-<color>-strong` | Link hover | 30% darker |
64
- | `--color-zl-<color>-bg` | Button background | The color itself (`warning`: `yellow-500`) |
65
- | `--color-zl-<color>-hover` | Button hover | The background, 15% darker |
66
- | `--color-zl-<color>-on` | Text on the background | White (`warning`: `gray-900`) |
61
+ | Value | Used for | Default |
62
+ | --------------------------- | ----------------------- | ------------------------------------------ |
63
+ | `--color-zl-<color>-strong` | Link hover and Tag text | 30% darker |
64
+ | `--color-zl-<color>-bg` | Button background | The color itself (`warning`: `yellow-500`) |
65
+ | `--color-zl-<color>-hover` | Button hover | The background, 15% darker |
66
+ | `--color-zl-<color>-on` | Text on the background | White (`warning`: `gray-900`) |
67
+
68
+ A `Tag` also takes the auxiliary colors `orange`, `pink` and `purple`, which have no meaning of their own: use them to tell categories apart. Each has only `--color-zl-<color>` and `--color-zl-<color>-strong`. The first, at 15%, is the `Tag` background, and the second is its text.
67
69
 
68
70
  Only the defaults are checked for contrast. Check your own choice: 4.5:1 for text, on `--color-zl-<color>` against the page and on `-on` against `-bg`, and 3:1 for the focus outline. A value set on a nested element doesn't reach the values derived from it, so set them in `@theme` or `:root`.
69
71
 
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode, ChangeEvent, FormEvent, HTMLInputAutoCompleteAttribute, FocusEvent, KeyboardEvent, Ref } from 'react';
3
- import { S as SemanticColor, D as DataColor, R as ReduxProviderProps } from './redux-provider.interface-BmROR8Ev.js';
3
+ import { S as SemanticColor, D as DataColor, A as AuxiliaryColor, R as ReduxProviderProps } from './redux-provider.interface-DXOZKAMA.js';
4
4
  export { FormInput, FormInputProps, FormProvider, FormProviderProps } from './rhf/index.js';
5
5
  export { toast } from 'sonner';
6
6
  import * as zustand from 'zustand';
@@ -262,13 +262,15 @@ interface SidebarProps {
262
262
 
263
263
  declare const Sidebar: ({ sections, user, activeHref, defaultCollapsed, collapseLabel, homeHref, homeLabel, onLogout, }: SidebarProps) => react.JSX.Element;
264
264
 
265
+ type TagColor = Exclude<SemanticColor, "none"> | AuxiliaryColor;
265
266
  interface TagProps {
266
267
  children: ReactNode;
267
- color?: DataColor;
268
+ color?: TagColor;
268
269
  onRemove?: () => void;
270
+ removeLabel?: string;
269
271
  }
270
272
 
271
- declare const Tag: ({ children, color, onRemove }: TagProps) => react.JSX.Element;
273
+ declare const Tag: ({ children, color, onRemove, removeLabel, }: TagProps) => react.JSX.Element;
272
274
 
273
275
  declare const Toaster: () => react.JSX.Element;
274
276
 
@@ -465,5 +467,5 @@ declare class HTTPClient {
465
467
  patch<T = unknown>(url: string, config?: HttpRequestConfig): Promise<T | undefined>;
466
468
  }
467
469
 
468
- export { Button, Checkbox, ConnectedModal, DataColor, DataGrid, Error, Form, HTTPClient, Heading, Icon, Input, Loader, Modal, Radio, ReduxProvider, ReduxProviderProps, Select, SemanticColor, Sidebar, Spinner, StatsCard, Tag, Text, TextArea, Toaster, WhatsAppButton, splitURLasPath, useAppStore, useModalStore, usePageStore, useRouterStore, useToastStore };
469
- export type { AppState, ButtonColor, ButtonProps, ButtonVariant, CheckboxProps, CheckboxVariant, ConnectedModalProps, DataGridColumn, DataGridProps, ErrorProps, FormProps, HeadingProps, HttpClientConfig, HttpRequestConfig, IconName, IconProps, InputProps, LoaderProps, ModalEntry, ModalProps, ModalState, PageState, RadioProps, ReduxStore, RouterState, SelectOption, SelectProps, SidebarItem, SidebarProps, SidebarSection, SidebarUser, Size, SpinnerProps, SpinnerVariant, StatsCardProps, TagProps, TextAreaProps, TextProps, TextVariant, Toast, ToastState, ToastType, WhatsAppButtonProps };
470
+ export { AuxiliaryColor, Button, Checkbox, ConnectedModal, DataColor, DataGrid, Error, Form, HTTPClient, Heading, Icon, Input, Loader, Modal, Radio, ReduxProvider, ReduxProviderProps, Select, SemanticColor, Sidebar, Spinner, StatsCard, Tag, Text, TextArea, Toaster, WhatsAppButton, splitURLasPath, useAppStore, useModalStore, usePageStore, useRouterStore, useToastStore };
471
+ export type { AppState, ButtonColor, ButtonProps, ButtonVariant, CheckboxProps, CheckboxVariant, ConnectedModalProps, DataGridColumn, DataGridProps, ErrorProps, FormProps, HeadingProps, HttpClientConfig, HttpRequestConfig, IconName, IconProps, InputProps, LoaderProps, ModalEntry, ModalProps, ModalState, PageState, RadioProps, ReduxStore, RouterState, SelectOption, SelectProps, SidebarItem, SidebarProps, SidebarSection, SidebarUser, Size, SpinnerProps, SpinnerVariant, StatsCardProps, TagColor, TagProps, TextAreaProps, TextProps, TextVariant, Toast, ToastState, ToastType, WhatsAppButtonProps };
package/dist/index.js CHANGED
@@ -502,25 +502,42 @@ var tag = tv7({
502
502
  base: "inline-flex items-center gap-1 px-2 py-0.5 rounded text-xs font-medium",
503
503
  variants: {
504
504
  color: {
505
- blue: "bg-blue-100 text-blue-700",
506
- green: "bg-green-100 text-green-700",
507
- red: "bg-red-100 text-red-700",
508
- yellow: "bg-yellow-100 text-yellow-700",
509
- gray: "bg-slate-100 text-slate-700",
510
- orange: "bg-orange-100 text-orange-700"
505
+ primary: "bg-zl-primary/15 text-zl-primary-strong",
506
+ success: "bg-zl-success/15 text-zl-success-strong",
507
+ danger: "bg-zl-danger/15 text-zl-danger-strong",
508
+ warning: "bg-zl-warning/15 text-zl-warning-strong",
509
+ info: "bg-zl-info/15 text-zl-info-strong",
510
+ muted: "bg-zl-muted/15 text-zl-muted-strong",
511
+ orange: "bg-zl-orange/15 text-zl-orange-strong",
512
+ pink: "bg-zl-pink/15 text-zl-pink-strong",
513
+ purple: "bg-zl-purple/15 text-zl-purple-strong"
511
514
  }
512
515
  },
513
516
  defaultVariants: {
514
- color: "blue"
517
+ color: "primary"
515
518
  }
516
519
  });
517
520
 
518
521
  // core/tag/tag.tsx
519
522
  import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
520
- var Tag = ({ children, color = "blue", onRemove }) => {
523
+ var Tag = ({
524
+ children,
525
+ color = "primary",
526
+ onRemove,
527
+ removeLabel = "Remover"
528
+ }) => {
521
529
  return /* @__PURE__ */ jsxs7("span", { "data-testid": "tag", className: tag({ color }), children: [
522
530
  children,
523
- onRemove && /* @__PURE__ */ jsx8(Button, { size: "sm", icon: "X", "aria-label": "Remover", onClick: onRemove })
531
+ onRemove && /* @__PURE__ */ jsx8(
532
+ Button,
533
+ {
534
+ color: "ghost",
535
+ size: "sm",
536
+ icon: "X",
537
+ "aria-label": removeLabel,
538
+ onClick: onRemove
539
+ }
540
+ )
524
541
  ] });
525
542
  };
526
543
 
@@ -564,7 +581,6 @@ var DataGridStatusBar = ({
564
581
  activeFilters.map((filter) => /* @__PURE__ */ jsxs8(
565
582
  Tag,
566
583
  {
567
- color: "blue",
568
584
  onRemove: () => handleClearFilter(filter.column),
569
585
  children: [
570
586
  /* @__PURE__ */ jsxs8("span", { className: "font-medium", children: [
@@ -829,7 +845,7 @@ import Link from "next/link.js";
829
845
  // core/sidebar/sidebar.styles.ts
830
846
  import { tv as tv10 } from "tailwind-variants";
831
847
  var sidebar = tv10({
832
- base: "h-screen bg-neutral-800 text-neutral-300 flex flex-col overflow-hidden transition-all duration-200",
848
+ base: "h-screen bg-neutral-800 text-neutral-300 flex flex-col overflow-hidden transition-all duration-200 divide-y divide-neutral-600/50",
833
849
  variants: {
834
850
  collapsed: {
835
851
  true: "w-14",
@@ -841,62 +857,52 @@ var sidebar = tv10({
841
857
  }
842
858
  });
843
859
  var nav = tv10({
844
- base: "flex-1 min-h-0 overflow-y-auto overflow-x-hidden"
860
+ base: "flex-1 min-h-0 overflow-y-auto overflow-x-hidden divide-y divide-neutral-600/50"
845
861
  });
846
862
  var header2 = tv10({
847
- base: "shrink-0 border-b border-neutral-600/50 grid p-2"
863
+ base: "shrink-0 p-2"
848
864
  });
849
865
  var section = tv10({
850
- base: "border-b border-neutral-600/50 last:border-b-0 grid gap-1 p-2"
866
+ base: "grid gap-1 p-2"
851
867
  });
852
868
  var item = tv10({
853
- base: "flex w-full items-center rounded-md text-sm whitespace-nowrap transition-colors cursor-pointer p-1",
869
+ // [&>*+*] is the label: Text takes no className, and the icon comes first, so a link with no label has nothing to hide.
870
+ base: "flex items-center rounded-md transition-colors h-10 px-3 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-current [&>*+*]:truncate [&>*+*]:transition-all [&>*+*]:duration-200",
854
871
  variants: {
855
872
  active: {
856
873
  true: "bg-neutral-700 text-white",
857
874
  false: "text-neutral-400 hover:bg-neutral-700/50 hover:text-white"
875
+ },
876
+ collapsed: {
877
+ true: "[&>*+*]:w-0 [&>*+*]:opacity-0",
878
+ false: "[&>*+*]:ml-2 [&>*+*]:opacity-100"
858
879
  }
859
880
  },
860
881
  defaultVariants: {
861
- active: false
882
+ active: false,
883
+ collapsed: false
862
884
  }
863
885
  });
864
- var itemIcon = tv10({
865
- base: "p-2"
866
- });
867
- var itemLabel = tv10({
868
- base: "truncate transition-all duration-200",
886
+ var footer = tv10({
887
+ base: "shrink-0 h-16 p-3 flex items-center gap-3",
869
888
  variants: {
870
889
  collapsed: {
871
- true: "opacity-0 w-0",
872
- false: "opacity-100"
890
+ true: "justify-center"
873
891
  }
874
- },
875
- defaultVariants: {
876
- collapsed: false
877
892
  }
878
893
  });
879
- var footer = tv10({
880
- base: "shrink-0 border-t border-neutral-600/50 p-3 flex items-center gap-3 whitespace-nowrap"
881
- });
882
894
  var avatar = tv10({
883
- base: "shrink-0 w-8 h-8 rounded-full bg-neutral-600 text-white text-xs font-medium flex items-center justify-center"
895
+ base: "shrink-0 size-8 rounded-full bg-neutral-600 text-white text-xs font-medium flex items-center justify-center"
884
896
  });
885
897
  var userInfo = tv10({
886
- base: "flex flex-col min-w-0"
887
- });
888
- var userName = tv10({
889
- base: "text-sm text-white truncate"
890
- });
891
- var userEmail = tv10({
892
- base: "text-xs text-neutral-400"
898
+ base: "flex flex-col min-w-0 text-white [&>*]:truncate [&>*:last-child]:text-xs [&>*:last-child]:text-neutral-400"
893
899
  });
894
900
  var toggleButton = tv10({
895
- base: "shrink-0 border-t border-neutral-600/50 grid p-2 [&>button]:justify-start [&>button]:overflow-hidden [&>button]:whitespace-nowrap"
901
+ base: "shrink-0 h-14 grid p-2 [&>button]:justify-start [&>button]:px-3 [&>button]:overflow-hidden [&>button]:whitespace-nowrap"
896
902
  });
897
903
 
898
904
  // core/sidebar/sidebar.tsx
899
- import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
905
+ import { Fragment as Fragment3, jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
900
906
  var getInitials = (name) => {
901
907
  const parts = name.trim().split(/\s+/);
902
908
  if (parts.length >= 2) {
@@ -917,39 +923,42 @@ var Sidebar = ({
917
923
  const [collapsed, setCollapsed] = useState3(defaultCollapsed);
918
924
  const initials = getInitials(user.name);
919
925
  return /* @__PURE__ */ jsxs12("aside", { className: sidebar({ collapsed }), children: [
920
- homeHref && /* @__PURE__ */ jsx14(
926
+ homeHref && /* @__PURE__ */ jsx14("div", { className: header2(), children: /* @__PURE__ */ jsxs12(
921
927
  Link,
922
928
  {
923
929
  href: homeHref,
924
- className: header2(),
930
+ className: item({ active: homeHref === activeHref, collapsed }),
925
931
  "aria-label": homeLabel || "Home",
926
- children: /* @__PURE__ */ jsxs12("span", { className: item({ active: homeHref === activeHref }), children: [
927
- /* @__PURE__ */ jsx14("span", { className: itemIcon(), children: /* @__PURE__ */ jsx14(Icon, { name: "Home" }) }),
928
- /* @__PURE__ */ jsx14("span", { className: itemLabel({ collapsed }), children: homeLabel })
929
- ] })
932
+ ...homeHref === activeHref && { "aria-current": "page" },
933
+ children: [
934
+ /* @__PURE__ */ jsx14(Icon, { name: "Home" }),
935
+ homeLabel && /* @__PURE__ */ jsx14(Text, { as: "span", variant: "caption", children: homeLabel })
936
+ ]
930
937
  }
931
- ),
938
+ ) }),
932
939
  /* @__PURE__ */ jsx14("nav", { "aria-label": "Main navigation", className: nav(), children: sections.map((sectionData, i) => /* @__PURE__ */ jsx14("div", { className: section(), children: sectionData.items.map((sidebarItem) => {
933
940
  const isActive = sidebarItem.href === activeHref;
934
941
  return /* @__PURE__ */ jsxs12(
935
942
  Link,
936
943
  {
937
944
  href: sidebarItem.href,
938
- className: item({ active: isActive }),
945
+ className: item({ active: isActive, collapsed }),
939
946
  ...isActive && { "aria-current": "page" },
940
947
  children: [
941
- /* @__PURE__ */ jsx14("span", { className: itemIcon(), children: /* @__PURE__ */ jsx14(Icon, { name: sidebarItem.icon }) }),
942
- /* @__PURE__ */ jsx14("span", { className: itemLabel({ collapsed }), children: sidebarItem.label })
948
+ /* @__PURE__ */ jsx14(Icon, { name: sidebarItem.icon }),
949
+ /* @__PURE__ */ jsx14(Text, { as: "span", variant: "caption", children: sidebarItem.label })
943
950
  ]
944
951
  },
945
952
  sidebarItem.href
946
953
  );
947
954
  }) }, i)) }),
948
- /* @__PURE__ */ jsxs12("div", { className: footer(), children: [
949
- /* @__PURE__ */ jsx14("div", { className: avatar(), children: initials }),
950
- /* @__PURE__ */ jsxs12("div", { className: userInfo(), children: [
951
- /* @__PURE__ */ jsx14("span", { className: userName(), children: user.name }),
952
- /* @__PURE__ */ jsx14("span", { className: userEmail(), children: user.email })
955
+ /* @__PURE__ */ jsxs12("div", { className: footer({ collapsed }), children: [
956
+ !collapsed && /* @__PURE__ */ jsxs12(Fragment3, { children: [
957
+ /* @__PURE__ */ jsx14("div", { "aria-hidden": "true", className: avatar(), children: initials }),
958
+ /* @__PURE__ */ jsxs12("div", { className: userInfo(), children: [
959
+ /* @__PURE__ */ jsx14(Text, { as: "span", variant: "caption", children: user.name }),
960
+ /* @__PURE__ */ jsx14(Text, { as: "span", variant: "caption", children: user.email })
961
+ ] })
953
962
  ] }),
954
963
  /* @__PURE__ */ jsx14(
955
964
  Button,
@@ -964,11 +973,12 @@ var Sidebar = ({
964
973
  /* @__PURE__ */ jsx14("div", { className: toggleButton(), children: /* @__PURE__ */ jsx14(
965
974
  Button,
966
975
  {
976
+ variant: "default",
967
977
  color: "ghost",
968
978
  icon: collapsed ? "ChevronRight" : "ChevronLeft",
969
- "aria-label": collapsed ? "Expand sidebar" : "Collapse sidebar",
979
+ "aria-label": collapsed ? "Expand sidebar" : void 0,
970
980
  onClick: () => setCollapsed(!collapsed),
971
- children: collapseLabel
981
+ children: collapsed ? void 0 : collapseLabel
972
982
  }
973
983
  ) })
974
984
  ] });
@@ -9,6 +9,10 @@ type SemanticColor = "primary" | "success" | "danger" | "warning" | "info" | "mu
9
9
  * Literal colors for data visualization components (StatsCard, etc.)
10
10
  */
11
11
  type DataColor = "blue" | "red" | "yellow" | "green" | "gray" | "orange";
12
+ /**
13
+ * Extra colors with no meaning of their own, to tell categories apart (Tag)
14
+ */
15
+ type AuxiliaryColor = "orange" | "pink" | "purple";
12
16
 
13
17
  interface ReduxProviderProps {
14
18
  children: ReactNode;
@@ -18,4 +22,4 @@ interface ReduxProviderProps {
18
22
  coreReducers?: Record<string, Reducer>;
19
23
  }
20
24
 
21
- export type { DataColor as D, ReduxProviderProps as R, SemanticColor as S };
25
+ export type { AuxiliaryColor as A, DataColor as D, ReduxProviderProps as R, SemanticColor as S };
@@ -3,12 +3,17 @@
3
3
  the styles. Only the defaults are checked for contrast.
4
4
 
5
5
  Each color has five values, and the others follow the first unless redefined:
6
- --color-zl-<color> text and focus outline
7
- --color-zl-<color>-strong link hover
6
+ --color-zl-<color> text, focus outline and tag background, at 15%
7
+ --color-zl-<color>-strong link hover and tag text
8
8
  --color-zl-<color>-bg button background
9
9
  --color-zl-<color>-hover button hover
10
10
  --color-zl-<color>-on text on the background
11
11
 
12
+ The auxiliary colors (orange, pink, purple) have no meaning of their own. Tag
13
+ is their only user, so they have two values:
14
+ --color-zl-<color> tag background, at 15%
15
+ --color-zl-<color>-strong tag text
16
+
12
17
  Prettier is off for this block to keep one value per line. */
13
18
 
14
19
  /* prettier-ignore */
@@ -54,4 +59,16 @@
54
59
  --color-zl-muted-bg: var(--color-zl-muted);
55
60
  --color-zl-muted-hover: color-mix(in oklab, var(--color-zl-muted-bg), black 15%);
56
61
  --color-zl-muted-on: var(--color-white);
62
+
63
+ /* Orange */
64
+ --color-zl-orange: var(--color-orange-700);
65
+ --color-zl-orange-strong: color-mix(in oklab, var(--color-zl-orange), black 30%);
66
+
67
+ /* Pink */
68
+ --color-zl-pink: var(--color-pink-700);
69
+ --color-zl-pink-strong: color-mix(in oklab, var(--color-zl-pink), black 30%);
70
+
71
+ /* Purple */
72
+ --color-zl-purple: var(--color-purple-700);
73
+ --color-zl-purple-strong: color-mix(in oklab, var(--color-zl-purple), black 30%);
57
74
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alexandregme/zljs",
3
- "version": "1.19.0",
3
+ "version": "2.0.0",
4
4
  "description": "Opinionated, accessible React component library for enterprise apps (Next.js, Tailwind CSS v4).",
5
5
  "keywords": [
6
6
  "react",